diff options
author | Eliad Peller <eliad@wizery.com> | 2011-10-05 05:56:05 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-10-07 01:33:46 -0400 |
commit | c7ffb902cca655e4d6bdda4156407008573bb214 (patch) | |
tree | d5dc1af5d2fd29a59d45fe6dcde61c58c3aa9503 /drivers | |
parent | d0802abdf9c60b1dadb097e806022f3449b0cc6b (diff) |
wl12xx: move ap_hlid_map into wlvif.ap
Add wlvif->links_map bitmap to represent all the links
allocated for this vif.
AP vif also has a sta_hlid_map bitmap, which represents
the links stations connected to it (sta_hlid_bitmap is
a subset of wlvif->links_map, which itself is a subset
of the global wl->links_map)
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.c | 34 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/debugfs.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/event.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/event.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 92 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 35 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 24 |
9 files changed, 92 insertions, 117 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 68375ffb4123..102a8a5371e4 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -434,23 +434,25 @@ out: | |||
434 | return ret; | 434 | return ret; |
435 | } | 435 | } |
436 | 436 | ||
437 | static int wl12xx_allocate_link(struct wl1271 *wl, u8 *hlid) | 437 | int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) |
438 | { | 438 | { |
439 | u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); | 439 | u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); |
440 | if (link >= WL12XX_MAX_LINKS) | 440 | if (link >= WL12XX_MAX_LINKS) |
441 | return -EBUSY; | 441 | return -EBUSY; |
442 | 442 | ||
443 | __set_bit(link, wl->links_map); | 443 | __set_bit(link, wl->links_map); |
444 | __set_bit(link, wlvif->links_map); | ||
444 | *hlid = link; | 445 | *hlid = link; |
445 | return 0; | 446 | return 0; |
446 | } | 447 | } |
447 | 448 | ||
448 | static void wl12xx_free_link(struct wl1271 *wl, u8 *hlid) | 449 | void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) |
449 | { | 450 | { |
450 | if (*hlid == WL12XX_INVALID_LINK_ID) | 451 | if (*hlid == WL12XX_INVALID_LINK_ID) |
451 | return; | 452 | return; |
452 | 453 | ||
453 | __clear_bit(*hlid, wl->links_map); | 454 | __clear_bit(*hlid, wl->links_map); |
455 | __clear_bit(*hlid, wlvif->links_map); | ||
454 | *hlid = WL12XX_INVALID_LINK_ID; | 456 | *hlid = WL12XX_INVALID_LINK_ID; |
455 | } | 457 | } |
456 | 458 | ||
@@ -484,7 +486,7 @@ int wl12xx_cmd_role_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
484 | cmd->channel = wl->channel; | 486 | cmd->channel = wl->channel; |
485 | 487 | ||
486 | if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) { | 488 | if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) { |
487 | ret = wl12xx_allocate_link(wl, &wlvif->dev_hlid); | 489 | ret = wl12xx_allocate_link(wl, wlvif, &wlvif->dev_hlid); |
488 | if (ret) | 490 | if (ret) |
489 | goto out_free; | 491 | goto out_free; |
490 | } | 492 | } |
@@ -504,7 +506,7 @@ int wl12xx_cmd_role_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
504 | 506 | ||
505 | err_hlid: | 507 | err_hlid: |
506 | /* clear links on error */ | 508 | /* clear links on error */ |
507 | wl12xx_free_link(wl, &wlvif->dev_hlid); | 509 | wl12xx_free_link(wl, wlvif, &wlvif->dev_hlid); |
508 | 510 | ||
509 | out_free: | 511 | out_free: |
510 | kfree(cmd); | 512 | kfree(cmd); |
@@ -545,7 +547,7 @@ int wl12xx_cmd_role_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
545 | goto out_free; | 547 | goto out_free; |
546 | } | 548 | } |
547 | 549 | ||
548 | wl12xx_free_link(wl, &wlvif->dev_hlid); | 550 | wl12xx_free_link(wl, wlvif, &wlvif->dev_hlid); |
549 | 551 | ||
550 | out_free: | 552 | out_free: |
551 | kfree(cmd); | 553 | kfree(cmd); |
@@ -581,7 +583,7 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
581 | cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set); | 583 | cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set); |
582 | 584 | ||
583 | if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) { | 585 | if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) { |
584 | ret = wl12xx_allocate_link(wl, &wlvif->sta.hlid); | 586 | ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid); |
585 | if (ret) | 587 | if (ret) |
586 | goto out_free; | 588 | goto out_free; |
587 | } | 589 | } |
@@ -604,7 +606,7 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
604 | 606 | ||
605 | err_hlid: | 607 | err_hlid: |
606 | /* clear links on error. */ | 608 | /* clear links on error. */ |
607 | wl12xx_free_link(wl, &wlvif->sta.hlid); | 609 | wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid); |
608 | 610 | ||
609 | out_free: | 611 | out_free: |
610 | kfree(cmd); | 612 | kfree(cmd); |
@@ -640,7 +642,7 @@ int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
640 | goto out_free; | 642 | goto out_free; |
641 | } | 643 | } |
642 | 644 | ||
643 | wl12xx_free_link(wl, &wlvif->sta.hlid); | 645 | wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid); |
644 | 646 | ||
645 | out_free: | 647 | out_free: |
646 | kfree(cmd); | 648 | kfree(cmd); |
@@ -670,11 +672,11 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
670 | goto out; | 672 | goto out; |
671 | } | 673 | } |
672 | 674 | ||
673 | ret = wl12xx_allocate_link(wl, &wlvif->ap.global_hlid); | 675 | ret = wl12xx_allocate_link(wl, wlvif, &wlvif->ap.global_hlid); |
674 | if (ret < 0) | 676 | if (ret < 0) |
675 | goto out_free; | 677 | goto out_free; |
676 | 678 | ||
677 | ret = wl12xx_allocate_link(wl, &wlvif->ap.bcast_hlid); | 679 | ret = wl12xx_allocate_link(wl, wlvif, &wlvif->ap.bcast_hlid); |
678 | if (ret < 0) | 680 | if (ret < 0) |
679 | goto out_free_global; | 681 | goto out_free_global; |
680 | 682 | ||
@@ -724,10 +726,10 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
724 | goto out_free; | 726 | goto out_free; |
725 | 727 | ||
726 | out_free_bcast: | 728 | out_free_bcast: |
727 | wl12xx_free_link(wl, &wlvif->ap.bcast_hlid); | 729 | wl12xx_free_link(wl, wlvif, &wlvif->ap.bcast_hlid); |
728 | 730 | ||
729 | out_free_global: | 731 | out_free_global: |
730 | wl12xx_free_link(wl, &wlvif->ap.global_hlid); | 732 | wl12xx_free_link(wl, wlvif, &wlvif->ap.global_hlid); |
731 | 733 | ||
732 | out_free: | 734 | out_free: |
733 | kfree(cmd); | 735 | kfree(cmd); |
@@ -757,8 +759,8 @@ int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
757 | goto out_free; | 759 | goto out_free; |
758 | } | 760 | } |
759 | 761 | ||
760 | wl12xx_free_link(wl, &wlvif->ap.bcast_hlid); | 762 | wl12xx_free_link(wl, wlvif, &wlvif->ap.bcast_hlid); |
761 | wl12xx_free_link(wl, &wlvif->ap.global_hlid); | 763 | wl12xx_free_link(wl, wlvif, &wlvif->ap.global_hlid); |
762 | 764 | ||
763 | out_free: | 765 | out_free: |
764 | kfree(cmd); | 766 | kfree(cmd); |
@@ -796,7 +798,7 @@ int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
796 | cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set); | 798 | cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set); |
797 | 799 | ||
798 | if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) { | 800 | if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) { |
799 | ret = wl12xx_allocate_link(wl, &wlvif->sta.hlid); | 801 | ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid); |
800 | if (ret) | 802 | if (ret) |
801 | goto out_free; | 803 | goto out_free; |
802 | } | 804 | } |
@@ -821,7 +823,7 @@ int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
821 | 823 | ||
822 | err_hlid: | 824 | err_hlid: |
823 | /* clear links on error. */ | 825 | /* clear links on error. */ |
824 | wl12xx_free_link(wl, &wlvif->sta.hlid); | 826 | wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid); |
825 | 827 | ||
826 | out_free: | 828 | out_free: |
827 | kfree(cmd); | 829 | kfree(cmd); |
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 9624828b76e8..d2670d379b75 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h | |||
@@ -89,6 +89,9 @@ int wl12xx_cmd_stop_fwlog(struct wl1271 *wl); | |||
89 | int wl12xx_cmd_channel_switch(struct wl1271 *wl, | 89 | int wl12xx_cmd_channel_switch(struct wl1271 *wl, |
90 | struct ieee80211_channel_switch *ch_switch); | 90 | struct ieee80211_channel_switch *ch_switch); |
91 | int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl); | 91 | int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl); |
92 | int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, | ||
93 | u8 *hlid); | ||
94 | void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid); | ||
92 | 95 | ||
93 | enum wl1271_commands { | 96 | enum wl1271_commands { |
94 | CMD_INTERROGATE = 1, /*use this to read information elements*/ | 97 | CMD_INTERROGATE = 1, /*use this to read information elements*/ |
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index ee42a43d6a66..f0398d037d4d 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c | |||
@@ -355,7 +355,6 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf, | |||
355 | DRIVER_STATE_PRINT_INT(sg_enabled); | 355 | DRIVER_STATE_PRINT_INT(sg_enabled); |
356 | DRIVER_STATE_PRINT_INT(enable_11a); | 356 | DRIVER_STATE_PRINT_INT(enable_11a); |
357 | DRIVER_STATE_PRINT_INT(noise); | 357 | DRIVER_STATE_PRINT_INT(noise); |
358 | DRIVER_STATE_PRINT_LHEX(ap_hlid_map[0]); | ||
359 | DRIVER_STATE_PRINT_INT(last_tx_hlid); | 358 | DRIVER_STATE_PRINT_INT(last_tx_hlid); |
360 | DRIVER_STATE_PRINT_HEX(ap_fw_ps_map); | 359 | DRIVER_STATE_PRINT_HEX(ap_fw_ps_map); |
361 | DRIVER_STATE_PRINT_LHEX(ap_ps_map); | 360 | DRIVER_STATE_PRINT_LHEX(ap_ps_map); |
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 8c31274228ea..486c8ee0101a 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c | |||
@@ -189,11 +189,12 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
189 | ieee80211_stop_rx_ba_session(wl->vif, wlvif->sta.ba_rx_bitmap, | 189 | ieee80211_stop_rx_ba_session(wl->vif, wlvif->sta.ba_rx_bitmap, |
190 | wl->vif->bss_conf.bssid); | 190 | wl->vif->bss_conf.bssid); |
191 | } else { | 191 | } else { |
192 | int i; | 192 | u8 hlid; |
193 | struct wl1271_link *lnk; | 193 | struct wl1271_link *lnk; |
194 | for (i = WL1271_AP_STA_HLID_START; i < AP_MAX_LINKS; i++) { | 194 | for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, |
195 | lnk = &wl->links[i]; | 195 | WL12XX_MAX_LINKS) { |
196 | if (!wl1271_is_active_sta(wl, i) || !lnk->ba_bitmap) | 196 | lnk = &wl->links[hlid]; |
197 | if (!lnk->ba_bitmap) | ||
197 | continue; | 198 | continue; |
198 | 199 | ||
199 | ieee80211_stop_rx_ba_session(wl->vif, | 200 | ieee80211_stop_rx_ba_session(wl->vif, |
@@ -355,10 +356,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | |||
355 | const u8 *addr; | 356 | const u8 *addr; |
356 | int h; | 357 | int h; |
357 | 358 | ||
358 | for (h = find_first_bit(&sta_bitmap, AP_MAX_LINKS); | 359 | for_each_set_bit(h, &sta_bitmap, WL12XX_MAX_LINKS) { |
359 | h < AP_MAX_LINKS; | 360 | if (!test_bit(h, wlvif->ap.sta_hlid_map)) |
360 | h = find_next_bit(&sta_bitmap, AP_MAX_LINKS, h+1)) { | ||
361 | if (!wl1271_is_active_sta(wl, h)) | ||
362 | continue; | 361 | continue; |
363 | 362 | ||
364 | addr = wl->links[h].addr; | 363 | addr = wl->links[h].addr; |
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h index 49c1a0ede5b1..1d878ba47bf4 100644 --- a/drivers/net/wireless/wl12xx/event.h +++ b/drivers/net/wireless/wl12xx/event.h | |||
@@ -132,7 +132,4 @@ void wl1271_event_mbox_config(struct wl1271 *wl); | |||
132 | int wl1271_event_handle(struct wl1271 *wl, u8 mbox); | 132 | int wl1271_event_handle(struct wl1271 *wl, u8 mbox); |
133 | void wl1271_pspoll_work(struct work_struct *work); | 133 | void wl1271_pspoll_work(struct work_struct *work); |
134 | 134 | ||
135 | /* Functions from main.c */ | ||
136 | bool wl1271_is_active_sta(struct wl1271 *wl, u8 hlid); | ||
137 | |||
138 | #endif | 135 | #endif |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 984dae881a8d..f712f0fb50be 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -778,10 +778,6 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts) | |||
778 | { | 778 | { |
779 | bool fw_ps, single_sta; | 779 | bool fw_ps, single_sta; |
780 | 780 | ||
781 | /* only regulate station links */ | ||
782 | if (hlid < WL1271_AP_STA_HLID_START) | ||
783 | return; | ||
784 | |||
785 | fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); | 781 | fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); |
786 | single_sta = (wl->active_sta_count == 1); | 782 | single_sta = (wl->active_sta_count == 1); |
787 | 783 | ||
@@ -801,21 +797,11 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts) | |||
801 | wl1271_ps_link_start(wl, hlid, true); | 797 | wl1271_ps_link_start(wl, hlid, true); |
802 | } | 798 | } |
803 | 799 | ||
804 | bool wl1271_is_active_sta(struct wl1271 *wl, u8 hlid) | ||
805 | { | ||
806 | int id; | ||
807 | |||
808 | /* global/broadcast "stations" are always active */ | ||
809 | if (hlid < WL1271_AP_STA_HLID_START) | ||
810 | return true; | ||
811 | |||
812 | id = hlid - WL1271_AP_STA_HLID_START; | ||
813 | return test_bit(id, wl->ap_hlid_map); | ||
814 | } | ||
815 | |||
816 | static void wl12xx_irq_update_links_status(struct wl1271 *wl, | 800 | static void wl12xx_irq_update_links_status(struct wl1271 *wl, |
801 | struct wl12xx_vif *wlvif, | ||
817 | struct wl12xx_fw_status *status) | 802 | struct wl12xx_fw_status *status) |
818 | { | 803 | { |
804 | struct wl1271_link *lnk; | ||
819 | u32 cur_fw_ps_map; | 805 | u32 cur_fw_ps_map; |
820 | u8 hlid, cnt; | 806 | u8 hlid, cnt; |
821 | 807 | ||
@@ -831,19 +817,14 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl, | |||
831 | wl->ap_fw_ps_map = cur_fw_ps_map; | 817 | wl->ap_fw_ps_map = cur_fw_ps_map; |
832 | } | 818 | } |
833 | 819 | ||
834 | for (hlid = WL1271_AP_STA_HLID_START; hlid < AP_MAX_LINKS; hlid++) { | 820 | for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) { |
835 | if (!wl1271_is_active_sta(wl, hlid)) | 821 | lnk = &wl->links[hlid]; |
836 | continue; | 822 | cnt = status->tx_lnk_free_pkts[hlid] - lnk->prev_freed_pkts; |
837 | |||
838 | cnt = status->tx_lnk_free_pkts[hlid] - | ||
839 | wl->links[hlid].prev_freed_pkts; | ||
840 | 823 | ||
841 | wl->links[hlid].prev_freed_pkts = | 824 | lnk->prev_freed_pkts = status->tx_lnk_free_pkts[hlid]; |
842 | status->tx_lnk_free_pkts[hlid]; | 825 | lnk->allocated_pkts -= cnt; |
843 | wl->links[hlid].allocated_pkts -= cnt; | ||
844 | 826 | ||
845 | wl12xx_irq_ps_regulate_link(wl, hlid, | 827 | wl12xx_irq_ps_regulate_link(wl, hlid, lnk->allocated_pkts); |
846 | wl->links[hlid].allocated_pkts); | ||
847 | } | 828 | } |
848 | } | 829 | } |
849 | 830 | ||
@@ -907,7 +888,7 @@ static void wl12xx_fw_status(struct wl1271 *wl, | |||
907 | 888 | ||
908 | /* for AP update num of allocated TX blocks per link and ps status */ | 889 | /* for AP update num of allocated TX blocks per link and ps status */ |
909 | if (wlvif->bss_type == BSS_TYPE_AP_BSS) | 890 | if (wlvif->bss_type == BSS_TYPE_AP_BSS) |
910 | wl12xx_irq_update_links_status(wl, status); | 891 | wl12xx_irq_update_links_status(wl, wlvif, status); |
911 | 892 | ||
912 | /* update the host-chipset time offset */ | 893 | /* update the host-chipset time offset */ |
913 | getnstimeofday(&ts); | 894 | getnstimeofday(&ts); |
@@ -1505,7 +1486,7 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1505 | 1486 | ||
1506 | /* queue the packet */ | 1487 | /* queue the packet */ |
1507 | if (wlvif->bss_type == BSS_TYPE_AP_BSS) { | 1488 | if (wlvif->bss_type == BSS_TYPE_AP_BSS) { |
1508 | if (!wl1271_is_active_sta(wl, hlid)) { | 1489 | if (!test_bit(hlid, wlvif->links_map)) { |
1509 | wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", | 1490 | wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", |
1510 | hlid, q); | 1491 | hlid, q); |
1511 | dev_kfree_skb(skb); | 1492 | dev_kfree_skb(skb); |
@@ -2152,7 +2133,7 @@ deinit: | |||
2152 | wl->vif = NULL; | 2133 | wl->vif = NULL; |
2153 | wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; | 2134 | wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; |
2154 | wl1271_free_ap_keys(wl); | 2135 | wl1271_free_ap_keys(wl); |
2155 | memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map)); | 2136 | memset(wlvif->ap.sta_hlid_map, 0, sizeof(wlvif->ap.sta_hlid_map)); |
2156 | wl->ap_fw_ps_map = 0; | 2137 | wl->ap_fw_ps_map = 0; |
2157 | wl->ap_ps_map = 0; | 2138 | wl->ap_ps_map = 0; |
2158 | wl->sched_scanning = false; | 2139 | wl->sched_scanning = false; |
@@ -3946,43 +3927,44 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, | |||
3946 | } | 3927 | } |
3947 | 3928 | ||
3948 | static int wl1271_allocate_sta(struct wl1271 *wl, | 3929 | static int wl1271_allocate_sta(struct wl1271 *wl, |
3949 | struct ieee80211_sta *sta, | 3930 | struct wl12xx_vif *wlvif, |
3950 | u8 *hlid) | 3931 | struct ieee80211_sta *sta) |
3951 | { | 3932 | { |
3952 | struct wl1271_station *wl_sta; | 3933 | struct wl1271_station *wl_sta; |
3953 | int id; | 3934 | int ret; |
3954 | 3935 | ||
3955 | id = find_first_zero_bit(wl->ap_hlid_map, AP_MAX_STATIONS); | 3936 | |
3956 | if (id >= AP_MAX_STATIONS) { | 3937 | if (wl->active_sta_count >= AP_MAX_STATIONS) { |
3957 | wl1271_warning("could not allocate HLID - too much stations"); | 3938 | wl1271_warning("could not allocate HLID - too much stations"); |
3958 | return -EBUSY; | 3939 | return -EBUSY; |
3959 | } | 3940 | } |
3960 | 3941 | ||
3961 | wl_sta = (struct wl1271_station *)sta->drv_priv; | 3942 | wl_sta = (struct wl1271_station *)sta->drv_priv; |
3962 | set_bit(id, wl->ap_hlid_map); | 3943 | ret = wl12xx_allocate_link(wl, wlvif, &wl_sta->hlid); |
3963 | wl_sta->hlid = WL1271_AP_STA_HLID_START + id; | 3944 | if (ret < 0) { |
3964 | *hlid = wl_sta->hlid; | 3945 | wl1271_warning("could not allocate HLID - too many links"); |
3946 | return -EBUSY; | ||
3947 | } | ||
3948 | |||
3949 | set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map); | ||
3965 | memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN); | 3950 | memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN); |
3966 | wl->active_sta_count++; | 3951 | wl->active_sta_count++; |
3967 | return 0; | 3952 | return 0; |
3968 | } | 3953 | } |
3969 | 3954 | ||
3970 | void wl1271_free_sta(struct wl1271 *wl, u8 hlid) | 3955 | /* TODO: change wl1271_tx_reset(), so we can get sta as param */ |
3956 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) | ||
3971 | { | 3957 | { |
3972 | int id = hlid - WL1271_AP_STA_HLID_START; | 3958 | if (!test_bit(hlid, wlvif->ap.sta_hlid_map)) |
3973 | |||
3974 | if (hlid < WL1271_AP_STA_HLID_START) | ||
3975 | return; | 3959 | return; |
3976 | 3960 | ||
3977 | if (!test_bit(id, wl->ap_hlid_map)) | 3961 | clear_bit(hlid, wlvif->ap.sta_hlid_map); |
3978 | return; | ||
3979 | |||
3980 | clear_bit(id, wl->ap_hlid_map); | ||
3981 | memset(wl->links[hlid].addr, 0, ETH_ALEN); | 3962 | memset(wl->links[hlid].addr, 0, ETH_ALEN); |
3982 | wl->links[hlid].ba_bitmap = 0; | 3963 | wl->links[hlid].ba_bitmap = 0; |
3983 | wl1271_tx_reset_link_queues(wl, hlid); | 3964 | wl1271_tx_reset_link_queues(wl, hlid); |
3984 | __clear_bit(hlid, &wl->ap_ps_map); | 3965 | __clear_bit(hlid, &wl->ap_ps_map); |
3985 | __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); | 3966 | __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); |
3967 | wl12xx_free_link(wl, wlvif, &hlid); | ||
3986 | wl->active_sta_count--; | 3968 | wl->active_sta_count--; |
3987 | } | 3969 | } |
3988 | 3970 | ||
@@ -3992,6 +3974,7 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw, | |||
3992 | { | 3974 | { |
3993 | struct wl1271 *wl = hw->priv; | 3975 | struct wl1271 *wl = hw->priv; |
3994 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | 3976 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); |
3977 | struct wl1271_station *wl_sta; | ||
3995 | int ret = 0; | 3978 | int ret = 0; |
3996 | u8 hlid; | 3979 | u8 hlid; |
3997 | 3980 | ||
@@ -4005,10 +3988,13 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw, | |||
4005 | 3988 | ||
4006 | wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); | 3989 | wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); |
4007 | 3990 | ||
4008 | ret = wl1271_allocate_sta(wl, sta, &hlid); | 3991 | ret = wl1271_allocate_sta(wl, wlvif, sta); |
4009 | if (ret < 0) | 3992 | if (ret < 0) |
4010 | goto out; | 3993 | goto out; |
4011 | 3994 | ||
3995 | wl_sta = (struct wl1271_station *)sta->drv_priv; | ||
3996 | hlid = wl_sta->hlid; | ||
3997 | |||
4012 | ret = wl1271_ps_elp_wakeup(wl); | 3998 | ret = wl1271_ps_elp_wakeup(wl); |
4013 | if (ret < 0) | 3999 | if (ret < 0) |
4014 | goto out_free_sta; | 4000 | goto out_free_sta; |
@@ -4030,7 +4016,7 @@ out_sleep: | |||
4030 | 4016 | ||
4031 | out_free_sta: | 4017 | out_free_sta: |
4032 | if (ret < 0) | 4018 | if (ret < 0) |
4033 | wl1271_free_sta(wl, hlid); | 4019 | wl1271_free_sta(wl, wlvif, hlid); |
4034 | 4020 | ||
4035 | out: | 4021 | out: |
4036 | mutex_unlock(&wl->mutex); | 4022 | mutex_unlock(&wl->mutex); |
@@ -4057,8 +4043,8 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw, | |||
4057 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); | 4043 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); |
4058 | 4044 | ||
4059 | wl_sta = (struct wl1271_station *)sta->drv_priv; | 4045 | wl_sta = (struct wl1271_station *)sta->drv_priv; |
4060 | id = wl_sta->hlid - WL1271_AP_STA_HLID_START; | 4046 | id = wl_sta->hlid; |
4061 | if (WARN_ON(!test_bit(id, wl->ap_hlid_map))) | 4047 | if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) |
4062 | goto out; | 4048 | goto out; |
4063 | 4049 | ||
4064 | ret = wl1271_ps_elp_wakeup(wl); | 4050 | ret = wl1271_ps_elp_wakeup(wl); |
@@ -4069,7 +4055,7 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw, | |||
4069 | if (ret < 0) | 4055 | if (ret < 0) |
4070 | goto out_sleep; | 4056 | goto out_sleep; |
4071 | 4057 | ||
4072 | wl1271_free_sta(wl, wl_sta->hlid); | 4058 | wl1271_free_sta(wl, wlvif, wl_sta->hlid); |
4073 | 4059 | ||
4074 | out_sleep: | 4060 | out_sleep: |
4075 | wl1271_ps_elp_sleep(wl); | 4061 | wl1271_ps_elp_sleep(wl); |
@@ -4841,7 +4827,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
4841 | int i, j, ret; | 4827 | int i, j, ret; |
4842 | unsigned int order; | 4828 | unsigned int order; |
4843 | 4829 | ||
4844 | BUILD_BUG_ON(AP_MAX_LINKS > WL12XX_MAX_LINKS); | 4830 | BUILD_BUG_ON(AP_MAX_STATIONS > WL12XX_MAX_LINKS); |
4845 | 4831 | ||
4846 | hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); | 4832 | hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); |
4847 | if (!hw) { | 4833 | if (!hw) { |
@@ -4869,7 +4855,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
4869 | skb_queue_head_init(&wl->tx_queue[i]); | 4855 | skb_queue_head_init(&wl->tx_queue[i]); |
4870 | 4856 | ||
4871 | for (i = 0; i < NUM_TX_QUEUES; i++) | 4857 | for (i = 0; i < NUM_TX_QUEUES; i++) |
4872 | for (j = 0; j < AP_MAX_LINKS; j++) | 4858 | for (j = 0; j < WL12XX_MAX_LINKS; j++) |
4873 | skb_queue_head_init(&wl->links[j].tx_queue[i]); | 4859 | skb_queue_head_init(&wl->links[j].tx_queue[i]); |
4874 | 4860 | ||
4875 | skb_queue_head_init(&wl->deferred_rx_queue); | 4861 | skb_queue_head_init(&wl->deferred_rx_queue); |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 6ce61635f3bd..1b3d8e3f35a8 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -125,18 +125,16 @@ static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, | |||
125 | wl1271_acx_set_inconnection_sta(wl, hdr->addr1); | 125 | wl1271_acx_set_inconnection_sta(wl, hdr->addr1); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void wl1271_tx_regulate_link(struct wl1271 *wl, u8 hlid) | 128 | static void wl1271_tx_regulate_link(struct wl1271 *wl, |
129 | struct wl12xx_vif *wlvif, | ||
130 | u8 hlid) | ||
129 | { | 131 | { |
130 | bool fw_ps, single_sta; | 132 | bool fw_ps, single_sta; |
131 | u8 tx_pkts; | 133 | u8 tx_pkts; |
132 | 134 | ||
133 | /* only regulate station links */ | 135 | if (WARN_ON(!test_bit(hlid, wlvif->links_map))) |
134 | if (hlid < WL1271_AP_STA_HLID_START) | ||
135 | return; | 136 | return; |
136 | 137 | ||
137 | if (WARN_ON(!wl1271_is_active_sta(wl, hlid))) | ||
138 | return; | ||
139 | |||
140 | fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); | 138 | fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); |
141 | tx_pkts = wl->links[hlid].allocated_pkts; | 139 | tx_pkts = wl->links[hlid].allocated_pkts; |
142 | single_sta = (wl->active_sta_count == 1); | 140 | single_sta = (wl->active_sta_count == 1); |
@@ -266,7 +264,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct ieee80211_vif *vif, | |||
266 | wl->tx_allocated_pkts[ac]++; | 264 | wl->tx_allocated_pkts[ac]++; |
267 | 265 | ||
268 | if (wlvif->bss_type == BSS_TYPE_AP_BSS && | 266 | if (wlvif->bss_type == BSS_TYPE_AP_BSS && |
269 | hlid >= WL1271_AP_STA_HLID_START) | 267 | test_bit(hlid, wlvif->ap.sta_hlid_map)) |
270 | wl->links[hlid].allocated_pkts++; | 268 | wl->links[hlid].allocated_pkts++; |
271 | 269 | ||
272 | ret = 0; | 270 | ret = 0; |
@@ -445,7 +443,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, | |||
445 | 443 | ||
446 | if (wlvif->bss_type == BSS_TYPE_AP_BSS && !is_dummy) { | 444 | if (wlvif->bss_type == BSS_TYPE_AP_BSS && !is_dummy) { |
447 | wl1271_tx_ap_update_inconnection_sta(wl, skb); | 445 | wl1271_tx_ap_update_inconnection_sta(wl, skb); |
448 | wl1271_tx_regulate_link(wl, hlid); | 446 | wl1271_tx_regulate_link(wl, wlvif, hlid); |
449 | } | 447 | } |
450 | 448 | ||
451 | /* | 449 | /* |
@@ -563,7 +561,8 @@ out: | |||
563 | return skb; | 561 | return skb; |
564 | } | 562 | } |
565 | 563 | ||
566 | static struct sk_buff *wl1271_ap_skb_dequeue(struct wl1271 *wl) | 564 | static struct sk_buff *wl1271_ap_skb_dequeue(struct wl1271 *wl, |
565 | struct wl12xx_vif *wlvif) | ||
567 | { | 566 | { |
568 | struct sk_buff *skb = NULL; | 567 | struct sk_buff *skb = NULL; |
569 | unsigned long flags; | 568 | unsigned long flags; |
@@ -571,15 +570,14 @@ static struct sk_buff *wl1271_ap_skb_dequeue(struct wl1271 *wl) | |||
571 | struct sk_buff_head *queue; | 570 | struct sk_buff_head *queue; |
572 | 571 | ||
573 | /* start from the link after the last one */ | 572 | /* start from the link after the last one */ |
574 | start_hlid = (wl->last_tx_hlid + 1) % AP_MAX_LINKS; | 573 | start_hlid = (wl->last_tx_hlid + 1) % WL12XX_MAX_LINKS; |
575 | 574 | ||
576 | /* dequeue according to AC, round robin on each link */ | 575 | /* dequeue according to AC, round robin on each link */ |
577 | for (i = 0; i < AP_MAX_LINKS; i++) { | 576 | for (i = 0; i < WL12XX_MAX_LINKS; i++) { |
578 | h = (start_hlid + i) % AP_MAX_LINKS; | 577 | h = (start_hlid + i) % WL12XX_MAX_LINKS; |
579 | 578 | ||
580 | /* only consider connected stations */ | 579 | /* only consider connected stations */ |
581 | if (h >= WL1271_AP_STA_HLID_START && | 580 | if (!test_bit(h, wlvif->links_map)) |
582 | !test_bit(h - WL1271_AP_STA_HLID_START, wl->ap_hlid_map)) | ||
583 | continue; | 581 | continue; |
584 | 582 | ||
585 | queue = wl1271_select_queue(wl, wl->links[h].tx_queue); | 583 | queue = wl1271_select_queue(wl, wl->links[h].tx_queue); |
@@ -611,7 +609,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl, | |||
611 | struct sk_buff *skb = NULL; | 609 | struct sk_buff *skb = NULL; |
612 | 610 | ||
613 | if (wlvif->bss_type == BSS_TYPE_AP_BSS) | 611 | if (wlvif->bss_type == BSS_TYPE_AP_BSS) |
614 | skb = wl1271_ap_skb_dequeue(wl); | 612 | skb = wl1271_ap_skb_dequeue(wl, wlvif); |
615 | else | 613 | else |
616 | skb = wl1271_sta_skb_dequeue(wl); | 614 | skb = wl1271_sta_skb_dequeue(wl); |
617 | 615 | ||
@@ -643,7 +641,8 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct ieee80211_vif *vif, | |||
643 | skb_queue_head(&wl->links[hlid].tx_queue[q], skb); | 641 | skb_queue_head(&wl->links[hlid].tx_queue[q], skb); |
644 | 642 | ||
645 | /* make sure we dequeue the same packet next time */ | 643 | /* make sure we dequeue the same packet next time */ |
646 | wl->last_tx_hlid = (hlid + AP_MAX_LINKS - 1) % AP_MAX_LINKS; | 644 | wl->last_tx_hlid = (hlid + WL12XX_MAX_LINKS - 1) % |
645 | WL12XX_MAX_LINKS; | ||
647 | } else { | 646 | } else { |
648 | skb_queue_head(&wl->tx_queue[q], skb); | 647 | skb_queue_head(&wl->tx_queue[q], skb); |
649 | } | 648 | } |
@@ -918,8 +917,8 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues) | |||
918 | 917 | ||
919 | /* TX failure */ | 918 | /* TX failure */ |
920 | if (wlvif->bss_type == BSS_TYPE_AP_BSS) { | 919 | if (wlvif->bss_type == BSS_TYPE_AP_BSS) { |
921 | for (i = 0; i < AP_MAX_LINKS; i++) { | 920 | for (i = 0; i < WL12XX_MAX_LINKS; i++) { |
922 | wl1271_free_sta(wl, i); | 921 | wl1271_free_sta(wl, wlvif, i); |
923 | wl1271_tx_reset_link_queues(wl, i); | 922 | wl1271_tx_reset_link_queues(wl, i); |
924 | wl->links[i].allocated_pkts = 0; | 923 | wl->links[i].allocated_pkts = 0; |
925 | wl->links[i].prev_freed_pkts = 0; | 924 | wl->links[i].prev_freed_pkts = 0; |
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 0964c9335316..add4402d7931 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h | |||
@@ -219,6 +219,6 @@ void wl1271_handle_tx_low_watermark(struct wl1271 *wl); | |||
219 | bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); | 219 | bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); |
220 | 220 | ||
221 | /* from main.c */ | 221 | /* from main.c */ |
222 | void wl1271_free_sta(struct wl1271 *wl, u8 hlid); | 222 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); |
223 | 223 | ||
224 | #endif | 224 | #endif |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index fcc779147c1c..5fd3c262bc5f 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -146,12 +146,6 @@ extern u32 wl12xx_debug_level; | |||
146 | #define WL12XX_SYSTEM_HLID 0 | 146 | #define WL12XX_SYSTEM_HLID 0 |
147 | 147 | ||
148 | /* | 148 | /* |
149 | * TODO: we currently don't support multirole. remove | ||
150 | * this constant from the code when we do. | ||
151 | */ | ||
152 | #define WL1271_AP_STA_HLID_START 3 | ||
153 | |||
154 | /* | ||
155 | * When in AP-mode, we allow (at least) this number of packets | 149 | * When in AP-mode, we allow (at least) this number of packets |
156 | * to be transmitted to FW for a STA in PS-mode. Only when packets are | 150 | * to be transmitted to FW for a STA in PS-mode. Only when packets are |
157 | * present in the FW buffers it will wake the sleeping STA. We want to put | 151 | * present in the FW buffers it will wake the sleeping STA. We want to put |
@@ -236,13 +230,6 @@ struct wl1271_stats { | |||
236 | 230 | ||
237 | #define AP_MAX_STATIONS 8 | 231 | #define AP_MAX_STATIONS 8 |
238 | 232 | ||
239 | /* Broadcast and Global links + system link + links to stations */ | ||
240 | /* | ||
241 | * TODO: when WL1271_AP_STA_HLID_START is no longer constant, change all | ||
242 | * the places that use this. | ||
243 | */ | ||
244 | #define AP_MAX_LINKS (AP_MAX_STATIONS + WL1271_AP_STA_HLID_START) | ||
245 | |||
246 | /* FW status registers */ | 233 | /* FW status registers */ |
247 | struct wl12xx_fw_status { | 234 | struct wl12xx_fw_status { |
248 | __le32 intr; | 235 | __le32 intr; |
@@ -537,9 +524,6 @@ struct wl1271 { | |||
537 | /* Most recently reported noise in dBm */ | 524 | /* Most recently reported noise in dBm */ |
538 | s8 noise; | 525 | s8 noise; |
539 | 526 | ||
540 | /* map for HLIDs of associated stations - when operating in AP mode */ | ||
541 | unsigned long ap_hlid_map[BITS_TO_LONGS(AP_MAX_STATIONS)]; | ||
542 | |||
543 | /* recoreded keys for AP-mode - set here before AP startup */ | 527 | /* recoreded keys for AP-mode - set here before AP startup */ |
544 | struct wl1271_ap_key *recorded_ap_keys[MAX_NUM_KEYS]; | 528 | struct wl1271_ap_key *recorded_ap_keys[MAX_NUM_KEYS]; |
545 | 529 | ||
@@ -559,7 +543,7 @@ struct wl1271 { | |||
559 | * AP-mode - links indexed by HLID. The global and broadcast links | 543 | * AP-mode - links indexed by HLID. The global and broadcast links |
560 | * are always active. | 544 | * are always active. |
561 | */ | 545 | */ |
562 | struct wl1271_link links[AP_MAX_LINKS]; | 546 | struct wl1271_link links[WL12XX_MAX_LINKS]; |
563 | 547 | ||
564 | /* the hlid of the link where the last transmitted skb came from */ | 548 | /* the hlid of the link where the last transmitted skb came from */ |
565 | int last_tx_hlid; | 549 | int last_tx_hlid; |
@@ -605,9 +589,15 @@ struct wl12xx_vif { | |||
605 | struct { | 589 | struct { |
606 | u8 global_hlid; | 590 | u8 global_hlid; |
607 | u8 bcast_hlid; | 591 | u8 bcast_hlid; |
592 | |||
593 | /* HLIDs bitmap of associated stations */ | ||
594 | unsigned long sta_hlid_map[BITS_TO_LONGS( | ||
595 | WL12XX_MAX_LINKS)]; | ||
608 | } ap; | 596 | } ap; |
609 | }; | 597 | }; |
610 | 598 | ||
599 | unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; | ||
600 | |||
611 | u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; | 601 | u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; |
612 | u8 ssid_len; | 602 | u8 ssid_len; |
613 | 603 | ||