diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-05-29 04:35:13 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-03 15:00:25 -0400 |
commit | 972cf447d20df30dbd74edfc00ae179c4b822c68 (patch) | |
tree | c5daa3264a16a2fc5d44ebbdd3f1c97e9dccfcad | |
parent | 17b889290a184b52ee394c31dd5a52b8c1b3456d (diff) |
iwlwifi: implement txq invalidate byte count table
This is required to overcome a bug in 5000 HW byte count table.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 5 |
3 files changed, 28 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index dc9f3b683795..6a10526d939b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -955,6 +955,26 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | |||
955 | } | 955 | } |
956 | } | 956 | } |
957 | 957 | ||
958 | static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, | ||
959 | struct iwl_tx_queue *txq) | ||
960 | { | ||
961 | int txq_id = txq->q.id; | ||
962 | struct iwl5000_shared *shared_data = priv->shared_virt; | ||
963 | u8 sta = 0; | ||
964 | |||
965 | if (txq_id != IWL_CMD_QUEUE_NUM) | ||
966 | sta = txq->cmd[txq->q.read_ptr].cmd.tx.sta_id; | ||
967 | |||
968 | shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr]. | ||
969 | val = cpu_to_le16(1 | (sta << 12)); | ||
970 | |||
971 | if (txq->q.write_ptr < IWL50_MAX_WIN_SIZE) { | ||
972 | shared_data->queues_byte_cnt_tbls[txq_id]. | ||
973 | tfd_offset[IWL50_QUEUE_SIZE + txq->q.read_ptr]. | ||
974 | val = cpu_to_le16(1 | (sta << 12)); | ||
975 | } | ||
976 | } | ||
977 | |||
958 | static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) | 978 | static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) |
959 | { | 979 | { |
960 | u16 size = (u16)sizeof(struct iwl_addsta_cmd); | 980 | u16 size = (u16)sizeof(struct iwl_addsta_cmd); |
@@ -1248,6 +1268,7 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
1248 | .free_shared_mem = iwl5000_free_shared_mem, | 1268 | .free_shared_mem = iwl5000_free_shared_mem, |
1249 | .shared_mem_rx_idx = iwl5000_shared_mem_rx_idx, | 1269 | .shared_mem_rx_idx = iwl5000_shared_mem_rx_idx, |
1250 | .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, | 1270 | .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, |
1271 | .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, | ||
1251 | .txq_set_sched = iwl5000_txq_set_sched, | 1272 | .txq_set_sched = iwl5000_txq_set_sched, |
1252 | .rx_handler_setup = iwl5000_rx_handler_setup, | 1273 | .rx_handler_setup = iwl5000_rx_handler_setup, |
1253 | .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, | 1274 | .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 8264b4e65857..1941a9184aa2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -107,10 +107,12 @@ struct iwl_lib_ops { | |||
107 | void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv, | 107 | void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv, |
108 | struct iwl_tx_queue *txq, | 108 | struct iwl_tx_queue *txq, |
109 | u16 byte_cnt); | 109 | u16 byte_cnt); |
110 | void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv, | ||
111 | struct iwl_tx_queue *txq); | ||
112 | void (*txq_set_sched)(struct iwl_priv *priv, u32 mask); | ||
110 | /* setup Rx handler */ | 113 | /* setup Rx handler */ |
111 | void (*rx_handler_setup)(struct iwl_priv *priv); | 114 | void (*rx_handler_setup)(struct iwl_priv *priv); |
112 | /* nic Tx fifo handling */ | 115 | /* nic Tx fifo handling */ |
113 | void (*txq_set_sched)(struct iwl_priv *priv, u32 mask); | ||
114 | /* alive notification after init uCode load */ | 116 | /* alive notification after init uCode load */ |
115 | void (*init_alive_start)(struct iwl_priv *priv); | 117 | void (*init_alive_start)(struct iwl_priv *priv); |
116 | /* alive notification */ | 118 | /* alive notification */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index b2b2ed29602a..224bcec21e5b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -1080,8 +1080,11 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
1080 | tx_info = &txq->txb[txq->q.read_ptr]; | 1080 | tx_info = &txq->txb[txq->q.read_ptr]; |
1081 | ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); | 1081 | ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); |
1082 | tx_info->skb[0] = NULL; | 1082 | tx_info->skb[0] = NULL; |
1083 | iwl_hw_txq_free_tfd(priv, txq); | ||
1084 | 1083 | ||
1084 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) | ||
1085 | priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); | ||
1086 | |||
1087 | iwl_hw_txq_free_tfd(priv, txq); | ||
1085 | nfreed++; | 1088 | nfreed++; |
1086 | } | 1089 | } |
1087 | return nfreed; | 1090 | return nfreed; |