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.c448
1 files changed, 348 insertions, 100 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 6107304cb94c..74a269ebbeb9 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;
676
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;
581 682
582 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0); 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,
@@ -779,6 +928,13 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
779 928
780 mac->ack_pending = 1; 929 mac->ack_pending = 1;
781 mac->ack_signal = stats->signal; 930 mac->ack_signal = stats->signal;
931
932 /* Prevent pending tx-packet on AP-mode */
933 if (mac->type == NL80211_IFTYPE_AP) {
934 skb = __skb_dequeue(q);
935 zd_mac_tx_status(hw, skb, mac->ack_signal, NULL);
936 mac->ack_pending = 0;
937 }
782 } 938 }
783 939
784 spin_unlock_irqrestore(&q->lock, flags); 940 spin_unlock_irqrestore(&q->lock, flags);
@@ -882,13 +1038,16 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,
882 case NL80211_IFTYPE_MESH_POINT: 1038 case NL80211_IFTYPE_MESH_POINT:
883 case NL80211_IFTYPE_STATION: 1039 case NL80211_IFTYPE_STATION:
884 case NL80211_IFTYPE_ADHOC: 1040 case NL80211_IFTYPE_ADHOC:
1041 case NL80211_IFTYPE_AP:
885 mac->type = vif->type; 1042 mac->type = vif->type;
886 break; 1043 break;
887 default: 1044 default:
888 return -EOPNOTSUPP; 1045 return -EOPNOTSUPP;
889 } 1046 }
890 1047
891 return zd_write_mac_addr(&mac->chip, vif->addr); 1048 mac->vif = vif;
1049
1050 return set_mac_and_bssid(mac);
892} 1051}
893 1052
894static void zd_op_remove_interface(struct ieee80211_hw *hw, 1053static void zd_op_remove_interface(struct ieee80211_hw *hw,
@@ -896,7 +1055,8 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw,
896{ 1055{
897 struct zd_mac *mac = zd_hw_mac(hw); 1056 struct zd_mac *mac = zd_hw_mac(hw);
898 mac->type = NL80211_IFTYPE_UNSPECIFIED; 1057 mac->type = NL80211_IFTYPE_UNSPECIFIED;
899 zd_set_beacon_interval(&mac->chip, 0); 1058 mac->vif = NULL;
1059 zd_set_beacon_interval(&mac->chip, 0, 0, NL80211_IFTYPE_UNSPECIFIED);
900 zd_write_mac_addr(&mac->chip, NULL); 1060 zd_write_mac_addr(&mac->chip, NULL);
901} 1061}
902 1062
@@ -905,49 +1065,67 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
905 struct zd_mac *mac = zd_hw_mac(hw); 1065 struct zd_mac *mac = zd_hw_mac(hw);
906 struct ieee80211_conf *conf = &hw->conf; 1066 struct ieee80211_conf *conf = &hw->conf;
907 1067
1068 spin_lock_irq(&mac->lock);
1069 mac->channel = conf->channel->hw_value;
1070 spin_unlock_irq(&mac->lock);
1071
908 return zd_chip_set_channel(&mac->chip, conf->channel->hw_value); 1072 return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
909} 1073}
910 1074
911static void zd_process_intr(struct work_struct *work) 1075static void zd_beacon_done(struct zd_mac *mac)
912{ 1076{
913 u16 int_status; 1077 struct sk_buff *skb, *beacon;
914 struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
915 1078
916 int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4)); 1079 if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags))
917 if (int_status & INT_CFG_NEXT_BCN) 1080 return;
918 dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n"); 1081 if (!mac->vif || mac->vif->type != NL80211_IFTYPE_AP)
919 else 1082 return;
920 dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
921
922 zd_chip_enable_hwint(&mac->chip);
923}
924 1083
1084 /*
1085 * Send out buffered broad- and multicast frames.
1086 */
1087 while (!ieee80211_queue_stopped(mac->hw, 0)) {
1088 skb = ieee80211_get_buffered_bc(mac->hw, mac->vif);
1089 if (!skb)
1090 break;
1091 zd_op_tx(mac->hw, skb);
1092 }
925 1093
926static void set_multicast_hash_handler(struct work_struct *work) 1094 /*
927{ 1095 * Fetch next beacon so that tim_count is updated.
928 struct zd_mac *mac = 1096 */
929 container_of(work, struct zd_mac, set_multicast_hash_work); 1097 beacon = ieee80211_beacon_get(mac->hw, mac->vif);
930 struct zd_mc_hash hash; 1098 if (beacon) {
1099 zd_mac_config_beacon(mac->hw, beacon);
1100 kfree_skb(beacon);
1101 }
931 1102
932 spin_lock_irq(&mac->lock); 1103 spin_lock_irq(&mac->lock);
933 hash = mac->multicast_hash; 1104 mac->beacon.last_update = jiffies;
934 spin_unlock_irq(&mac->lock); 1105 spin_unlock_irq(&mac->lock);
935
936 zd_chip_set_multicast_hash(&mac->chip, &hash);
937} 1106}
938 1107
939static void set_rx_filter_handler(struct work_struct *work) 1108static void zd_process_intr(struct work_struct *work)
940{ 1109{
941 struct zd_mac *mac = 1110 u16 int_status;
942 container_of(work, struct zd_mac, set_rx_filter_work); 1111 unsigned long flags;
943 int r; 1112 struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
944 1113
945 dev_dbg_f(zd_mac_dev(mac), "\n"); 1114 spin_lock_irqsave(&mac->lock, flags);
946 r = set_rx_filter(mac); 1115 int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer + 4));
947 if (r) 1116 spin_unlock_irqrestore(&mac->lock, flags);
948 dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r); 1117
1118 if (int_status & INT_CFG_NEXT_BCN) {
1119 /*dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");*/
1120 zd_beacon_done(mac);
1121 } else {
1122 dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
1123 }
1124
1125 zd_chip_enable_hwint(&mac->chip);
949} 1126}
950 1127
1128
951static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw, 1129static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw,
952 struct netdev_hw_addr_list *mc_list) 1130 struct netdev_hw_addr_list *mc_list)
953{ 1131{
@@ -979,6 +1157,7 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
979 }; 1157 };
980 struct zd_mac *mac = zd_hw_mac(hw); 1158 struct zd_mac *mac = zd_hw_mac(hw);
981 unsigned long flags; 1159 unsigned long flags;
1160 int r;
982 1161
983 /* Only deal with supported flags */ 1162 /* Only deal with supported flags */
984 changed_flags &= SUPPORTED_FIF_FLAGS; 1163 changed_flags &= SUPPORTED_FIF_FLAGS;
@@ -1000,11 +1179,13 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
1000 mac->multicast_hash = hash; 1179 mac->multicast_hash = hash;
1001 spin_unlock_irqrestore(&mac->lock, flags); 1180 spin_unlock_irqrestore(&mac->lock, flags);
1002 1181
1003 /* XXX: these can be called here now, can sleep now! */ 1182 zd_chip_set_multicast_hash(&mac->chip, &hash);
1004 queue_work(zd_workqueue, &mac->set_multicast_hash_work);
1005 1183
1006 if (changed_flags & FIF_CONTROL) 1184 if (changed_flags & FIF_CONTROL) {
1007 queue_work(zd_workqueue, &mac->set_rx_filter_work); 1185 r = set_rx_filter(mac);
1186 if (r)
1187 dev_err(zd_mac_dev(mac), "set_rx_filter error %d\n", r);
1188 }
1008 1189
1009 /* no handling required for FIF_OTHER_BSS as we don't currently 1190 /* no handling required for FIF_OTHER_BSS as we don't currently
1010 * do BSSID filtering */ 1191 * do BSSID filtering */
@@ -1016,20 +1197,9 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
1016 * time. */ 1197 * time. */
1017} 1198}
1018 1199
1019static void set_rts_cts_work(struct work_struct *work) 1200static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble)
1020{ 1201{
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); 1202 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); 1203 zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble);
1034 mutex_unlock(&mac->chip.mutex); 1204 mutex_unlock(&mac->chip.mutex);
1035} 1205}
@@ -1040,33 +1210,42 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
1040 u32 changes) 1210 u32 changes)
1041{ 1211{
1042 struct zd_mac *mac = zd_hw_mac(hw); 1212 struct zd_mac *mac = zd_hw_mac(hw);
1043 unsigned long flags;
1044 int associated; 1213 int associated;
1045 1214
1046 dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); 1215 dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
1047 1216
1048 if (mac->type == NL80211_IFTYPE_MESH_POINT || 1217 if (mac->type == NL80211_IFTYPE_MESH_POINT ||
1049 mac->type == NL80211_IFTYPE_ADHOC) { 1218 mac->type == NL80211_IFTYPE_ADHOC ||
1219 mac->type == NL80211_IFTYPE_AP) {
1050 associated = true; 1220 associated = true;
1051 if (changes & BSS_CHANGED_BEACON) { 1221 if (changes & BSS_CHANGED_BEACON) {
1052 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 1222 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
1053 1223
1054 if (beacon) { 1224 if (beacon) {
1225 zd_chip_disable_hwint(&mac->chip);
1055 zd_mac_config_beacon(hw, beacon); 1226 zd_mac_config_beacon(hw, beacon);
1227 zd_chip_enable_hwint(&mac->chip);
1056 kfree_skb(beacon); 1228 kfree_skb(beacon);
1057 } 1229 }
1058 } 1230 }
1059 1231
1060 if (changes & BSS_CHANGED_BEACON_ENABLED) { 1232 if (changes & BSS_CHANGED_BEACON_ENABLED) {
1061 u32 interval; 1233 u16 interval = 0;
1234 u8 period = 0;
1062 1235
1063 if (bss_conf->enable_beacon) 1236 if (bss_conf->enable_beacon) {
1064 interval = BCN_MODE_IBSS | 1237 period = bss_conf->dtim_period;
1065 bss_conf->beacon_int; 1238 interval = bss_conf->beacon_int;
1066 else 1239 }
1067 interval = 0;
1068 1240
1069 zd_set_beacon_interval(&mac->chip, interval); 1241 spin_lock_irq(&mac->lock);
1242 mac->beacon.period = period;
1243 mac->beacon.interval = interval;
1244 mac->beacon.last_update = jiffies;
1245 spin_unlock_irq(&mac->lock);
1246
1247 zd_set_beacon_interval(&mac->chip, interval, period,
1248 mac->type);
1070 } 1249 }
1071 } else 1250 } else
1072 associated = is_valid_ether_addr(bss_conf->bssid); 1251 associated = is_valid_ether_addr(bss_conf->bssid);
@@ -1078,15 +1257,11 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
1078 /* TODO: do hardware bssid filtering */ 1257 /* TODO: do hardware bssid filtering */
1079 1258
1080 if (changes & BSS_CHANGED_ERP_PREAMBLE) { 1259 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
1081 spin_lock_irqsave(&mac->lock, flags); 1260 spin_lock_irq(&mac->lock);
1082 mac->short_preamble = bss_conf->use_short_preamble; 1261 mac->short_preamble = bss_conf->use_short_preamble;
1083 if (!mac->updating_rts_rate) { 1262 spin_unlock_irq(&mac->lock);
1084 mac->updating_rts_rate = 1; 1263
1085 /* FIXME: should disable TX here, until work has 1264 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 } 1265 }
1091} 1266}
1092 1267
@@ -1138,12 +1313,14 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
1138 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; 1313 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
1139 1314
1140 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 1315 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1141 IEEE80211_HW_SIGNAL_UNSPEC; 1316 IEEE80211_HW_SIGNAL_UNSPEC |
1317 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
1142 1318
1143 hw->wiphy->interface_modes = 1319 hw->wiphy->interface_modes =
1144 BIT(NL80211_IFTYPE_MESH_POINT) | 1320 BIT(NL80211_IFTYPE_MESH_POINT) |
1145 BIT(NL80211_IFTYPE_STATION) | 1321 BIT(NL80211_IFTYPE_STATION) |
1146 BIT(NL80211_IFTYPE_ADHOC); 1322 BIT(NL80211_IFTYPE_ADHOC) |
1323 BIT(NL80211_IFTYPE_AP);
1147 1324
1148 hw->max_signal = 100; 1325 hw->max_signal = 100;
1149 hw->queues = 1; 1326 hw->queues = 1;
@@ -1160,15 +1337,82 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
1160 1337
1161 zd_chip_init(&mac->chip, hw, intf); 1338 zd_chip_init(&mac->chip, hw, intf);
1162 housekeeping_init(mac); 1339 housekeeping_init(mac);
1163 INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); 1340 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); 1341 INIT_WORK(&mac->process_intr, zd_process_intr);
1167 1342
1168 SET_IEEE80211_DEV(hw, &intf->dev); 1343 SET_IEEE80211_DEV(hw, &intf->dev);
1169 return hw; 1344 return hw;
1170} 1345}
1171 1346
1347#define BEACON_WATCHDOG_DELAY round_jiffies_relative(HZ)
1348
1349static void beacon_watchdog_handler(struct work_struct *work)
1350{
1351 struct zd_mac *mac =
1352 container_of(work, struct zd_mac, beacon.watchdog_work.work);
1353 struct sk_buff *beacon;
1354 unsigned long timeout;
1355 int interval, period;
1356
1357 if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags))
1358 goto rearm;
1359 if (mac->type != NL80211_IFTYPE_AP || !mac->vif)
1360 goto rearm;
1361
1362 spin_lock_irq(&mac->lock);
1363 interval = mac->beacon.interval;
1364 period = mac->beacon.period;
1365 timeout = mac->beacon.last_update + msecs_to_jiffies(interval) + HZ;
1366 spin_unlock_irq(&mac->lock);
1367
1368 if (interval > 0 && time_is_before_jiffies(timeout)) {
1369 dev_dbg_f(zd_mac_dev(mac), "beacon interrupt stalled, "
1370 "restarting. "
1371 "(interval: %d, dtim: %d)\n",
1372 interval, period);
1373
1374 zd_chip_disable_hwint(&mac->chip);
1375
1376 beacon = ieee80211_beacon_get(mac->hw, mac->vif);
1377 if (beacon) {
1378 zd_mac_config_beacon(mac->hw, beacon);
1379 kfree_skb(beacon);
1380 }
1381
1382 zd_set_beacon_interval(&mac->chip, interval, period, mac->type);
1383
1384 zd_chip_enable_hwint(&mac->chip);
1385
1386 spin_lock_irq(&mac->lock);
1387 mac->beacon.last_update = jiffies;
1388 spin_unlock_irq(&mac->lock);
1389 }
1390
1391rearm:
1392 queue_delayed_work(zd_workqueue, &mac->beacon.watchdog_work,
1393 BEACON_WATCHDOG_DELAY);
1394}
1395
1396static void beacon_init(struct zd_mac *mac)
1397{
1398 INIT_DELAYED_WORK(&mac->beacon.watchdog_work, beacon_watchdog_handler);
1399}
1400
1401static void beacon_enable(struct zd_mac *mac)
1402{
1403 dev_dbg_f(zd_mac_dev(mac), "\n");
1404
1405 mac->beacon.last_update = jiffies;
1406 queue_delayed_work(zd_workqueue, &mac->beacon.watchdog_work,
1407 BEACON_WATCHDOG_DELAY);
1408}
1409
1410static void beacon_disable(struct zd_mac *mac)
1411{
1412 dev_dbg_f(zd_mac_dev(mac), "\n");
1413 cancel_delayed_work_sync(&mac->beacon.watchdog_work);
1414}
1415
1172#define LINK_LED_WORK_DELAY HZ 1416#define LINK_LED_WORK_DELAY HZ
1173 1417
1174static void link_led_handler(struct work_struct *work) 1418static void link_led_handler(struct work_struct *work)
@@ -1179,6 +1423,9 @@ static void link_led_handler(struct work_struct *work)
1179 int is_associated; 1423 int is_associated;
1180 int r; 1424 int r;
1181 1425
1426 if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags))
1427 goto requeue;
1428
1182 spin_lock_irq(&mac->lock); 1429 spin_lock_irq(&mac->lock);
1183 is_associated = mac->associated; 1430 is_associated = mac->associated;
1184 spin_unlock_irq(&mac->lock); 1431 spin_unlock_irq(&mac->lock);
@@ -1188,6 +1435,7 @@ static void link_led_handler(struct work_struct *work)
1188 if (r) 1435 if (r)
1189 dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r); 1436 dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);
1190 1437
1438requeue:
1191 queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, 1439 queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
1192 LINK_LED_WORK_DELAY); 1440 LINK_LED_WORK_DELAY);
1193} 1441}