diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans.h')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.h | 99 |
1 files changed, 91 insertions, 8 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index b76532e238c1..0f85eb305878 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -308,6 +308,16 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | |||
308 | #define IWL_FRAME_LIMIT 64 | 308 | #define IWL_FRAME_LIMIT 64 |
309 | 309 | ||
310 | /** | 310 | /** |
311 | * enum iwl_wowlan_status - WoWLAN image/device status | ||
312 | * @IWL_D3_STATUS_ALIVE: firmware is still running after resume | ||
313 | * @IWL_D3_STATUS_RESET: device was reset while suspended | ||
314 | */ | ||
315 | enum iwl_d3_status { | ||
316 | IWL_D3_STATUS_ALIVE, | ||
317 | IWL_D3_STATUS_RESET, | ||
318 | }; | ||
319 | |||
320 | /** | ||
311 | * struct iwl_trans_config - transport configuration | 321 | * struct iwl_trans_config - transport configuration |
312 | * | 322 | * |
313 | * @op_mode: pointer to the upper layer. | 323 | * @op_mode: pointer to the upper layer. |
@@ -321,6 +331,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | |||
321 | * @n_no_reclaim_cmds: # of commands in list | 331 | * @n_no_reclaim_cmds: # of commands in list |
322 | * @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs, | 332 | * @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs, |
323 | * if unset 4k will be the RX buffer size | 333 | * if unset 4k will be the RX buffer size |
334 | * @bc_table_dword: set to true if the BC table expects the byte count to be | ||
335 | * in DWORD (as opposed to bytes) | ||
324 | * @queue_watchdog_timeout: time (in ms) after which queues | 336 | * @queue_watchdog_timeout: time (in ms) after which queues |
325 | * are considered stuck and will trigger device restart | 337 | * are considered stuck and will trigger device restart |
326 | * @command_names: array of command names, must be 256 entries | 338 | * @command_names: array of command names, must be 256 entries |
@@ -335,6 +347,7 @@ struct iwl_trans_config { | |||
335 | int n_no_reclaim_cmds; | 347 | int n_no_reclaim_cmds; |
336 | 348 | ||
337 | bool rx_buf_size_8k; | 349 | bool rx_buf_size_8k; |
350 | bool bc_table_dword; | ||
338 | unsigned int queue_watchdog_timeout; | 351 | unsigned int queue_watchdog_timeout; |
339 | const char **command_names; | 352 | const char **command_names; |
340 | }; | 353 | }; |
@@ -360,9 +373,12 @@ struct iwl_trans; | |||
360 | * May sleep | 373 | * May sleep |
361 | * @stop_device:stops the whole device (embedded CPU put to reset) | 374 | * @stop_device:stops the whole device (embedded CPU put to reset) |
362 | * May sleep | 375 | * May sleep |
363 | * @wowlan_suspend: put the device into the correct mode for WoWLAN during | 376 | * @d3_suspend: put the device into the correct mode for WoWLAN during |
364 | * suspend. This is optional, if not implemented WoWLAN will not be | 377 | * suspend. This is optional, if not implemented WoWLAN will not be |
365 | * supported. This callback may sleep. | 378 | * supported. This callback may sleep. |
379 | * @d3_resume: resume the device after WoWLAN, enabling the opmode to | ||
380 | * talk to the WoWLAN image to get its status. This is optional, if not | ||
381 | * implemented WoWLAN will not be supported. This callback may sleep. | ||
366 | * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted. | 382 | * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted. |
367 | * If RFkill is asserted in the middle of a SYNC host command, it must | 383 | * If RFkill is asserted in the middle of a SYNC host command, it must |
368 | * return -ERFKILL straight away. | 384 | * return -ERFKILL straight away. |
@@ -387,20 +403,27 @@ struct iwl_trans; | |||
387 | * @read32: read a u32 register at offset ofs from the BAR | 403 | * @read32: read a u32 register at offset ofs from the BAR |
388 | * @read_prph: read a DWORD from a periphery register | 404 | * @read_prph: read a DWORD from a periphery register |
389 | * @write_prph: write a DWORD to a periphery register | 405 | * @write_prph: write a DWORD to a periphery register |
406 | * @read_mem: read device's SRAM in DWORD | ||
407 | * @write_mem: write device's SRAM in DWORD. If %buf is %NULL, then the memory | ||
408 | * will be zeroed. | ||
390 | * @configure: configure parameters required by the transport layer from | 409 | * @configure: configure parameters required by the transport layer from |
391 | * the op_mode. May be called several times before start_fw, can't be | 410 | * the op_mode. May be called several times before start_fw, can't be |
392 | * called after that. | 411 | * called after that. |
393 | * @set_pmi: set the power pmi state | 412 | * @set_pmi: set the power pmi state |
413 | * @grab_nic_access: wake the NIC to be able to access non-HBUS regs | ||
414 | * @release_nic_access: let the NIC go to sleep | ||
394 | */ | 415 | */ |
395 | struct iwl_trans_ops { | 416 | struct iwl_trans_ops { |
396 | 417 | ||
397 | int (*start_hw)(struct iwl_trans *iwl_trans); | 418 | int (*start_hw)(struct iwl_trans *iwl_trans); |
398 | void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); | 419 | void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); |
399 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); | 420 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, |
421 | bool run_in_rfkill); | ||
400 | void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); | 422 | void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); |
401 | void (*stop_device)(struct iwl_trans *trans); | 423 | void (*stop_device)(struct iwl_trans *trans); |
402 | 424 | ||
403 | void (*wowlan_suspend)(struct iwl_trans *trans); | 425 | void (*d3_suspend)(struct iwl_trans *trans); |
426 | int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status); | ||
404 | 427 | ||
405 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | 428 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
406 | 429 | ||
@@ -424,9 +447,15 @@ struct iwl_trans_ops { | |||
424 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); | 447 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); |
425 | u32 (*read_prph)(struct iwl_trans *trans, u32 ofs); | 448 | u32 (*read_prph)(struct iwl_trans *trans, u32 ofs); |
426 | void (*write_prph)(struct iwl_trans *trans, u32 ofs, u32 val); | 449 | void (*write_prph)(struct iwl_trans *trans, u32 ofs, u32 val); |
450 | int (*read_mem)(struct iwl_trans *trans, u32 addr, | ||
451 | void *buf, int dwords); | ||
452 | int (*write_mem)(struct iwl_trans *trans, u32 addr, | ||
453 | void *buf, int dwords); | ||
427 | void (*configure)(struct iwl_trans *trans, | 454 | void (*configure)(struct iwl_trans *trans, |
428 | const struct iwl_trans_config *trans_cfg); | 455 | const struct iwl_trans_config *trans_cfg); |
429 | void (*set_pmi)(struct iwl_trans *trans, bool state); | 456 | void (*set_pmi)(struct iwl_trans *trans, bool state); |
457 | bool (*grab_nic_access)(struct iwl_trans *trans, bool silent); | ||
458 | void (*release_nic_access)(struct iwl_trans *trans); | ||
430 | }; | 459 | }; |
431 | 460 | ||
432 | /** | 461 | /** |
@@ -528,13 +557,14 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr) | |||
528 | } | 557 | } |
529 | 558 | ||
530 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, | 559 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, |
531 | const struct fw_img *fw) | 560 | const struct fw_img *fw, |
561 | bool run_in_rfkill) | ||
532 | { | 562 | { |
533 | might_sleep(); | 563 | might_sleep(); |
534 | 564 | ||
535 | WARN_ON_ONCE(!trans->rx_mpdu_cmd); | 565 | WARN_ON_ONCE(!trans->rx_mpdu_cmd); |
536 | 566 | ||
537 | return trans->ops->start_fw(trans, fw); | 567 | return trans->ops->start_fw(trans, fw, run_in_rfkill); |
538 | } | 568 | } |
539 | 569 | ||
540 | static inline void iwl_trans_stop_device(struct iwl_trans *trans) | 570 | static inline void iwl_trans_stop_device(struct iwl_trans *trans) |
@@ -546,10 +576,17 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) | |||
546 | trans->state = IWL_TRANS_NO_FW; | 576 | trans->state = IWL_TRANS_NO_FW; |
547 | } | 577 | } |
548 | 578 | ||
549 | static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) | 579 | static inline void iwl_trans_d3_suspend(struct iwl_trans *trans) |
580 | { | ||
581 | might_sleep(); | ||
582 | trans->ops->d3_suspend(trans); | ||
583 | } | ||
584 | |||
585 | static inline int iwl_trans_d3_resume(struct iwl_trans *trans, | ||
586 | enum iwl_d3_status *status) | ||
550 | { | 587 | { |
551 | might_sleep(); | 588 | might_sleep(); |
552 | trans->ops->wowlan_suspend(trans); | 589 | return trans->ops->d3_resume(trans, status); |
553 | } | 590 | } |
554 | 591 | ||
555 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | 592 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, |
@@ -636,7 +673,7 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) | |||
636 | } | 673 | } |
637 | 674 | ||
638 | static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, | 675 | static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, |
639 | struct dentry *dir) | 676 | struct dentry *dir) |
640 | { | 677 | { |
641 | return trans->ops->dbgfs_register(trans, dir); | 678 | return trans->ops->dbgfs_register(trans, dir); |
642 | } | 679 | } |
@@ -679,11 +716,57 @@ static inline void iwl_trans_write_prph(struct iwl_trans *trans, u32 ofs, | |||
679 | return trans->ops->write_prph(trans, ofs, val); | 716 | return trans->ops->write_prph(trans, ofs, val); |
680 | } | 717 | } |
681 | 718 | ||
719 | static inline int iwl_trans_read_mem(struct iwl_trans *trans, u32 addr, | ||
720 | void *buf, int dwords) | ||
721 | { | ||
722 | return trans->ops->read_mem(trans, addr, buf, dwords); | ||
723 | } | ||
724 | |||
725 | #define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize) \ | ||
726 | do { \ | ||
727 | if (__builtin_constant_p(bufsize)) \ | ||
728 | BUILD_BUG_ON((bufsize) % sizeof(u32)); \ | ||
729 | iwl_trans_read_mem(trans, addr, buf, (bufsize) / sizeof(u32));\ | ||
730 | } while (0) | ||
731 | |||
732 | static inline u32 iwl_trans_read_mem32(struct iwl_trans *trans, u32 addr) | ||
733 | { | ||
734 | u32 value; | ||
735 | |||
736 | if (WARN_ON(iwl_trans_read_mem(trans, addr, &value, 1))) | ||
737 | return 0xa5a5a5a5; | ||
738 | |||
739 | return value; | ||
740 | } | ||
741 | |||
742 | static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr, | ||
743 | void *buf, int dwords) | ||
744 | { | ||
745 | return trans->ops->write_mem(trans, addr, buf, dwords); | ||
746 | } | ||
747 | |||
748 | static inline u32 iwl_trans_write_mem32(struct iwl_trans *trans, u32 addr, | ||
749 | u32 val) | ||
750 | { | ||
751 | return iwl_trans_write_mem(trans, addr, &val, 1); | ||
752 | } | ||
753 | |||
682 | static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state) | 754 | static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state) |
683 | { | 755 | { |
684 | trans->ops->set_pmi(trans, state); | 756 | trans->ops->set_pmi(trans, state); |
685 | } | 757 | } |
686 | 758 | ||
759 | #define iwl_trans_grab_nic_access(trans, silent) \ | ||
760 | __cond_lock(nic_access, \ | ||
761 | likely((trans)->ops->grab_nic_access(trans, silent))) | ||
762 | |||
763 | static inline void __releases(nic_access) | ||
764 | iwl_trans_release_nic_access(struct iwl_trans *trans) | ||
765 | { | ||
766 | trans->ops->release_nic_access(trans); | ||
767 | __release(nic_access); | ||
768 | } | ||
769 | |||
687 | /***************************************************** | 770 | /***************************************************** |
688 | * driver (transport) register/unregister functions | 771 | * driver (transport) register/unregister functions |
689 | ******************************************************/ | 772 | ******************************************************/ |