diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2011-07-07 08:50:10 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-07-16 10:39:42 -0400 |
commit | b3c2ce131c7cd8c53b72b0cc04241cde17ce0c1d (patch) | |
tree | dd6e9946011a2179749f4c2b0b0a394e6171bc50 /drivers/net/wireless | |
parent | 1a361cd838173879672cb0f0ebe1e7654d7edff6 (diff) |
iwlagn: add tx start API to transport layer
tx start will start the tx queues: basically configure the SCD
Remove the IWLAGN prefix to SCD defines on the way.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 51 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 136 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-prph.h | 82 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.c | 153 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.h | 5 |
7 files changed, 222 insertions, 210 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 554750d993ed..ece3202427f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -166,10 +166,10 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, | |||
166 | u32 tbl_dw; | 166 | u32 tbl_dw; |
167 | u16 scd_q2ratid; | 167 | u16 scd_q2ratid; |
168 | 168 | ||
169 | scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK; | 169 | scd_q2ratid = ra_tid & SCD_QUEUE_RA_TID_MAP_RATID_MSK; |
170 | 170 | ||
171 | tbl_dw_addr = priv->scd_base_addr + | 171 | tbl_dw_addr = priv->scd_base_addr + |
172 | IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id); | 172 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); |
173 | 173 | ||
174 | tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr); | 174 | tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr); |
175 | 175 | ||
@@ -188,9 +188,9 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id) | |||
188 | /* Simply stop the queue, but don't change any configuration; | 188 | /* Simply stop the queue, but don't change any configuration; |
189 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | 189 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ |
190 | iwl_write_prph(priv, | 190 | iwl_write_prph(priv, |
191 | IWLAGN_SCD_QUEUE_STATUS_BITS(txq_id), | 191 | SCD_QUEUE_STATUS_BITS(txq_id), |
192 | (0 << IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE)| | 192 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| |
193 | (1 << IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | 193 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); |
194 | } | 194 | } |
195 | 195 | ||
196 | void iwlagn_set_wr_ptrs(struct iwl_priv *priv, | 196 | void iwlagn_set_wr_ptrs(struct iwl_priv *priv, |
@@ -198,7 +198,7 @@ void iwlagn_set_wr_ptrs(struct iwl_priv *priv, | |||
198 | { | 198 | { |
199 | iwl_write_direct32(priv, HBUS_TARG_WRPTR, | 199 | iwl_write_direct32(priv, HBUS_TARG_WRPTR, |
200 | (index & 0xff) | (txq_id << 8)); | 200 | (index & 0xff) | (txq_id << 8)); |
201 | iwl_write_prph(priv, IWLAGN_SCD_QUEUE_RDPTR(txq_id), index); | 201 | iwl_write_prph(priv, SCD_QUEUE_RDPTR(txq_id), index); |
202 | } | 202 | } |
203 | 203 | ||
204 | void iwlagn_tx_queue_set_status(struct iwl_priv *priv, | 204 | void iwlagn_tx_queue_set_status(struct iwl_priv *priv, |
@@ -208,11 +208,11 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv, | |||
208 | int txq_id = txq->q.id; | 208 | int txq_id = txq->q.id; |
209 | int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0; | 209 | int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0; |
210 | 210 | ||
211 | iwl_write_prph(priv, IWLAGN_SCD_QUEUE_STATUS_BITS(txq_id), | 211 | iwl_write_prph(priv, SCD_QUEUE_STATUS_BITS(txq_id), |
212 | (active << IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE) | | 212 | (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) | |
213 | (tx_fifo_id << IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF) | | 213 | (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) | |
214 | (1 << IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL) | | 214 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | |
215 | IWLAGN_SCD_QUEUE_STTS_REG_MSK); | 215 | SCD_QUEUE_STTS_REG_MSK); |
216 | 216 | ||
217 | txq->sched_retry = scd_retry; | 217 | txq->sched_retry = scd_retry; |
218 | 218 | ||
@@ -271,10 +271,10 @@ void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv, | |||
271 | iwlagn_tx_queue_set_q2ratid(priv, ra_tid, txq_id); | 271 | iwlagn_tx_queue_set_q2ratid(priv, ra_tid, txq_id); |
272 | 272 | ||
273 | /* Set this queue as a chain-building queue */ | 273 | /* Set this queue as a chain-building queue */ |
274 | iwl_set_bits_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL, (1<<txq_id)); | 274 | iwl_set_bits_prph(priv, SCD_QUEUECHAIN_SEL, (1<<txq_id)); |
275 | 275 | ||
276 | /* enable aggregations for the queue */ | 276 | /* enable aggregations for the queue */ |
277 | iwl_set_bits_prph(priv, IWLAGN_SCD_AGGR_SEL, (1<<txq_id)); | 277 | iwl_set_bits_prph(priv, SCD_AGGR_SEL, (1<<txq_id)); |
278 | 278 | ||
279 | /* Place first TFD at index corresponding to start sequence number. | 279 | /* Place first TFD at index corresponding to start sequence number. |
280 | * Assumes that ssn_idx is valid (!= 0xFFF) */ | 280 | * Assumes that ssn_idx is valid (!= 0xFFF) */ |
@@ -284,16 +284,16 @@ void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv, | |||
284 | 284 | ||
285 | /* Set up Tx window size and frame limit for this queue */ | 285 | /* Set up Tx window size and frame limit for this queue */ |
286 | iwl_write_targ_mem(priv, priv->scd_base_addr + | 286 | iwl_write_targ_mem(priv, priv->scd_base_addr + |
287 | IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + | 287 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + |
288 | sizeof(u32), | 288 | sizeof(u32), |
289 | ((frame_limit << | 289 | ((frame_limit << |
290 | IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | 290 | SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & |
291 | IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | 291 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | |
292 | ((frame_limit << | 292 | ((frame_limit << |
293 | IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | 293 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & |
294 | IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | 294 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); |
295 | 295 | ||
296 | iwl_set_bits_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, (1 << txq_id)); | 296 | iwl_set_bits_prph(priv, SCD_INTERRUPT_MASK, (1 << txq_id)); |
297 | 297 | ||
298 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ | 298 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ |
299 | iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); | 299 | iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); |
@@ -317,29 +317,20 @@ static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | |||
317 | 317 | ||
318 | iwlagn_tx_queue_stop_scheduler(priv, txq_id); | 318 | iwlagn_tx_queue_stop_scheduler(priv, txq_id); |
319 | 319 | ||
320 | iwl_clear_bits_prph(priv, IWLAGN_SCD_AGGR_SEL, (1 << txq_id)); | 320 | iwl_clear_bits_prph(priv, SCD_AGGR_SEL, (1 << txq_id)); |
321 | 321 | ||
322 | priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); | 322 | priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); |
323 | priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); | 323 | priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); |
324 | /* supposes that ssn_idx is valid (!= 0xFFF) */ | 324 | /* supposes that ssn_idx is valid (!= 0xFFF) */ |
325 | iwlagn_set_wr_ptrs(priv, txq_id, ssn_idx); | 325 | iwlagn_set_wr_ptrs(priv, txq_id, ssn_idx); |
326 | 326 | ||
327 | iwl_clear_bits_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, (1 << txq_id)); | 327 | iwl_clear_bits_prph(priv, SCD_INTERRUPT_MASK, (1 << txq_id)); |
328 | iwl_txq_ctx_deactivate(priv, txq_id); | 328 | iwl_txq_ctx_deactivate(priv, txq_id); |
329 | iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); | 329 | iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); |
330 | 330 | ||
331 | return 0; | 331 | return 0; |
332 | } | 332 | } |
333 | 333 | ||
334 | /* | ||
335 | * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask | ||
336 | * must be called under priv->lock and mac access | ||
337 | */ | ||
338 | void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask) | ||
339 | { | ||
340 | iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask); | ||
341 | } | ||
342 | |||
343 | static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, | 334 | static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, |
344 | struct ieee80211_tx_info *info, | 335 | struct ieee80211_tx_info *info, |
345 | __le16 fc, __le32 *tx_flags) | 336 | __le16 fc, __le32 *tx_flags) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index c15a1f7f4ff8..aebd5c71f9da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -41,38 +41,6 @@ | |||
41 | #include "iwl-agn-calib.h" | 41 | #include "iwl-agn-calib.h" |
42 | #include "iwl-trans.h" | 42 | #include "iwl-trans.h" |
43 | 43 | ||
44 | #define IWL_AC_UNSET -1 | ||
45 | |||
46 | struct queue_to_fifo_ac { | ||
47 | s8 fifo, ac; | ||
48 | }; | ||
49 | |||
50 | static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = { | ||
51 | { IWL_TX_FIFO_VO, IEEE80211_AC_VO, }, | ||
52 | { IWL_TX_FIFO_VI, IEEE80211_AC_VI, }, | ||
53 | { IWL_TX_FIFO_BE, IEEE80211_AC_BE, }, | ||
54 | { IWL_TX_FIFO_BK, IEEE80211_AC_BK, }, | ||
55 | { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, | ||
56 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
57 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
58 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
59 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
60 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
61 | }; | ||
62 | |||
63 | static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { | ||
64 | { IWL_TX_FIFO_VO, IEEE80211_AC_VO, }, | ||
65 | { IWL_TX_FIFO_VI, IEEE80211_AC_VI, }, | ||
66 | { IWL_TX_FIFO_BE, IEEE80211_AC_BE, }, | ||
67 | { IWL_TX_FIFO_BK, IEEE80211_AC_BK, }, | ||
68 | { IWL_TX_FIFO_BK_IPAN, IEEE80211_AC_BK, }, | ||
69 | { IWL_TX_FIFO_BE_IPAN, IEEE80211_AC_BE, }, | ||
70 | { IWL_TX_FIFO_VI_IPAN, IEEE80211_AC_VI, }, | ||
71 | { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, }, | ||
72 | { IWL_TX_FIFO_BE_IPAN, 2, }, | ||
73 | { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, | ||
74 | }; | ||
75 | |||
76 | static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { | 44 | static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { |
77 | {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, | 45 | {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, |
78 | 0, COEX_UNASSOC_IDLE_FLAGS}, | 46 | 0, COEX_UNASSOC_IDLE_FLAGS}, |
@@ -379,111 +347,9 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) | |||
379 | 347 | ||
380 | static int iwlagn_alive_notify(struct iwl_priv *priv) | 348 | static int iwlagn_alive_notify(struct iwl_priv *priv) |
381 | { | 349 | { |
382 | const struct queue_to_fifo_ac *queue_to_fifo; | ||
383 | struct iwl_rxon_context *ctx; | ||
384 | u32 a; | ||
385 | unsigned long flags; | ||
386 | int i, chan; | ||
387 | u32 reg_val; | ||
388 | int ret; | 350 | int ret; |
389 | 351 | ||
390 | spin_lock_irqsave(&priv->lock, flags); | 352 | trans_tx_start(priv); |
391 | |||
392 | priv->scd_base_addr = iwl_read_prph(priv, IWLAGN_SCD_SRAM_BASE_ADDR); | ||
393 | a = priv->scd_base_addr + IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND; | ||
394 | /* reset conext data memory */ | ||
395 | for (; a < priv->scd_base_addr + IWLAGN_SCD_CONTEXT_MEM_UPPER_BOUND; | ||
396 | a += 4) | ||
397 | iwl_write_targ_mem(priv, a, 0); | ||
398 | /* reset tx status memory */ | ||
399 | for (; a < priv->scd_base_addr + IWLAGN_SCD_TX_STTS_MEM_UPPER_BOUND; | ||
400 | a += 4) | ||
401 | iwl_write_targ_mem(priv, a, 0); | ||
402 | for (; a < priv->scd_base_addr + | ||
403 | IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4) | ||
404 | iwl_write_targ_mem(priv, a, 0); | ||
405 | |||
406 | iwl_write_prph(priv, IWLAGN_SCD_DRAM_BASE_ADDR, | ||
407 | priv->scd_bc_tbls.dma >> 10); | ||
408 | |||
409 | /* Enable DMA channel */ | ||
410 | for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) | ||
411 | iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan), | ||
412 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
413 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); | ||
414 | |||
415 | /* Update FH chicken bits */ | ||
416 | reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG); | ||
417 | iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG, | ||
418 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | ||
419 | |||
420 | iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL, | ||
421 | IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv)); | ||
422 | iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0); | ||
423 | |||
424 | /* initiate the queues */ | ||
425 | for (i = 0; i < priv->hw_params.max_txq_num; i++) { | ||
426 | iwl_write_prph(priv, IWLAGN_SCD_QUEUE_RDPTR(i), 0); | ||
427 | iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8)); | ||
428 | iwl_write_targ_mem(priv, priv->scd_base_addr + | ||
429 | IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(i), 0); | ||
430 | iwl_write_targ_mem(priv, priv->scd_base_addr + | ||
431 | IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(i) + | ||
432 | sizeof(u32), | ||
433 | ((SCD_WIN_SIZE << | ||
434 | IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | ||
435 | IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | ||
436 | ((SCD_FRAME_LIMIT << | ||
437 | IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | ||
438 | IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | ||
439 | } | ||
440 | |||
441 | iwl_write_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, | ||
442 | IWL_MASK(0, priv->hw_params.max_txq_num)); | ||
443 | |||
444 | /* Activate all Tx DMA/FIFO channels */ | ||
445 | iwlagn_txq_set_sched(priv, IWL_MASK(0, 7)); | ||
446 | |||
447 | /* map queues to FIFOs */ | ||
448 | if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) | ||
449 | queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo; | ||
450 | else | ||
451 | queue_to_fifo = iwlagn_default_queue_to_tx_fifo; | ||
452 | |||
453 | iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0); | ||
454 | |||
455 | /* make sure all queue are not stopped */ | ||
456 | memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); | ||
457 | for (i = 0; i < 4; i++) | ||
458 | atomic_set(&priv->queue_stop_count[i], 0); | ||
459 | for_each_context(priv, ctx) | ||
460 | ctx->last_tx_rejected = false; | ||
461 | |||
462 | /* reset to 0 to enable all the queue first */ | ||
463 | priv->txq_ctx_active_msk = 0; | ||
464 | |||
465 | BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10); | ||
466 | BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10); | ||
467 | |||
468 | for (i = 0; i < 10; i++) { | ||
469 | int fifo = queue_to_fifo[i].fifo; | ||
470 | int ac = queue_to_fifo[i].ac; | ||
471 | |||
472 | iwl_txq_ctx_activate(priv, i); | ||
473 | |||
474 | if (fifo == IWL_TX_FIFO_UNUSED) | ||
475 | continue; | ||
476 | |||
477 | if (ac != IWL_AC_UNSET) | ||
478 | iwl_set_swq_id(&priv->txq[i], ac, i); | ||
479 | iwlagn_tx_queue_set_status(priv, &priv->txq[i], fifo, 0); | ||
480 | } | ||
481 | |||
482 | spin_unlock_irqrestore(&priv->lock, flags); | ||
483 | |||
484 | /* Enable L1-Active */ | ||
485 | iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG, | ||
486 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
487 | 353 | ||
488 | ret = iwlagn_send_wimax_coex(priv); | 354 | ret = iwlagn_send_wimax_coex(priv); |
489 | if (ret) | 355 | if (ret) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index c851fc2fb6b2..0e8ccb9c99b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -136,7 +136,6 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | |||
136 | void iwlagn_tx_queue_set_status(struct iwl_priv *priv, | 136 | void iwlagn_tx_queue_set_status(struct iwl_priv *priv, |
137 | struct iwl_tx_queue *txq, | 137 | struct iwl_tx_queue *txq, |
138 | int tx_fifo_id, int scd_retry); | 138 | int tx_fifo_id, int scd_retry); |
139 | void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); | ||
140 | void iwl_free_tfds_in_queue(struct iwl_priv *priv, | 139 | void iwl_free_tfds_in_queue(struct iwl_priv *priv, |
141 | int sta_id, int tid, int freed); | 140 | int sta_id, int tid, int freed); |
142 | 141 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index cf6f4b2e2cd5..fddc23627644 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1234,10 +1234,11 @@ struct iwl_trans; | |||
1234 | 1234 | ||
1235 | /** | 1235 | /** |
1236 | * struct iwl_trans_ops - transport specific operations | 1236 | * struct iwl_trans_ops - transport specific operations |
1237 | |||
1238 | * @rx_init: inits the rx memory, allocate it if needed | 1237 | * @rx_init: inits the rx memory, allocate it if needed |
1239 | * @rx_free: frees the rx memory | 1238 | * @rx_free: frees the rx memory |
1240 | * @tx_init:inits the tx memory, allocate if needed | 1239 | * @tx_init:inits the tx memory, allocate if needed |
1240 | * @tx_start: starts and configures all the Tx fifo - usually done once the fw | ||
1241 | * is alive. | ||
1241 | * @tx_free: frees the tx memory | 1242 | * @tx_free: frees the tx memory |
1242 | * @stop_device:stops the whole device (embedded CPU put to reset) | 1243 | * @stop_device:stops the whole device (embedded CPU put to reset) |
1243 | * @send_cmd:send a host command | 1244 | * @send_cmd:send a host command |
@@ -1256,6 +1257,7 @@ struct iwl_trans_ops { | |||
1256 | void (*rx_free)(struct iwl_priv *priv); | 1257 | void (*rx_free)(struct iwl_priv *priv); |
1257 | 1258 | ||
1258 | int (*tx_init)(struct iwl_priv *priv); | 1259 | int (*tx_init)(struct iwl_priv *priv); |
1260 | void (*tx_start)(struct iwl_priv *priv); | ||
1259 | void (*tx_free)(struct iwl_priv *priv); | 1261 | void (*tx_free)(struct iwl_priv *priv); |
1260 | 1262 | ||
1261 | void (*stop_device)(struct iwl_priv *priv); | 1263 | void (*stop_device)(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 1cc0ed1f488c..2f267b8aabbb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -178,61 +178,61 @@ | |||
178 | #define SCD_WIN_SIZE 64 | 178 | #define SCD_WIN_SIZE 64 |
179 | #define SCD_FRAME_LIMIT 64 | 179 | #define SCD_FRAME_LIMIT 64 |
180 | 180 | ||
181 | #define IWL_SCD_TXFIFO_POS_TID (0) | 181 | #define SCD_TXFIFO_POS_TID (0) |
182 | #define IWL_SCD_TXFIFO_POS_RA (4) | 182 | #define SCD_TXFIFO_POS_RA (4) |
183 | #define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) | 183 | #define SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) |
184 | 184 | ||
185 | /* agn SCD */ | 185 | /* agn SCD */ |
186 | #define IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF (0) | 186 | #define SCD_QUEUE_STTS_REG_POS_TXF (0) |
187 | #define IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE (3) | 187 | #define SCD_QUEUE_STTS_REG_POS_ACTIVE (3) |
188 | #define IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL (4) | 188 | #define SCD_QUEUE_STTS_REG_POS_WSL (4) |
189 | #define IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19) | 189 | #define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19) |
190 | #define IWLAGN_SCD_QUEUE_STTS_REG_MSK (0x00FF0000) | 190 | #define SCD_QUEUE_STTS_REG_MSK (0x00FF0000) |
191 | 191 | ||
192 | #define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_POS (8) | 192 | #define SCD_QUEUE_CTX_REG1_CREDIT_POS (8) |
193 | #define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) | 193 | #define SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) |
194 | #define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS (24) | 194 | #define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS (24) |
195 | #define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK (0xFF000000) | 195 | #define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK (0xFF000000) |
196 | #define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS (0) | 196 | #define SCD_QUEUE_CTX_REG2_WIN_SIZE_POS (0) |
197 | #define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F) | 197 | #define SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F) |
198 | #define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) | 198 | #define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) |
199 | #define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) | 199 | #define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) |
200 | 200 | ||
201 | /* Context Data */ | 201 | /* Context Data */ |
202 | #define IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x600) | 202 | #define SCD_CONTEXT_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x600) |
203 | #define IWLAGN_SCD_CONTEXT_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x6A0) | 203 | #define SCD_CONTEXT_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x6A0) |
204 | 204 | ||
205 | /* Tx status */ | 205 | /* Tx status */ |
206 | #define IWLAGN_SCD_TX_STTS_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x6A0) | 206 | #define SCD_TX_STTS_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x6A0) |
207 | #define IWLAGN_SCD_TX_STTS_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x7E0) | 207 | #define SCD_TX_STTS_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x7E0) |
208 | 208 | ||
209 | /* Translation Data */ | 209 | /* Translation Data */ |
210 | #define IWLAGN_SCD_TRANS_TBL_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x7E0) | 210 | #define SCD_TRANS_TBL_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x7E0) |
211 | #define IWLAGN_SCD_TRANS_TBL_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x808) | 211 | #define SCD_TRANS_TBL_MEM_UPPER_BOUND (SCD_MEM_LOWER_BOUND + 0x808) |
212 | 212 | ||
213 | #define IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(x)\ | 213 | #define SCD_CONTEXT_QUEUE_OFFSET(x)\ |
214 | (IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8)) | 214 | (SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8)) |
215 | 215 | ||
216 | #define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ | 216 | #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ |
217 | ((IWLAGN_SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) | 217 | ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) |
218 | 218 | ||
219 | #define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv) \ | 219 | #define SCD_QUEUECHAIN_SEL_ALL(priv) \ |
220 | (((1<<(priv)->hw_params.max_txq_num) - 1) &\ | 220 | (((1<<(priv)->hw_params.max_txq_num) - 1) &\ |
221 | (~(1<<(priv)->cmd_queue))) | 221 | (~(1<<(priv)->cmd_queue))) |
222 | 222 | ||
223 | #define IWLAGN_SCD_BASE (PRPH_BASE + 0xa02c00) | 223 | #define SCD_BASE (PRPH_BASE + 0xa02c00) |
224 | 224 | ||
225 | #define IWLAGN_SCD_SRAM_BASE_ADDR (IWLAGN_SCD_BASE + 0x0) | 225 | #define SCD_SRAM_BASE_ADDR (SCD_BASE + 0x0) |
226 | #define IWLAGN_SCD_DRAM_BASE_ADDR (IWLAGN_SCD_BASE + 0x8) | 226 | #define SCD_DRAM_BASE_ADDR (SCD_BASE + 0x8) |
227 | #define IWLAGN_SCD_AIT (IWLAGN_SCD_BASE + 0x0c) | 227 | #define SCD_AIT (SCD_BASE + 0x0c) |
228 | #define IWLAGN_SCD_TXFACT (IWLAGN_SCD_BASE + 0x10) | 228 | #define SCD_TXFACT (SCD_BASE + 0x10) |
229 | #define IWLAGN_SCD_ACTIVE (IWLAGN_SCD_BASE + 0x14) | 229 | #define SCD_ACTIVE (SCD_BASE + 0x14) |
230 | #define IWLAGN_SCD_QUEUE_WRPTR(x) (IWLAGN_SCD_BASE + 0x18 + (x) * 4) | 230 | #define SCD_QUEUE_WRPTR(x) (SCD_BASE + 0x18 + (x) * 4) |
231 | #define IWLAGN_SCD_QUEUE_RDPTR(x) (IWLAGN_SCD_BASE + 0x68 + (x) * 4) | 231 | #define SCD_QUEUE_RDPTR(x) (SCD_BASE + 0x68 + (x) * 4) |
232 | #define IWLAGN_SCD_QUEUECHAIN_SEL (IWLAGN_SCD_BASE + 0xe8) | 232 | #define SCD_QUEUECHAIN_SEL (SCD_BASE + 0xe8) |
233 | #define IWLAGN_SCD_AGGR_SEL (IWLAGN_SCD_BASE + 0x248) | 233 | #define SCD_AGGR_SEL (SCD_BASE + 0x248) |
234 | #define IWLAGN_SCD_INTERRUPT_MASK (IWLAGN_SCD_BASE + 0x108) | 234 | #define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) |
235 | #define IWLAGN_SCD_QUEUE_STATUS_BITS(x) (IWLAGN_SCD_BASE + 0x10c + (x) * 4) | 235 | #define SCD_QUEUE_STATUS_BITS(x) (SCD_BASE + 0x10c + (x) * 4) |
236 | 236 | ||
237 | /*********************** END TX SCHEDULER *************************************/ | 237 | /*********************** END TX SCHEDULER *************************************/ |
238 | 238 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 8d4555404799..7c748f65c86f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c | |||
@@ -547,7 +547,7 @@ static int iwl_trans_tx_init(struct iwl_priv *priv) | |||
547 | spin_lock_irqsave(&priv->lock, flags); | 547 | spin_lock_irqsave(&priv->lock, flags); |
548 | 548 | ||
549 | /* Turn off all Tx DMA fifos */ | 549 | /* Turn off all Tx DMA fifos */ |
550 | iwl_write_prph(priv, IWLAGN_SCD_TXFACT, 0); | 550 | iwl_write_prph(priv, SCD_TXFACT, 0); |
551 | 551 | ||
552 | /* Tell NIC where to find the "keep warm" buffer */ | 552 | /* Tell NIC where to find the "keep warm" buffer */ |
553 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); | 553 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); |
@@ -574,6 +574,154 @@ error: | |||
574 | return ret; | 574 | return ret; |
575 | } | 575 | } |
576 | 576 | ||
577 | /* | ||
578 | * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask | ||
579 | * must be called under priv->lock and mac access | ||
580 | */ | ||
581 | static void iwl_trans_txq_set_sched(struct iwl_priv *priv, u32 mask) | ||
582 | { | ||
583 | iwl_write_prph(priv, SCD_TXFACT, mask); | ||
584 | } | ||
585 | |||
586 | #define IWL_AC_UNSET -1 | ||
587 | |||
588 | struct queue_to_fifo_ac { | ||
589 | s8 fifo, ac; | ||
590 | }; | ||
591 | |||
592 | static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = { | ||
593 | { IWL_TX_FIFO_VO, IEEE80211_AC_VO, }, | ||
594 | { IWL_TX_FIFO_VI, IEEE80211_AC_VI, }, | ||
595 | { IWL_TX_FIFO_BE, IEEE80211_AC_BE, }, | ||
596 | { IWL_TX_FIFO_BK, IEEE80211_AC_BK, }, | ||
597 | { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, | ||
598 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
599 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
600 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
601 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
602 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
603 | }; | ||
604 | |||
605 | static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { | ||
606 | { IWL_TX_FIFO_VO, IEEE80211_AC_VO, }, | ||
607 | { IWL_TX_FIFO_VI, IEEE80211_AC_VI, }, | ||
608 | { IWL_TX_FIFO_BE, IEEE80211_AC_BE, }, | ||
609 | { IWL_TX_FIFO_BK, IEEE80211_AC_BK, }, | ||
610 | { IWL_TX_FIFO_BK_IPAN, IEEE80211_AC_BK, }, | ||
611 | { IWL_TX_FIFO_BE_IPAN, IEEE80211_AC_BE, }, | ||
612 | { IWL_TX_FIFO_VI_IPAN, IEEE80211_AC_VI, }, | ||
613 | { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, }, | ||
614 | { IWL_TX_FIFO_BE_IPAN, 2, }, | ||
615 | { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, | ||
616 | }; | ||
617 | static void iwl_trans_tx_start(struct iwl_priv *priv) | ||
618 | { | ||
619 | const struct queue_to_fifo_ac *queue_to_fifo; | ||
620 | struct iwl_rxon_context *ctx; | ||
621 | u32 a; | ||
622 | unsigned long flags; | ||
623 | int i, chan; | ||
624 | u32 reg_val; | ||
625 | |||
626 | spin_lock_irqsave(&priv->lock, flags); | ||
627 | |||
628 | priv->scd_base_addr = iwl_read_prph(priv, SCD_SRAM_BASE_ADDR); | ||
629 | a = priv->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; | ||
630 | /* reset conext data memory */ | ||
631 | for (; a < priv->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; | ||
632 | a += 4) | ||
633 | iwl_write_targ_mem(priv, a, 0); | ||
634 | /* reset tx status memory */ | ||
635 | for (; a < priv->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; | ||
636 | a += 4) | ||
637 | iwl_write_targ_mem(priv, a, 0); | ||
638 | for (; a < priv->scd_base_addr + | ||
639 | SCD_TRANS_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4) | ||
640 | iwl_write_targ_mem(priv, a, 0); | ||
641 | |||
642 | iwl_write_prph(priv, SCD_DRAM_BASE_ADDR, | ||
643 | priv->scd_bc_tbls.dma >> 10); | ||
644 | |||
645 | /* Enable DMA channel */ | ||
646 | for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) | ||
647 | iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan), | ||
648 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
649 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); | ||
650 | |||
651 | /* Update FH chicken bits */ | ||
652 | reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG); | ||
653 | iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG, | ||
654 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | ||
655 | |||
656 | iwl_write_prph(priv, SCD_QUEUECHAIN_SEL, | ||
657 | SCD_QUEUECHAIN_SEL_ALL(priv)); | ||
658 | iwl_write_prph(priv, SCD_AGGR_SEL, 0); | ||
659 | |||
660 | /* initiate the queues */ | ||
661 | for (i = 0; i < priv->hw_params.max_txq_num; i++) { | ||
662 | iwl_write_prph(priv, SCD_QUEUE_RDPTR(i), 0); | ||
663 | iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8)); | ||
664 | iwl_write_targ_mem(priv, priv->scd_base_addr + | ||
665 | SCD_CONTEXT_QUEUE_OFFSET(i), 0); | ||
666 | iwl_write_targ_mem(priv, priv->scd_base_addr + | ||
667 | SCD_CONTEXT_QUEUE_OFFSET(i) + | ||
668 | sizeof(u32), | ||
669 | ((SCD_WIN_SIZE << | ||
670 | SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | ||
671 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | ||
672 | ((SCD_FRAME_LIMIT << | ||
673 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | ||
674 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | ||
675 | } | ||
676 | |||
677 | iwl_write_prph(priv, SCD_INTERRUPT_MASK, | ||
678 | IWL_MASK(0, priv->hw_params.max_txq_num)); | ||
679 | |||
680 | /* Activate all Tx DMA/FIFO channels */ | ||
681 | iwl_trans_txq_set_sched(priv, IWL_MASK(0, 7)); | ||
682 | |||
683 | /* map queues to FIFOs */ | ||
684 | if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) | ||
685 | queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo; | ||
686 | else | ||
687 | queue_to_fifo = iwlagn_default_queue_to_tx_fifo; | ||
688 | |||
689 | iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0); | ||
690 | |||
691 | /* make sure all queue are not stopped */ | ||
692 | memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); | ||
693 | for (i = 0; i < 4; i++) | ||
694 | atomic_set(&priv->queue_stop_count[i], 0); | ||
695 | for_each_context(priv, ctx) | ||
696 | ctx->last_tx_rejected = false; | ||
697 | |||
698 | /* reset to 0 to enable all the queue first */ | ||
699 | priv->txq_ctx_active_msk = 0; | ||
700 | |||
701 | BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10); | ||
702 | BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10); | ||
703 | |||
704 | for (i = 0; i < 10; i++) { | ||
705 | int fifo = queue_to_fifo[i].fifo; | ||
706 | int ac = queue_to_fifo[i].ac; | ||
707 | |||
708 | iwl_txq_ctx_activate(priv, i); | ||
709 | |||
710 | if (fifo == IWL_TX_FIFO_UNUSED) | ||
711 | continue; | ||
712 | |||
713 | if (ac != IWL_AC_UNSET) | ||
714 | iwl_set_swq_id(&priv->txq[i], ac, i); | ||
715 | iwlagn_tx_queue_set_status(priv, &priv->txq[i], fifo, 0); | ||
716 | } | ||
717 | |||
718 | spin_unlock_irqrestore(&priv->lock, flags); | ||
719 | |||
720 | /* Enable L1-Active */ | ||
721 | iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG, | ||
722 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
723 | } | ||
724 | |||
577 | /** | 725 | /** |
578 | * iwlagn_txq_ctx_stop - Stop all Tx DMA channels | 726 | * iwlagn_txq_ctx_stop - Stop all Tx DMA channels |
579 | */ | 727 | */ |
@@ -585,7 +733,7 @@ static int iwl_trans_tx_stop(struct iwl_priv *priv) | |||
585 | /* Turn off all Tx DMA fifos */ | 733 | /* Turn off all Tx DMA fifos */ |
586 | spin_lock_irqsave(&priv->lock, flags); | 734 | spin_lock_irqsave(&priv->lock, flags); |
587 | 735 | ||
588 | iwlagn_txq_set_sched(priv, 0); | 736 | iwl_trans_txq_set_sched(priv, 0); |
589 | 737 | ||
590 | /* Stop each Tx DMA channel, and wait for it to be idle */ | 738 | /* Stop each Tx DMA channel, and wait for it to be idle */ |
591 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { | 739 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { |
@@ -822,6 +970,7 @@ static const struct iwl_trans_ops trans_ops = { | |||
822 | .rx_free = iwl_trans_rx_free, | 970 | .rx_free = iwl_trans_rx_free, |
823 | 971 | ||
824 | .tx_init = iwl_trans_tx_init, | 972 | .tx_init = iwl_trans_tx_init, |
973 | .tx_start = iwl_trans_tx_start, | ||
825 | .tx_free = iwl_trans_tx_free, | 974 | .tx_free = iwl_trans_tx_free, |
826 | 975 | ||
827 | .stop_device = iwl_trans_stop_device, | 976 | .stop_device = iwl_trans_stop_device, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 55e6c333bfa1..16cdb89b02fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -79,6 +79,11 @@ static inline int trans_tx_init(struct iwl_priv *priv) | |||
79 | return priv->trans.ops->tx_init(priv); | 79 | return priv->trans.ops->tx_init(priv); |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline void trans_tx_start(struct iwl_priv *priv) | ||
83 | { | ||
84 | priv->trans.ops->tx_start(priv); | ||
85 | } | ||
86 | |||
82 | static inline void trans_tx_free(struct iwl_priv *priv) | 87 | static inline void trans_tx_free(struct iwl_priv *priv) |
83 | { | 88 | { |
84 | priv->trans.ops->tx_free(priv); | 89 | priv->trans.ops->tx_free(priv); |