2
* Packet driver interface for Gero's bootstrap IP/TFTP and
3
* Linux ethernet driver environment of the other side.
4
* This is developed for the context of Proll.
7
#include <general.h> /* __P() */
8
#include <net.h> /* ETH_ALEN for netpriv.h */
9
#include <romlib.h> /* printk() */
10
#include "./netpriv.h" /* Our own protos */
12
#define ETH_FRAME_MIN (ETH_DATA_MIN + ETH_HLEN) /* Min. bytes in frame w/o FCS*/
13
#define ETH_FRAME_MAX (ETH_DATA_MAX + ETH_HLEN) /* Max. bytes in frame w/o FCS*/
14
#define ETH_BUF_SIZE (ETH_FRAME_MAX + ETH_FLEN) /* Buffer size includes FCS */
23
static struct treg tregv[MAXTYPES];
25
#define MAXSKBS 35 /* hme: 32, then some */
26
#define SKBLN (1536) /* hme wants ETH_FRAME_LEN + 2, aligned to 64 */
34
static char skb_rbuf[64 + MAXSKBS*SKBLN];
35
static struct skb_ent skev[MAXSKBS];
37
static struct device *eth0;
40
unsigned char s[ETH_BUF_SIZE + 4];
43
static struct sk_buff *rskb;
52
printk("init_packet: no eth0\n");
56
memcpy(myhwaddr, eth0->dev_addr, ETH_ALEN);
57
if ((*eth0->open)(eth0) != 0) {
58
printk("init_packet: eth0 open error\n");
62
for (i = 0; i < MAXSKBS; i++) {
63
skev[i].skb.allocn = i;
67
unsigned char *reg_type(int ptype, int (*func)())
74
if (n >= MAXTYPES) return 0;
75
if (tp->type == ptype) break;
76
if (tp->func == 0) break;
84
int write_packet(int leng, int type, unsigned char *dst)
95
if (n >= MAXTYPES) return -1;
96
if (tp->type == ptype) break;
101
if ((skb = dev_alloc_skb(14+leng)) == 0) {
102
printk("write_packet: no skb %d\n", leng);
105
s = (unsigned char *)skb->data;
107
bcopy(dst, s+0, ETH_ALEN);
108
bcopy(myhwaddr, s+6, ETH_ALEN);
111
bcopy(wbuf.s, s+14, leng);
112
skb->len = 14 + leng;
114
if ((*eth0->hard_start_xmit)(skb, eth0) != 0) {
115
printk("write_packet: tranmission error\n");
131
/* P3 */ printk("empty_buf: already free\n");
136
* Hardware driver registers with us.
138
void ether_setup(struct device *dev) {
141
printk("Duplicate ether_setup\n");
148
struct sk_buff *dev_alloc_skb(unsigned int size)
151
struct skb_ent *skep;
154
printk("dev_alloc_skb: too long (%d)\n", size);
159
for (i = 0; i < MAXSKBS; i++) {
162
skep->skb.data = (char *)
163
(((unsigned)skb_rbuf + 63) & (~63)) + i*SKBLN;
165
/* skep->skb.truesize = size; */
167
skep->skb.protocol = 0;
176
void dev_kfree_skb(struct sk_buff *skb) {
179
if (skev[x].queued) {
180
/* P3 */ printk("kfree_skb: %d was queued\n", x);
185
void skb_reserve(struct sk_buff *skb, unsigned int len) {
190
* Add data to an sk_buff
192
unsigned char *skb_put(struct sk_buff *skb, unsigned int len) {
193
char *p = skb->data + skb->len;
194
if ((skb->len += len) > SKBLN) {
195
printk("skb_put: too long (+%d %d)\n", len, skb->len);
203
void skb_trim(struct sk_buff *skb, unsigned int len) {
204
if (skb->len > len) {
212
eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int len, int base)
214
bcopy(src, dest->data, len);
217
unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev)
219
unsigned char *s = skb->data + 12;
220
return s[0] << 8 | s[1]; /* Network order word */
223
void netif_rx(struct sk_buff *skb)
227
struct skb_ent *skep;
232
skev[skb->allocn].queued = 1;
238
for (i = 0, skep = skev; i < MAXSKBS; i++, skep++) {
239
if (nqskb == 0 || rskb != 0) /* Optimize || deferred */
251
for (n = 0, tp = tregv; n < MAXTYPES; n++, tp++) {
252
if (tp->type == skb->protocol && tp->func != 0)
256
#if 1 /* Useful. Comment it out for busy networks. */
257
printk("netif_rx: dropping type %x, no func\n",
265
if ((*tp->func)(skb->data + ETH_HLEN,
266
skb->len - ETH_HLEN, skb->data+6) == 0) {
277
unsigned int ld4(void *ptr) {
278
unsigned char *s = ptr;
279
return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
282
void st4(void *ptr, unsigned int n) {
283
unsigned char *s = ptr;
284
s[0] = n >> 24; s[1] = n >> 16; s[2] = n >> 8; s[3] = n;