diff options
author | Eliad Peller <eliad@wizery.com> | 2011-10-11 05:55:44 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-11-08 08:36:45 -0500 |
commit | 679a673414473239d189b5b41ea4014b088be7b9 (patch) | |
tree | 39a21f67c8ebc6b9e16bdcbfd2ecb4cfb488ae3f | |
parent | 0f1680147ce2509383e053fa843020e0e9f3c6ce (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.c | 53 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 40 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/scan.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 6 |
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 | ||
471 | int wl12xx_cmd_role_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) | 471 | static 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 | ||
519 | int wl12xx_cmd_role_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) | 520 | static 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: | |||
1776 | out: | 1778 | out: |
1777 | return ret; | 1779 | return ret; |
1778 | } | 1780 | } |
1781 | |||
1782 | /* start dev role and roc on its channel */ | ||
1783 | int 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 | |||
1801 | out_stop: | ||
1802 | wl12xx_cmd_role_stop_dev(wl, wlvif); | ||
1803 | out: | ||
1804 | return ret; | ||
1805 | } | ||
1806 | |||
1807 | /* croc dev hlid, and stop the role */ | ||
1808 | int 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; | ||
1825 | out: | ||
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); | |||
39 | int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, | 39 | int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, |
40 | u8 *role_id); | 40 | u8 *role_id); |
41 | int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id); | 41 | int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id); |
42 | int wl12xx_cmd_role_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif); | ||
43 | int wl12xx_cmd_role_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif); | ||
44 | int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 42 | int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
45 | int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 43 | int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
46 | int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 44 | int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
47 | int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 45 | int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
48 | int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 46 | int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
47 | int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif); | ||
48 | int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif); | ||
49 | int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); | 49 | int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); |
50 | int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); | 50 | int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); |
51 | int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); | 51 | int 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; |
109 | out: | 105 | out: |