aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c155
1 files changed, 122 insertions, 33 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index d3fe2d23748..fd031e821f4 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -799,6 +799,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
799 799
800 qparam.uapsd = false; 800 qparam.uapsd = false;
801 801
802 local->tx_conf[queue] = qparam;
802 drv_conf_tx(local, queue, &qparam); 803 drv_conf_tx(local, queue, &qparam);
803 } 804 }
804 805
@@ -1016,9 +1017,10 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1016} 1017}
1017 1018
1018struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1019struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1019 u8 *dst, 1020 u8 *dst, u32 ratemask,
1020 const u8 *ssid, size_t ssid_len, 1021 const u8 *ssid, size_t ssid_len,
1021 const u8 *ie, size_t ie_len) 1022 const u8 *ie, size_t ie_len,
1023 bool directed)
1022{ 1024{
1023 struct ieee80211_local *local = sdata->local; 1025 struct ieee80211_local *local = sdata->local;
1024 struct sk_buff *skb; 1026 struct sk_buff *skb;
@@ -1035,18 +1037,26 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1035 return NULL; 1037 return NULL;
1036 } 1038 }
1037 1039
1038 chan = ieee80211_frequency_to_channel( 1040 /*
1039 local->hw.conf.channel->center_freq); 1041 * Do not send DS Channel parameter for directed probe requests
1042 * in order to maximize the chance that we get a response. Some
1043 * badly-behaved APs don't respond when this parameter is included.
1044 */
1045 if (directed)
1046 chan = 0;
1047 else
1048 chan = ieee80211_frequency_to_channel(
1049 local->hw.conf.channel->center_freq);
1040 1050
1041 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, 1051 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
1042 local->hw.conf.channel->band, 1052 local->hw.conf.channel->band,
1043 sdata->rc_rateidx_mask 1053 ratemask, chan);
1044 [local->hw.conf.channel->band],
1045 chan);
1046 1054
1047 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 1055 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1048 ssid, ssid_len, 1056 ssid, ssid_len,
1049 buf, buf_len); 1057 buf, buf_len);
1058 if (!skb)
1059 goto out;
1050 1060
1051 if (dst) { 1061 if (dst) {
1052 mgmt = (struct ieee80211_mgmt *) skb->data; 1062 mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -1055,6 +1065,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1055 } 1065 }
1056 1066
1057 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 1067 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1068
1069 out:
1058 kfree(buf); 1070 kfree(buf);
1059 1071
1060 return skb; 1072 return skb;
@@ -1062,11 +1074,13 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1062 1074
1063void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1075void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1064 const u8 *ssid, size_t ssid_len, 1076 const u8 *ssid, size_t ssid_len,
1065 const u8 *ie, size_t ie_len) 1077 const u8 *ie, size_t ie_len,
1078 u32 ratemask, bool directed)
1066{ 1079{
1067 struct sk_buff *skb; 1080 struct sk_buff *skb;
1068 1081
1069 skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len); 1082 skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len,
1083 ie, ie_len, directed);
1070 if (skb) 1084 if (skb)
1071 ieee80211_tx_skb(sdata, skb); 1085 ieee80211_tx_skb(sdata, skb);
1072} 1086}
@@ -1123,7 +1137,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1123 struct ieee80211_hw *hw = &local->hw; 1137 struct ieee80211_hw *hw = &local->hw;
1124 struct ieee80211_sub_if_data *sdata; 1138 struct ieee80211_sub_if_data *sdata;
1125 struct sta_info *sta; 1139 struct sta_info *sta;
1126 int res; 1140 int res, i;
1127 1141
1128#ifdef CONFIG_PM 1142#ifdef CONFIG_PM
1129 if (local->suspended) 1143 if (local->suspended)
@@ -1146,27 +1160,37 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1146 } 1160 }
1147#endif 1161#endif
1148 1162
1149 /* restart hardware */ 1163 /* setup fragmentation threshold */
1150 if (local->open_count) { 1164 drv_set_frag_threshold(local, hw->wiphy->frag_threshold);
1151 /* 1165
1152 * Upon resume hardware can sometimes be goofy due to 1166 /* setup RTS threshold */
1153 * various platform / driver / bus issues, so restarting 1167 drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
1154 * the device may at times not work immediately. Propagate 1168
1155 * the error. 1169 /* reset coverage class */
1156 */ 1170 drv_set_coverage_class(local, hw->wiphy->coverage_class);
1157 res = drv_start(local);
1158 if (res) {
1159 WARN(local->suspended, "Hardware became unavailable "
1160 "upon resume. This could be a software issue "
1161 "prior to suspend or a hardware issue.\n");
1162 return res;
1163 }
1164 1171
1165 ieee80211_led_radio(local, true); 1172 /* everything else happens only if HW was up & running */
1166 ieee80211_mod_tpt_led_trig(local, 1173 if (!local->open_count)
1167 IEEE80211_TPT_LEDTRIG_FL_RADIO, 0); 1174 goto wake_up;
1175
1176 /*
1177 * Upon resume hardware can sometimes be goofy due to
1178 * various platform / driver / bus issues, so restarting
1179 * the device may at times not work immediately. Propagate
1180 * the error.
1181 */
1182 res = drv_start(local);
1183 if (res) {
1184 WARN(local->suspended, "Hardware became unavailable "
1185 "upon resume. This could be a software issue "
1186 "prior to suspend or a hardware issue.\n");
1187 return res;
1168 } 1188 }
1169 1189
1190 ieee80211_led_radio(local, true);
1191 ieee80211_mod_tpt_led_trig(local,
1192 IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
1193
1170 /* add interfaces */ 1194 /* add interfaces */
1171 list_for_each_entry(sdata, &local->interfaces, list) { 1195 list_for_each_entry(sdata, &local->interfaces, list) {
1172 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 1196 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
@@ -1190,11 +1214,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1190 } 1214 }
1191 mutex_unlock(&local->sta_mtx); 1215 mutex_unlock(&local->sta_mtx);
1192 1216
1193 /* setup fragmentation threshold */ 1217 /* reconfigure tx conf */
1194 drv_set_frag_threshold(local, hw->wiphy->frag_threshold); 1218 for (i = 0; i < hw->queues; i++)
1195 1219 drv_conf_tx(local, i, &local->tx_conf[i]);
1196 /* setup RTS threshold */
1197 drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
1198 1220
1199 /* reconfigure hardware */ 1221 /* reconfigure hardware */
1200 ieee80211_hw_config(local, ~0); 1222 ieee80211_hw_config(local, ~0);
@@ -1321,6 +1343,33 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1321 return 0; 1343 return 0;
1322} 1344}
1323 1345
1346void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
1347{
1348 struct ieee80211_sub_if_data *sdata;
1349 struct ieee80211_local *local;
1350 struct ieee80211_key *key;
1351
1352 if (WARN_ON(!vif))
1353 return;
1354
1355 sdata = vif_to_sdata(vif);
1356 local = sdata->local;
1357
1358 if (WARN_ON(!local->resuming))
1359 return;
1360
1361 if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
1362 return;
1363
1364 sdata->flags |= IEEE80211_SDATA_DISCONNECT_RESUME;
1365
1366 mutex_lock(&local->key_mtx);
1367 list_for_each_entry(key, &sdata->key_list, list)
1368 key->flags |= KEY_FLAG_TAINTED;
1369 mutex_unlock(&local->key_mtx);
1370}
1371EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect);
1372
1324static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, 1373static int check_mgd_smps(struct ieee80211_if_managed *ifmgd,
1325 enum ieee80211_smps_mode *smps_mode) 1374 enum ieee80211_smps_mode *smps_mode)
1326{ 1375{
@@ -1437,3 +1486,43 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
1437 1486
1438 return pos; 1487 return pos;
1439} 1488}
1489
1490static void _ieee80211_enable_rssi_reports(struct ieee80211_sub_if_data *sdata,
1491 int rssi_min_thold,
1492 int rssi_max_thold)
1493{
1494 trace_api_enable_rssi_reports(sdata, rssi_min_thold, rssi_max_thold);
1495
1496 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
1497 return;
1498
1499 /*
1500 * Scale up threshold values before storing it, as the RSSI averaging
1501 * algorithm uses a scaled up value as well. Change this scaling
1502 * factor if the RSSI averaging algorithm changes.
1503 */
1504 sdata->u.mgd.rssi_min_thold = rssi_min_thold*16;
1505 sdata->u.mgd.rssi_max_thold = rssi_max_thold*16;
1506}
1507
1508void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
1509 int rssi_min_thold,
1510 int rssi_max_thold)
1511{
1512 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1513
1514 WARN_ON(rssi_min_thold == rssi_max_thold ||
1515 rssi_min_thold > rssi_max_thold);
1516
1517 _ieee80211_enable_rssi_reports(sdata, rssi_min_thold,
1518 rssi_max_thold);
1519}
1520EXPORT_SYMBOL(ieee80211_enable_rssi_reports);
1521
1522void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif)
1523{
1524 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1525
1526 _ieee80211_enable_rssi_reports(sdata, 0, 0);
1527}
1528EXPORT_SYMBOL(ieee80211_disable_rssi_reports);