1 /* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
4 * Ethernet portion of AoE driver
7 #include <linux/hdreg.h>
8 #include <linux/blkdev.h>
9 #include <linux/netdevice.h>
14 static char *aoe_errlist
[] =
17 "unrecognized command code",
18 "bad argument parameter",
20 "config string present",
28 static char aoe_iflist
[IFLISTSZ
];
31 is_aoe_netif(struct net_device
*ifp
)
36 if (aoe_iflist
[0] == '\0')
39 for (p
= aoe_iflist
; *p
; p
= q
+ strspn(q
, WHITESPACE
)) {
40 q
= p
+ strcspn(p
, WHITESPACE
);
44 len
= strlen(p
); /* last token in aoe_iflist */
46 if (strlen(ifp
->name
) == len
&& !strncmp(ifp
->name
, p
, len
))
56 set_aoe_iflist(const char __user
*user_str
, size_t size
)
61 if (copy_from_user(aoe_iflist
, user_str
, size
)) {
62 printk(KERN_INFO
"aoe: %s: copy from user failed\n", __FUNCTION__
);
65 aoe_iflist
[size
] = 0x00;
70 mac_addr(char addr
[6])
73 char *p
= (char *) &n
;
75 memcpy(p
+ 2, addr
, 6); /* (sizeof addr != 6) */
77 return __be64_to_cpu(n
);
80 static struct sk_buff
*
81 skb_check(struct sk_buff
*skb
)
83 if (skb_is_nonlinear(skb
))
84 if ((skb
= skb_share_check(skb
, GFP_ATOMIC
)))
85 if (skb_linearize(skb
, GFP_ATOMIC
) < 0) {
93 aoenet_xmit(struct sk_buff
*sl
)
99 skb
->next
= skb
->prev
= NULL
;
105 * (1) len doesn't include the header by default. I want this.
108 aoenet_rcv(struct sk_buff
*skb
, struct net_device
*ifp
, struct packet_type
*pt
)
113 skb
= skb_check(skb
);
117 if (!is_aoe_netif(ifp
))
120 //skb->len += ETH_HLEN; /* (1) */
121 skb_push(skb
, ETH_HLEN
); /* (1) */
123 h
= (struct aoe_hdr
*) skb
->mac
.raw
;
124 n
= __be32_to_cpu(*((u32
*) h
->tag
));
125 if ((h
->verfl
& AOEFL_RSP
) == 0 || (n
& 1<<31))
128 if (h
->verfl
& AOEFL_ERR
) {
133 printk(KERN_ERR
"aoe: aoenet_rcv: error packet from %d.%d; "
135 __be16_to_cpu(*((u16
*) h
->major
)), h
->minor
,
136 h
->err
, aoe_errlist
[n
]);
148 printk(KERN_INFO
"aoe: aoenet_rcv: unknown cmd %d\n", h
->cmd
);
155 static struct packet_type aoe_pt
= {
156 .type
= __constant_htons(ETH_P_AOE
),
163 dev_add_pack(&aoe_pt
);
170 dev_remove_pack(&aoe_pt
);