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.23.
11 #include <net/compat.h>
13 /* All things not in 2.6.22 */
14 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23))
16 /* On net/core/dev.c as of 2.6.24 */
17 int __dev_addr_delete(struct dev_addr_list **list, int *count,
18 void *addr, int alen, int glbl)
20 struct dev_addr_list *da;
22 for (; (da = *list) != NULL; list = &da->next) {
23 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
24 alen == da->da_addrlen) {
26 int old_glbl = da->da_gusers;
42 EXPORT_SYMBOL(__dev_addr_delete);
44 /* On net/core/dev.c as of 2.6.24. This is not yet used by mac80211 but
45 * might as well add it */
46 int __dev_addr_add(struct dev_addr_list **list, int *count,
47 void *addr, int alen, int glbl)
49 struct dev_addr_list *da;
51 for (da = *list; da != NULL; da = da->next) {
52 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
53 da->da_addrlen == alen) {
55 int old_glbl = da->da_gusers;
65 da = kmalloc(sizeof(*da), GFP_ATOMIC);
68 memcpy(da->da_addr, addr, alen);
69 da->da_addrlen = alen;
71 da->da_gusers = glbl ? 1 : 0;
77 EXPORT_SYMBOL(__dev_addr_add);
80 /* Part of net/core/dev_mcast.c as of 2.6.23. This is a slightly different version.
81 * Since da->da_synced is not part of 2.6.22 we need to take longer route when
85 * dev_mc_sync - Synchronize device's multicast list to another device
86 * @to: destination device
87 * @from: source device
89 * Add newly added addresses to the destination device and release
90 * addresses that have no users left. The source device must be
91 * locked by netif_tx_lock_bh.
93 * This function is intended to be called from the dev->set_multicast_list
94 * function of layered software devices.
96 int dev_mc_sync(struct net_device *to, struct net_device *from)
98 struct dev_addr_list *da, *next, *da_to;
101 netif_tx_lock_bh(to);
107 /* 2.6.22 does not have da->da_synced so lets take the long route */
108 while (da_to != NULL) {
109 if (memcmp(da_to->da_addr, da->da_addr, da_to->da_addrlen) == 0 &&
110 da->da_addrlen == da_to->da_addrlen)
115 err = __dev_addr_add(&to->mc_list, &to->mc_count,
116 da->da_addr, da->da_addrlen, 0);
120 } else if (da->da_users == 1) {
121 __dev_addr_delete(&to->mc_list, &to->mc_count,
122 da->da_addr, da->da_addrlen, 0);
123 __dev_addr_delete(&from->mc_list, &from->mc_count,
124 da->da_addr, da->da_addrlen, 0);
129 __dev_set_rx_mode(to);
130 netif_tx_unlock_bh(to);
134 EXPORT_SYMBOL(dev_mc_sync);
137 /* Part of net/core/dev_mcast.c as of 2.6.23. This is a slighty different version.
138 * Since da->da_synced is not part of 2.6.22 we need to take longer route when
142 * dev_mc_unsync - Remove synchronized addresses from the destination
144 * @to: destination device
145 * @from: source device
147 * Remove all addresses that were added to the destination device by
148 * dev_mc_sync(). This function is intended to be called from the
149 * dev->stop function of layered software devices.
151 void dev_mc_unsync(struct net_device *to, struct net_device *from)
153 struct dev_addr_list *da, *next, *da_to;
155 netif_tx_lock_bh(from);
156 netif_tx_lock_bh(to);
163 /* 2.6.22 does not have da->da_synced so lets take the long route */
164 while (da_to != NULL) {
165 if (memcmp(da_to->da_addr, da->da_addr, da_to->da_addrlen) == 0 &&
166 da->da_addrlen == da_to->da_addrlen)
174 __dev_addr_delete(&to->mc_list, &to->mc_count,
175 da->da_addr, da->da_addrlen, 0);
176 __dev_addr_delete(&from->mc_list, &from->mc_count,
177 da->da_addr, da->da_addrlen, 0);
180 __dev_set_rx_mode(to);
182 netif_tx_unlock_bh(to);
183 netif_tx_unlock_bh(from);
185 EXPORT_SYMBOL(dev_mc_unsync);
187 /* Added as of 2.6.23 on net/core/dev.c. Slightly modifed, no dev->set_rx_mode on
188 * 2.6.22 so ignore that. */
191 * Upload unicast and multicast address lists to device and
192 * configure RX filtering. When the device doesn't support unicast
193 * filtering it is put in promiscous mode while unicast addresses
196 void __dev_set_rx_mode(struct net_device *dev)
198 /* dev_open will call this function so the list will stay sane. */
199 if (!(dev->flags&IFF_UP))
202 if (!netif_device_present(dev))
205 /* This needs to be ported to 2.6.22 framework */
207 /* Unicast addresses changes may only happen under the rtnl,
208 * therefore calling __dev_set_promiscuity here is safe.
210 if (dev->uc_count > 0 && !dev->uc_promisc) {
211 __dev_set_promiscuity(dev, 1);
213 } else if (dev->uc_count == 0 && dev->uc_promisc) {
214 __dev_set_promiscuity(dev, -1);
219 if (dev->set_multicast_list)
220 dev->set_multicast_list(dev);
223 #ifndef HAVE_PCI_SET_MWI
224 int pci_try_set_mwi(struct pci_dev *dev)
228 EXPORT_SYMBOL(pci_try_set_mwi);
232 * pci_try_set_mwi - enables memory-write-invalidate PCI transaction
233 * @dev: the PCI device for which MWI is enabled
235 * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND.
236 * Callers are not required to check the return value.
238 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
240 int pci_try_set_mwi(struct pci_dev *dev)
242 int rc = pci_set_mwi(dev);
245 EXPORT_SYMBOL(pci_try_set_mwi);
248 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) */