2 * Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
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.
8 * Compatibility file for Linux wireless for kernels 2.6.24.
11 #include <net/compat.h>
13 /* All things not in 2.6.22 and 2.6.23 */
14 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
18 /* Part of net/ethernet/eth.c as of 2.6.24 */
19 char *print_mac(char *buf, const u8 *addr)
22 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
25 EXPORT_SYMBOL(print_mac);
27 /* On net/core/dev.c as of 2.6.24 */
28 int __dev_addr_delete(struct dev_addr_list **list, int *count,
29 void *addr, int alen, int glbl)
31 struct dev_addr_list *da;
33 for (; (da = *list) != NULL; list = &da->next) {
34 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
35 alen == da->da_addrlen) {
37 int old_glbl = da->da_gusers;
54 /* On net/core/dev.c as of 2.6.24. This is not yet used by mac80211 but
55 * might as well add it */
56 int __dev_addr_add(struct dev_addr_list **list, int *count,
57 void *addr, int alen, int glbl)
59 struct dev_addr_list *da;
61 for (da = *list; da != NULL; da = da->next) {
62 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
63 da->da_addrlen == alen) {
65 int old_glbl = da->da_gusers;
75 da = kmalloc(sizeof(*da), GFP_ATOMIC);
78 memcpy(da->da_addr, addr, alen);
79 da->da_addrlen = alen;
81 da->da_gusers = glbl ? 1 : 0;
88 /* 2.6.22 and 2.6.23 have eth_header_cache_update defined as extern in include/linux/etherdevice.h
89 * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
92 * eth_header_cache_update - update cache entry
93 * @hh: destination cache entry
94 * @dev: network device
95 * @haddr: new hardware address
97 * Called by Address Resolution module to notify changes in address.
99 void eth_header_cache_update(struct hh_cache *hh,
100 struct net_device *dev,
101 unsigned char *haddr)
103 memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
106 EXPORT_SYMBOL(eth_header_cache_update);
108 /* 2.6.22 and 2.6.23 have eth_header_cache defined as extern in include/linux/etherdevice.h
109 * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
112 * eth_header_cache - fill cache entry from neighbour
113 * @neigh: source neighbour
114 * @hh: destination cache entry
115 * Create an Ethernet header template from the neighbour.
117 int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
119 __be16 type = hh->hh_type;
121 const struct net_device *dev = neigh->dev;
123 eth = (struct ethhdr *)
124 (((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
126 if (type == htons(ETH_P_802_3))
130 memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
131 memcpy(eth->h_dest, neigh->ha, ETH_ALEN);
132 hh->hh_len = ETH_HLEN;
135 EXPORT_SYMBOL(eth_header_cache);
137 /* 2.6.22 and 2.6.23 have eth_header() defined as extern in include/linux/etherdevice.h
138 * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
141 * eth_header - create the Ethernet header
142 * @skb: buffer to alter
143 * @dev: source device
144 * @type: Ethernet type field
145 * @daddr: destination address (NULL leave destination address)
146 * @saddr: source address (NULL use device source address)
147 * @len: packet length (<= skb->len)
150 * Set the protocol type. For a packet of type ETH_P_802_3 we put the length
151 * in here instead. It is up to the 802.2 layer to carry protocol information.
153 int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
154 void *daddr, void *saddr, unsigned len)
156 struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
158 if (type != ETH_P_802_3)
159 eth->h_proto = htons(type);
161 eth->h_proto = htons(len);
164 * Set the source hardware address.
168 saddr = dev->dev_addr;
169 memcpy(eth->h_source, saddr, dev->addr_len);
172 memcpy(eth->h_dest, daddr, dev->addr_len);
177 * Anyway, the loopback-device should never use this function...
180 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
181 memset(eth->h_dest, 0, dev->addr_len);
188 EXPORT_SYMBOL(eth_header);
190 /* 2.6.22 and 2.6.23 have eth_rebuild_header defined as extern in include/linux/etherdevice.h
191 * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
194 * eth_rebuild_header- rebuild the Ethernet MAC header.
195 * @skb: socket buffer to update
197 * This is called after an ARP or IPV6 ndisc it's resolution on this
198 * sk_buff. We now let protocol (ARP) fill in the other fields.
200 * This routine CANNOT use cached dst->neigh!
201 * Really, it is used only when dst->neigh is wrong.
203 int eth_rebuild_header(struct sk_buff *skb)
205 struct ethhdr *eth = (struct ethhdr *)skb->data;
206 struct net_device *dev = skb->dev;
208 switch (eth->h_proto) {
210 case __constant_htons(ETH_P_IP):
211 return arp_find(eth->h_dest, skb);
215 "%s: unable to resolve type %X addresses.\n",
216 dev->name, (int)eth->h_proto);
218 memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
224 EXPORT_SYMBOL(eth_rebuild_header);
226 /* 2.6.24 will introduce struct pci_dev is_pcie bit. To help
227 * with the compatibility code (compat.diff) being smaller, we provide a helper
228 * so in cases where that will be used we can simply slap ifdefs with this
229 * routine. Use compat_ prefex to not pollute namespace. */
230 int compat_is_pcie(struct pci_dev *pdev)
233 cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
236 EXPORT_SYMBOL(compat_is_pcie);
238 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */