aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c85
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c5
11 files changed, 87 insertions, 133 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 8848333bc3a9..fec026212326 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -260,7 +260,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
260 .shadow_ram_support = false, 260 .shadow_ram_support = false,
261 .ht_greenfield_support = true, 261 .ht_greenfield_support = true,
262 .led_compensation = 51, 262 .led_compensation = 51,
263 .use_rts_for_ht = true, /* use rts/cts protection */ 263 .use_rts_for_aggregation = true, /* use rts/cts protection */
264 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 264 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
265 .support_ct_kill_exit = true, 265 .support_ct_kill_exit = true,
266 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, 266 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index a07310fefcf2..6950a783913b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -769,22 +769,6 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
769 rts_retry_limit = data_retry_limit; 769 rts_retry_limit = data_retry_limit;
770 tx_cmd->rts_retry_limit = rts_retry_limit; 770 tx_cmd->rts_retry_limit = rts_retry_limit;
771 771
772 if (ieee80211_is_mgmt(fc)) {
773 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
774 case cpu_to_le16(IEEE80211_STYPE_AUTH):
775 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
776 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
777 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
778 if (tx_flags & TX_CMD_FLG_RTS_MSK) {
779 tx_flags &= ~TX_CMD_FLG_RTS_MSK;
780 tx_flags |= TX_CMD_FLG_CTS_MSK;
781 }
782 break;
783 default:
784 break;
785 }
786 }
787
788 tx_cmd->rate = rate; 772 tx_cmd->rate = rate;
789 tx_cmd->tx_flags = tx_flags; 773 tx_cmd->tx_flags = tx_flags;
790 774
@@ -2717,7 +2701,7 @@ static struct iwl_lib_ops iwl3945_lib = {
2717static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2701static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2718 .get_hcmd_size = iwl3945_get_hcmd_size, 2702 .get_hcmd_size = iwl3945_get_hcmd_size,
2719 .build_addsta_hcmd = iwl3945_build_addsta_hcmd, 2703 .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
2720 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, 2704 .tx_cmd_protection = iwlcore_tx_cmd_protection,
2721 .request_scan = iwl3945_request_scan, 2705 .request_scan = iwl3945_request_scan,
2722}; 2706};
2723 2707
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index d6531ad3906a..d6da356608fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2223,7 +2223,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2223 .build_addsta_hcmd = iwl4965_build_addsta_hcmd, 2223 .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
2224 .chain_noise_reset = iwl4965_chain_noise_reset, 2224 .chain_noise_reset = iwl4965_chain_noise_reset,
2225 .gain_computation = iwl4965_gain_computation, 2225 .gain_computation = iwl4965_gain_computation,
2226 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, 2226 .tx_cmd_protection = iwlcore_tx_cmd_protection,
2227 .calc_rssi = iwl4965_calc_rssi, 2227 .calc_rssi = iwl4965_calc_rssi,
2228 .request_scan = iwlagn_request_scan, 2228 .request_scan = iwlagn_request_scan,
2229}; 2229};
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 8093ce2804fb..aacf3770f075 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -506,7 +506,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
506 .use_bsm = false, 506 .use_bsm = false,
507 .ht_greenfield_support = true, 507 .ht_greenfield_support = true,
508 .led_compensation = 51, 508 .led_compensation = 51,
509 .use_rts_for_ht = true, /* use rts/cts protection */ 509 .use_rts_for_aggregation = true, /* use rts/cts protection */
510 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 510 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
511 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 511 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
512 .chain_noise_scale = 1000, 512 .chain_noise_scale = 1000,
@@ -537,7 +537,7 @@ struct iwl_cfg iwl5100_bgn_cfg = {
537 .use_bsm = false, 537 .use_bsm = false,
538 .ht_greenfield_support = true, 538 .ht_greenfield_support = true,
539 .led_compensation = 51, 539 .led_compensation = 51,
540 .use_rts_for_ht = true, /* use rts/cts protection */ 540 .use_rts_for_aggregation = true, /* use rts/cts protection */
541 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 541 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
542 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 542 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
543 .chain_noise_scale = 1000, 543 .chain_noise_scale = 1000,
@@ -597,7 +597,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
597 .use_bsm = false, 597 .use_bsm = false,
598 .ht_greenfield_support = true, 598 .ht_greenfield_support = true,
599 .led_compensation = 51, 599 .led_compensation = 51,
600 .use_rts_for_ht = true, /* use rts/cts protection */ 600 .use_rts_for_aggregation = true, /* use rts/cts protection */
601 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 601 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
602 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 602 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
603 .chain_noise_scale = 1000, 603 .chain_noise_scale = 1000,
@@ -628,7 +628,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
628 .use_bsm = false, 628 .use_bsm = false,
629 .ht_greenfield_support = true, 629 .ht_greenfield_support = true,
630 .led_compensation = 51, 630 .led_compensation = 51,
631 .use_rts_for_ht = true, /* use rts/cts protection */ 631 .use_rts_for_aggregation = true, /* use rts/cts protection */
632 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 632 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
633 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 633 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
634 .chain_noise_scale = 1000, 634 .chain_noise_scale = 1000,
@@ -659,7 +659,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
659 .use_bsm = false, 659 .use_bsm = false,
660 .ht_greenfield_support = true, 660 .ht_greenfield_support = true,
661 .led_compensation = 51, 661 .led_compensation = 51,
662 .use_rts_for_ht = true, /* use rts/cts protection */ 662 .use_rts_for_aggregation = true, /* use rts/cts protection */
663 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 663 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
664 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 664 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
665 .chain_noise_scale = 1000, 665 .chain_noise_scale = 1000,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 58270529a0e4..af4fd50f3405 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -381,7 +381,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
381 .shadow_ram_support = true, 381 .shadow_ram_support = true,
382 .ht_greenfield_support = true, 382 .ht_greenfield_support = true,
383 .led_compensation = 51, 383 .led_compensation = 51,
384 .use_rts_for_ht = true, /* use rts/cts protection */ 384 .use_rts_for_aggregation = true, /* use rts/cts protection */
385 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 385 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
386 .supports_idle = true, 386 .supports_idle = true,
387 .adv_thermal_throttle = true, 387 .adv_thermal_throttle = true,
@@ -489,7 +489,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
489 .shadow_ram_support = true, 489 .shadow_ram_support = true,
490 .ht_greenfield_support = true, 490 .ht_greenfield_support = true,
491 .led_compensation = 51, 491 .led_compensation = 51,
492 .use_rts_for_ht = true, /* use rts/cts protection */ 492 .use_rts_for_aggregation = true, /* use rts/cts protection */
493 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 493 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
494 .supports_idle = true, 494 .supports_idle = true,
495 .adv_thermal_throttle = true, 495 .adv_thermal_throttle = true,
@@ -563,7 +563,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
563 .shadow_ram_support = true, 563 .shadow_ram_support = true,
564 .ht_greenfield_support = true, 564 .ht_greenfield_support = true,
565 .led_compensation = 51, 565 .led_compensation = 51,
566 .use_rts_for_ht = true, /* use rts/cts protection */ 566 .use_rts_for_aggregation = true, /* use rts/cts protection */
567 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 567 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
568 .supports_idle = true, 568 .supports_idle = true,
569 .adv_thermal_throttle = true, 569 .adv_thermal_throttle = true,
@@ -637,7 +637,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
637 .shadow_ram_support = true, 637 .shadow_ram_support = true,
638 .ht_greenfield_support = true, 638 .ht_greenfield_support = true,
639 .led_compensation = 51, 639 .led_compensation = 51,
640 .use_rts_for_ht = true, /* use rts/cts protection */ 640 .use_rts_for_aggregation = true, /* use rts/cts protection */
641 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 641 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
642 .supports_idle = true, 642 .supports_idle = true,
643 .adv_thermal_throttle = true, 643 .adv_thermal_throttle = true,
@@ -714,7 +714,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
714 .shadow_ram_support = true, 714 .shadow_ram_support = true,
715 .ht_greenfield_support = true, 715 .ht_greenfield_support = true,
716 .led_compensation = 51, 716 .led_compensation = 51,
717 .use_rts_for_ht = true, /* use rts/cts protection */ 717 .use_rts_for_aggregation = true, /* use rts/cts protection */
718 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 718 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
719 .supports_idle = true, 719 .supports_idle = true,
720 .adv_thermal_throttle = true, 720 .adv_thermal_throttle = true,
@@ -821,7 +821,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
821 .shadow_ram_support = true, 821 .shadow_ram_support = true,
822 .ht_greenfield_support = true, 822 .ht_greenfield_support = true,
823 .led_compensation = 51, 823 .led_compensation = 51,
824 .use_rts_for_ht = true, /* use rts/cts protection */ 824 .use_rts_for_aggregation = true, /* use rts/cts protection */
825 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 825 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
826 .supports_idle = true, 826 .supports_idle = true,
827 .adv_thermal_throttle = true, 827 .adv_thermal_throttle = true,
@@ -859,7 +859,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = {
859 .shadow_ram_support = true, 859 .shadow_ram_support = true,
860 .ht_greenfield_support = true, 860 .ht_greenfield_support = true,
861 .led_compensation = 51, 861 .led_compensation = 51,
862 .use_rts_for_ht = true, /* use rts/cts protection */ 862 .use_rts_for_aggregation = true, /* use rts/cts protection */
863 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 863 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
864 .supports_idle = true, 864 .supports_idle = true,
865 .adv_thermal_throttle = true, 865 .adv_thermal_throttle = true,
@@ -933,7 +933,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
933 .shadow_ram_support = true, 933 .shadow_ram_support = true,
934 .ht_greenfield_support = true, 934 .ht_greenfield_support = true,
935 .led_compensation = 51, 935 .led_compensation = 51,
936 .use_rts_for_ht = true, /* use rts/cts protection */ 936 .use_rts_for_aggregation = true, /* use rts/cts protection */
937 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 937 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
938 .supports_idle = true, 938 .supports_idle = true,
939 .adv_thermal_throttle = true, 939 .adv_thermal_throttle = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index a7216dda9786..75b901b3eb1e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -211,10 +211,21 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
211 } 211 }
212} 212}
213 213
214static void iwlagn_rts_tx_cmd_flag(struct ieee80211_tx_info *info, 214static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
215 __le32 *tx_flags) 215 struct ieee80211_tx_info *info,
216 __le16 fc, __le32 *tx_flags)
216{ 217{
217 *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; 218 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS ||
219 info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
220 *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
221 return;
222 }
223
224 if (priv->cfg->use_rts_for_aggregation &&
225 info->flags & IEEE80211_TX_CTL_AMPDU) {
226 *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
227 return;
228 }
218} 229}
219 230
220/* Calc max signal level (dBm) among 3 possible receivers */ 231/* Calc max signal level (dBm) among 3 possible receivers */
@@ -268,7 +279,7 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
268 .build_addsta_hcmd = iwlagn_build_addsta_hcmd, 279 .build_addsta_hcmd = iwlagn_build_addsta_hcmd,
269 .gain_computation = iwlagn_gain_computation, 280 .gain_computation = iwlagn_gain_computation,
270 .chain_noise_reset = iwlagn_chain_noise_reset, 281 .chain_noise_reset = iwlagn_chain_noise_reset,
271 .rts_tx_cmd_flag = iwlagn_rts_tx_cmd_flag, 282 .tx_cmd_protection = iwlagn_tx_cmd_protection,
272 .calc_rssi = iwlagn_calc_rssi, 283 .calc_rssi = iwlagn_calc_rssi,
273 .request_scan = iwlagn_request_scan, 284 .request_scan = iwlagn_request_scan,
274}; 285};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index d04502d54df3..69155aa448fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -379,10 +379,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
379 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; 379 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
380 } 380 }
381 381
382 priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags); 382 priv->cfg->ops->utils->tx_cmd_protection(priv, info, fc, &tx_flags);
383
384 if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
385 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
386 383
387 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); 384 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
388 if (ieee80211_is_mgmt(fc)) { 385 if (ieee80211_is_mgmt(fc)) {
@@ -456,21 +453,6 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
456 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE)) 453 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
457 rate_flags |= RATE_MCS_CCK_MSK; 454 rate_flags |= RATE_MCS_CCK_MSK;
458 455
459 /* Set up RTS and CTS flags for certain packets */
460 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
461 case cpu_to_le16(IEEE80211_STYPE_AUTH):
462 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
463 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
464 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
465 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
466 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
467 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
468 }
469 break;
470 default:
471 break;
472 }
473
474 /* Set up antennas */ 456 /* Set up antennas */
475 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, 457 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
476 priv->hw_params.valid_tx_ant); 458 priv->hw_params.valid_tx_ant);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 35337b1e7cac..c1882fd8345d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -202,13 +202,6 @@ int iwl_commit_rxon(struct iwl_priv *priv)
202 202
203 priv->start_calib = 0; 203 priv->start_calib = 0;
204 if (new_assoc) { 204 if (new_assoc) {
205 /*
206 * allow CTS-to-self if possible for new association.
207 * this is relevant only for 5000 series and up,
208 * but will not damage 4965
209 */
210 priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
211
212 /* Apply the new configuration 205 /* Apply the new configuration
213 * RXON assoc doesn't clear the station table in uCode, 206 * RXON assoc doesn't clear the station table in uCode,
214 */ 207 */
@@ -1618,45 +1611,9 @@ static ssize_t store_tx_power(struct device *d,
1618 1611
1619static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); 1612static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
1620 1613
1621static ssize_t show_rts_ht_protection(struct device *d,
1622 struct device_attribute *attr, char *buf)
1623{
1624 struct iwl_priv *priv = dev_get_drvdata(d);
1625
1626 return sprintf(buf, "%s\n",
1627 priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self");
1628}
1629
1630static ssize_t store_rts_ht_protection(struct device *d,
1631 struct device_attribute *attr,
1632 const char *buf, size_t count)
1633{
1634 struct iwl_priv *priv = dev_get_drvdata(d);
1635 unsigned long val;
1636 int ret;
1637
1638 ret = strict_strtoul(buf, 10, &val);
1639 if (ret)
1640 IWL_INFO(priv, "Input is not in decimal form.\n");
1641 else {
1642 if (!iwl_is_associated(priv))
1643 priv->cfg->use_rts_for_ht = val ? true : false;
1644 else
1645 IWL_ERR(priv, "Sta associated with AP - "
1646 "Change protection mechanism is not allowed\n");
1647 ret = count;
1648 }
1649 return ret;
1650}
1651
1652static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO,
1653 show_rts_ht_protection, store_rts_ht_protection);
1654
1655
1656static struct attribute *iwl_sysfs_entries[] = { 1614static struct attribute *iwl_sysfs_entries[] = {
1657 &dev_attr_temperature.attr, 1615 &dev_attr_temperature.attr,
1658 &dev_attr_tx_power.attr, 1616 &dev_attr_tx_power.attr,
1659 &dev_attr_rts_ht_protection.attr,
1660#ifdef CONFIG_IWLWIFI_DEBUG 1617#ifdef CONFIG_IWLWIFI_DEBUG
1661 &dev_attr_debug_level.attr, 1618 &dev_attr_debug_level.attr,
1662#endif 1619#endif
@@ -3464,25 +3421,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3464 return ret; 3421 return ret;
3465} 3422}
3466 3423
3467/*
3468 * switch to RTS/CTS for TX
3469 */
3470static void iwl_enable_rts_cts(struct iwl_priv *priv)
3471{
3472
3473 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3474 return;
3475
3476 priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
3477 if (!test_bit(STATUS_SCANNING, &priv->status)) {
3478 IWL_DEBUG_INFO(priv, "use RTS/CTS protection\n");
3479 iwlcore_commit_rxon(priv);
3480 } else {
3481 /* scanning, defer the request until scan completed */
3482 IWL_DEBUG_INFO(priv, "defer setting RTS/CTS protection\n");
3483 }
3484}
3485
3486static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, 3424static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3487 struct ieee80211_vif *vif, 3425 struct ieee80211_vif *vif,
3488 enum ieee80211_ampdu_mlme_action action, 3426 enum ieee80211_ampdu_mlme_action action,
@@ -3529,14 +3467,33 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3529 } 3467 }
3530 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3468 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3531 ret = 0; 3469 ret = 0;
3470 if (priv->cfg->use_rts_for_aggregation) {
3471 struct iwl_station_priv *sta_priv =
3472 (void *) sta->drv_priv;
3473 /*
3474 * switch off RTS/CTS if it was previously enabled
3475 */
3476
3477 sta_priv->lq_sta.lq.general_params.flags &=
3478 ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
3479 iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq,
3480 CMD_ASYNC, false);
3481 }
3532 break; 3482 break;
3533 case IEEE80211_AMPDU_TX_OPERATIONAL: 3483 case IEEE80211_AMPDU_TX_OPERATIONAL:
3534 if (priv->cfg->use_rts_for_ht) { 3484 if (priv->cfg->use_rts_for_aggregation) {
3485 struct iwl_station_priv *sta_priv =
3486 (void *) sta->drv_priv;
3487
3535 /* 3488 /*
3536 * switch to RTS/CTS if it is the prefer protection 3489 * switch to RTS/CTS if it is the prefer protection
3537 * method for HT traffic 3490 * method for HT traffic
3538 */ 3491 */
3539 iwl_enable_rts_cts(priv); 3492
3493 sta_priv->lq_sta.lq.general_params.flags |=
3494 LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
3495 iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq,
3496 CMD_ASYNC, false);
3540 } 3497 }
3541 ret = 0; 3498 ret = 0;
3542 break; 3499 break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 8ccb6d205b6d..2c03c6e20a72 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -401,21 +401,38 @@ void iwlcore_free_geos(struct iwl_priv *priv)
401EXPORT_SYMBOL(iwlcore_free_geos); 401EXPORT_SYMBOL(iwlcore_free_geos);
402 402
403/* 403/*
404 * iwlcore_rts_tx_cmd_flag: Set rts/cts. 3945 and 4965 only share this 404 * iwlcore_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this
405 * function. 405 * function.
406 */ 406 */
407void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info, 407void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
408 __le32 *tx_flags) 408 struct ieee80211_tx_info *info,
409 __le16 fc, __le32 *tx_flags)
409{ 410{
410 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { 411 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
411 *tx_flags |= TX_CMD_FLG_RTS_MSK; 412 *tx_flags |= TX_CMD_FLG_RTS_MSK;
412 *tx_flags &= ~TX_CMD_FLG_CTS_MSK; 413 *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
414 *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
415
416 if (!ieee80211_is_mgmt(fc))
417 return;
418
419 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
420 case cpu_to_le16(IEEE80211_STYPE_AUTH):
421 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
422 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
423 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
424 *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
425 *tx_flags |= TX_CMD_FLG_CTS_MSK;
426 break;
427 }
413 } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 428 } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
414 *tx_flags &= ~TX_CMD_FLG_RTS_MSK; 429 *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
415 *tx_flags |= TX_CMD_FLG_CTS_MSK; 430 *tx_flags |= TX_CMD_FLG_CTS_MSK;
431 *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
416 } 432 }
417} 433}
418EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag); 434EXPORT_SYMBOL(iwlcore_tx_cmd_protection);
435
419 436
420static bool is_single_rx_stream(struct iwl_priv *priv) 437static bool is_single_rx_stream(struct iwl_priv *priv)
421{ 438{
@@ -1869,6 +1886,10 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1869 priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; 1886 priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
1870 else 1887 else
1871 priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; 1888 priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
1889 if (bss_conf->use_cts_prot)
1890 priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
1891 else
1892 priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
1872 } 1893 }
1873 1894
1874 if (changes & BSS_CHANGED_BASIC_RATES) { 1895 if (changes & BSS_CHANGED_BASIC_RATES) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index e9d23f2f869d..4a71dfb10a15 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -104,8 +104,9 @@ struct iwl_hcmd_utils_ops {
104 u32 min_average_noise, 104 u32 min_average_noise,
105 u8 default_chain); 105 u8 default_chain);
106 void (*chain_noise_reset)(struct iwl_priv *priv); 106 void (*chain_noise_reset)(struct iwl_priv *priv);
107 void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info, 107 void (*tx_cmd_protection)(struct iwl_priv *priv,
108 __le32 *tx_flags); 108 struct ieee80211_tx_info *info,
109 __le16 fc, __le32 *tx_flags);
109 int (*calc_rssi)(struct iwl_priv *priv, 110 int (*calc_rssi)(struct iwl_priv *priv,
110 struct iwl_rx_phy_res *rx_resp); 111 struct iwl_rx_phy_res *rx_resp);
111 void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); 112 void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
@@ -249,7 +250,7 @@ struct iwl_mod_params {
249 * @led_compensation: compensate on the led on/off time per HW according 250 * @led_compensation: compensate on the led on/off time per HW according
250 * to the deviation to achieve the desired led frequency. 251 * to the deviation to achieve the desired led frequency.
251 * The detail algorithm is described in iwl-led.c 252 * The detail algorithm is described in iwl-led.c
252 * @use_rts_for_ht: use rts/cts protection for HT traffic 253 * @use_rts_for_aggregation: use rts/cts protection for HT traffic
253 * @chain_noise_num_beacons: number of beacons used to compute chain noise 254 * @chain_noise_num_beacons: number of beacons used to compute chain noise
254 * @adv_thermal_throttle: support advance thermal throttle 255 * @adv_thermal_throttle: support advance thermal throttle
255 * @support_ct_kill_exit: support ct kill exit condition 256 * @support_ct_kill_exit: support ct kill exit condition
@@ -318,7 +319,7 @@ struct iwl_cfg {
318 const bool ht_greenfield_support; 319 const bool ht_greenfield_support;
319 u16 led_compensation; 320 u16 led_compensation;
320 const bool broken_powersave; 321 const bool broken_powersave;
321 bool use_rts_for_ht; 322 bool use_rts_for_aggregation;
322 int chain_noise_num_beacons; 323 int chain_noise_num_beacons;
323 const bool supports_idle; 324 const bool supports_idle;
324 bool adv_thermal_throttle; 325 bool adv_thermal_throttle;
@@ -390,8 +391,9 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif);
390void iwl_mac_reset_tsf(struct ieee80211_hw *hw); 391void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
391int iwl_alloc_txq_mem(struct iwl_priv *priv); 392int iwl_alloc_txq_mem(struct iwl_priv *priv);
392void iwl_free_txq_mem(struct iwl_priv *priv); 393void iwl_free_txq_mem(struct iwl_priv *priv);
393void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info, 394void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
394 __le32 *tx_flags); 395 struct ieee80211_tx_info *info,
396 __le16 fc, __le32 *tx_flags);
395#ifdef CONFIG_IWLWIFI_DEBUGFS 397#ifdef CONFIG_IWLWIFI_DEBUGFS
396int iwl_alloc_traffic_mem(struct iwl_priv *priv); 398int iwl_alloc_traffic_mem(struct iwl_priv *priv);
397void iwl_free_traffic_mem(struct iwl_priv *priv); 399void iwl_free_traffic_mem(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d24eb47d3705..70c4b8fba0ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -435,10 +435,7 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
435 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; 435 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
436 } 436 }
437 437
438 priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags); 438 priv->cfg->ops->utils->tx_cmd_protection(priv, info, fc, &tx_flags);
439
440 if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
441 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
442 439
443 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); 440 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
444 if (ieee80211_is_mgmt(fc)) { 441 if (ieee80211_is_mgmt(fc)) {