aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-07-10 23:53:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-14 14:52:58 -0400
commita326a5d096f031af46c0073dd78eb80dea1f311a (patch)
tree311fc3ee1cd88d5cef57f7cd062a8e5a164b134e
parent474086396276a01190974797a69a95fb14ae7cc9 (diff)
iwlwifi: fixes RTS / CTS support
This patch fixes the RTS / CTS support in iwlwifi. 5000 will send CTS to self when allowed by spec, 4965 will send RTS or CTS to self according to mac80211 request. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c3
6 files changed, 37 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 04365b39279c..e0e43bdb05e0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -642,6 +642,18 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
642 data->beacon_count = 0; 642 data->beacon_count = 0;
643} 643}
644 644
645static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
646 __le32 *tx_flags)
647{
648 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
649 *tx_flags |= TX_CMD_FLG_RTS_MSK;
650 *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
651 } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
652 *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
653 *tx_flags |= TX_CMD_FLG_CTS_MSK;
654 }
655}
656
645static void iwl4965_bg_txpower_work(struct work_struct *work) 657static void iwl4965_bg_txpower_work(struct work_struct *work)
646{ 658{
647 struct iwl_priv *priv = container_of(work, struct iwl_priv, 659 struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -2372,6 +2384,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2372 .build_addsta_hcmd = iwl4965_build_addsta_hcmd, 2384 .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
2373 .chain_noise_reset = iwl4965_chain_noise_reset, 2385 .chain_noise_reset = iwl4965_chain_noise_reset,
2374 .gain_computation = iwl4965_gain_computation, 2386 .gain_computation = iwl4965_gain_computation,
2387 .rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
2375}; 2388};
2376 2389
2377static struct iwl_lib_ops iwl4965_lib = { 2390static struct iwl_lib_ops iwl4965_lib = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 3697d0335103..b518792c7231 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -370,6 +370,16 @@ static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
370 } 370 }
371} 371}
372 372
373static void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
374 __le32 *tx_flags)
375{
376 if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
377 (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
378 *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
379 else
380 *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK;
381}
382
373static struct iwl_sensitivity_ranges iwl5000_sensitivity = { 383static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
374 .min_nrg_cck = 95, 384 .min_nrg_cck = 95,
375 .max_nrg_cck = 0, 385 .max_nrg_cck = 0,
@@ -1437,6 +1447,7 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
1437 .build_addsta_hcmd = iwl5000_build_addsta_hcmd, 1447 .build_addsta_hcmd = iwl5000_build_addsta_hcmd,
1438 .gain_computation = iwl5000_gain_computation, 1448 .gain_computation = iwl5000_gain_computation,
1439 .chain_noise_reset = iwl5000_chain_noise_reset, 1449 .chain_noise_reset = iwl5000_chain_noise_reset,
1450 .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
1440}; 1451};
1441 1452
1442static struct iwl_lib_ops iwl5000_lib = { 1453static struct iwl_lib_ops iwl5000_lib = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index fe05d60ebe63..d877039e2d45 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -556,6 +556,8 @@ enum {
556#define RXON_FLG_CHANNEL_MODE_MSK __constant_cpu_to_le32(0x3 << 25) 556#define RXON_FLG_CHANNEL_MODE_MSK __constant_cpu_to_le32(0x3 << 25)
557#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK __constant_cpu_to_le32(0x1 << 25) 557#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK __constant_cpu_to_le32(0x1 << 25)
558#define RXON_FLG_CHANNEL_MODE_MIXED_MSK __constant_cpu_to_le32(0x2 << 25) 558#define RXON_FLG_CHANNEL_MODE_MIXED_MSK __constant_cpu_to_le32(0x2 << 25)
559/* CTS to self (if spec allows) flag */
560#define RXON_FLG_SELF_CTS_EN __constant_cpu_to_le32(0x1<<30)
559 561
560/* rx_config filter flags */ 562/* rx_config filter flags */
561/* accept all data frames */ 563/* accept all data frames */
@@ -1139,6 +1141,11 @@ struct iwl4965_rx_mpdu_res_start {
1139 1141
1140/* REPLY_TX Tx flags field */ 1142/* REPLY_TX Tx flags field */
1141 1143
1144/* 1: Use RTS/CTS protocol or CTS-to-self if spec alows it
1145 * before this frame. if CTS-to-self required check
1146 * RXON_FLG_SELF_CTS_EN status. */
1147#define TX_CMD_FLG_RTS_CTS_MSK __constant_cpu_to_le32(1 << 0)
1148
1142/* 1: Use Request-To-Send protocol before this frame. 1149/* 1: Use Request-To-Send protocol before this frame.
1143 * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ 1150 * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */
1144#define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1) 1151#define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index dafd62c7dfd6..8d18227dc4b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -93,6 +93,8 @@ struct iwl_hcmd_utils_ops {
93 u16 min_average_noise_antennat_i, 93 u16 min_average_noise_antennat_i,
94 u32 min_average_noise); 94 u32 min_average_noise);
95 void (*chain_noise_reset)(struct iwl_priv *priv); 95 void (*chain_noise_reset)(struct iwl_priv *priv);
96 void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info,
97 __le32 *tx_flags);
96}; 98};
97 99
98struct iwl_lib_ops { 100struct iwl_lib_ops {
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 0be2a71990b0..9b50b1052b09 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -601,13 +601,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
601 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; 601 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
602 } 602 }
603 603
604 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { 604 priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags);
605 tx_flags |= TX_CMD_FLG_RTS_MSK;
606 tx_flags &= ~TX_CMD_FLG_CTS_MSK;
607 } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
608 tx_flags &= ~TX_CMD_FLG_RTS_MSK;
609 tx_flags |= TX_CMD_FLG_CTS_MSK;
610 }
611 605
612 if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK)) 606 if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
613 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; 607 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index aca67d4a305b..516508f5fd49 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -250,6 +250,9 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
250 250
251 /* always get timestamp with Rx frame */ 251 /* always get timestamp with Rx frame */
252 priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; 252 priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
253 /* allow CTS-to-self if possible. this is relevant only for
254 * 5000, but will not damage 4965 */
255 priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
253 256
254 ret = iwl4965_check_rxon_cmd(&priv->staging_rxon); 257 ret = iwl4965_check_rxon_cmd(&priv->staging_rxon);
255 if (ret) { 258 if (ret) {