aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-10-11 05:55:44 -0400
committerLuciano Coelho <coelho@ti.com>2011-11-08 08:36:45 -0500
commit679a673414473239d189b5b41ea4014b088be7b9 (patch)
tree39a21f67c8ebc6b9e16bdcbfd2ecb4cfb488ae3f
parent0f1680147ce2509383e053fa843020e0e9f3c6ce (diff)
wl12xx: couple role_start_dev with roc
Device role is always started along with ROC. Couple them together by introducing new wl12xx_start_dev and wl12xx_stop_dev functions. By using these functions, we solve a bug that occured during channel switch - we started the dev role on one channel, and ROCed on a different one. Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c53
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h4
-rw-r--r--drivers/net/wireless/wl12xx/main.c40
-rw-r--r--drivers/net/wireless/wl12xx/scan.c3
-rw-r--r--drivers/net/wireless/wl12xx/tx.c6
5 files changed, 65 insertions, 41 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 2413c43d089..afd597387e7 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -468,7 +468,8 @@ static int wl12xx_get_new_session_id(struct wl1271 *wl,
468 return wlvif->session_counter; 468 return wlvif->session_counter;
469} 469}
470 470
471int wl12xx_cmd_role_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) 471static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
472 struct wl12xx_vif *wlvif)
472{ 473{
473 struct wl12xx_cmd_role_start *cmd; 474 struct wl12xx_cmd_role_start *cmd;
474 int ret; 475 int ret;
@@ -516,7 +517,8 @@ out:
516 return ret; 517 return ret;
517} 518}
518 519
519int wl12xx_cmd_role_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) 520static int wl12xx_cmd_role_stop_dev(struct wl1271 *wl,
521 struct wl12xx_vif *wlvif)
520{ 522{
521 struct wl12xx_cmd_role_stop *cmd; 523 struct wl12xx_cmd_role_stop *cmd;
522 int ret; 524 int ret;
@@ -1776,3 +1778,50 @@ out_free:
1776out: 1778out:
1777 return ret; 1779 return ret;
1778} 1780}
1781
1782/* start dev role and roc on its channel */
1783int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1784{
1785 int ret;
1786
1787 if (WARN_ON(!(wlvif->bss_type == BSS_TYPE_STA_BSS ||
1788 wlvif->bss_type == BSS_TYPE_IBSS)))
1789 return -EINVAL;
1790
1791 ret = wl12xx_cmd_role_start_dev(wl, wlvif);
1792 if (ret < 0)
1793 goto out;
1794
1795 ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id);
1796 if (ret < 0)
1797 goto out_stop;
1798
1799 return 0;
1800
1801out_stop:
1802 wl12xx_cmd_role_stop_dev(wl, wlvif);
1803out:
1804 return ret;
1805}
1806
1807/* croc dev hlid, and stop the role */
1808int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1809{
1810 int ret;
1811
1812 if (WARN_ON(!(wlvif->bss_type == BSS_TYPE_STA_BSS ||
1813 wlvif->bss_type == BSS_TYPE_IBSS)))
1814 return -EINVAL;
1815
1816 if (test_bit(wlvif->dev_role_id, wl->roc_map)) {
1817 ret = wl12xx_croc(wl, wlvif->dev_role_id);
1818 if (ret < 0)
1819 goto out;
1820 }
1821
1822 ret = wl12xx_cmd_role_stop_dev(wl, wlvif);
1823 if (ret < 0)
1824 goto out;
1825out:
1826 return ret;
1827}
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index 968d5bdc0b6..3f7d0b93c24 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -39,13 +39,13 @@ int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
39int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, 39int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type,
40 u8 *role_id); 40 u8 *role_id);
41int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id); 41int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id);
42int wl12xx_cmd_role_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif);
43int wl12xx_cmd_role_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif);
44int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif); 42int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif);
45int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif); 43int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif);
46int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif); 44int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif);
47int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif); 45int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif);
48int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif); 46int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif);
47int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif);
48int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif);
49int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); 49int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
50int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); 50int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
51int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); 51int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index f76be5ad8ab..44070e66cfe 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2429,11 +2429,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2429 if (idle) { 2429 if (idle) {
2430 /* no need to croc if we weren't busy (e.g. during boot) */ 2430 /* no need to croc if we weren't busy (e.g. during boot) */
2431 if (wl12xx_is_roc(wl)) { 2431 if (wl12xx_is_roc(wl)) {
2432 ret = wl12xx_croc(wl, wlvif->dev_role_id); 2432 ret = wl12xx_stop_dev(wl, wlvif);
2433 if (ret < 0)
2434 goto out;
2435
2436 ret = wl12xx_cmd_role_stop_dev(wl, wlvif);
2437 if (ret < 0) 2433 if (ret < 0)
2438 goto out; 2434 goto out;
2439 } 2435 }
@@ -2455,11 +2451,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2455 ieee80211_sched_scan_stopped(wl->hw); 2451 ieee80211_sched_scan_stopped(wl->hw);
2456 } 2452 }
2457 2453
2458 ret = wl12xx_cmd_role_start_dev(wl, wlvif); 2454 ret = wl12xx_start_dev(wl, wlvif);
2459 if (ret < 0)
2460 goto out;
2461
2462 ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id);
2463 if (ret < 0) 2455 if (ret < 0)
2464 goto out; 2456 goto out;
2465 clear_bit(WL1271_FLAG_IDLE, &wl->flags); 2457 clear_bit(WL1271_FLAG_IDLE, &wl->flags);
@@ -2525,16 +2517,13 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2525 */ 2517 */
2526 if (wl12xx_is_roc(wl) && 2518 if (wl12xx_is_roc(wl) &&
2527 !(conf->flags & IEEE80211_CONF_IDLE)) { 2519 !(conf->flags & IEEE80211_CONF_IDLE)) {
2528 ret = wl12xx_croc(wl, 2520 ret = wl12xx_stop_dev(wl, wlvif);
2529 wlvif->dev_role_id);
2530 if (ret < 0) 2521 if (ret < 0)
2531 return ret; 2522 return ret;
2532 2523
2533 ret = wl12xx_roc(wl, wlvif, 2524 ret = wl12xx_start_dev(wl, wlvif);
2534 wlvif->dev_role_id);
2535 if (ret < 0) 2525 if (ret < 0)
2536 wl1271_warning("roc failed %d", 2526 return ret;
2537 ret);
2538 } 2527 }
2539 } 2528 }
2540 } 2529 }
@@ -3087,8 +3076,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
3087 ret = -EBUSY; 3076 ret = -EBUSY;
3088 goto out_sleep; 3077 goto out_sleep;
3089 } 3078 }
3090 wl12xx_croc(wl, wlvif->dev_role_id); 3079 wl12xx_stop_dev(wl, wlvif);
3091 wl12xx_cmd_role_stop_dev(wl, wlvif);
3092 } 3080 }
3093 3081
3094 ret = wl1271_scan(hw->priv, vif, ssid, len, req); 3082 ret = wl1271_scan(hw->priv, vif, ssid, len, req);
@@ -3599,8 +3587,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3599 if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, 3587 if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED,
3600 &wlvif->flags)) { 3588 &wlvif->flags)) {
3601 wl1271_unjoin(wl, wlvif); 3589 wl1271_unjoin(wl, wlvif);
3602 wl12xx_cmd_role_start_dev(wl, wlvif); 3590 wl12xx_start_dev(wl, wlvif);
3603 wl12xx_roc(wl, wlvif, wlvif->dev_role_id);
3604 } 3591 }
3605 } 3592 }
3606 } 3593 }
@@ -3776,11 +3763,8 @@ sta_not_found:
3776 } 3763 }
3777 3764
3778 wl1271_unjoin(wl, wlvif); 3765 wl1271_unjoin(wl, wlvif);
3779 if (!(conf_flags & IEEE80211_CONF_IDLE)) { 3766 if (!(conf_flags & IEEE80211_CONF_IDLE))
3780 wl12xx_cmd_role_start_dev(wl, wlvif); 3767 wl12xx_start_dev(wl, wlvif);
3781 wl12xx_roc(wl, wlvif,
3782 wlvif->dev_role_id);
3783 }
3784 } 3768 }
3785 } 3769 }
3786 } 3770 }
@@ -3859,11 +3843,7 @@ sta_not_found:
3859 * STA role). TODO: make it better. 3843 * STA role). TODO: make it better.
3860 */ 3844 */
3861 if (wlvif->dev_role_id != WL12XX_INVALID_ROLE_ID) { 3845 if (wlvif->dev_role_id != WL12XX_INVALID_ROLE_ID) {
3862 ret = wl12xx_croc(wl, wlvif->dev_role_id); 3846 ret = wl12xx_stop_dev(wl, wlvif);
3863 if (ret < 0)
3864 goto out;
3865
3866 ret = wl12xx_cmd_role_stop_dev(wl, wlvif);
3867 if (ret < 0) 3847 if (ret < 0)
3868 goto out; 3848 goto out;
3869 } 3849 }
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
index fb2c4319749..898d03d5b52 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -77,8 +77,7 @@ void wl1271_scan_complete_work(struct work_struct *work)
77 (is_ibss && !test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags))) && 77 (is_ibss && !test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags))) &&
78 !test_bit(wlvif->dev_role_id, wl->roc_map)) { 78 !test_bit(wlvif->dev_role_id, wl->roc_map)) {
79 /* restore remain on channel */ 79 /* restore remain on channel */
80 wl12xx_cmd_role_start_dev(wl, wlvif); 80 wl12xx_start_dev(wl, wlvif);
81 wl12xx_roc(wl, wlvif, wlvif->dev_role_id);
82 } 81 }
83 wl1271_ps_elp_sleep(wl); 82 wl1271_ps_elp_sleep(wl);
84 83
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index c7ad4f5976c..3a9d2a6b8a0 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -99,11 +99,7 @@ static int wl1271_tx_update_filters(struct wl1271 *wl,
99 goto out; 99 goto out;
100 100
101 wl1271_debug(DEBUG_CMD, "starting device role for roaming"); 101 wl1271_debug(DEBUG_CMD, "starting device role for roaming");
102 ret = wl12xx_cmd_role_start_dev(wl, wlvif); 102 ret = wl12xx_start_dev(wl, wlvif);
103 if (ret < 0)
104 goto out;
105
106 ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id);
107 if (ret < 0) 103 if (ret < 0)
108 goto out; 104 goto out;
109out: 105out: