aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-10-10 04:13:13 -0400
committerLuciano Coelho <coelho@ti.com>2011-10-11 08:12:13 -0400
commit6e8cd3310491b10db20d0f7eaf5713b05fa7b753 (patch)
tree45022c388445ae10ab24f2ad08a247060effbc88
parent9f259c4e5e42d5f0c25675dc1088cd96dc81a9f1 (diff)
wl12xx: replace all remaining wl->vif references
wl->vif is appropriate only when a single vif is being used. Instead, pass wlvif as parameter or iterate through all the vifs (e.g. when a global configuration was changed) Leave wl->vif only to determine whether a vif was already added (this check will be removed as well after both the driver and fw will support multiple vifs) Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c15
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c11
-rw-r--r--drivers/net/wireless/wl12xx/main.c112
-rw-r--r--drivers/net/wireless/wl12xx/ps.c11
-rw-r--r--drivers/net/wireless/wl12xx/ps.h5
-rw-r--r--drivers/net/wireless/wl12xx/tx.c2
6 files changed, 91 insertions, 65 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 4c5c51810fd..65bf9526576 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -654,7 +654,8 @@ out:
654int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) 654int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
655{ 655{
656 struct wl12xx_cmd_role_start *cmd; 656 struct wl12xx_cmd_role_start *cmd;
657 struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf; 657 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
658 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
658 int ret; 659 int ret;
659 660
660 wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id); 661 wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id);
@@ -773,7 +774,7 @@ int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif)
773{ 774{
774 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 775 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
775 struct wl12xx_cmd_role_start *cmd; 776 struct wl12xx_cmd_role_start *cmd;
776 struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf; 777 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
777 int ret; 778 int ret;
778 779
779 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 780 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -1096,10 +1097,11 @@ out:
1096int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1097int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1097 u16 aid) 1098 u16 aid)
1098{ 1099{
1100 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
1099 struct sk_buff *skb; 1101 struct sk_buff *skb;
1100 int ret = 0; 1102 int ret = 0;
1101 1103
1102 skb = ieee80211_pspoll_get(wl->hw, wl->vif); 1104 skb = ieee80211_pspoll_get(wl->hw, vif);
1103 if (!skb) 1105 if (!skb)
1104 goto out; 1106 goto out;
1105 1107
@@ -1176,6 +1178,7 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1176 __be32 ip_addr) 1178 __be32 ip_addr)
1177{ 1179{
1178 int ret; 1180 int ret;
1181 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
1179 struct wl12xx_arp_rsp_template tmpl; 1182 struct wl12xx_arp_rsp_template tmpl;
1180 struct ieee80211_hdr_3addr *hdr; 1183 struct ieee80211_hdr_3addr *hdr;
1181 struct arphdr *arp_hdr; 1184 struct arphdr *arp_hdr;
@@ -1187,8 +1190,8 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1187 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 1190 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
1188 IEEE80211_STYPE_DATA | 1191 IEEE80211_STYPE_DATA |
1189 IEEE80211_FCTL_TODS); 1192 IEEE80211_FCTL_TODS);
1190 memcpy(hdr->addr1, wl->vif->bss_conf.bssid, ETH_ALEN); 1193 memcpy(hdr->addr1, vif->bss_conf.bssid, ETH_ALEN);
1191 memcpy(hdr->addr2, wl->vif->addr, ETH_ALEN); 1194 memcpy(hdr->addr2, vif->addr, ETH_ALEN);
1192 memset(hdr->addr3, 0xff, ETH_ALEN); 1195 memset(hdr->addr3, 0xff, ETH_ALEN);
1193 1196
1194 /* llc layer */ 1197 /* llc layer */
@@ -1204,7 +1207,7 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1204 arp_hdr->ar_op = cpu_to_be16(ARPOP_REPLY); 1207 arp_hdr->ar_op = cpu_to_be16(ARPOP_REPLY);
1205 1208
1206 /* arp payload */ 1209 /* arp payload */
1207 memcpy(tmpl.sender_hw, wl->vif->addr, ETH_ALEN); 1210 memcpy(tmpl.sender_hw, vif->addr, ETH_ALEN);
1208 tmpl.sender_ip = ip_addr; 1211 tmpl.sender_ip = ip_addr;
1209 1212
1210 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, 1213 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP,
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 4abff8274ac..d6c2d0c1b6c 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -615,19 +615,12 @@ static ssize_t beacon_filtering_write(struct file *file,
615 size_t count, loff_t *ppos) 615 size_t count, loff_t *ppos)
616{ 616{
617 struct wl1271 *wl = file->private_data; 617 struct wl1271 *wl = file->private_data;
618 struct ieee80211_vif *vif;
619 struct wl12xx_vif *wlvif; 618 struct wl12xx_vif *wlvif;
620 char buf[10]; 619 char buf[10];
621 size_t len; 620 size_t len;
622 unsigned long value; 621 unsigned long value;
623 int ret; 622 int ret;
624 623
625 if (!wl->vif)
626 return -EINVAL;
627
628 vif = wl->vif;
629 wlvif = wl12xx_vif_to_data(vif);
630
631 len = min(count, sizeof(buf) - 1); 624 len = min(count, sizeof(buf) - 1);
632 if (copy_from_user(buf, user_buf, len)) 625 if (copy_from_user(buf, user_buf, len))
633 return -EFAULT; 626 return -EFAULT;
@@ -645,7 +638,9 @@ static ssize_t beacon_filtering_write(struct file *file,
645 if (ret < 0) 638 if (ret < 0)
646 goto out; 639 goto out;
647 640
648 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, !!value); 641 wl12xx_for_each_wlvif(wl, wlvif) {
642 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, !!value);
643 }
649 644
650 wl1271_ps_elp_sleep(wl); 645 wl1271_ps_elp_sleep(wl);
651out: 646out:
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index b2640edcc3a..08fc9d46428 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -779,7 +779,9 @@ static int wl1271_plt_init(struct wl1271 *wl)
779 return ret; 779 return ret;
780} 780}
781 781
782static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts) 782static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
783 struct wl12xx_vif *wlvif,
784 u8 hlid, u8 tx_pkts)
783{ 785{
784 bool fw_ps, single_sta; 786 bool fw_ps, single_sta;
785 787
@@ -791,7 +793,7 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts)
791 * packets in FW or if the STA is awake. 793 * packets in FW or if the STA is awake.
792 */ 794 */
793 if (!fw_ps || tx_pkts < WL1271_PS_STA_MAX_PACKETS) 795 if (!fw_ps || tx_pkts < WL1271_PS_STA_MAX_PACKETS)
794 wl1271_ps_link_end(wl, hlid); 796 wl12xx_ps_link_end(wl, wlvif, hlid);
795 797
796 /* 798 /*
797 * Start high-level PS if the STA is asleep with enough blocks in FW. 799 * Start high-level PS if the STA is asleep with enough blocks in FW.
@@ -799,7 +801,7 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts)
799 * case FW-memory congestion is not a problem. 801 * case FW-memory congestion is not a problem.
800 */ 802 */
801 else if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) 803 else if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
802 wl1271_ps_link_start(wl, hlid, true); 804 wl12xx_ps_link_start(wl, wlvif, hlid, true);
803} 805}
804 806
805static void wl12xx_irq_update_links_status(struct wl1271 *wl, 807static void wl12xx_irq_update_links_status(struct wl1271 *wl,
@@ -829,15 +831,15 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
829 lnk->prev_freed_pkts = status->tx_lnk_free_pkts[hlid]; 831 lnk->prev_freed_pkts = status->tx_lnk_free_pkts[hlid];
830 lnk->allocated_pkts -= cnt; 832 lnk->allocated_pkts -= cnt;
831 833
832 wl12xx_irq_ps_regulate_link(wl, hlid, lnk->allocated_pkts); 834 wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
835 lnk->allocated_pkts);
833 } 836 }
834} 837}
835 838
836static void wl12xx_fw_status(struct wl1271 *wl, 839static void wl12xx_fw_status(struct wl1271 *wl,
837 struct wl12xx_fw_status *status) 840 struct wl12xx_fw_status *status)
838{ 841{
839 struct ieee80211_vif *vif = wl->vif; /* TODO: get as param */ 842 struct wl12xx_vif *wlvif;
840 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
841 struct timespec ts; 843 struct timespec ts;
842 u32 old_tx_blk_count = wl->tx_blocks_available; 844 u32 old_tx_blk_count = wl->tx_blocks_available;
843 int avail, freed_blocks; 845 int avail, freed_blocks;
@@ -892,8 +894,9 @@ static void wl12xx_fw_status(struct wl1271 *wl,
892 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); 894 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
893 895
894 /* for AP update num of allocated TX blocks per link and ps status */ 896 /* for AP update num of allocated TX blocks per link and ps status */
895 if (wlvif->bss_type == BSS_TYPE_AP_BSS) 897 wl12xx_for_each_wlvif_ap(wl, wlvif) {
896 wl12xx_irq_update_links_status(wl, wlvif, status); 898 wl12xx_irq_update_links_status(wl, wlvif, status);
899 }
897 900
898 /* update the host-chipset time offset */ 901 /* update the host-chipset time offset */
899 getnstimeofday(&ts); 902 getnstimeofday(&ts);
@@ -1212,6 +1215,7 @@ static void wl1271_recovery_work(struct work_struct *work)
1212 struct wl1271 *wl = 1215 struct wl1271 *wl =
1213 container_of(work, struct wl1271, recovery_work); 1216 container_of(work, struct wl1271, recovery_work);
1214 struct wl12xx_vif *wlvif; 1217 struct wl12xx_vif *wlvif;
1218 struct ieee80211_vif *vif;
1215 1219
1216 mutex_lock(&wl->mutex); 1220 mutex_lock(&wl->mutex);
1217 1221
@@ -1249,7 +1253,12 @@ static void wl1271_recovery_work(struct work_struct *work)
1249 } 1253 }
1250 1254
1251 /* reboot the chipset */ 1255 /* reboot the chipset */
1252 __wl1271_op_remove_interface(wl, wl->vif, false); 1256 while (!list_empty(&wl->wlvif_list)) {
1257 wlvif = list_first_entry(&wl->wlvif_list,
1258 struct wl12xx_vif, list);
1259 vif = wl12xx_wlvif_to_vif(wlvif);
1260 __wl1271_op_remove_interface(wl, vif, false);
1261 }
1253 1262
1254 clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); 1263 clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
1255 1264
@@ -1721,18 +1730,19 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1721 struct cfg80211_wowlan *wow) 1730 struct cfg80211_wowlan *wow)
1722{ 1731{
1723 struct wl1271 *wl = hw->priv; 1732 struct wl1271 *wl = hw->priv;
1724 struct ieee80211_vif *vif = wl->vif; /* TODO: get as param */ 1733 struct wl12xx_vif *wlvif;
1725 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
1726 int ret; 1734 int ret;
1727 1735
1728 wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); 1736 wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
1729 WARN_ON(!wow || !wow->any); 1737 WARN_ON(!wow || !wow->any);
1730 1738
1731 wl->wow_enabled = true; 1739 wl->wow_enabled = true;
1732 ret = wl1271_configure_suspend(wl, wlvif); 1740 wl12xx_for_each_wlvif(wl, wlvif) {
1733 if (ret < 0) { 1741 ret = wl1271_configure_suspend(wl, wlvif);
1734 wl1271_warning("couldn't prepare device to suspend"); 1742 if (ret < 0) {
1735 return ret; 1743 wl1271_warning("couldn't prepare device to suspend");
1744 return ret;
1745 }
1736 } 1746 }
1737 /* flush any remaining work */ 1747 /* flush any remaining work */
1738 wl1271_debug(DEBUG_MAC80211, "flushing remaining works"); 1748 wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
@@ -1751,7 +1761,9 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1751 1761
1752 wl1271_enable_interrupts(wl); 1762 wl1271_enable_interrupts(wl);
1753 flush_work(&wl->tx_work); 1763 flush_work(&wl->tx_work);
1754 flush_delayed_work(&wlvif->pspoll_work); 1764 wl12xx_for_each_wlvif(wl, wlvif) {
1765 flush_delayed_work(&wlvif->pspoll_work);
1766 }
1755 flush_delayed_work(&wl->elp_work); 1767 flush_delayed_work(&wl->elp_work);
1756 1768
1757 return 0; 1769 return 0;
@@ -1760,8 +1772,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1760static int wl1271_op_resume(struct ieee80211_hw *hw) 1772static int wl1271_op_resume(struct ieee80211_hw *hw)
1761{ 1773{
1762 struct wl1271 *wl = hw->priv; 1774 struct wl1271 *wl = hw->priv;
1763 struct ieee80211_vif *vif = wl->vif; /* TODO: get as param */ 1775 struct wl12xx_vif *wlvif;
1764 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
1765 unsigned long flags; 1776 unsigned long flags;
1766 bool run_irq_work = false; 1777 bool run_irq_work = false;
1767 1778
@@ -1785,7 +1796,9 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
1785 wl1271_irq(0, wl); 1796 wl1271_irq(0, wl);
1786 wl1271_enable_interrupts(wl); 1797 wl1271_enable_interrupts(wl);
1787 } 1798 }
1788 wl1271_configure_resume(wl, wlvif); 1799 wl12xx_for_each_wlvif(wl, wlvif) {
1800 wl1271_configure_resume(wl, wlvif);
1801 }
1789 wl->wow_enabled = false; 1802 wl->wow_enabled = false;
1790 1803
1791 return 0; 1804 return 0;
@@ -2242,6 +2255,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
2242{ 2255{
2243 struct wl1271 *wl = hw->priv; 2256 struct wl1271 *wl = hw->priv;
2244 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 2257 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
2258 struct wl12xx_vif *iter;
2245 2259
2246 mutex_lock(&wl->mutex); 2260 mutex_lock(&wl->mutex);
2247 2261
@@ -2253,10 +2267,14 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
2253 * wl->vif can be null here if someone shuts down the interface 2267 * wl->vif can be null here if someone shuts down the interface
2254 * just when hardware recovery has been started. 2268 * just when hardware recovery has been started.
2255 */ 2269 */
2256 if (wl->vif) { 2270 wl12xx_for_each_wlvif(wl, iter) {
2257 WARN_ON(wl->vif != vif); 2271 if (iter != wlvif)
2272 continue;
2273
2258 __wl1271_op_remove_interface(wl, vif, true); 2274 __wl1271_op_remove_interface(wl, vif, true);
2275 break;
2259 } 2276 }
2277 WARN_ON(iter != wlvif);
2260out: 2278out:
2261 mutex_unlock(&wl->mutex); 2279 mutex_unlock(&wl->mutex);
2262 cancel_work_sync(&wl->recovery_work); 2280 cancel_work_sync(&wl->recovery_work);
@@ -2326,8 +2344,10 @@ static int wl1271_unjoin(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2326 int ret; 2344 int ret;
2327 2345
2328 if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) { 2346 if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) {
2347 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
2348
2329 wl12xx_cmd_stop_channel_switch(wl); 2349 wl12xx_cmd_stop_channel_switch(wl);
2330 ieee80211_chswitch_done(wl->vif, false); 2350 ieee80211_chswitch_done(vif, false);
2331 } 2351 }
2332 2352
2333 /* to stop listening to a channel, we disconnect */ 2353 /* to stop listening to a channel, we disconnect */
@@ -2642,8 +2662,7 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
2642{ 2662{
2643 struct wl1271_filter_params *fp = (void *)(unsigned long)multicast; 2663 struct wl1271_filter_params *fp = (void *)(unsigned long)multicast;
2644 struct wl1271 *wl = hw->priv; 2664 struct wl1271 *wl = hw->priv;
2645 struct ieee80211_vif *vif = wl->vif; /* TODO: get as param */ 2665 struct wl12xx_vif *wlvif;
2646 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
2647 2666
2648 int ret; 2667 int ret;
2649 2668
@@ -2662,17 +2681,20 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
2662 if (ret < 0) 2681 if (ret < 0)
2663 goto out; 2682 goto out;
2664 2683
2665 if (wlvif->bss_type != BSS_TYPE_AP_BSS) { 2684 wl12xx_for_each_wlvif(wl, wlvif) {
2666 if (*total & FIF_ALLMULTI) 2685 if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
2667 ret = wl1271_acx_group_address_tbl(wl, wlvif, false, 2686 if (*total & FIF_ALLMULTI)
2668 NULL, 0); 2687 ret = wl1271_acx_group_address_tbl(wl, wlvif,
2669 else if (fp) 2688 false,
2670 ret = wl1271_acx_group_address_tbl(wl, wlvif, 2689 NULL, 0);
2671 fp->enabled, 2690 else if (fp)
2672 fp->mc_list, 2691 ret = wl1271_acx_group_address_tbl(wl, wlvif,
2673 fp->mc_list_length); 2692 fp->enabled,
2674 if (ret < 0) 2693 fp->mc_list,
2675 goto out_sleep; 2694 fp->mc_list_length);
2695 if (ret < 0)
2696 goto out_sleep;
2697 }
2676 } 2698 }
2677 2699
2678 /* 2700 /*
@@ -3162,8 +3184,7 @@ out:
3162static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 3184static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3163{ 3185{
3164 struct wl1271 *wl = hw->priv; 3186 struct wl1271 *wl = hw->priv;
3165 struct ieee80211_vif *vif = wl->vif; 3187 struct wl12xx_vif *wlvif;
3166 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3167 int ret = 0; 3188 int ret = 0;
3168 3189
3169 mutex_lock(&wl->mutex); 3190 mutex_lock(&wl->mutex);
@@ -3177,10 +3198,11 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3177 if (ret < 0) 3198 if (ret < 0)
3178 goto out; 3199 goto out;
3179 3200
3180 ret = wl1271_acx_rts_threshold(wl, wlvif, value); 3201 wl12xx_for_each_wlvif(wl, wlvif) {
3181 if (ret < 0) 3202 ret = wl1271_acx_rts_threshold(wl, wlvif, value);
3182 wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret); 3203 if (ret < 0)
3183 3204 wl1271_warning("set rts threshold failed: %d", ret);
3205 }
3184 wl1271_ps_elp_sleep(wl); 3206 wl1271_ps_elp_sleep(wl);
3185 3207
3186out: 3208out:
@@ -3669,7 +3691,7 @@ sta_not_found:
3669 wlvif->probereq = NULL; 3691 wlvif->probereq = NULL;
3670 3692
3671 /* re-enable dynamic ps - just in case */ 3693 /* re-enable dynamic ps - just in case */
3672 ieee80211_enable_dyn_ps(wl->vif); 3694 ieee80211_enable_dyn_ps(vif);
3673 3695
3674 /* revert back to minimum rates for the current band */ 3696 /* revert back to minimum rates for the current band */
3675 wl1271_set_band_rate(wl, wlvif); 3697 wl1271_set_band_rate(wl, wlvif);
@@ -4305,9 +4327,11 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
4305 mutex_lock(&wl->mutex); 4327 mutex_lock(&wl->mutex);
4306 4328
4307 if (unlikely(wl->state == WL1271_STATE_OFF)) { 4329 if (unlikely(wl->state == WL1271_STATE_OFF)) {
4308 mutex_unlock(&wl->mutex); 4330 wl12xx_for_each_wlvif_sta(wl, wlvif) {
4309 ieee80211_chswitch_done(wl->vif, false); 4331 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
4310 return; 4332 ieee80211_chswitch_done(vif, false);
4333 }
4334 goto out;
4311 } 4335 }
4312 4336
4313 ret = wl1271_ps_elp_wakeup(wl); 4337 ret = wl1271_ps_elp_wakeup(wl);
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index 8153408233b..84a1afac6f5 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -232,9 +232,11 @@ static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid)
232 wl1271_handle_tx_low_watermark(wl); 232 wl1271_handle_tx_low_watermark(wl);
233} 233}
234 234
235void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues) 235void wl12xx_ps_link_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
236 u8 hlid, bool clean_queues)
236{ 237{
237 struct ieee80211_sta *sta; 238 struct ieee80211_sta *sta;
239 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
238 240
239 if (test_bit(hlid, &wl->ap_ps_map)) 241 if (test_bit(hlid, &wl->ap_ps_map))
240 return; 242 return;
@@ -244,7 +246,7 @@ void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues)
244 clean_queues); 246 clean_queues);
245 247
246 rcu_read_lock(); 248 rcu_read_lock();
247 sta = ieee80211_find_sta(wl->vif, wl->links[hlid].addr); 249 sta = ieee80211_find_sta(vif, wl->links[hlid].addr);
248 if (!sta) { 250 if (!sta) {
249 wl1271_error("could not find sta %pM for starting ps", 251 wl1271_error("could not find sta %pM for starting ps",
250 wl->links[hlid].addr); 252 wl->links[hlid].addr);
@@ -262,9 +264,10 @@ void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues)
262 __set_bit(hlid, &wl->ap_ps_map); 264 __set_bit(hlid, &wl->ap_ps_map);
263} 265}
264 266
265void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid) 267void wl12xx_ps_link_end(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
266{ 268{
267 struct ieee80211_sta *sta; 269 struct ieee80211_sta *sta;
270 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
268 271
269 if (!test_bit(hlid, &wl->ap_ps_map)) 272 if (!test_bit(hlid, &wl->ap_ps_map))
270 return; 273 return;
@@ -274,7 +277,7 @@ void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid)
274 __clear_bit(hlid, &wl->ap_ps_map); 277 __clear_bit(hlid, &wl->ap_ps_map);
275 278
276 rcu_read_lock(); 279 rcu_read_lock();
277 sta = ieee80211_find_sta(wl->vif, wl->links[hlid].addr); 280 sta = ieee80211_find_sta(vif, wl->links[hlid].addr);
278 if (!sta) { 281 if (!sta) {
279 wl1271_error("could not find sta %pM for ending ps", 282 wl1271_error("could not find sta %pM for ending ps",
280 wl->links[hlid].addr); 283 wl->links[hlid].addr);
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
index 6ad0a0bd29b..a12052f0202 100644
--- a/drivers/net/wireless/wl12xx/ps.h
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -32,8 +32,9 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
32void wl1271_ps_elp_sleep(struct wl1271 *wl); 32void wl1271_ps_elp_sleep(struct wl1271 *wl);
33int wl1271_ps_elp_wakeup(struct wl1271 *wl); 33int wl1271_ps_elp_wakeup(struct wl1271 *wl);
34void wl1271_elp_work(struct work_struct *work); 34void wl1271_elp_work(struct work_struct *work);
35void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues); 35void wl12xx_ps_link_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
36void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid); 36 u8 hlid, bool clean_queues);
37void wl12xx_ps_link_end(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
37 38
38#define WL1271_PS_COMPLETE_TIMEOUT 500 39#define WL1271_PS_COMPLETE_TIMEOUT 500
39 40
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 604913ff42b..185a65d971f 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -146,7 +146,7 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
146 * case FW-memory congestion is not a problem. 146 * case FW-memory congestion is not a problem.
147 */ 147 */
148 if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) 148 if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
149 wl1271_ps_link_start(wl, hlid, true); 149 wl12xx_ps_link_start(wl, wlvif, hlid, true);
150} 150}
151 151
152bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb) 152bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb)