diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-05-05 16:14:16 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-05-05 16:14:16 -0400 |
commit | 83163244f845c296a118ce85c653872dbff6abfe (patch) | |
tree | ce2eac695a1c198f23d537e20ed86c16ece21f7e /drivers/net/wireless/wl12xx/wl1271_main.c | |
parent | 0a12761bcd5646691c5d16dd93df84d1b8849285 (diff) | |
parent | adfba3c7c026a6a5560d2a43fefc9b198cb74462 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts:
drivers/net/wireless/libertas_tf/cmd.c
drivers/net/wireless/libertas_tf/main.c
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_main.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 97 |
1 files changed, 51 insertions, 46 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index e47a58d2cc19..62e544041d0d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -1118,14 +1118,13 @@ static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) | |||
1118 | } | 1118 | } |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | static int wl1271_join_channel(struct wl1271 *wl, int channel) | 1121 | static int wl1271_dummy_join(struct wl1271 *wl) |
1122 | { | 1122 | { |
1123 | int ret = 0; | 1123 | int ret = 0; |
1124 | /* we need to use a dummy BSSID for now */ | 1124 | /* we need to use a dummy BSSID for now */ |
1125 | static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, | 1125 | static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, |
1126 | 0xad, 0xbe, 0xef }; | 1126 | 0xad, 0xbe, 0xef }; |
1127 | 1127 | ||
1128 | wl->channel = channel; | ||
1129 | memcpy(wl->bssid, dummy_bssid, ETH_ALEN); | 1128 | memcpy(wl->bssid, dummy_bssid, ETH_ALEN); |
1130 | 1129 | ||
1131 | /* pass through frames from all BSS */ | 1130 | /* pass through frames from all BSS */ |
@@ -1141,7 +1140,47 @@ out: | |||
1141 | return ret; | 1140 | return ret; |
1142 | } | 1141 | } |
1143 | 1142 | ||
1144 | static int wl1271_unjoin_channel(struct wl1271 *wl) | 1143 | static int wl1271_join(struct wl1271 *wl) |
1144 | { | ||
1145 | int ret; | ||
1146 | |||
1147 | ret = wl1271_cmd_join(wl, wl->set_bss_type); | ||
1148 | if (ret < 0) | ||
1149 | goto out; | ||
1150 | |||
1151 | set_bit(WL1271_FLAG_JOINED, &wl->flags); | ||
1152 | |||
1153 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) | ||
1154 | goto out; | ||
1155 | |||
1156 | /* | ||
1157 | * The join command disable the keep-alive mode, shut down its process, | ||
1158 | * and also clear the template config, so we need to reset it all after | ||
1159 | * the join. The acx_aid starts the keep-alive process, and the order | ||
1160 | * of the commands below is relevant. | ||
1161 | */ | ||
1162 | ret = wl1271_acx_keep_alive_mode(wl, true); | ||
1163 | if (ret < 0) | ||
1164 | goto out; | ||
1165 | |||
1166 | ret = wl1271_acx_aid(wl, wl->aid); | ||
1167 | if (ret < 0) | ||
1168 | goto out; | ||
1169 | |||
1170 | ret = wl1271_cmd_build_klv_null_data(wl); | ||
1171 | if (ret < 0) | ||
1172 | goto out; | ||
1173 | |||
1174 | ret = wl1271_acx_keep_alive_config(wl, CMD_TEMPL_KLV_IDX_NULL_DATA, | ||
1175 | ACX_KEEP_ALIVE_TPL_VALID); | ||
1176 | if (ret < 0) | ||
1177 | goto out; | ||
1178 | |||
1179 | out: | ||
1180 | return ret; | ||
1181 | } | ||
1182 | |||
1183 | static int wl1271_unjoin(struct wl1271 *wl) | ||
1145 | { | 1184 | { |
1146 | int ret; | 1185 | int ret; |
1147 | 1186 | ||
@@ -1231,7 +1270,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1231 | "failed %d", ret); | 1270 | "failed %d", ret); |
1232 | 1271 | ||
1233 | if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { | 1272 | if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { |
1234 | ret = wl1271_cmd_join(wl, wl->set_bss_type); | 1273 | ret = wl1271_join(wl); |
1235 | if (ret < 0) | 1274 | if (ret < 0) |
1236 | wl1271_warning("cmd join to update channel " | 1275 | wl1271_warning("cmd join to update channel " |
1237 | "failed %d", ret); | 1276 | "failed %d", ret); |
@@ -1241,9 +1280,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1241 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { | 1280 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { |
1242 | if (conf->flags & IEEE80211_CONF_IDLE && | 1281 | if (conf->flags & IEEE80211_CONF_IDLE && |
1243 | test_bit(WL1271_FLAG_JOINED, &wl->flags)) | 1282 | test_bit(WL1271_FLAG_JOINED, &wl->flags)) |
1244 | wl1271_unjoin_channel(wl); | 1283 | wl1271_unjoin(wl); |
1245 | else if (!(conf->flags & IEEE80211_CONF_IDLE)) | 1284 | else if (!(conf->flags & IEEE80211_CONF_IDLE)) |
1246 | wl1271_join_channel(wl, channel); | 1285 | wl1271_dummy_join(wl); |
1247 | 1286 | ||
1248 | if (conf->flags & IEEE80211_CONF_IDLE) { | 1287 | if (conf->flags & IEEE80211_CONF_IDLE) { |
1249 | wl->rate_set = wl1271_min_rate_get(wl); | 1288 | wl->rate_set = wl1271_min_rate_get(wl); |
@@ -1519,6 +1558,7 @@ out: | |||
1519 | } | 1558 | } |
1520 | 1559 | ||
1521 | static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | 1560 | static int wl1271_op_hw_scan(struct ieee80211_hw *hw, |
1561 | struct ieee80211_vif *vif, | ||
1522 | struct cfg80211_scan_request *req) | 1562 | struct cfg80211_scan_request *req) |
1523 | { | 1563 | { |
1524 | struct wl1271 *wl = hw->priv; | 1564 | struct wl1271 *wl = hw->priv; |
@@ -1607,7 +1647,6 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1607 | enum wl1271_cmd_ps_mode mode; | 1647 | enum wl1271_cmd_ps_mode mode; |
1608 | struct wl1271 *wl = hw->priv; | 1648 | struct wl1271 *wl = hw->priv; |
1609 | bool do_join = false; | 1649 | bool do_join = false; |
1610 | bool do_keepalive = false; | ||
1611 | int ret; | 1650 | int ret; |
1612 | 1651 | ||
1613 | wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); | 1652 | wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); |
@@ -1702,6 +1741,10 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1702 | if (ret < 0) | 1741 | if (ret < 0) |
1703 | goto out_sleep; | 1742 | goto out_sleep; |
1704 | 1743 | ||
1744 | ret = wl1271_build_qos_null_data(wl); | ||
1745 | if (ret < 0) | ||
1746 | goto out_sleep; | ||
1747 | |||
1705 | /* filter out all packets not from this BSSID */ | 1748 | /* filter out all packets not from this BSSID */ |
1706 | wl1271_configure_filters(wl, 0); | 1749 | wl1271_configure_filters(wl, 0); |
1707 | 1750 | ||
@@ -1746,19 +1789,6 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1746 | ret = wl1271_cmd_build_probe_req(wl, NULL, 0, | 1789 | ret = wl1271_cmd_build_probe_req(wl, NULL, 0, |
1747 | NULL, 0, wl->band); | 1790 | NULL, 0, wl->band); |
1748 | 1791 | ||
1749 | /* Enable the keep-alive feature */ | ||
1750 | ret = wl1271_acx_keep_alive_mode(wl, true); | ||
1751 | if (ret < 0) | ||
1752 | goto out_sleep; | ||
1753 | |||
1754 | /* | ||
1755 | * This is awkward. The keep-alive configs must be done | ||
1756 | * *after* the join command, because otherwise it will | ||
1757 | * not work, but it must only be done *once* because | ||
1758 | * otherwise the firmware will start complaining. | ||
1759 | */ | ||
1760 | do_keepalive = true; | ||
1761 | |||
1762 | /* enable the connection monitoring feature */ | 1792 | /* enable the connection monitoring feature */ |
1763 | ret = wl1271_acx_conn_monit_params(wl, true); | 1793 | ret = wl1271_acx_conn_monit_params(wl, true); |
1764 | if (ret < 0) | 1794 | if (ret < 0) |
@@ -1826,35 +1856,11 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1826 | } | 1856 | } |
1827 | 1857 | ||
1828 | if (do_join) { | 1858 | if (do_join) { |
1829 | ret = wl1271_cmd_join(wl, wl->set_bss_type); | 1859 | ret = wl1271_join(wl); |
1830 | if (ret < 0) { | 1860 | if (ret < 0) { |
1831 | wl1271_warning("cmd join failed %d", ret); | 1861 | wl1271_warning("cmd join failed %d", ret); |
1832 | goto out_sleep; | 1862 | goto out_sleep; |
1833 | } | 1863 | } |
1834 | set_bit(WL1271_FLAG_JOINED, &wl->flags); | ||
1835 | } | ||
1836 | |||
1837 | /* | ||
1838 | * The JOIN operation shuts down the firmware keep-alive as a side | ||
1839 | * effect, and the ACX_AID will start the keep-alive as a side effect. | ||
1840 | * Hence, for non-IBSS, the ACX_AID must always happen *after* the | ||
1841 | * JOIN operation, and the template config after the ACX_AID. | ||
1842 | */ | ||
1843 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { | ||
1844 | ret = wl1271_acx_aid(wl, wl->aid); | ||
1845 | if (ret < 0) | ||
1846 | goto out_sleep; | ||
1847 | } | ||
1848 | |||
1849 | if (do_keepalive) { | ||
1850 | ret = wl1271_cmd_build_klv_null_data(wl); | ||
1851 | if (ret < 0) | ||
1852 | goto out_sleep; | ||
1853 | ret = wl1271_acx_keep_alive_config( | ||
1854 | wl, CMD_TEMPL_KLV_IDX_NULL_DATA, | ||
1855 | ACX_KEEP_ALIVE_TPL_VALID); | ||
1856 | if (ret < 0) | ||
1857 | goto out_sleep; | ||
1858 | } | 1864 | } |
1859 | 1865 | ||
1860 | out_sleep: | 1866 | out_sleep: |
@@ -2265,7 +2271,6 @@ int wl1271_init_ieee80211(struct wl1271 *wl) | |||
2265 | wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; | 2271 | wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; |
2266 | 2272 | ||
2267 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 2273 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
2268 | IEEE80211_HW_NOISE_DBM | | ||
2269 | IEEE80211_HW_BEACON_FILTER | | 2274 | IEEE80211_HW_BEACON_FILTER | |
2270 | IEEE80211_HW_SUPPORTS_PS | | 2275 | IEEE80211_HW_SUPPORTS_PS | |
2271 | IEEE80211_HW_SUPPORTS_UAPSD | | 2276 | IEEE80211_HW_SUPPORTS_UAPSD | |