diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 2 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 73 | ||||
-rw-r--r-- | net/mac80211/tx.c | 2 | ||||
-rw-r--r-- | net/wireless/reg.c | 17 | ||||
-rw-r--r-- | net/wireless/scan.c | 1 |
5 files changed, 57 insertions, 38 deletions
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 3824990d340b..70df3dcc3cf6 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -476,7 +476,7 @@ minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
476 | return NULL; | 476 | return NULL; |
477 | 477 | ||
478 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 478 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
479 | sband = hw->wiphy->bands[hw->conf.channel->band]; | 479 | sband = hw->wiphy->bands[i]; |
480 | if (sband->n_bitrates > max_rates) | 480 | if (sband->n_bitrates > max_rates) |
481 | max_rates = sband->n_bitrates; | 481 | max_rates = sband->n_bitrates; |
482 | } | 482 | } |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index b16801cde06f..01d59a8e334c 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -317,13 +317,44 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
317 | struct ieee80211_sta *sta, void *priv_sta) | 317 | struct ieee80211_sta *sta, void *priv_sta) |
318 | { | 318 | { |
319 | struct rc_pid_sta_info *spinfo = priv_sta; | 319 | struct rc_pid_sta_info *spinfo = priv_sta; |
320 | struct rc_pid_info *pinfo = priv; | ||
321 | struct rc_pid_rateinfo *rinfo = pinfo->rinfo; | ||
320 | struct sta_info *si; | 322 | struct sta_info *si; |
323 | int i, j, tmp; | ||
324 | bool s; | ||
321 | 325 | ||
322 | /* TODO: This routine should consider using RSSI from previous packets | 326 | /* TODO: This routine should consider using RSSI from previous packets |
323 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. | 327 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. |
324 | * Until that method is implemented, we will use the lowest supported | 328 | * Until that method is implemented, we will use the lowest supported |
325 | * rate as a workaround. */ | 329 | * rate as a workaround. */ |
326 | 330 | ||
331 | /* Sort the rates. This is optimized for the most common case (i.e. | ||
332 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed | ||
333 | * mapping too. */ | ||
334 | for (i = 0; i < sband->n_bitrates; i++) { | ||
335 | rinfo[i].index = i; | ||
336 | rinfo[i].rev_index = i; | ||
337 | if (RC_PID_FAST_START) | ||
338 | rinfo[i].diff = 0; | ||
339 | else | ||
340 | rinfo[i].diff = i * pinfo->norm_offset; | ||
341 | } | ||
342 | for (i = 1; i < sband->n_bitrates; i++) { | ||
343 | s = 0; | ||
344 | for (j = 0; j < sband->n_bitrates - i; j++) | ||
345 | if (unlikely(sband->bitrates[rinfo[j].index].bitrate > | ||
346 | sband->bitrates[rinfo[j + 1].index].bitrate)) { | ||
347 | tmp = rinfo[j].index; | ||
348 | rinfo[j].index = rinfo[j + 1].index; | ||
349 | rinfo[j + 1].index = tmp; | ||
350 | rinfo[rinfo[j].index].rev_index = j; | ||
351 | rinfo[rinfo[j + 1].index].rev_index = j + 1; | ||
352 | s = 1; | ||
353 | } | ||
354 | if (!s) | ||
355 | break; | ||
356 | } | ||
357 | |||
327 | spinfo->txrate_idx = rate_lowest_index(sband, sta); | 358 | spinfo->txrate_idx = rate_lowest_index(sband, sta); |
328 | /* HACK */ | 359 | /* HACK */ |
329 | si = container_of(sta, struct sta_info, sta); | 360 | si = container_of(sta, struct sta_info, sta); |
@@ -336,21 +367,22 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw, | |||
336 | struct rc_pid_info *pinfo; | 367 | struct rc_pid_info *pinfo; |
337 | struct rc_pid_rateinfo *rinfo; | 368 | struct rc_pid_rateinfo *rinfo; |
338 | struct ieee80211_supported_band *sband; | 369 | struct ieee80211_supported_band *sband; |
339 | int i, j, tmp; | 370 | int i, max_rates = 0; |
340 | bool s; | ||
341 | #ifdef CONFIG_MAC80211_DEBUGFS | 371 | #ifdef CONFIG_MAC80211_DEBUGFS |
342 | struct rc_pid_debugfs_entries *de; | 372 | struct rc_pid_debugfs_entries *de; |
343 | #endif | 373 | #endif |
344 | 374 | ||
345 | sband = hw->wiphy->bands[hw->conf.channel->band]; | ||
346 | |||
347 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); | 375 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); |
348 | if (!pinfo) | 376 | if (!pinfo) |
349 | return NULL; | 377 | return NULL; |
350 | 378 | ||
351 | /* We can safely assume that sband won't change unless we get | 379 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
352 | * reinitialized. */ | 380 | sband = hw->wiphy->bands[i]; |
353 | rinfo = kmalloc(sizeof(*rinfo) * sband->n_bitrates, GFP_ATOMIC); | 381 | if (sband->n_bitrates > max_rates) |
382 | max_rates = sband->n_bitrates; | ||
383 | } | ||
384 | |||
385 | rinfo = kmalloc(sizeof(*rinfo) * max_rates, GFP_ATOMIC); | ||
354 | if (!rinfo) { | 386 | if (!rinfo) { |
355 | kfree(pinfo); | 387 | kfree(pinfo); |
356 | return NULL; | 388 | return NULL; |
@@ -368,33 +400,6 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw, | |||
368 | pinfo->rinfo = rinfo; | 400 | pinfo->rinfo = rinfo; |
369 | pinfo->oldrate = 0; | 401 | pinfo->oldrate = 0; |
370 | 402 | ||
371 | /* Sort the rates. This is optimized for the most common case (i.e. | ||
372 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed | ||
373 | * mapping too. */ | ||
374 | for (i = 0; i < sband->n_bitrates; i++) { | ||
375 | rinfo[i].index = i; | ||
376 | rinfo[i].rev_index = i; | ||
377 | if (RC_PID_FAST_START) | ||
378 | rinfo[i].diff = 0; | ||
379 | else | ||
380 | rinfo[i].diff = i * pinfo->norm_offset; | ||
381 | } | ||
382 | for (i = 1; i < sband->n_bitrates; i++) { | ||
383 | s = 0; | ||
384 | for (j = 0; j < sband->n_bitrates - i; j++) | ||
385 | if (unlikely(sband->bitrates[rinfo[j].index].bitrate > | ||
386 | sband->bitrates[rinfo[j + 1].index].bitrate)) { | ||
387 | tmp = rinfo[j].index; | ||
388 | rinfo[j].index = rinfo[j + 1].index; | ||
389 | rinfo[j + 1].index = tmp; | ||
390 | rinfo[rinfo[j].index].rev_index = j; | ||
391 | rinfo[rinfo[j + 1].index].rev_index = j + 1; | ||
392 | s = 1; | ||
393 | } | ||
394 | if (!s) | ||
395 | break; | ||
396 | } | ||
397 | |||
398 | #ifdef CONFIG_MAC80211_DEBUGFS | 403 | #ifdef CONFIG_MAC80211_DEBUGFS |
399 | de = &pinfo->dentries; | 404 | de = &pinfo->dentries; |
400 | de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR, | 405 | de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR, |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 3fb04a86444d..63656266d567 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -772,7 +772,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
772 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 772 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
773 | 773 | ||
774 | /* internal error, why is TX_FRAGMENTED set? */ | 774 | /* internal error, why is TX_FRAGMENTED set? */ |
775 | if (WARN_ON(skb->len <= frag_threshold)) | 775 | if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) |
776 | return TX_DROP; | 776 | return TX_DROP; |
777 | 777 | ||
778 | /* | 778 | /* |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 6c1993d99902..08265ca15785 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -907,6 +907,7 @@ EXPORT_SYMBOL(freq_reg_info); | |||
907 | int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth, | 907 | int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth, |
908 | const struct ieee80211_reg_rule **reg_rule) | 908 | const struct ieee80211_reg_rule **reg_rule) |
909 | { | 909 | { |
910 | assert_cfg80211_lock(); | ||
910 | return freq_reg_info_regd(wiphy, center_freq, | 911 | return freq_reg_info_regd(wiphy, center_freq, |
911 | bandwidth, reg_rule, NULL); | 912 | bandwidth, reg_rule, NULL); |
912 | } | 913 | } |
@@ -1133,7 +1134,8 @@ static bool reg_is_world_roaming(struct wiphy *wiphy) | |||
1133 | if (is_world_regdom(cfg80211_regdomain->alpha2) || | 1134 | if (is_world_regdom(cfg80211_regdomain->alpha2) || |
1134 | (wiphy->regd && is_world_regdom(wiphy->regd->alpha2))) | 1135 | (wiphy->regd && is_world_regdom(wiphy->regd->alpha2))) |
1135 | return true; | 1136 | return true; |
1136 | if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && | 1137 | if (last_request && |
1138 | last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && | ||
1137 | wiphy->custom_regulatory) | 1139 | wiphy->custom_regulatory) |
1138 | return true; | 1140 | return true; |
1139 | return false; | 1141 | return false; |
@@ -1142,6 +1144,12 @@ static bool reg_is_world_roaming(struct wiphy *wiphy) | |||
1142 | /* Reap the advantages of previously found beacons */ | 1144 | /* Reap the advantages of previously found beacons */ |
1143 | static void reg_process_beacons(struct wiphy *wiphy) | 1145 | static void reg_process_beacons(struct wiphy *wiphy) |
1144 | { | 1146 | { |
1147 | /* | ||
1148 | * Means we are just firing up cfg80211, so no beacons would | ||
1149 | * have been processed yet. | ||
1150 | */ | ||
1151 | if (!last_request) | ||
1152 | return; | ||
1145 | if (!reg_is_world_roaming(wiphy)) | 1153 | if (!reg_is_world_roaming(wiphy)) |
1146 | return; | 1154 | return; |
1147 | wiphy_update_beacon_reg(wiphy); | 1155 | wiphy_update_beacon_reg(wiphy); |
@@ -1176,6 +1184,8 @@ static void handle_channel_custom(struct wiphy *wiphy, | |||
1176 | struct ieee80211_supported_band *sband; | 1184 | struct ieee80211_supported_band *sband; |
1177 | struct ieee80211_channel *chan; | 1185 | struct ieee80211_channel *chan; |
1178 | 1186 | ||
1187 | assert_cfg80211_lock(); | ||
1188 | |||
1179 | sband = wiphy->bands[band]; | 1189 | sband = wiphy->bands[band]; |
1180 | BUG_ON(chan_idx >= sband->n_channels); | 1190 | BUG_ON(chan_idx >= sband->n_channels); |
1181 | chan = &sband->channels[chan_idx]; | 1191 | chan = &sband->channels[chan_idx]; |
@@ -1214,10 +1224,13 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy, | |||
1214 | const struct ieee80211_regdomain *regd) | 1224 | const struct ieee80211_regdomain *regd) |
1215 | { | 1225 | { |
1216 | enum ieee80211_band band; | 1226 | enum ieee80211_band band; |
1227 | |||
1228 | mutex_lock(&cfg80211_mutex); | ||
1217 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 1229 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
1218 | if (wiphy->bands[band]) | 1230 | if (wiphy->bands[band]) |
1219 | handle_band_custom(wiphy, band, regd); | 1231 | handle_band_custom(wiphy, band, regd); |
1220 | } | 1232 | } |
1233 | mutex_unlock(&cfg80211_mutex); | ||
1221 | } | 1234 | } |
1222 | EXPORT_SYMBOL(wiphy_apply_custom_regulatory); | 1235 | EXPORT_SYMBOL(wiphy_apply_custom_regulatory); |
1223 | 1236 | ||
@@ -1423,7 +1436,7 @@ new_request: | |||
1423 | return call_crda(last_request->alpha2); | 1436 | return call_crda(last_request->alpha2); |
1424 | } | 1437 | } |
1425 | 1438 | ||
1426 | /* This currently only processes user and driver regulatory hints */ | 1439 | /* This processes *all* regulatory hints */ |
1427 | static void reg_process_hint(struct regulatory_request *reg_request) | 1440 | static void reg_process_hint(struct regulatory_request *reg_request) |
1428 | { | 1441 | { |
1429 | int r = 0; | 1442 | int r = 0; |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 2ae65b39b529..1f260c40b6ca 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -395,6 +395,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
395 | memcpy(ies, res->pub.information_elements, ielen); | 395 | memcpy(ies, res->pub.information_elements, ielen); |
396 | found->ies_allocated = true; | 396 | found->ies_allocated = true; |
397 | found->pub.information_elements = ies; | 397 | found->pub.information_elements = ies; |
398 | found->pub.len_information_elements = ielen; | ||
398 | } | 399 | } |
399 | } | 400 | } |
400 | } | 401 | } |