diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans.h')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.h | 56 |
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 | */ |
432 | struct iwl_trans { | 442 | struct 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 | ||
537 | static inline struct iwl_device_cmd * | ||
538 | iwl_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 | |||
549 | static 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 | |||
523 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | 557 | static 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 | ||
541 | static inline void iwl_trans_tx_agg_disable(struct iwl_trans *trans, int queue) | 575 | static 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 | ||
549 | static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, int queue, | 583 | static 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 | ||