Add initial 2.6.22 support
[~emulex/for-vlad/old/compat.git] / compat / compat-2.6.24.c
1 /*
2  * Copyright 2007       Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * Compatibility file for Linux wireless for kernels 2.6.24.
9  */
10
11 #include <net/compat.h>
12
13 /* All things not in 2.6.22 and 2.6.23 */
14 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
15
16 #include <net/arp.h>
17
18 /*
19  * We simply won't use it though, just declare it for our wrappers and
20  * for usage with tons of code that makes mention to it.
21  */
22 struct net init_net;
23 EXPORT_SYMBOL(init_net);
24
25 /* Part of net/ethernet/eth.c as of 2.6.24 */
26 char *print_mac(char *buf, const u8 *addr)
27 {
28         sprintf(buf, MAC_FMT,
29                 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
30         return buf;
31 }
32 EXPORT_SYMBOL(print_mac);
33
34 /* 2.6.22 and 2.6.23 have eth_header_cache_update defined as extern in include/linux/etherdevice.h
35  * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
36
37 /**
38  * eth_header_cache_update - update cache entry
39  * @hh: destination cache entry
40  * @dev: network device
41  * @haddr: new hardware address
42  *
43  * Called by Address Resolution module to notify changes in address.
44  */
45 void eth_header_cache_update(struct hh_cache *hh,
46                              struct net_device *dev,
47                              unsigned char *haddr)
48 {
49         memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
50                 haddr, ETH_ALEN);
51 }
52 EXPORT_SYMBOL(eth_header_cache_update);
53
54 /* 2.6.22 and 2.6.23 have eth_header_cache defined as extern in include/linux/etherdevice.h
55  * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
56
57 /**
58  * eth_header_cache - fill cache entry from neighbour
59  * @neigh: source neighbour
60  * @hh: destination cache entry
61  * Create an Ethernet header template from the neighbour.
62  */
63 int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
64 {
65         __be16 type = hh->hh_type;
66         struct ethhdr *eth;
67         const struct net_device *dev = neigh->dev;
68
69         eth = (struct ethhdr *)
70             (((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
71
72         if (type == htons(ETH_P_802_3))
73                 return -1;
74
75         eth->h_proto = type;
76         memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
77         memcpy(eth->h_dest, neigh->ha, ETH_ALEN);
78         hh->hh_len = ETH_HLEN;
79         return 0;
80 }
81 EXPORT_SYMBOL(eth_header_cache);
82
83 /* 2.6.22 and 2.6.23 have eth_header() defined as extern in include/linux/etherdevice.h
84  * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
85
86 /**
87  * eth_header - create the Ethernet header
88  * @skb:        buffer to alter
89  * @dev:        source device
90  * @type:       Ethernet type field
91  * @daddr: destination address (NULL leave destination address)
92  * @saddr: source address (NULL use device source address)
93  * @len:   packet length (<= skb->len)
94  *
95  *
96  * Set the protocol type. For a packet of type ETH_P_802_3 we put the length
97  * in here instead. It is up to the 802.2 layer to carry protocol information.
98  */
99 int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
100                void *daddr, void *saddr, unsigned len)
101 {
102         struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
103
104         if (type != ETH_P_802_3)
105                 eth->h_proto = htons(type);
106         else
107                 eth->h_proto = htons(len);
108
109         /*
110          *      Set the source hardware address.
111          */
112
113         if (!saddr)
114                 saddr = dev->dev_addr;
115         memcpy(eth->h_source, saddr, dev->addr_len);
116
117         if (daddr) {
118                 memcpy(eth->h_dest, daddr, dev->addr_len);
119                 return ETH_HLEN;
120         }
121
122         /*
123          *      Anyway, the loopback-device should never use this function...
124          */
125
126         if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
127                 memset(eth->h_dest, 0, dev->addr_len);
128                 return ETH_HLEN;
129         }
130
131         return -ETH_HLEN;
132 }
133
134 EXPORT_SYMBOL(eth_header);
135
136 /* 2.6.22 and 2.6.23 have eth_rebuild_header defined as extern in include/linux/etherdevice.h
137  * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
138
139 /**
140  * eth_rebuild_header- rebuild the Ethernet MAC header.
141  * @skb: socket buffer to update
142  *
143  * This is called after an ARP or IPV6 ndisc it's resolution on this
144  * sk_buff. We now let protocol (ARP) fill in the other fields.
145  *
146  * This routine CANNOT use cached dst->neigh!
147  * Really, it is used only when dst->neigh is wrong.
148  */
149 int eth_rebuild_header(struct sk_buff *skb)
150 {
151         struct ethhdr *eth = (struct ethhdr *)skb->data;
152         struct net_device *dev = skb->dev;
153
154         switch (eth->h_proto) {
155 #ifdef CONFIG_INET
156         case __constant_htons(ETH_P_IP):
157                 return arp_find(eth->h_dest, skb);
158 #endif
159         default:
160                 printk(KERN_DEBUG
161                        "%s: unable to resolve type %X addresses.\n",
162                        dev->name, (int)eth->h_proto);
163
164                 memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
165                 break;
166         }
167
168         return 0;
169 }
170 EXPORT_SYMBOL(eth_rebuild_header);
171
172 /* 2.6.24 will introduce struct pci_dev is_pcie bit. To help
173  * with the compatibility code (compat.diff) being smaller, we provide a helper
174  * so in cases where that will be used we can simply slap ifdefs with this
175  * routine. Use compat_ prefex to not pollute namespace.  */
176 int compat_is_pcie(struct pci_dev *pdev)
177 {
178         int cap;
179         cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
180         return cap ? 1 : 0;
181 }
182 EXPORT_SYMBOL(compat_is_pcie);
183
184 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */
185