diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-10-09 06:13:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-10-31 19:00:06 -0400 |
commit | d9fe60dea7779d412b34679f1177c5ca1940ea8d (patch) | |
tree | a51e16b013f7c1d16ded502cb32c03872bcbfcaa /drivers/net/wireless/iwlwifi/iwl-core.c | |
parent | 40333e4fb476014cdd939d27e20eb54573172b32 (diff) |
802.11: clean up/fix HT support
This patch cleans up a number of things:
* the unusable definition of the HT capabilities/HT information
information elements
* variable names that are hard to understand
* mac80211: move ieee80211_handle_ht to ht.c and remove the unused
enable_ht parameter
* mac80211: fix bug with MCS rate 32 in ieee80211_handle_ht
* mac80211: fix bug with casting the result of ieee80211_bss_get_ie
to an information element _contents_ rather than the
whole element, add size checking (another out-of-bounds
access bug fixed!)
* mac80211: remove some unused return values in favour of BUG_ON
checking
* a few minor other things
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-core.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 71 |
1 files changed, 36 insertions, 35 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4c312c55f90..4678da447ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -382,10 +382,10 @@ void iwl_reset_qos(struct iwl_priv *priv) | |||
382 | } | 382 | } |
383 | EXPORT_SYMBOL(iwl_reset_qos); | 383 | EXPORT_SYMBOL(iwl_reset_qos); |
384 | 384 | ||
385 | #define MAX_BIT_RATE_40_MHZ 0x96 /* 150 Mbps */ | 385 | #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ |
386 | #define MAX_BIT_RATE_20_MHZ 0x48 /* 72 Mbps */ | 386 | #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ |
387 | static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | 387 | static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, |
388 | struct ieee80211_ht_info *ht_info, | 388 | struct ieee80211_sta_ht_cap *ht_info, |
389 | enum ieee80211_band band) | 389 | enum ieee80211_band band) |
390 | { | 390 | { |
391 | u16 max_bit_rate = 0; | 391 | u16 max_bit_rate = 0; |
@@ -393,45 +393,46 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | |||
393 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 393 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
394 | 394 | ||
395 | ht_info->cap = 0; | 395 | ht_info->cap = 0; |
396 | memset(ht_info->supp_mcs_set, 0, 16); | 396 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); |
397 | 397 | ||
398 | ht_info->ht_supported = 1; | 398 | ht_info->ht_supported = true; |
399 | 399 | ||
400 | ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD; | 400 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; |
401 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20; | 401 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; |
402 | ht_info->cap |= (u16)(IEEE80211_HT_CAP_SM_PS & | 402 | ht_info->cap |= (IEEE80211_HT_CAP_SM_PS & |
403 | (WLAN_HT_CAP_SM_PS_DISABLED << 2)); | 403 | (WLAN_HT_CAP_SM_PS_DISABLED << 2)); |
404 | 404 | ||
405 | max_bit_rate = MAX_BIT_RATE_20_MHZ; | 405 | max_bit_rate = MAX_BIT_RATE_20_MHZ; |
406 | if (priv->hw_params.fat_channel & BIT(band)) { | 406 | if (priv->hw_params.fat_channel & BIT(band)) { |
407 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH; | 407 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
408 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40; | 408 | ht_info->cap |= IEEE80211_HT_CAP_SGI_40; |
409 | ht_info->supp_mcs_set[4] = 0x01; | 409 | ht_info->mcs.rx_mask[4] = 0x01; |
410 | max_bit_rate = MAX_BIT_RATE_40_MHZ; | 410 | max_bit_rate = MAX_BIT_RATE_40_MHZ; |
411 | } | 411 | } |
412 | 412 | ||
413 | if (priv->cfg->mod_params->amsdu_size_8K) | 413 | if (priv->cfg->mod_params->amsdu_size_8K) |
414 | ht_info->cap |= (u16)IEEE80211_HT_CAP_MAX_AMSDU; | 414 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; |
415 | 415 | ||
416 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; | 416 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; |
417 | ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; | 417 | ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; |
418 | 418 | ||
419 | ht_info->supp_mcs_set[0] = 0xFF; | 419 | ht_info->mcs.rx_mask[0] = 0xFF; |
420 | if (rx_chains_num >= 2) | 420 | if (rx_chains_num >= 2) |
421 | ht_info->supp_mcs_set[1] = 0xFF; | 421 | ht_info->mcs.rx_mask[1] = 0xFF; |
422 | if (rx_chains_num >= 3) | 422 | if (rx_chains_num >= 3) |
423 | ht_info->supp_mcs_set[2] = 0xFF; | 423 | ht_info->mcs.rx_mask[2] = 0xFF; |
424 | 424 | ||
425 | /* Highest supported Rx data rate */ | 425 | /* Highest supported Rx data rate */ |
426 | max_bit_rate *= rx_chains_num; | 426 | max_bit_rate *= rx_chains_num; |
427 | ht_info->supp_mcs_set[10] = (u8)(max_bit_rate & 0x00FF); | 427 | WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); |
428 | ht_info->supp_mcs_set[11] = (u8)((max_bit_rate & 0xFF00) >> 8); | 428 | ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); |
429 | 429 | ||
430 | /* Tx MCS capabilities */ | 430 | /* Tx MCS capabilities */ |
431 | ht_info->supp_mcs_set[12] = IEEE80211_HT_CAP_MCS_TX_DEFINED; | 431 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; |
432 | if (tx_chains_num != rx_chains_num) { | 432 | if (tx_chains_num != rx_chains_num) { |
433 | ht_info->supp_mcs_set[12] |= IEEE80211_HT_CAP_MCS_TX_RX_DIFF; | 433 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; |
434 | ht_info->supp_mcs_set[12] |= ((tx_chains_num - 1) << 2); | 434 | ht_info->mcs.tx_params |= ((tx_chains_num - 1) << |
435 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
435 | } | 436 | } |
436 | } | 437 | } |
437 | 438 | ||
@@ -495,7 +496,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv) | |||
495 | sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; | 496 | sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; |
496 | 497 | ||
497 | if (priv->cfg->sku & IWL_SKU_N) | 498 | if (priv->cfg->sku & IWL_SKU_N) |
498 | iwlcore_init_ht_hw_capab(priv, &sband->ht_info, | 499 | iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, |
499 | IEEE80211_BAND_5GHZ); | 500 | IEEE80211_BAND_5GHZ); |
500 | 501 | ||
501 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | 502 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; |
@@ -505,7 +506,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv) | |||
505 | sband->n_bitrates = IWL_RATE_COUNT; | 506 | sband->n_bitrates = IWL_RATE_COUNT; |
506 | 507 | ||
507 | if (priv->cfg->sku & IWL_SKU_N) | 508 | if (priv->cfg->sku & IWL_SKU_N) |
508 | iwlcore_init_ht_hw_capab(priv, &sband->ht_info, | 509 | iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, |
509 | IEEE80211_BAND_2GHZ); | 510 | IEEE80211_BAND_2GHZ); |
510 | 511 | ||
511 | priv->ieee_channels = channels; | 512 | priv->ieee_channels = channels; |
@@ -595,8 +596,8 @@ static void iwlcore_free_geos(struct iwl_priv *priv) | |||
595 | static bool is_single_rx_stream(struct iwl_priv *priv) | 596 | static bool is_single_rx_stream(struct iwl_priv *priv) |
596 | { | 597 | { |
597 | return !priv->current_ht_config.is_ht || | 598 | return !priv->current_ht_config.is_ht || |
598 | ((priv->current_ht_config.supp_mcs_set[1] == 0) && | 599 | ((priv->current_ht_config.mcs.rx_mask[1] == 0) && |
599 | (priv->current_ht_config.supp_mcs_set[2] == 0)); | 600 | (priv->current_ht_config.mcs.rx_mask[2] == 0)); |
600 | } | 601 | } |
601 | 602 | ||
602 | static u8 iwl_is_channel_extension(struct iwl_priv *priv, | 603 | static u8 iwl_is_channel_extension(struct iwl_priv *priv, |
@@ -609,10 +610,10 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv, | |||
609 | if (!is_channel_valid(ch_info)) | 610 | if (!is_channel_valid(ch_info)) |
610 | return 0; | 611 | return 0; |
611 | 612 | ||
612 | if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) | 613 | if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) |
613 | return !(ch_info->fat_extension_channel & | 614 | return !(ch_info->fat_extension_channel & |
614 | IEEE80211_CHAN_NO_FAT_ABOVE); | 615 | IEEE80211_CHAN_NO_FAT_ABOVE); |
615 | else if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) | 616 | else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) |
616 | return !(ch_info->fat_extension_channel & | 617 | return !(ch_info->fat_extension_channel & |
617 | IEEE80211_CHAN_NO_FAT_BELOW); | 618 | IEEE80211_CHAN_NO_FAT_BELOW); |
618 | 619 | ||
@@ -620,18 +621,18 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv, | |||
620 | } | 621 | } |
621 | 622 | ||
622 | u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, | 623 | u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, |
623 | struct ieee80211_ht_info *sta_ht_inf) | 624 | struct ieee80211_sta_ht_cap *sta_ht_inf) |
624 | { | 625 | { |
625 | struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; | 626 | struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; |
626 | 627 | ||
627 | if ((!iwl_ht_conf->is_ht) || | 628 | if ((!iwl_ht_conf->is_ht) || |
628 | (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || | 629 | (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || |
629 | (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE)) | 630 | (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE)) |
630 | return 0; | 631 | return 0; |
631 | 632 | ||
632 | if (sta_ht_inf) { | 633 | if (sta_ht_inf) { |
633 | if ((!sta_ht_inf->ht_supported) || | 634 | if ((!sta_ht_inf->ht_supported) || |
634 | (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))) | 635 | (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))) |
635 | return 0; | 636 | return 0; |
636 | } | 637 | } |
637 | 638 | ||
@@ -671,13 +672,13 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | |||
671 | 672 | ||
672 | /* Note: control channel is opposite of extension channel */ | 673 | /* Note: control channel is opposite of extension channel */ |
673 | switch (ht_info->extension_chan_offset) { | 674 | switch (ht_info->extension_chan_offset) { |
674 | case IEEE80211_HT_IE_CHA_SEC_ABOVE: | 675 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
675 | rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | 676 | rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); |
676 | break; | 677 | break; |
677 | case IEEE80211_HT_IE_CHA_SEC_BELOW: | 678 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
678 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | 679 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; |
679 | break; | 680 | break; |
680 | case IEEE80211_HT_IE_CHA_SEC_NONE: | 681 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: |
681 | default: | 682 | default: |
682 | rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; | 683 | rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; |
683 | break; | 684 | break; |
@@ -693,9 +694,9 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | |||
693 | "rxon flags 0x%X operation mode :0x%X " | 694 | "rxon flags 0x%X operation mode :0x%X " |
694 | "extension channel offset 0x%x " | 695 | "extension channel offset 0x%x " |
695 | "control chan %d\n", | 696 | "control chan %d\n", |
696 | ht_info->supp_mcs_set[0], | 697 | ht_info->mcs.rx_mask[0], |
697 | ht_info->supp_mcs_set[1], | 698 | ht_info->mcs.rx_mask[1], |
698 | ht_info->supp_mcs_set[2], | 699 | ht_info->mcs.rx_mask[2], |
699 | le32_to_cpu(rxon->flags), ht_info->ht_protection, | 700 | le32_to_cpu(rxon->flags), ht_info->ht_protection, |
700 | ht_info->extension_chan_offset, | 701 | ht_info->extension_chan_offset, |
701 | ht_info->control_channel); | 702 | ht_info->control_channel); |