aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-trans.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans.h')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h56
1 files changed, 45 insertions, 11 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 79a1e7ae4995..00efde8e5536 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -154,6 +154,9 @@ struct iwl_cmd_header {
154 __le16 sequence; 154 __le16 sequence;
155} __packed; 155} __packed;
156 156
157/* iwl_cmd_header flags value */
158#define IWL_CMD_FAILED_MSK 0x40
159
157 160
158#define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ 161#define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */
159#define FH_RSCSR_FRAME_INVALID 0x55550000 162#define FH_RSCSR_FRAME_INVALID 0x55550000
@@ -280,6 +283,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
280 283
281#define MAX_NO_RECLAIM_CMDS 6 284#define MAX_NO_RECLAIM_CMDS 6
282 285
286#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
287
283/* 288/*
284 * Maximum number of HW queues the transport layer 289 * Maximum number of HW queues the transport layer
285 * currently supports 290 * currently supports
@@ -350,10 +355,10 @@ struct iwl_trans;
350 * Must be atomic 355 * Must be atomic
351 * @reclaim: free packet until ssn. Returns a list of freed packets. 356 * @reclaim: free packet until ssn. Returns a list of freed packets.
352 * Must be atomic 357 * Must be atomic
353 * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is 358 * @txq_enable: setup a tx queue for AMPDU - will be called once the HW is
354 * ready and a successful ADDBA response has been received. 359 * ready and a successful ADDBA response has been received.
355 * May sleep 360 * May sleep
356 * @tx_agg_disable: de-configure a Tx queue to send AMPDUs 361 * @txq_disable: de-configure a Tx queue to send AMPDUs
357 * Must be atomic 362 * Must be atomic
358 * @wait_tx_queue_empty: wait until all tx queues are empty 363 * @wait_tx_queue_empty: wait until all tx queues are empty
359 * May sleep 364 * May sleep
@@ -386,9 +391,9 @@ struct iwl_trans_ops {
386 void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, 391 void (*reclaim)(struct iwl_trans *trans, int queue, int ssn,
387 struct sk_buff_head *skbs); 392 struct sk_buff_head *skbs);
388 393
389 void (*tx_agg_setup)(struct iwl_trans *trans, int queue, int fifo, 394 void (*txq_enable)(struct iwl_trans *trans, int queue, int fifo,
390 int sta_id, int tid, int frame_limit, u16 ssn); 395 int sta_id, int tid, int frame_limit, u16 ssn);
391 void (*tx_agg_disable)(struct iwl_trans *trans, int queue); 396 void (*txq_disable)(struct iwl_trans *trans, int queue);
392 397
393 int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); 398 int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
394 int (*wait_tx_queue_empty)(struct iwl_trans *trans); 399 int (*wait_tx_queue_empty)(struct iwl_trans *trans);
@@ -428,6 +433,11 @@ enum iwl_trans_state {
428 * @hw_id_str: a string with info about HW ID. Set during transport allocation. 433 * @hw_id_str: a string with info about HW ID. Set during transport allocation.
429 * @pm_support: set to true in start_hw if link pm is supported 434 * @pm_support: set to true in start_hw if link pm is supported
430 * @wait_command_queue: the wait_queue for SYNC host commands 435 * @wait_command_queue: the wait_queue for SYNC host commands
436 * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
437 * The user should use iwl_trans_{alloc,free}_tx_cmd.
438 * @dev_cmd_headroom: room needed for the transport's private use before the
439 * device_cmd for Tx - for internal use only
440 * The user should use iwl_trans_{alloc,free}_tx_cmd.
431 */ 441 */
432struct iwl_trans { 442struct iwl_trans {
433 const struct iwl_trans_ops *ops; 443 const struct iwl_trans_ops *ops;
@@ -445,6 +455,10 @@ struct iwl_trans {
445 455
446 wait_queue_head_t wait_command_queue; 456 wait_queue_head_t wait_command_queue;
447 457
458 /* The following fields are internal only */
459 struct kmem_cache *dev_cmd_pool;
460 size_t dev_cmd_headroom;
461
448 /* pointer to trans specific struct */ 462 /* pointer to trans specific struct */
449 /*Ensure that this pointer will always be aligned to sizeof pointer */ 463 /*Ensure that this pointer will always be aligned to sizeof pointer */
450 char trans_specific[0] __aligned(sizeof(void *)); 464 char trans_specific[0] __aligned(sizeof(void *));
@@ -520,6 +534,26 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
520 return trans->ops->send_cmd(trans, cmd); 534 return trans->ops->send_cmd(trans, cmd);
521} 535}
522 536
537static inline struct iwl_device_cmd *
538iwl_trans_alloc_tx_cmd(struct iwl_trans *trans)
539{
540 u8 *dev_cmd_ptr = kmem_cache_alloc(trans->dev_cmd_pool, GFP_ATOMIC);
541
542 if (unlikely(dev_cmd_ptr == NULL))
543 return NULL;
544
545 return (struct iwl_device_cmd *)
546 (dev_cmd_ptr + trans->dev_cmd_headroom);
547}
548
549static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans,
550 struct iwl_device_cmd *dev_cmd)
551{
552 u8 *dev_cmd_ptr = (u8 *)dev_cmd - trans->dev_cmd_headroom;
553
554 kmem_cache_free(trans->dev_cmd_pool, dev_cmd_ptr);
555}
556
523static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, 557static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
524 struct iwl_device_cmd *dev_cmd, int queue) 558 struct iwl_device_cmd *dev_cmd, int queue)
525{ 559{
@@ -538,24 +572,24 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
538 trans->ops->reclaim(trans, queue, ssn, skbs); 572 trans->ops->reclaim(trans, queue, ssn, skbs);
539} 573}
540 574
541static inline void iwl_trans_tx_agg_disable(struct iwl_trans *trans, int queue) 575static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue)
542{ 576{
543 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, 577 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
544 "%s bad state = %d", __func__, trans->state); 578 "%s bad state = %d", __func__, trans->state);
545 579
546 trans->ops->tx_agg_disable(trans, queue); 580 trans->ops->txq_disable(trans, queue);
547} 581}
548 582
549static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, int queue, 583static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
550 int fifo, int sta_id, int tid, 584 int fifo, int sta_id, int tid,
551 int frame_limit, u16 ssn) 585 int frame_limit, u16 ssn)
552{ 586{
553 might_sleep(); 587 might_sleep();
554 588
555 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, 589 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
556 "%s bad state = %d", __func__, trans->state); 590 "%s bad state = %d", __func__, trans->state);
557 591
558 trans->ops->tx_agg_setup(trans, queue, fifo, sta_id, tid, 592 trans->ops->txq_enable(trans, queue, fifo, sta_id, tid,
559 frame_limit, ssn); 593 frame_limit, ssn);
560} 594}
561 595