]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * NET3: Fibre Channel device handling subroutines | |
9afa0949 | 3 | * |
1da177e4 LT |
4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License | |
6 | * as published by the Free Software Foundation; either version | |
7 | * 2 of the License, or (at your option) any later version. | |
8 | * | |
9 | * Vineet Abraham <[email protected]> | |
10 | * v 1.0 03/22/99 | |
11 | */ | |
12 | ||
1da177e4 | 13 | #include <asm/uaccess.h> |
1da177e4 LT |
14 | #include <linux/types.h> |
15 | #include <linux/kernel.h> | |
1da177e4 LT |
16 | #include <linux/string.h> |
17 | #include <linux/mm.h> | |
18 | #include <linux/socket.h> | |
19 | #include <linux/in.h> | |
20 | #include <linux/inet.h> | |
21 | #include <linux/netdevice.h> | |
22 | #include <linux/fcdevice.h> | |
23 | #include <linux/skbuff.h> | |
24 | #include <linux/errno.h> | |
25 | #include <linux/timer.h> | |
26 | #include <linux/net.h> | |
27 | #include <linux/proc_fs.h> | |
28 | #include <linux/init.h> | |
bc3b2d7f | 29 | #include <linux/export.h> |
1da177e4 LT |
30 | #include <net/arp.h> |
31 | ||
32 | /* | |
9afa0949 | 33 | * Put the headers on a Fibre Channel packet. |
1da177e4 | 34 | */ |
9afa0949 | 35 | |
1da177e4 LT |
36 | static int fc_header(struct sk_buff *skb, struct net_device *dev, |
37 | unsigned short type, | |
95c96174 | 38 | const void *daddr, const void *saddr, unsigned int len) |
1da177e4 LT |
39 | { |
40 | struct fch_hdr *fch; | |
41 | int hdr_len; | |
42 | ||
9afa0949 YH |
43 | /* |
44 | * Add the 802.2 SNAP header if IP as the IPv4 code calls | |
1da177e4 LT |
45 | * dev->hard_header directly. |
46 | */ | |
47 | if (type == ETH_P_IP || type == ETH_P_ARP) | |
48 | { | |
49 | struct fcllc *fcllc; | |
50 | ||
51 | hdr_len = sizeof(struct fch_hdr) + sizeof(struct fcllc); | |
52 | fch = (struct fch_hdr *)skb_push(skb, hdr_len); | |
53 | fcllc = (struct fcllc *)(fch+1); | |
54 | fcllc->dsap = fcllc->ssap = EXTENDED_SAP; | |
55 | fcllc->llc = UI_CMD; | |
56 | fcllc->protid[0] = fcllc->protid[1] = fcllc->protid[2] = 0x00; | |
57 | fcllc->ethertype = htons(type); | |
58 | } | |
59 | else | |
60 | { | |
61 | hdr_len = sizeof(struct fch_hdr); | |
9afa0949 | 62 | fch = (struct fch_hdr *)skb_push(skb, hdr_len); |
1da177e4 LT |
63 | } |
64 | ||
65 | if(saddr) | |
66 | memcpy(fch->saddr,saddr,dev->addr_len); | |
67 | else | |
68 | memcpy(fch->saddr,dev->dev_addr,dev->addr_len); | |
69 | ||
9afa0949 | 70 | if(daddr) |
1da177e4 LT |
71 | { |
72 | memcpy(fch->daddr,daddr,dev->addr_len); | |
a02cec21 | 73 | return hdr_len; |
1da177e4 LT |
74 | } |
75 | return -hdr_len; | |
76 | } | |
9afa0949 | 77 | |
3b04ddde SH |
78 | static const struct header_ops fc_header_ops = { |
79 | .create = fc_header, | |
3b04ddde SH |
80 | }; |
81 | ||
1da177e4 LT |
82 | static void fc_setup(struct net_device *dev) |
83 | { | |
3b04ddde | 84 | dev->header_ops = &fc_header_ops; |
1da177e4 LT |
85 | dev->type = ARPHRD_IEEE802; |
86 | dev->hard_header_len = FC_HLEN; | |
87 | dev->mtu = 2024; | |
88 | dev->addr_len = FC_ALEN; | |
89 | dev->tx_queue_len = 100; /* Long queues on fc */ | |
90 | dev->flags = IFF_BROADCAST; | |
91 | ||
92 | memset(dev->broadcast, 0xFF, FC_ALEN); | |
93 | } | |
94 | ||
95 | /** | |
96 | * alloc_fcdev - Register fibre channel device | |
97 | * @sizeof_priv: Size of additional driver-private structure to be allocated | |
98 | * for this fibre channel device | |
99 | * | |
100 | * Fill in the fields of the device structure with fibre channel-generic values. | |
101 | * | |
102 | * Constructs a new net device, complete with a private data area of | |
103 | * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for | |
104 | * this private data area. | |
105 | */ | |
106 | struct net_device *alloc_fcdev(int sizeof_priv) | |
107 | { | |
c835a677 | 108 | return alloc_netdev(sizeof_priv, "fc%d", NET_NAME_UNKNOWN, fc_setup); |
1da177e4 LT |
109 | } |
110 | EXPORT_SYMBOL(alloc_fcdev); |