aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw/zd_mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_mac.c')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c453
1 files changed, 350 insertions, 103 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 6107304cb94c..5037c8b2b415 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -138,6 +138,12 @@ static const struct ieee80211_channel zd_channels[] = {
138static void housekeeping_init(struct zd_mac *mac); 138static void housekeeping_init(struct zd_mac *mac);
139static void housekeeping_enable(struct zd_mac *mac); 139static void housekeeping_enable(struct zd_mac *mac);
140static void housekeeping_disable(struct zd_mac *mac); 140static void housekeeping_disable(struct zd_mac *mac);
141static void beacon_init(struct zd_mac *mac);
142static void beacon_enable(struct zd_mac *mac);
143static void beacon_disable(struct zd_mac *mac);
144static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble);
145static int zd_mac_config_beacon(struct ieee80211_hw *hw,
146 struct sk_buff *beacon);
141 147
142static int zd_reg2alpha2(u8 regdomain, char *alpha2) 148static int zd_reg2alpha2(u8 regdomain, char *alpha2)
143{ 149{
@@ -231,6 +237,26 @@ static int set_rx_filter(struct zd_mac *mac)
231 return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter); 237 return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter);
232} 238}
233 239
240static int set_mac_and_bssid(struct zd_mac *mac)
241{
242 int r;
243
244 if (!mac->vif)
245 return -1;
246
247 r = zd_write_mac_addr(&mac->chip, mac->vif->addr);
248 if (r)
249 return r;
250
251 /* Vendor driver after setting MAC either sets BSSID for AP or
252 * filter for other modes.
253 */
254 if (mac->type != NL80211_IFTYPE_AP)
255 return set_rx_filter(mac);
256 else
257 return zd_write_bssid(&mac->chip, mac->vif->addr);
258}
259
234static int set_mc_hash(struct zd_mac *mac) 260static int set_mc_hash(struct zd_mac *mac)
235{ 261{
236 struct zd_mc_hash hash; 262 struct zd_mc_hash hash;
@@ -238,7 +264,7 @@ static int set_mc_hash(struct zd_mac *mac)
238 return zd_chip_set_multicast_hash(&mac->chip, &hash); 264 return zd_chip_set_multicast_hash(&mac->chip, &hash);
239} 265}
240 266
241static int zd_op_start(struct ieee80211_hw *hw) 267int zd_op_start(struct ieee80211_hw *hw)
242{ 268{
243 struct zd_mac *mac = zd_hw_mac(hw); 269 struct zd_mac *mac = zd_hw_mac(hw);
244 struct zd_chip *chip = &mac->chip; 270 struct zd_chip *chip = &mac->chip;
@@ -275,6 +301,8 @@ static int zd_op_start(struct ieee80211_hw *hw)
275 goto disable_rxtx; 301 goto disable_rxtx;
276 302
277 housekeeping_enable(mac); 303 housekeeping_enable(mac);
304 beacon_enable(mac);
305 set_bit(ZD_DEVICE_RUNNING, &mac->flags);
278 return 0; 306 return 0;
279disable_rxtx: 307disable_rxtx:
280 zd_chip_disable_rxtx(chip); 308 zd_chip_disable_rxtx(chip);
@@ -286,19 +314,22 @@ out:
286 return r; 314 return r;
287} 315}
288 316
289static void zd_op_stop(struct ieee80211_hw *hw) 317void zd_op_stop(struct ieee80211_hw *hw)
290{ 318{
291 struct zd_mac *mac = zd_hw_mac(hw); 319 struct zd_mac *mac = zd_hw_mac(hw);
292 struct zd_chip *chip = &mac->chip; 320 struct zd_chip *chip = &mac->chip;
293 struct sk_buff *skb; 321 struct sk_buff *skb;
294 struct sk_buff_head *ack_wait_queue = &mac->ack_wait_queue; 322 struct sk_buff_head *ack_wait_queue = &mac->ack_wait_queue;
295 323
324 clear_bit(ZD_DEVICE_RUNNING, &mac->flags);
325
296 /* The order here deliberately is a little different from the open() 326 /* The order here deliberately is a little different from the open()
297 * method, since we need to make sure there is no opportunity for RX 327 * method, since we need to make sure there is no opportunity for RX
298 * frames to be processed by mac80211 after we have stopped it. 328 * frames to be processed by mac80211 after we have stopped it.
299 */ 329 */
300 330
301 zd_chip_disable_rxtx(chip); 331 zd_chip_disable_rxtx(chip);
332 beacon_disable(mac);
302 housekeeping_disable(mac); 333 housekeeping_disable(mac);
303 flush_workqueue(zd_workqueue); 334 flush_workqueue(zd_workqueue);
304 335
@@ -311,6 +342,68 @@ static void zd_op_stop(struct ieee80211_hw *hw)
311 dev_kfree_skb_any(skb); 342 dev_kfree_skb_any(skb);
312} 343}
313 344
345int zd_restore_settings(struct zd_mac *mac)
346{
347 struct sk_buff *beacon;
348 struct zd_mc_hash multicast_hash;
349 unsigned int short_preamble;
350 int r, beacon_interval, beacon_period;
351 u8 channel;
352
353 dev_dbg_f(zd_mac_dev(mac), "\n");
354
355 spin_lock_irq(&mac->lock);
356 multicast_hash = mac->multicast_hash;
357 short_preamble = mac->short_preamble;
358 beacon_interval = mac->beacon.interval;
359 beacon_period = mac->beacon.period;
360 channel = mac->channel;
361 spin_unlock_irq(&mac->lock);
362
363 r = set_mac_and_bssid(mac);
364 if (r < 0) {
365 dev_dbg_f(zd_mac_dev(mac), "set_mac_and_bssid failed, %d\n", r);
366 return r;
367 }
368
369 r = zd_chip_set_channel(&mac->chip, channel);
370 if (r < 0) {
371 dev_dbg_f(zd_mac_dev(mac), "zd_chip_set_channel failed, %d\n",
372 r);
373 return r;
374 }
375
376 set_rts_cts(mac, short_preamble);
377
378 r = zd_chip_set_multicast_hash(&mac->chip, &multicast_hash);
379 if (r < 0) {
380 dev_dbg_f(zd_mac_dev(mac),
381 "zd_chip_set_multicast_hash failed, %d\n", r);
382 return r;
383 }
384
385 if (mac->type == NL80211_IFTYPE_MESH_POINT ||
386 mac->type == NL80211_IFTYPE_ADHOC ||
387 mac->type == NL80211_IFTYPE_AP) {
388 if (mac->vif != NULL) {
389 beacon = ieee80211_beacon_get(mac->hw, mac->vif);
390 if (beacon) {
391 zd_mac_config_beacon(mac->hw, beacon);
392 kfree_skb(beacon);
393 }
394 }
395
396 zd_set_beacon_interval(&mac->chip, beacon_interval,
397 beacon_period, mac->type);
398
399 spin_lock_irq(&mac->lock);
400 mac->beacon.last_update = jiffies;
401 spin_unlock_irq(&mac->lock);
402 }
403
404 return 0;
405}
406
314/** 407/**
315 * zd_mac_tx_status - reports tx status of a packet if required 408 * zd_mac_tx_status - reports tx status of a packet if required
316 * @hw - a &struct ieee80211_hw pointer 409 * @hw - a &struct ieee80211_hw pointer
@@ -574,64 +667,120 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
574static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) 667static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
575{ 668{
576 struct zd_mac *mac = zd_hw_mac(hw); 669 struct zd_mac *mac = zd_hw_mac(hw);
577 int r; 670 int r, ret, num_cmds, req_pos = 0;
578 u32 tmp, j = 0; 671 u32 tmp, j = 0;
579 /* 4 more bytes for tail CRC */ 672 /* 4 more bytes for tail CRC */
580 u32 full_len = beacon->len + 4; 673 u32 full_len = beacon->len + 4;
674 unsigned long end_jiffies, message_jiffies;
675 struct zd_ioreq32 *ioreqs;
581 676
582 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0); 677 /* Alloc memory for full beacon write at once. */
678 num_cmds = 1 + zd_chip_is_zd1211b(&mac->chip) + full_len;
679 ioreqs = kmalloc(num_cmds * sizeof(struct zd_ioreq32), GFP_KERNEL);
680 if (!ioreqs)
681 return -ENOMEM;
682
683 mutex_lock(&mac->chip.mutex);
684
685 r = zd_iowrite32_locked(&mac->chip, 0, CR_BCN_FIFO_SEMAPHORE);
583 if (r < 0) 686 if (r < 0)
584 return r; 687 goto out;
585 r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); 688 r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE);
586 if (r < 0) 689 if (r < 0)
587 return r; 690 goto release_sema;
588 691
692 end_jiffies = jiffies + HZ / 2; /*~500ms*/
693 message_jiffies = jiffies + HZ / 10; /*~100ms*/
589 while (tmp & 0x2) { 694 while (tmp & 0x2) {
590 r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); 695 r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE);
591 if (r < 0) 696 if (r < 0)
592 return r; 697 goto release_sema;
593 if ((++j % 100) == 0) { 698 if (time_is_before_eq_jiffies(message_jiffies)) {
594 printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n"); 699 message_jiffies = jiffies + HZ / 10;
595 if (j >= 500) { 700 dev_err(zd_mac_dev(mac),
596 printk(KERN_ERR "Giving up beacon config.\n"); 701 "CR_BCN_FIFO_SEMAPHORE not ready\n");
597 return -ETIMEDOUT; 702 if (time_is_before_eq_jiffies(end_jiffies)) {
703 dev_err(zd_mac_dev(mac),
704 "Giving up beacon config.\n");
705 r = -ETIMEDOUT;
706 goto reset_device;
598 } 707 }
599 } 708 }
600 msleep(1); 709 msleep(20);
601 } 710 }
602 711
603 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1); 712 ioreqs[req_pos].addr = CR_BCN_FIFO;
604 if (r < 0) 713 ioreqs[req_pos].value = full_len - 1;
605 return r; 714 req_pos++;
606 if (zd_chip_is_zd1211b(&mac->chip)) { 715 if (zd_chip_is_zd1211b(&mac->chip)) {
607 r = zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1); 716 ioreqs[req_pos].addr = CR_BCN_LENGTH;
608 if (r < 0) 717 ioreqs[req_pos].value = full_len - 1;
609 return r; 718 req_pos++;
610 } 719 }
611 720
612 for (j = 0 ; j < beacon->len; j++) { 721 for (j = 0 ; j < beacon->len; j++) {
613 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, 722 ioreqs[req_pos].addr = CR_BCN_FIFO;
614 *((u8 *)(beacon->data + j))); 723 ioreqs[req_pos].value = *((u8 *)(beacon->data + j));
615 if (r < 0) 724 req_pos++;
616 return r;
617 } 725 }
618 726
619 for (j = 0; j < 4; j++) { 727 for (j = 0; j < 4; j++) {
620 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0); 728 ioreqs[req_pos].addr = CR_BCN_FIFO;
621 if (r < 0) 729 ioreqs[req_pos].value = 0x0;
622 return r; 730 req_pos++;
623 } 731 }
624 732
625 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1); 733 BUG_ON(req_pos != num_cmds);
626 if (r < 0) 734
627 return r; 735 r = zd_iowrite32a_locked(&mac->chip, ioreqs, num_cmds);
736
737release_sema:
738 /*
739 * Try very hard to release device beacon semaphore, as otherwise
740 * device/driver can be left in unusable state.
741 */
742 end_jiffies = jiffies + HZ / 2; /*~500ms*/
743 ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE);
744 while (ret < 0) {
745 if (time_is_before_eq_jiffies(end_jiffies)) {
746 ret = -ETIMEDOUT;
747 break;
748 }
749
750 msleep(20);
751 ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE);
752 }
753
754 if (ret < 0)
755 dev_err(zd_mac_dev(mac), "Could not release "
756 "CR_BCN_FIFO_SEMAPHORE!\n");
757 if (r < 0 || ret < 0) {
758 if (r >= 0)
759 r = ret;
760 goto out;
761 }
628 762
629 /* 802.11b/g 2.4G CCK 1Mb 763 /* 802.11b/g 2.4G CCK 1Mb
630 * 802.11a, not yet implemented, uses different values (see GPL vendor 764 * 802.11a, not yet implemented, uses different values (see GPL vendor
631 * driver) 765 * driver)
632 */ 766 */
633 return zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 | 767 r = zd_iowrite32_locked(&mac->chip, 0x00000400 | (full_len << 19),
634 (full_len << 19)); 768 CR_BCN_PLCP_CFG);
769out:
770 mutex_unlock(&mac->chip.mutex);
771 kfree(ioreqs);
772 return r;
773
774reset_device:
775 mutex_unlock(&mac->chip.mutex);
776 kfree(ioreqs);
777
778 /* semaphore stuck, reset device to avoid fw freeze later */
779 dev_warn(zd_mac_dev(mac), "CR_BCN_FIFO_SEMAPHORE stuck, "
780 "reseting device...");
781 usb_queue_reset_device(mac->chip.usb.intf);
782
783 return r;
635} 784}
636 785
637static int fill_ctrlset(struct zd_mac *mac, 786static int fill_ctrlset(struct zd_mac *mac,
@@ -701,7 +850,7 @@ static int fill_ctrlset(struct zd_mac *mac,
701 * control block of the skbuff will be initialized. If necessary the incoming 850 * control block of the skbuff will be initialized. If necessary the incoming
702 * mac80211 queues will be stopped. 851 * mac80211 queues will be stopped.
703 */ 852 */
704static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 853static void zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
705{ 854{
706 struct zd_mac *mac = zd_hw_mac(hw); 855 struct zd_mac *mac = zd_hw_mac(hw);
707 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 856 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -716,11 +865,10 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
716 r = zd_usb_tx(&mac->chip.usb, skb); 865 r = zd_usb_tx(&mac->chip.usb, skb);
717 if (r) 866 if (r)
718 goto fail; 867 goto fail;
719 return 0; 868 return;
720 869
721fail: 870fail:
722 dev_kfree_skb(skb); 871 dev_kfree_skb(skb);
723 return 0;
724} 872}
725 873
726/** 874/**
@@ -779,6 +927,13 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
779 927
780 mac->ack_pending = 1; 928 mac->ack_pending = 1;
781 mac->ack_signal = stats->signal; 929 mac->ack_signal = stats->signal;
930
931 /* Prevent pending tx-packet on AP-mode */
932 if (mac->type == NL80211_IFTYPE_AP) {
933 skb = __skb_dequeue(q);
934 zd_mac_tx_status(hw, skb, mac->ack_signal, NULL);
935 mac->ack_pending = 0;
936 }
782 } 937 }
783 938
784 spin_unlock_irqrestore(&q->lock, flags); 939 spin_unlock_irqrestore(&q->lock, flags);
@@ -882,13 +1037,16 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,
882 case NL80211_IFTYPE_MESH_POINT: 1037 case NL80211_IFTYPE_MESH_POINT:
883 case NL80211_IFTYPE_STATION: 1038 case NL80211_IFTYPE_STATION:
884 case NL80211_IFTYPE_ADHOC: 1039 case NL80211_IFTYPE_ADHOC:
1040 case NL80211_IFTYPE_AP:
885 mac->type = vif->type; 1041 mac->type = vif->type;
886 break; 1042 break;
887 default: 1043 default:
888 return -EOPNOTSUPP; 1044 return -EOPNOTSUPP;
889 } 1045 }
890 1046
891 return zd_write_mac_addr(&mac->chip, vif->addr); 1047 mac->vif = vif;
1048
1049 return set_mac_and_bssid(mac);
892} 1050}
893 1051
894static void zd_op_remove_interface(struct ieee80211_hw *hw, 1052static void zd_op_remove_interface(struct ieee80211_hw *hw,
@@ -896,7 +1054,8 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw,
896{ 1054{
897 struct zd_mac *mac = zd_hw_mac(hw); 1055 struct zd_mac *mac = zd_hw_mac(hw);
898 mac->type = NL80211_IFTYPE_UNSPECIFIED; 1056 mac->type = NL80211_IFTYPE_UNSPECIFIED;
899 zd_set_beacon_interval(&mac->chip, 0); 1057 mac->vif = NULL;
1058 zd_set_beacon_interval(&mac->chip, 0, 0, NL80211_IFTYPE_UNSPECIFIED);
900 zd_write_mac_addr(&mac->chip, NULL); 1059 zd_write_mac_addr(&mac->chip, NULL);
901} 1060}
902 1061
@@ -905,49 +1064,67 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
905 struct zd_mac *mac = zd_hw_mac(hw); 1064 struct zd_mac *mac = zd_hw_mac(hw);
906 struct ieee80211_conf *conf = &hw->conf; 1065 struct ieee80211_conf *conf = &hw->conf;
907 1066
1067 spin_lock_irq(&mac->lock);
1068 mac->channel = conf->channel->hw_value;
1069 spin_unlock_irq(&mac->lock);
1070
908 return zd_chip_set_channel(&mac->chip, conf->channel->hw_value); 1071 return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
909} 1072}
910 1073
911static void zd_process_intr(struct work_struct *work) 1074static void zd_beacon_done(struct zd_mac *mac)
912{ 1075{
913 u16 int_status; 1076 struct sk_buff *skb, *beacon;
914 struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
915 1077
916 int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4)); 1078 if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags))
917 if (int_status & INT_CFG_NEXT_BCN) 1079 return;
918 dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n"); 1080 if (!mac->vif || mac->vif->type != NL80211_IFTYPE_AP)
919 else 1081 return;
920 dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
921
922 zd_chip_enable_hwint(&mac->chip);
923}
924 1082
1083 /*
1084 * Send out buffered broad- and multicast frames.
1085 */
1086 while (!ieee80211_queue_stopped(mac->hw, 0)) {
1087 skb = ieee80211_get_buffered_bc(mac->hw, mac->vif);
1088 if (!skb)
1089 break;
1090 zd_op_tx(mac->hw, skb);
1091 }
925 1092
926static void set_multicast_hash_handler(struct work_struct *work) 1093 /*
927{ 1094 * Fetch next beacon so that tim_count is updated.
928 struct zd_mac *mac = 1095 */
929 container_of(work, struct zd_mac, set_multicast_hash_work); 1096 beacon = ieee80211_beacon_get(mac->hw, mac->vif);
930 struct zd_mc_hash hash; 1097 if (beacon) {
1098 zd_mac_config_beacon(mac->hw, beacon);
1099 kfree_skb(beacon);
1100 }
931 1101
932 spin_lock_irq(&mac->lock); 1102 spin_lock_irq(&mac->lock);
933 hash = mac->multicast_hash; 1103 mac->beacon.last_update = jiffies;
934 spin_unlock_irq(&mac->lock); 1104 spin_unlock_irq(&mac->lock);
935
936 zd_chip_set_multicast_hash(&mac->chip, &hash);
937} 1105}
938 1106
939static void set_rx_filter_handler(struct work_struct *work) 1107static void zd_process_intr(struct work_struct *work)
940{ 1108{
941 struct zd_mac *mac = 1109 u16 int_status;
942 container_of(work, struct zd_mac, set_rx_filter_work); 1110 unsigned long flags;
943 int r; 1111 struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
944 1112
945 dev_dbg_f(zd_mac_dev(mac), "\n"); 1113 spin_lock_irqsave(&mac->lock, flags);
946 r = set_rx_filter(mac); 1114 int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer + 4));
947 if (r) 1115 spin_unlock_irqrestore(&mac->lock, flags);
948 dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r); 1116
1117 if (int_status & INT_CFG_NEXT_BCN) {
1118 /*dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");*/
1119 zd_beacon_done(mac);
1120 } else {
1121 dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
1122 }
1123
1124 zd_chip_enable_hwint(&mac->chip);
949} 1125}
950 1126
1127
951static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw, 1128static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw,
952 struct netdev_hw_addr_list *mc_list) 1129 struct netdev_hw_addr_list *mc_list)
953{ 1130{
@@ -979,6 +1156,7 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
979 }; 1156 };
980 struct zd_mac *mac = zd_hw_mac(hw); 1157 struct zd_mac *mac = zd_hw_mac(hw);
981 unsigned long flags; 1158 unsigned long flags;
1159 int r;
982 1160
983 /* Only deal with supported flags */ 1161 /* Only deal with supported flags */
984 changed_flags &= SUPPORTED_FIF_FLAGS; 1162 changed_flags &= SUPPORTED_FIF_FLAGS;
@@ -1000,11 +1178,13 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
1000 mac->multicast_hash = hash; 1178 mac->multicast_hash = hash;
1001 spin_unlock_irqrestore(&mac->lock, flags); 1179 spin_unlock_irqrestore(&mac->lock, flags);
1002 1180
1003 /* XXX: these can be called here now, can sleep now! */ 1181 zd_chip_set_multicast_hash(&mac->chip, &hash);
1004 queue_work(zd_workqueue, &mac->set_multicast_hash_work);
1005 1182
1006 if (changed_flags & FIF_CONTROL) 1183 if (changed_flags & FIF_CONTROL) {
1007 queue_work(zd_workqueue, &mac->set_rx_filter_work); 1184 r = set_rx_filter(mac);
1185 if (r)
1186 dev_err(zd_mac_dev(mac), "set_rx_filter error %d\n", r);
1187 }
1008 1188
1009 /* no handling required for FIF_OTHER_BSS as we don't currently 1189 /* no handling required for FIF_OTHER_BSS as we don't currently
1010 * do BSSID filtering */ 1190 * do BSSID filtering */
@@ -1016,20 +1196,9 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
1016 * time. */ 1196 * time. */
1017} 1197}
1018 1198
1019static void set_rts_cts_work(struct work_struct *work) 1199static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble)
1020{ 1200{
1021 struct zd_mac *mac =
1022 container_of(work, struct zd_mac, set_rts_cts_work);
1023 unsigned long flags;
1024 unsigned int short_preamble;
1025
1026 mutex_lock(&mac->chip.mutex); 1201 mutex_lock(&mac->chip.mutex);
1027
1028 spin_lock_irqsave(&mac->lock, flags);
1029 mac->updating_rts_rate = 0;
1030 short_preamble = mac->short_preamble;
1031 spin_unlock_irqrestore(&mac->lock, flags);
1032
1033 zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble); 1202 zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble);
1034 mutex_unlock(&mac->chip.mutex); 1203 mutex_unlock(&mac->chip.mutex);
1035} 1204}
@@ -1040,33 +1209,42 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
1040 u32 changes) 1209 u32 changes)
1041{ 1210{
1042 struct zd_mac *mac = zd_hw_mac(hw); 1211 struct zd_mac *mac = zd_hw_mac(hw);
1043 unsigned long flags;
1044 int associated; 1212 int associated;
1045 1213
1046 dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); 1214 dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
1047 1215
1048 if (mac->type == NL80211_IFTYPE_MESH_POINT || 1216 if (mac->type == NL80211_IFTYPE_MESH_POINT ||
1049 mac->type == NL80211_IFTYPE_ADHOC) { 1217 mac->type == NL80211_IFTYPE_ADHOC ||
1218 mac->type == NL80211_IFTYPE_AP) {
1050 associated = true; 1219 associated = true;
1051 if (changes & BSS_CHANGED_BEACON) { 1220 if (changes & BSS_CHANGED_BEACON) {
1052 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 1221 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
1053 1222
1054 if (beacon) { 1223 if (beacon) {
1224 zd_chip_disable_hwint(&mac->chip);
1055 zd_mac_config_beacon(hw, beacon); 1225 zd_mac_config_beacon(hw, beacon);
1226 zd_chip_enable_hwint(&mac->chip);
1056 kfree_skb(beacon); 1227 kfree_skb(beacon);
1057 } 1228 }
1058 } 1229 }
1059 1230
1060 if (changes & BSS_CHANGED_BEACON_ENABLED) { 1231 if (changes & BSS_CHANGED_BEACON_ENABLED) {
1061 u32 interval; 1232 u16 interval = 0;
1233 u8 period = 0;
1062 1234
1063 if (bss_conf->enable_beacon) 1235 if (bss_conf->enable_beacon) {
1064 interval = BCN_MODE_IBSS | 1236 period = bss_conf->dtim_period;
1065 bss_conf->beacon_int; 1237 interval = bss_conf->beacon_int;
1066 else 1238 }
1067 interval = 0;
1068 1239
1069 zd_set_beacon_interval(&mac->chip, interval); 1240 spin_lock_irq(&mac->lock);
1241 mac->beacon.period = period;
1242 mac->beacon.interval = interval;
1243 mac->beacon.last_update = jiffies;
1244 spin_unlock_irq(&mac->lock);
1245
1246 zd_set_beacon_interval(&mac->chip, interval, period,
1247 mac->type);
1070 } 1248 }
1071 } else 1249 } else
1072 associated = is_valid_ether_addr(bss_conf->bssid); 1250 associated = is_valid_ether_addr(bss_conf->bssid);
@@ -1078,15 +1256,11 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
1078 /* TODO: do hardware bssid filtering */ 1256 /* TODO: do hardware bssid filtering */
1079 1257
1080 if (changes & BSS_CHANGED_ERP_PREAMBLE) { 1258 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
1081 spin_lock_irqsave(&mac->lock, flags); 1259 spin_lock_irq(&mac->lock);
1082 mac->short_preamble = bss_conf->use_short_preamble; 1260 mac->short_preamble = bss_conf->use_short_preamble;
1083 if (!mac->updating_rts_rate) { 1261 spin_unlock_irq(&mac->lock);
1084 mac->updating_rts_rate = 1; 1262
1085 /* FIXME: should disable TX here, until work has 1263 set_rts_cts(mac, bss_conf->use_short_preamble);
1086 * completed and RTS_CTS reg is updated */
1087 queue_work(zd_workqueue, &mac->set_rts_cts_work);
1088 }
1089 spin_unlock_irqrestore(&mac->lock, flags);
1090 } 1264 }
1091} 1265}
1092 1266
@@ -1138,12 +1312,14 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
1138 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; 1312 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
1139 1313
1140 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 1314 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1141 IEEE80211_HW_SIGNAL_UNSPEC; 1315 IEEE80211_HW_SIGNAL_UNSPEC |
1316 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
1142 1317
1143 hw->wiphy->interface_modes = 1318 hw->wiphy->interface_modes =
1144 BIT(NL80211_IFTYPE_MESH_POINT) | 1319 BIT(NL80211_IFTYPE_MESH_POINT) |
1145 BIT(NL80211_IFTYPE_STATION) | 1320 BIT(NL80211_IFTYPE_STATION) |
1146 BIT(NL80211_IFTYPE_ADHOC); 1321 BIT(NL80211_IFTYPE_ADHOC) |
1322 BIT(NL80211_IFTYPE_AP);
1147 1323
1148 hw->max_signal = 100; 1324 hw->max_signal = 100;
1149 hw->queues = 1; 1325 hw->queues = 1;
@@ -1160,15 +1336,82 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
1160 1336
1161 zd_chip_init(&mac->chip, hw, intf); 1337 zd_chip_init(&mac->chip, hw, intf);
1162 housekeeping_init(mac); 1338 housekeeping_init(mac);
1163 INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); 1339 beacon_init(mac);
1164 INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
1165 INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler);
1166 INIT_WORK(&mac->process_intr, zd_process_intr); 1340 INIT_WORK(&mac->process_intr, zd_process_intr);
1167 1341
1168 SET_IEEE80211_DEV(hw, &intf->dev); 1342 SET_IEEE80211_DEV(hw, &intf->dev);
1169 return hw; 1343 return hw;
1170} 1344}
1171 1345
1346#define BEACON_WATCHDOG_DELAY round_jiffies_relative(HZ)
1347
1348static void beacon_watchdog_handler(struct work_struct *work)
1349{
1350 struct zd_mac *mac =
1351 container_of(work, struct zd_mac, beacon.watchdog_work.work);
1352 struct sk_buff *beacon;
1353 unsigned long timeout;
1354 int interval, period;
1355
1356 if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags))
1357 goto rearm;
1358 if (mac->type != NL80211_IFTYPE_AP || !mac->vif)
1359 goto rearm;
1360
1361 spin_lock_irq(&mac->lock);
1362 interval = mac->beacon.interval;
1363 period = mac->beacon.period;
1364 timeout = mac->beacon.last_update + msecs_to_jiffies(interval) + HZ;
1365 spin_unlock_irq(&mac->lock);
1366
1367 if (interval > 0 && time_is_before_jiffies(timeout)) {
1368 dev_dbg_f(zd_mac_dev(mac), "beacon interrupt stalled, "
1369 "restarting. "
1370 "(interval: %d, dtim: %d)\n",
1371 interval, period);
1372
1373 zd_chip_disable_hwint(&mac->chip);
1374
1375 beacon = ieee80211_beacon_get(mac->hw, mac->vif);
1376 if (beacon) {
1377 zd_mac_config_beacon(mac->hw, beacon);
1378 kfree_skb(beacon);
1379 }
1380
1381 zd_set_beacon_interval(&mac->chip, interval, period, mac->type);
1382
1383 zd_chip_enable_hwint(&mac->chip);
1384
1385 spin_lock_irq(&mac->lock);
1386 mac->beacon.last_update = jiffies;
1387 spin_unlock_irq(&mac->lock);
1388 }
1389
1390rearm:
1391 queue_delayed_work(zd_workqueue, &mac->beacon.watchdog_work,
1392 BEACON_WATCHDOG_DELAY);
1393}
1394
1395static void beacon_init(struct zd_mac *mac)
1396{
1397 INIT_DELAYED_WORK(&mac->beacon.watchdog_work, beacon_watchdog_handler);
1398}
1399
1400static void beacon_enable(struct zd_mac *mac)
1401{
1402 dev_dbg_f(zd_mac_dev(mac), "\n");
1403
1404 mac->beacon.last_update = jiffies;
1405 queue_delayed_work(zd_workqueue, &mac->beacon.watchdog_work,
1406 BEACON_WATCHDOG_DELAY);
1407}
1408
1409static void beacon_disable(struct zd_mac *mac)
1410{
1411 dev_dbg_f(zd_mac_dev(mac), "\n");
1412 cancel_delayed_work_sync(&mac->beacon.watchdog_work);
1413}
1414
1172#define LINK_LED_WORK_DELAY HZ 1415#define LINK_LED_WORK_DELAY HZ
1173 1416
1174static void link_led_handler(struct work_struct *work) 1417static void link_led_handler(struct work_struct *work)
@@ -1179,6 +1422,9 @@ static void link_led_handler(struct work_struct *work)
1179 int is_associated; 1422 int is_associated;
1180 int r; 1423 int r;
1181 1424
1425 if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags))
1426 goto requeue;
1427
1182 spin_lock_irq(&mac->lock); 1428 spin_lock_irq(&mac->lock);
1183 is_associated = mac->associated; 1429 is_associated = mac->associated;
1184 spin_unlock_irq(&mac->lock); 1430 spin_unlock_irq(&mac->lock);
@@ -1188,6 +1434,7 @@ static void link_led_handler(struct work_struct *work)
1188 if (r) 1434 if (r)
1189 dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r); 1435 dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);
1190 1436
1437requeue:
1191 queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, 1438 queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
1192 LINK_LED_WORK_DELAY); 1439 LINK_LED_WORK_DELAY);
1193} 1440}