Backport pm-qos for kernels <= 2.6.24
[~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 /* Part of net/ethernet/eth.c as of 2.6.24 */
17 char *print_mac(char *buf, const u8 *addr)
18 {
19         sprintf(buf, MAC_FMT,
20                 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
21         return buf;
22 }
23 EXPORT_SYMBOL(print_mac);
24
25 /* On net/core/dev.c as of 2.6.24 */
26 int __dev_addr_delete(struct dev_addr_list **list, int *count,
27                       void *addr, int alen, int glbl)
28 {
29         struct dev_addr_list *da;
30
31         for (; (da = *list) != NULL; list = &da->next) {
32                 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
33                         alen == da->da_addrlen) {
34                         if (glbl) {
35                                 int old_glbl = da->da_gusers;
36                                 da->da_gusers = 0;
37                                 if (old_glbl == 0)
38                                         break;
39                         }
40                         if (--da->da_users)
41                                 return 0;
42
43                         *list = da->next;
44                         kfree(da);
45                         (*count)--;
46                         return 0;
47                 }
48         }
49         return -ENOENT;
50 }
51
52 /* On net/core/dev.c as of 2.6.24. This is not yet used by mac80211 but
53  * might as well add it */
54 int __dev_addr_add(struct dev_addr_list **list, int *count,
55                    void *addr, int alen, int glbl)
56 {
57         struct dev_addr_list *da;
58
59         for (da = *list; da != NULL; da = da->next) {
60                 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
61                         da->da_addrlen == alen) {
62                         if (glbl) {
63                                 int old_glbl = da->da_gusers;
64                                 da->da_gusers = 1;
65                                 if (old_glbl)
66                                         return 0;
67                         }
68                         da->da_users++;
69                         return 0;
70                 }
71         }
72
73         da = kmalloc(sizeof(*da), GFP_ATOMIC);
74         if (da == NULL)
75                 return -ENOMEM;
76         memcpy(da->da_addr, addr, alen);
77         da->da_addrlen = alen;
78         da->da_users = 1;
79         da->da_gusers = glbl ? 1 : 0;
80         da->next = *list;
81         *list = da;
82         (*count)++;
83         return 0;
84 }
85
86 /* 2.6.22 and 2.6.23 have eth_header_cache_update defined as extern in include/linux/etherdevice.h
87  * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
88
89 /**
90  * eth_header_cache_update - update cache entry
91  * @hh: destination cache entry
92  * @dev: network device
93  * @haddr: new hardware address
94  *
95  * Called by Address Resolution module to notify changes in address.
96  */
97 void eth_header_cache_update(struct hh_cache *hh,
98                              struct net_device *dev,
99                              unsigned char *haddr)
100 {
101         memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
102                 haddr, ETH_ALEN);
103 }
104 EXPORT_SYMBOL(eth_header_cache_update);
105
106 /* 2.6.22 and 2.6.23 have eth_header_cache defined as extern in include/linux/etherdevice.h
107  * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
108
109 /**
110  * eth_header_cache - fill cache entry from neighbour
111  * @neigh: source neighbour
112  * @hh: destination cache entry
113  * Create an Ethernet header template from the neighbour.
114  */
115 int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
116 {
117         __be16 type = hh->hh_type;
118         struct ethhdr *eth;
119         const struct net_device *dev = neigh->dev;
120
121         eth = (struct ethhdr *)
122             (((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
123
124         if (type == htons(ETH_P_802_3))
125                 return -1;
126
127         eth->h_proto = type;
128         memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
129         memcpy(eth->h_dest, neigh->ha, ETH_ALEN);
130         hh->hh_len = ETH_HLEN;
131         return 0;
132 }
133 EXPORT_SYMBOL(eth_header_cache);
134
135 /* 2.6.22 and 2.6.23 have eth_header() defined as extern in include/linux/etherdevice.h
136  * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
137
138 /**
139  * eth_header - create the Ethernet header
140  * @skb:        buffer to alter
141  * @dev:        source device
142  * @type:       Ethernet type field
143  * @daddr: destination address (NULL leave destination address)
144  * @saddr: source address (NULL use device source address)
145  * @len:   packet length (<= skb->len)
146  *
147  *
148  * Set the protocol type. For a packet of type ETH_P_802_3 we put the length
149  * in here instead. It is up to the 802.2 layer to carry protocol information.
150  */
151 int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
152                void *daddr, void *saddr, unsigned len)
153 {
154         struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
155
156         if (type != ETH_P_802_3)
157                 eth->h_proto = htons(type);
158         else
159                 eth->h_proto = htons(len);
160
161         /*
162          *      Set the source hardware address.
163          */
164
165         if (!saddr)
166                 saddr = dev->dev_addr;
167         memcpy(eth->h_source, saddr, dev->addr_len);
168
169         if (daddr) {
170                 memcpy(eth->h_dest, daddr, dev->addr_len);
171                 return ETH_HLEN;
172         }
173
174         /*
175          *      Anyway, the loopback-device should never use this function...
176          */
177
178         if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
179                 memset(eth->h_dest, 0, dev->addr_len);
180                 return ETH_HLEN;
181         }
182
183         return -ETH_HLEN;
184 }
185
186 EXPORT_SYMBOL(eth_header);
187
188 /* 2.6.22 and 2.6.23 have eth_rebuild_header defined as extern in include/linux/etherdevice.h
189  * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
190
191 /**
192  * eth_rebuild_header- rebuild the Ethernet MAC header.
193  * @skb: socket buffer to update
194  *
195  * This is called after an ARP or IPV6 ndisc it's resolution on this
196  * sk_buff. We now let protocol (ARP) fill in the other fields.
197  *
198  * This routine CANNOT use cached dst->neigh!
199  * Really, it is used only when dst->neigh is wrong.
200  */
201 int eth_rebuild_header(struct sk_buff *skb)
202 {
203         struct ethhdr *eth = (struct ethhdr *)skb->data;
204         struct net_device *dev = skb->dev;
205
206         switch (eth->h_proto) {
207 #ifdef CONFIG_INET
208         case __constant_htons(ETH_P_IP):
209                 return arp_find(eth->h_dest, skb);
210 #endif
211         default:
212                 printk(KERN_DEBUG
213                        "%s: unable to resolve type %X addresses.\n",
214                        dev->name, (int)eth->h_proto);
215
216                 memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
217                 break;
218         }
219
220         return 0;
221 }
222 EXPORT_SYMBOL(eth_rebuild_header);
223
224 /* 2.6.24 will introduce struct pci_dev is_pcie bit. To help
225  * with the compatibility code (compat.diff) being smaller, we provide a helper
226  * so in cases where that will be used we can simply slap ifdefs with this
227  * routine. Use compat_ prefex to not pollute namespace.  */
228 int compat_is_pcie(struct pci_dev *pdev)
229 {
230         int cap;
231         cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
232         return cap ? 1 : 0;
233 }
234 EXPORT_SYMBOL(compat_is_pcie);
235
236 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */
237