diff options
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 44 |
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 | ||
874 | static 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 | |||
879 | int zd_chip_lock_phy_regs(struct zd_chip *chip); | 874 | int zd_chip_lock_phy_regs(struct zd_chip *chip); |
880 | int zd_chip_unlock_phy_regs(struct zd_chip *chip); | 875 | int 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 | ||
164 | static int reset_mode(struct zd_mac *mac) | 164 | static 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 | ||
171 | static 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 | |||
179 | static 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 | |||
171 | int zd_mac_open(struct net_device *netdev) | 191 | int 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 | ||
299 | void zd_mac_set_multicast_list(struct net_device *dev) | 325 | void 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 | } |