aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw
diff options
context:
space:
mode:
authorUlrich Kunitz <kune@deine-taler.de>2007-07-21 17:42:13 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:49:34 -0400
commitc5691235cf70ae2bd71c1f445eb991191530ec6c (patch)
tree9ef5650cca1e85fce72c8d441036cd15dad62e0c /drivers/net/wireless/zd1211rw
parentcc0b88cf5ecf13cdd750f08e201ce8fadcdb601f (diff)
[PATCH] zd1211rw: monitor all packets
While in monitor mode the zd1211rw received only a limited set of packets. This patch forwards now all packets the device receives. Notify that while monitoring no FCS checks are done; so strange packets might appear in the network sniffer of your choice. ATTENTION: Support for multiple interfaces on a single ZD1211 device is currently broken. So this code works only on the first interface. Here is an example to put the device in monitor mode. iwconfig wlan0 mode monitor ifconfig wlan0 up iwconfig wlan0 channel 10 [dsd@gentoo.org: backport to mainline] Signed-off-by: Ulrich Kunitz <kune@deine-taler.de> Signed-off-by: Daniel Drake <dsd@gentoo.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c44
2 files changed, 38 insertions, 11 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index f4698576ab71..8009b70213e2 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -871,11 +871,6 @@ static inline int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates)
871 return r; 871 return r;
872} 872}
873 873
874static inline int zd_chip_set_rx_filter(struct zd_chip *chip, u32 filter)
875{
876 return zd_iowrite32(chip, CR_RX_FILTER, filter);
877}
878
879int zd_chip_lock_phy_regs(struct zd_chip *chip); 874int zd_chip_lock_phy_regs(struct zd_chip *chip);
880int zd_chip_unlock_phy_regs(struct zd_chip *chip); 875int zd_chip_unlock_phy_regs(struct zd_chip *chip);
881 876
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 26869d107e52..7ec1fcf37fc3 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -161,13 +161,33 @@ void zd_mac_clear(struct zd_mac *mac)
161 ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); 161 ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
162} 162}
163 163
164static int reset_mode(struct zd_mac *mac) 164static int set_rx_filter(struct zd_mac *mac)
165{ 165{
166 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); 166 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
167 u32 filter = (ieee->iw_mode == IW_MODE_MONITOR) ? ~0 : STA_RX_FILTER; 167 u32 filter = (ieee->iw_mode == IW_MODE_MONITOR) ? ~0 : STA_RX_FILTER;
168 return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter); 168 return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter);
169} 169}
170 170
171static int set_sniffer(struct zd_mac *mac)
172{
173 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
174 return zd_iowrite32(&mac->chip, CR_SNIFFER_ON,
175 ieee->iw_mode == IW_MODE_MONITOR ? 1 : 0);
176 return 0;
177}
178
179static int set_mc_hash(struct zd_mac *mac)
180{
181 struct zd_mc_hash hash;
182 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
183
184 zd_mc_clear(&hash);
185 if (ieee->iw_mode == IW_MODE_MONITOR)
186 zd_mc_add_all(&hash);
187
188 return zd_chip_set_multicast_hash(&mac->chip, &hash);
189}
190
171int zd_mac_open(struct net_device *netdev) 191int zd_mac_open(struct net_device *netdev)
172{ 192{
173 struct zd_mac *mac = zd_netdev_mac(netdev); 193 struct zd_mac *mac = zd_netdev_mac(netdev);
@@ -194,7 +214,13 @@ int zd_mac_open(struct net_device *netdev)
194 r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); 214 r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G);
195 if (r < 0) 215 if (r < 0)
196 goto disable_int; 216 goto disable_int;
197 r = reset_mode(mac); 217 r = set_rx_filter(mac);
218 if (r)
219 goto disable_int;
220 r = set_sniffer(mac);
221 if (r)
222 goto disable_int;
223 r = set_mc_hash(mac);
198 if (r) 224 if (r)
199 goto disable_int; 225 goto disable_int;
200 r = zd_chip_switch_radio_on(chip); 226 r = zd_chip_switch_radio_on(chip);
@@ -298,12 +324,14 @@ static void set_multicast_hash_handler(struct work_struct *work)
298 324
299void zd_mac_set_multicast_list(struct net_device *dev) 325void zd_mac_set_multicast_list(struct net_device *dev)
300{ 326{
301 struct zd_mc_hash hash;
302 struct zd_mac *mac = zd_netdev_mac(dev); 327 struct zd_mac *mac = zd_netdev_mac(dev);
328 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
329 struct zd_mc_hash hash;
303 struct dev_mc_list *mc; 330 struct dev_mc_list *mc;
304 unsigned long flags; 331 unsigned long flags;
305 332
306 if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) { 333 if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI) ||
334 ieee->iw_mode == IW_MODE_MONITOR) {
307 zd_mc_add_all(&hash); 335 zd_mc_add_all(&hash);
308 } else { 336 } else {
309 zd_mc_clear(&hash); 337 zd_mc_clear(&hash);
@@ -628,8 +656,12 @@ int zd_mac_set_mode(struct zd_mac *mac, u32 mode)
628 ieee->iw_mode = mode; 656 ieee->iw_mode = mode;
629 spin_unlock_irq(&ieee->lock); 657 spin_unlock_irq(&ieee->lock);
630 658
631 if (netif_running(mac->netdev)) 659 if (netif_running(mac->netdev)) {
632 return reset_mode(mac); 660 int r = set_rx_filter(mac);
661 if (r)
662 return r;
663 return set_sniffer(mac);
664 }
633 665
634 return 0; 666 return 0;
635} 667}