aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1271_main.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-05-05 16:14:16 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-05-05 16:14:16 -0400
commit83163244f845c296a118ce85c653872dbff6abfe (patch)
treece2eac695a1c198f23d537e20ed86c16ece21f7e /drivers/net/wireless/wl12xx/wl1271_main.c
parent0a12761bcd5646691c5d16dd93df84d1b8849285 (diff)
parentadfba3c7c026a6a5560d2a43fefc9b198cb74462 (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.c97
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
1121static int wl1271_join_channel(struct wl1271 *wl, int channel) 1121static 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
1144static int wl1271_unjoin_channel(struct wl1271 *wl) 1143static 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
1179out:
1180 return ret;
1181}
1182
1183static 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
1521static int wl1271_op_hw_scan(struct ieee80211_hw *hw, 1560static 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
1860out_sleep: 1866out_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 |