| .. | .. |
|---|
| 8 | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
|---|
| 9 | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
|---|
| 10 | 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
|---|
| 11 | + * Copyright(c) 2018 - 2019 Intel Corporation |
|---|
| 11 | 12 | * |
|---|
| 12 | 13 | * This program is free software; you can redistribute it and/or modify |
|---|
| 13 | 14 | * it under the terms of version 2 of the GNU General Public License as |
|---|
| .. | .. |
|---|
| 17 | 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 18 | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 19 | 20 | * General Public License for more details. |
|---|
| 20 | | - * |
|---|
| 21 | | - * You should have received a copy of the GNU General Public License |
|---|
| 22 | | - * along with this program; if not, write to the Free Software |
|---|
| 23 | | - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, |
|---|
| 24 | | - * USA |
|---|
| 25 | 21 | * |
|---|
| 26 | 22 | * The full GNU General Public License is included in this distribution |
|---|
| 27 | 23 | * in the file called COPYING. |
|---|
| .. | .. |
|---|
| 35 | 31 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
|---|
| 36 | 32 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
|---|
| 37 | 33 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
|---|
| 34 | + * Copyright(c) 2018 - 2019 Intel Corporation |
|---|
| 38 | 35 | * All rights reserved. |
|---|
| 39 | 36 | * |
|---|
| 40 | 37 | * Redistribution and use in source and binary forms, with or without |
|---|
| .. | .. |
|---|
| 76 | 73 | #include "iwl-config.h" |
|---|
| 77 | 74 | #include "fw/img.h" |
|---|
| 78 | 75 | #include "iwl-op-mode.h" |
|---|
| 76 | +#include <linux/firmware.h> |
|---|
| 79 | 77 | #include "fw/api/cmdhdr.h" |
|---|
| 80 | 78 | #include "fw/api/txq.h" |
|---|
| 79 | +#include "fw/api/dbg-tlv.h" |
|---|
| 80 | +#include "iwl-dbg-tlv.h" |
|---|
| 81 | 81 | |
|---|
| 82 | 82 | /** |
|---|
| 83 | 83 | * DOC: Transport layer - what is it ? |
|---|
| .. | .. |
|---|
| 112 | 112 | * |
|---|
| 113 | 113 | * 6) Eventually, the free function will be called. |
|---|
| 114 | 114 | */ |
|---|
| 115 | + |
|---|
| 116 | +#define IWL_TRANS_FW_DBG_DOMAIN(trans) IWL_FW_INI_DOMAIN_ALWAYS_ON |
|---|
| 115 | 117 | |
|---|
| 116 | 118 | #define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ |
|---|
| 117 | 119 | #define FH_RSCSR_FRAME_INVALID 0x55550000 |
|---|
| .. | .. |
|---|
| 160 | 162 | * @CMD_ASYNC: Return right away and don't wait for the response |
|---|
| 161 | 163 | * @CMD_WANT_SKB: Not valid with CMD_ASYNC. The caller needs the buffer of |
|---|
| 162 | 164 | * the response. The caller needs to call iwl_free_resp when done. |
|---|
| 163 | | - * @CMD_HIGH_PRIO: The command is high priority - it goes to the front of the |
|---|
| 164 | | - * command queue, but after other high priority commands. Valid only |
|---|
| 165 | | - * with CMD_ASYNC. |
|---|
| 166 | | - * @CMD_SEND_IN_IDLE: The command should be sent even when the trans is idle. |
|---|
| 167 | | - * @CMD_MAKE_TRANS_IDLE: The command response should mark the trans as idle. |
|---|
| 168 | | - * @CMD_WAKE_UP_TRANS: The command response should wake up the trans |
|---|
| 169 | | - * (i.e. mark it as non-idle). |
|---|
| 170 | 165 | * @CMD_WANT_ASYNC_CALLBACK: the op_mode's async callback function must be |
|---|
| 171 | 166 | * called after this command completes. Valid only with CMD_ASYNC. |
|---|
| 172 | 167 | */ |
|---|
| .. | .. |
|---|
| 174 | 169 | CMD_ASYNC = BIT(0), |
|---|
| 175 | 170 | CMD_WANT_SKB = BIT(1), |
|---|
| 176 | 171 | CMD_SEND_IN_RFKILL = BIT(2), |
|---|
| 177 | | - CMD_HIGH_PRIO = BIT(3), |
|---|
| 178 | | - CMD_SEND_IN_IDLE = BIT(4), |
|---|
| 179 | | - CMD_MAKE_TRANS_IDLE = BIT(5), |
|---|
| 180 | | - CMD_WAKE_UP_TRANS = BIT(6), |
|---|
| 181 | | - CMD_WANT_ASYNC_CALLBACK = BIT(7), |
|---|
| 172 | + CMD_WANT_ASYNC_CALLBACK = BIT(3), |
|---|
| 182 | 173 | }; |
|---|
| 183 | 174 | |
|---|
| 184 | 175 | #define DEF_CMD_PAYLOAD_SIZE 320 |
|---|
| .. | .. |
|---|
| 205 | 196 | }; |
|---|
| 206 | 197 | } __packed; |
|---|
| 207 | 198 | |
|---|
| 199 | +/** |
|---|
| 200 | + * struct iwl_device_tx_cmd - buffer for TX command |
|---|
| 201 | + * @hdr: the header |
|---|
| 202 | + * @payload: the payload placeholder |
|---|
| 203 | + * |
|---|
| 204 | + * The actual structure is sized dynamically according to need. |
|---|
| 205 | + */ |
|---|
| 206 | +struct iwl_device_tx_cmd { |
|---|
| 207 | + struct iwl_cmd_header hdr; |
|---|
| 208 | + u8 payload[]; |
|---|
| 209 | +} __packed; |
|---|
| 210 | + |
|---|
| 208 | 211 | #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) |
|---|
| 209 | 212 | |
|---|
| 210 | 213 | /* |
|---|
| .. | .. |
|---|
| 212 | 215 | * this is just the driver's idea, the hardware supports 20 |
|---|
| 213 | 216 | */ |
|---|
| 214 | 217 | #define IWL_MAX_CMD_TBS_PER_TFD 2 |
|---|
| 218 | + |
|---|
| 219 | +/* We need 2 entries for the TX command and header, and another one might |
|---|
| 220 | + * be needed for potential data in the SKB's head. The remaining ones can |
|---|
| 221 | + * be used for frags. |
|---|
| 222 | + */ |
|---|
| 223 | +#define IWL_TRANS_MAX_FRAGS(trans) ((trans)->txqs.tfd.max_tbs - 3) |
|---|
| 215 | 224 | |
|---|
| 216 | 225 | /** |
|---|
| 217 | 226 | * enum iwl_hcmd_dataflag - flag for each one of the chunks of the command |
|---|
| .. | .. |
|---|
| 231 | 240 | enum iwl_hcmd_dataflag { |
|---|
| 232 | 241 | IWL_HCMD_DFL_NOCOPY = BIT(0), |
|---|
| 233 | 242 | IWL_HCMD_DFL_DUP = BIT(1), |
|---|
| 243 | +}; |
|---|
| 244 | + |
|---|
| 245 | +enum iwl_error_event_table_status { |
|---|
| 246 | + IWL_ERROR_EVENT_TABLE_LMAC1 = BIT(0), |
|---|
| 247 | + IWL_ERROR_EVENT_TABLE_LMAC2 = BIT(1), |
|---|
| 248 | + IWL_ERROR_EVENT_TABLE_UMAC = BIT(2), |
|---|
| 234 | 249 | }; |
|---|
| 235 | 250 | |
|---|
| 236 | 251 | /** |
|---|
| .. | .. |
|---|
| 269 | 284 | bool _page_stolen; |
|---|
| 270 | 285 | u32 _rx_page_order; |
|---|
| 271 | 286 | unsigned int truesize; |
|---|
| 272 | | - u8 status; |
|---|
| 273 | 287 | }; |
|---|
| 274 | 288 | |
|---|
| 275 | 289 | static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r) |
|---|
| .. | .. |
|---|
| 309 | 323 | #define IWL_MGMT_TID 15 |
|---|
| 310 | 324 | #define IWL_FRAME_LIMIT 64 |
|---|
| 311 | 325 | #define IWL_MAX_RX_HW_QUEUES 16 |
|---|
| 326 | +#define IWL_9000_MAX_RX_HW_QUEUES 6 |
|---|
| 312 | 327 | |
|---|
| 313 | 328 | /** |
|---|
| 314 | 329 | * enum iwl_wowlan_status - WoWLAN image/device status |
|---|
| .. | .. |
|---|
| 362 | 377 | default: |
|---|
| 363 | 378 | WARN_ON(1); |
|---|
| 364 | 379 | return -1; |
|---|
| 380 | + } |
|---|
| 381 | +} |
|---|
| 382 | + |
|---|
| 383 | +static inline int |
|---|
| 384 | +iwl_trans_get_rb_size(enum iwl_amsdu_size rb_size) |
|---|
| 385 | +{ |
|---|
| 386 | + switch (rb_size) { |
|---|
| 387 | + case IWL_AMSDU_2K: |
|---|
| 388 | + return 2 * 1024; |
|---|
| 389 | + case IWL_AMSDU_4K: |
|---|
| 390 | + return 4 * 1024; |
|---|
| 391 | + case IWL_AMSDU_8K: |
|---|
| 392 | + return 8 * 1024; |
|---|
| 393 | + case IWL_AMSDU_12K: |
|---|
| 394 | + return 12 * 1024; |
|---|
| 395 | + default: |
|---|
| 396 | + WARN_ON(1); |
|---|
| 397 | + return 0; |
|---|
| 365 | 398 | } |
|---|
| 366 | 399 | } |
|---|
| 367 | 400 | |
|---|
| .. | .. |
|---|
| 459 | 492 | * |
|---|
| 460 | 493 | * All the handlers MUST be implemented |
|---|
| 461 | 494 | * |
|---|
| 462 | | - * @start_hw: starts the HW. If low_power is true, the NIC needs to be taken |
|---|
| 463 | | - * out of a low power state. From that point on, the HW can send |
|---|
| 464 | | - * interrupts. May sleep. |
|---|
| 495 | + * @start_hw: starts the HW. From that point on, the HW can send interrupts. |
|---|
| 496 | + * May sleep. |
|---|
| 465 | 497 | * @op_mode_leave: Turn off the HW RF kill indication if on |
|---|
| 466 | 498 | * May sleep |
|---|
| 467 | 499 | * @start_fw: allocates and inits all the resources for the transport |
|---|
| .. | .. |
|---|
| 471 | 503 | * the SCD base address in SRAM, then provide it here, or 0 otherwise. |
|---|
| 472 | 504 | * May sleep |
|---|
| 473 | 505 | * @stop_device: stops the whole device (embedded CPU put to reset) and stops |
|---|
| 474 | | - * the HW. If low_power is true, the NIC will be put in low power state. |
|---|
| 475 | | - * From that point on, the HW will be stopped but will still issue an |
|---|
| 476 | | - * interrupt if the HW RF kill switch is triggered. |
|---|
| 506 | + * the HW. From that point on, the HW will be stopped but will still issue |
|---|
| 507 | + * an interrupt if the HW RF kill switch is triggered. |
|---|
| 477 | 508 | * This callback must do the right thing and not crash even if %start_hw() |
|---|
| 478 | 509 | * was called but not &start_fw(). May sleep. |
|---|
| 479 | 510 | * @d3_suspend: put the device into the correct mode for WoWLAN during |
|---|
| .. | .. |
|---|
| 521 | 552 | * @read_mem: read device's SRAM in DWORD |
|---|
| 522 | 553 | * @write_mem: write device's SRAM in DWORD. If %buf is %NULL, then the memory |
|---|
| 523 | 554 | * will be zeroed. |
|---|
| 555 | + * @read_config32: read a u32 value from the device's config space at |
|---|
| 556 | + * the given offset. |
|---|
| 524 | 557 | * @configure: configure parameters required by the transport layer from |
|---|
| 525 | 558 | * the op_mode. May be called several times before start_fw, can't be |
|---|
| 526 | 559 | * called after that. |
|---|
| .. | .. |
|---|
| 531 | 564 | * @release_nic_access: let the NIC go to sleep. The "flags" parameter |
|---|
| 532 | 565 | * must be the same one that was sent before to the grab_nic_access. |
|---|
| 533 | 566 | * @set_bits_mask - set SRAM register according to value and mask. |
|---|
| 534 | | - * @ref: grab a reference to the transport/FW layers, disallowing |
|---|
| 535 | | - * certain low power states |
|---|
| 536 | | - * @unref: release a reference previously taken with @ref. Note that |
|---|
| 537 | | - * initially the reference count is 1, making an initial @unref |
|---|
| 538 | | - * necessary to allow low power states. |
|---|
| 539 | 567 | * @dump_data: return a vmalloc'ed buffer with debug data, maybe containing last |
|---|
| 540 | 568 | * TX'ed commands and similar. The buffer will be vfree'd by the caller. |
|---|
| 541 | 569 | * Note that the transport must fill in the proper file headers. |
|---|
| 542 | | - * @dump_regs: dump using IWL_ERR configuration space and memory mapped |
|---|
| 543 | | - * registers of the device to diagnose failure, e.g., when HW becomes |
|---|
| 544 | | - * inaccessible. |
|---|
| 570 | + * @debugfs_cleanup: used in the driver unload flow to make a proper cleanup |
|---|
| 571 | + * of the trans debugfs |
|---|
| 572 | + * @set_pnvm: set the pnvm data in the prph scratch buffer, inside the |
|---|
| 573 | + * context info. |
|---|
| 545 | 574 | */ |
|---|
| 546 | 575 | struct iwl_trans_ops { |
|---|
| 547 | 576 | |
|---|
| 548 | | - int (*start_hw)(struct iwl_trans *iwl_trans, bool low_power); |
|---|
| 577 | + int (*start_hw)(struct iwl_trans *iwl_trans); |
|---|
| 549 | 578 | void (*op_mode_leave)(struct iwl_trans *iwl_trans); |
|---|
| 550 | 579 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, |
|---|
| 551 | 580 | bool run_in_rfkill); |
|---|
| 552 | 581 | void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); |
|---|
| 553 | | - void (*stop_device)(struct iwl_trans *trans, bool low_power); |
|---|
| 582 | + void (*stop_device)(struct iwl_trans *trans); |
|---|
| 554 | 583 | |
|---|
| 555 | | - void (*d3_suspend)(struct iwl_trans *trans, bool test, bool reset); |
|---|
| 584 | + int (*d3_suspend)(struct iwl_trans *trans, bool test, bool reset); |
|---|
| 556 | 585 | int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status, |
|---|
| 557 | 586 | bool test, bool reset); |
|---|
| 558 | 587 | |
|---|
| 559 | 588 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
|---|
| 560 | 589 | |
|---|
| 561 | 590 | int (*tx)(struct iwl_trans *trans, struct sk_buff *skb, |
|---|
| 562 | | - struct iwl_device_cmd *dev_cmd, int queue); |
|---|
| 591 | + struct iwl_device_tx_cmd *dev_cmd, int queue); |
|---|
| 563 | 592 | void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, |
|---|
| 564 | 593 | struct sk_buff_head *skbs); |
|---|
| 594 | + |
|---|
| 595 | + void (*set_q_ptrs)(struct iwl_trans *trans, int queue, int ptr); |
|---|
| 565 | 596 | |
|---|
| 566 | 597 | bool (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn, |
|---|
| 567 | 598 | const struct iwl_trans_txq_scd_cfg *cfg, |
|---|
| .. | .. |
|---|
| 570 | 601 | bool configure_scd); |
|---|
| 571 | 602 | /* 22000 functions */ |
|---|
| 572 | 603 | int (*txq_alloc)(struct iwl_trans *trans, |
|---|
| 573 | | - struct iwl_tx_queue_cfg_cmd *cmd, |
|---|
| 604 | + __le16 flags, u8 sta_id, u8 tid, |
|---|
| 574 | 605 | int cmd_id, int size, |
|---|
| 575 | 606 | unsigned int queue_wdg_timeout); |
|---|
| 576 | 607 | void (*txq_free)(struct iwl_trans *trans, int queue); |
|---|
| .. | .. |
|---|
| 595 | 626 | void *buf, int dwords); |
|---|
| 596 | 627 | int (*write_mem)(struct iwl_trans *trans, u32 addr, |
|---|
| 597 | 628 | const void *buf, int dwords); |
|---|
| 629 | + int (*read_config32)(struct iwl_trans *trans, u32 ofs, u32 *val); |
|---|
| 598 | 630 | void (*configure)(struct iwl_trans *trans, |
|---|
| 599 | 631 | const struct iwl_trans_config *trans_cfg); |
|---|
| 600 | 632 | void (*set_pmi)(struct iwl_trans *trans, bool state); |
|---|
| .. | .. |
|---|
| 604 | 636 | unsigned long *flags); |
|---|
| 605 | 637 | void (*set_bits_mask)(struct iwl_trans *trans, u32 reg, u32 mask, |
|---|
| 606 | 638 | u32 value); |
|---|
| 607 | | - void (*ref)(struct iwl_trans *trans); |
|---|
| 608 | | - void (*unref)(struct iwl_trans *trans); |
|---|
| 609 | 639 | int (*suspend)(struct iwl_trans *trans); |
|---|
| 610 | 640 | void (*resume)(struct iwl_trans *trans); |
|---|
| 611 | 641 | |
|---|
| 612 | 642 | struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans, |
|---|
| 613 | | - const struct iwl_fw_dbg_trigger_tlv |
|---|
| 614 | | - *trigger); |
|---|
| 615 | | - |
|---|
| 616 | | - void (*dump_regs)(struct iwl_trans *trans); |
|---|
| 643 | + u32 dump_mask); |
|---|
| 644 | + void (*debugfs_cleanup)(struct iwl_trans *trans); |
|---|
| 645 | + void (*sync_nmi)(struct iwl_trans *trans); |
|---|
| 646 | + int (*set_pnvm)(struct iwl_trans *trans, const void *data, u32 len); |
|---|
| 617 | 647 | }; |
|---|
| 618 | 648 | |
|---|
| 619 | 649 | /** |
|---|
| .. | .. |
|---|
| 630 | 660 | /** |
|---|
| 631 | 661 | * DOC: Platform power management |
|---|
| 632 | 662 | * |
|---|
| 633 | | - * There are two types of platform power management: system-wide |
|---|
| 634 | | - * (WoWLAN) and runtime. |
|---|
| 635 | | - * |
|---|
| 636 | 663 | * In system-wide power management the entire platform goes into a low |
|---|
| 637 | 664 | * power state (e.g. idle or suspend to RAM) at the same time and the |
|---|
| 638 | 665 | * device is configured as a wakeup source for the entire platform. |
|---|
| .. | .. |
|---|
| 641 | 668 | * put the platform in low power mode). The device's behavior in this |
|---|
| 642 | 669 | * mode is dictated by the wake-on-WLAN configuration. |
|---|
| 643 | 670 | * |
|---|
| 644 | | - * In runtime power management, only the devices which are themselves |
|---|
| 645 | | - * idle enter a low power state. This is done at runtime, which means |
|---|
| 646 | | - * that the entire system is still running normally. This mode is |
|---|
| 647 | | - * usually triggered automatically by the device driver and requires |
|---|
| 648 | | - * the ability to enter and exit the low power modes in a very short |
|---|
| 649 | | - * time, so there is not much impact in usability. |
|---|
| 650 | | - * |
|---|
| 651 | 671 | * The terms used for the device's behavior are as follows: |
|---|
| 652 | 672 | * |
|---|
| 653 | 673 | * - D0: the device is fully powered and the host is awake; |
|---|
| 654 | 674 | * - D3: the device is in low power mode and only reacts to |
|---|
| 655 | 675 | * specific events (e.g. magic-packet received or scan |
|---|
| 656 | 676 | * results found); |
|---|
| 657 | | - * - D0I3: the device is in low power mode and reacts to any |
|---|
| 658 | | - * activity (e.g. RX); |
|---|
| 659 | 677 | * |
|---|
| 660 | 678 | * These terms reflect the power modes in the firmware and are not to |
|---|
| 661 | | - * be confused with the physical device power state. The NIC can be |
|---|
| 662 | | - * in D0I3 mode even if, for instance, the PCI device is in D3 state. |
|---|
| 679 | + * be confused with the physical device power state. |
|---|
| 663 | 680 | */ |
|---|
| 664 | 681 | |
|---|
| 665 | 682 | /** |
|---|
| 666 | 683 | * enum iwl_plat_pm_mode - platform power management mode |
|---|
| 667 | 684 | * |
|---|
| 668 | 685 | * This enumeration describes the device's platform power management |
|---|
| 669 | | - * behavior when in idle mode (i.e. runtime power management) or when |
|---|
| 670 | | - * in system-wide suspend (i.e WoWLAN). |
|---|
| 686 | + * behavior when in system-wide suspend (i.e WoWLAN). |
|---|
| 671 | 687 | * |
|---|
| 672 | 688 | * @IWL_PLAT_PM_MODE_DISABLED: power management is disabled for this |
|---|
| 673 | | - * device. At runtime, this means that nothing happens and the |
|---|
| 674 | | - * device always remains in active. In system-wide suspend mode, |
|---|
| 675 | | - * it means that the all connections will be closed automatically |
|---|
| 676 | | - * by mac80211 before the platform is suspended. |
|---|
| 689 | + * device. In system-wide suspend mode, it means that the all |
|---|
| 690 | + * connections will be closed automatically by mac80211 before |
|---|
| 691 | + * the platform is suspended. |
|---|
| 677 | 692 | * @IWL_PLAT_PM_MODE_D3: the device goes into D3 mode (i.e. WoWLAN). |
|---|
| 678 | | - * For runtime power management, this mode is not officially |
|---|
| 679 | | - * supported. |
|---|
| 680 | | - * @IWL_PLAT_PM_MODE_D0I3: the device goes into D0I3 mode. |
|---|
| 681 | 693 | */ |
|---|
| 682 | 694 | enum iwl_plat_pm_mode { |
|---|
| 683 | 695 | IWL_PLAT_PM_MODE_DISABLED, |
|---|
| 684 | 696 | IWL_PLAT_PM_MODE_D3, |
|---|
| 685 | | - IWL_PLAT_PM_MODE_D0I3, |
|---|
| 686 | 697 | }; |
|---|
| 687 | 698 | |
|---|
| 688 | | -/* Max time to wait for trans to become idle/non-idle on d0i3 |
|---|
| 689 | | - * enter/exit (in msecs). |
|---|
| 699 | +/** |
|---|
| 700 | + * enum iwl_ini_cfg_state |
|---|
| 701 | + * @IWL_INI_CFG_STATE_NOT_LOADED: no debug cfg was given |
|---|
| 702 | + * @IWL_INI_CFG_STATE_LOADED: debug cfg was found and loaded |
|---|
| 703 | + * @IWL_INI_CFG_STATE_CORRUPTED: debug cfg was found and some of the TLVs |
|---|
| 704 | + * are corrupted. The rest of the debug TLVs will still be used |
|---|
| 690 | 705 | */ |
|---|
| 691 | | -#define IWL_TRANS_IDLE_TIMEOUT 2000 |
|---|
| 706 | +enum iwl_ini_cfg_state { |
|---|
| 707 | + IWL_INI_CFG_STATE_NOT_LOADED, |
|---|
| 708 | + IWL_INI_CFG_STATE_LOADED, |
|---|
| 709 | + IWL_INI_CFG_STATE_CORRUPTED, |
|---|
| 710 | +}; |
|---|
| 711 | + |
|---|
| 712 | +/* Max time to wait for nmi interrupt */ |
|---|
| 713 | +#define IWL_TRANS_NMI_TIMEOUT (HZ / 4) |
|---|
| 714 | + |
|---|
| 715 | +/** |
|---|
| 716 | + * struct iwl_dram_data |
|---|
| 717 | + * @physical: page phy pointer |
|---|
| 718 | + * @block: pointer to the allocated block/page |
|---|
| 719 | + * @size: size of the block/page |
|---|
| 720 | + */ |
|---|
| 721 | +struct iwl_dram_data { |
|---|
| 722 | + dma_addr_t physical; |
|---|
| 723 | + void *block; |
|---|
| 724 | + int size; |
|---|
| 725 | +}; |
|---|
| 726 | + |
|---|
| 727 | +/** |
|---|
| 728 | + * struct iwl_fw_mon - fw monitor per allocation id |
|---|
| 729 | + * @num_frags: number of fragments |
|---|
| 730 | + * @frags: an array of DRAM buffer fragments |
|---|
| 731 | + */ |
|---|
| 732 | +struct iwl_fw_mon { |
|---|
| 733 | + u32 num_frags; |
|---|
| 734 | + struct iwl_dram_data *frags; |
|---|
| 735 | +}; |
|---|
| 736 | + |
|---|
| 737 | +/** |
|---|
| 738 | + * struct iwl_self_init_dram - dram data used by self init process |
|---|
| 739 | + * @fw: lmac and umac dram data |
|---|
| 740 | + * @fw_cnt: total number of items in array |
|---|
| 741 | + * @paging: paging dram data |
|---|
| 742 | + * @paging_cnt: total number of items in array |
|---|
| 743 | + */ |
|---|
| 744 | +struct iwl_self_init_dram { |
|---|
| 745 | + struct iwl_dram_data *fw; |
|---|
| 746 | + int fw_cnt; |
|---|
| 747 | + struct iwl_dram_data *paging; |
|---|
| 748 | + int paging_cnt; |
|---|
| 749 | +}; |
|---|
| 750 | + |
|---|
| 751 | +/** |
|---|
| 752 | + * struct iwl_trans_debug - transport debug related data |
|---|
| 753 | + * |
|---|
| 754 | + * @n_dest_reg: num of reg_ops in %dbg_dest_tlv |
|---|
| 755 | + * @rec_on: true iff there is a fw debug recording currently active |
|---|
| 756 | + * @dest_tlv: points to the destination TLV for debug |
|---|
| 757 | + * @conf_tlv: array of pointers to configuration TLVs for debug |
|---|
| 758 | + * @trigger_tlv: array of pointers to triggers TLVs for debug |
|---|
| 759 | + * @lmac_error_event_table: addrs of lmacs error tables |
|---|
| 760 | + * @umac_error_event_table: addr of umac error table |
|---|
| 761 | + * @error_event_table_tlv_status: bitmap that indicates what error table |
|---|
| 762 | + * pointers was recevied via TLV. uses enum &iwl_error_event_table_status |
|---|
| 763 | + * @internal_ini_cfg: internal debug cfg state. Uses &enum iwl_ini_cfg_state |
|---|
| 764 | + * @external_ini_cfg: external debug cfg state. Uses &enum iwl_ini_cfg_state |
|---|
| 765 | + * @fw_mon_cfg: debug buffer allocation configuration |
|---|
| 766 | + * @fw_mon_ini: DRAM buffer fragments per allocation id |
|---|
| 767 | + * @fw_mon: DRAM buffer for firmware monitor |
|---|
| 768 | + * @hw_error: equals true if hw error interrupt was received from the FW |
|---|
| 769 | + * @ini_dest: debug monitor destination uses &enum iwl_fw_ini_buffer_location |
|---|
| 770 | + * @active_regions: active regions |
|---|
| 771 | + * @debug_info_tlv_list: list of debug info TLVs |
|---|
| 772 | + * @time_point: array of debug time points |
|---|
| 773 | + * @periodic_trig_list: periodic triggers list |
|---|
| 774 | + * @domains_bitmap: bitmap of active domains other than |
|---|
| 775 | + * &IWL_FW_INI_DOMAIN_ALWAYS_ON |
|---|
| 776 | + */ |
|---|
| 777 | +struct iwl_trans_debug { |
|---|
| 778 | + u8 n_dest_reg; |
|---|
| 779 | + bool rec_on; |
|---|
| 780 | + |
|---|
| 781 | + const struct iwl_fw_dbg_dest_tlv_v1 *dest_tlv; |
|---|
| 782 | + const struct iwl_fw_dbg_conf_tlv *conf_tlv[FW_DBG_CONF_MAX]; |
|---|
| 783 | + struct iwl_fw_dbg_trigger_tlv * const *trigger_tlv; |
|---|
| 784 | + |
|---|
| 785 | + u32 lmac_error_event_table[2]; |
|---|
| 786 | + u32 umac_error_event_table; |
|---|
| 787 | + unsigned int error_event_table_tlv_status; |
|---|
| 788 | + |
|---|
| 789 | + enum iwl_ini_cfg_state internal_ini_cfg; |
|---|
| 790 | + enum iwl_ini_cfg_state external_ini_cfg; |
|---|
| 791 | + |
|---|
| 792 | + struct iwl_fw_ini_allocation_tlv fw_mon_cfg[IWL_FW_INI_ALLOCATION_NUM]; |
|---|
| 793 | + struct iwl_fw_mon fw_mon_ini[IWL_FW_INI_ALLOCATION_NUM]; |
|---|
| 794 | + |
|---|
| 795 | + struct iwl_dram_data fw_mon; |
|---|
| 796 | + |
|---|
| 797 | + bool hw_error; |
|---|
| 798 | + enum iwl_fw_ini_buffer_location ini_dest; |
|---|
| 799 | + |
|---|
| 800 | + struct iwl_ucode_tlv *active_regions[IWL_FW_INI_MAX_REGION_ID]; |
|---|
| 801 | + struct list_head debug_info_tlv_list; |
|---|
| 802 | + struct iwl_dbg_tlv_time_point_data |
|---|
| 803 | + time_point[IWL_FW_INI_TIME_POINT_NUM]; |
|---|
| 804 | + struct list_head periodic_trig_list; |
|---|
| 805 | + |
|---|
| 806 | + u32 domains_bitmap; |
|---|
| 807 | +}; |
|---|
| 808 | + |
|---|
| 809 | +struct iwl_dma_ptr { |
|---|
| 810 | + dma_addr_t dma; |
|---|
| 811 | + void *addr; |
|---|
| 812 | + size_t size; |
|---|
| 813 | +}; |
|---|
| 814 | + |
|---|
| 815 | +struct iwl_cmd_meta { |
|---|
| 816 | + /* only for SYNC commands, iff the reply skb is wanted */ |
|---|
| 817 | + struct iwl_host_cmd *source; |
|---|
| 818 | + u32 flags; |
|---|
| 819 | + u32 tbs; |
|---|
| 820 | +}; |
|---|
| 821 | + |
|---|
| 822 | +/* |
|---|
| 823 | + * The FH will write back to the first TB only, so we need to copy some data |
|---|
| 824 | + * into the buffer regardless of whether it should be mapped or not. |
|---|
| 825 | + * This indicates how big the first TB must be to include the scratch buffer |
|---|
| 826 | + * and the assigned PN. |
|---|
| 827 | + * Since PN location is 8 bytes at offset 12, it's 20 now. |
|---|
| 828 | + * If we make it bigger then allocations will be bigger and copy slower, so |
|---|
| 829 | + * that's probably not useful. |
|---|
| 830 | + */ |
|---|
| 831 | +#define IWL_FIRST_TB_SIZE 20 |
|---|
| 832 | +#define IWL_FIRST_TB_SIZE_ALIGN ALIGN(IWL_FIRST_TB_SIZE, 64) |
|---|
| 833 | + |
|---|
| 834 | +struct iwl_pcie_txq_entry { |
|---|
| 835 | + void *cmd; |
|---|
| 836 | + struct sk_buff *skb; |
|---|
| 837 | + /* buffer to free after command completes */ |
|---|
| 838 | + const void *free_buf; |
|---|
| 839 | + struct iwl_cmd_meta meta; |
|---|
| 840 | +}; |
|---|
| 841 | + |
|---|
| 842 | +struct iwl_pcie_first_tb_buf { |
|---|
| 843 | + u8 buf[IWL_FIRST_TB_SIZE_ALIGN]; |
|---|
| 844 | +}; |
|---|
| 845 | + |
|---|
| 846 | +/** |
|---|
| 847 | + * struct iwl_txq - Tx Queue for DMA |
|---|
| 848 | + * @q: generic Rx/Tx queue descriptor |
|---|
| 849 | + * @tfds: transmit frame descriptors (DMA memory) |
|---|
| 850 | + * @first_tb_bufs: start of command headers, including scratch buffers, for |
|---|
| 851 | + * the writeback -- this is DMA memory and an array holding one buffer |
|---|
| 852 | + * for each command on the queue |
|---|
| 853 | + * @first_tb_dma: DMA address for the first_tb_bufs start |
|---|
| 854 | + * @entries: transmit entries (driver state) |
|---|
| 855 | + * @lock: queue lock |
|---|
| 856 | + * @stuck_timer: timer that fires if queue gets stuck |
|---|
| 857 | + * @trans: pointer back to transport (for timer) |
|---|
| 858 | + * @need_update: indicates need to update read/write index |
|---|
| 859 | + * @ampdu: true if this queue is an ampdu queue for an specific RA/TID |
|---|
| 860 | + * @wd_timeout: queue watchdog timeout (jiffies) - per queue |
|---|
| 861 | + * @frozen: tx stuck queue timer is frozen |
|---|
| 862 | + * @frozen_expiry_remainder: remember how long until the timer fires |
|---|
| 863 | + * @bc_tbl: byte count table of the queue (relevant only for gen2 transport) |
|---|
| 864 | + * @write_ptr: 1-st empty entry (index) host_w |
|---|
| 865 | + * @read_ptr: last used entry (index) host_r |
|---|
| 866 | + * @dma_addr: physical addr for BD's |
|---|
| 867 | + * @n_window: safe queue window |
|---|
| 868 | + * @id: queue id |
|---|
| 869 | + * @low_mark: low watermark, resume queue if free space more than this |
|---|
| 870 | + * @high_mark: high watermark, stop queue if free space less than this |
|---|
| 871 | + * |
|---|
| 872 | + * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame |
|---|
| 873 | + * descriptors) and required locking structures. |
|---|
| 874 | + * |
|---|
| 875 | + * Note the difference between TFD_QUEUE_SIZE_MAX and n_window: the hardware |
|---|
| 876 | + * always assumes 256 descriptors, so TFD_QUEUE_SIZE_MAX is always 256 (unless |
|---|
| 877 | + * there might be HW changes in the future). For the normal TX |
|---|
| 878 | + * queues, n_window, which is the size of the software queue data |
|---|
| 879 | + * is also 256; however, for the command queue, n_window is only |
|---|
| 880 | + * 32 since we don't need so many commands pending. Since the HW |
|---|
| 881 | + * still uses 256 BDs for DMA though, TFD_QUEUE_SIZE_MAX stays 256. |
|---|
| 882 | + * This means that we end up with the following: |
|---|
| 883 | + * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 | |
|---|
| 884 | + * SW entries: | 0 | ... | 31 | |
|---|
| 885 | + * where N is a number between 0 and 7. This means that the SW |
|---|
| 886 | + * data is a window overlayed over the HW queue. |
|---|
| 887 | + */ |
|---|
| 888 | +struct iwl_txq { |
|---|
| 889 | + void *tfds; |
|---|
| 890 | + struct iwl_pcie_first_tb_buf *first_tb_bufs; |
|---|
| 891 | + dma_addr_t first_tb_dma; |
|---|
| 892 | + struct iwl_pcie_txq_entry *entries; |
|---|
| 893 | + /* lock for syncing changes on the queue */ |
|---|
| 894 | + spinlock_t lock; |
|---|
| 895 | + unsigned long frozen_expiry_remainder; |
|---|
| 896 | + struct timer_list stuck_timer; |
|---|
| 897 | + struct iwl_trans *trans; |
|---|
| 898 | + bool need_update; |
|---|
| 899 | + bool frozen; |
|---|
| 900 | + bool ampdu; |
|---|
| 901 | + int block; |
|---|
| 902 | + unsigned long wd_timeout; |
|---|
| 903 | + struct sk_buff_head overflow_q; |
|---|
| 904 | + struct iwl_dma_ptr bc_tbl; |
|---|
| 905 | + |
|---|
| 906 | + int write_ptr; |
|---|
| 907 | + int read_ptr; |
|---|
| 908 | + dma_addr_t dma_addr; |
|---|
| 909 | + int n_window; |
|---|
| 910 | + u32 id; |
|---|
| 911 | + int low_mark; |
|---|
| 912 | + int high_mark; |
|---|
| 913 | + |
|---|
| 914 | + bool overflow_tx; |
|---|
| 915 | +}; |
|---|
| 916 | + |
|---|
| 917 | +/** |
|---|
| 918 | + * struct iwl_trans_txqs - transport tx queues data |
|---|
| 919 | + * |
|---|
| 920 | + * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) |
|---|
| 921 | + * @page_offs: offset from skb->cb to mac header page pointer |
|---|
| 922 | + * @dev_cmd_offs: offset from skb->cb to iwl_device_tx_cmd pointer |
|---|
| 923 | + * @queue_used - bit mask of used queues |
|---|
| 924 | + * @queue_stopped - bit mask of stopped queues |
|---|
| 925 | + * @scd_bc_tbls: gen1 pointer to the byte count table of the scheduler |
|---|
| 926 | + */ |
|---|
| 927 | +struct iwl_trans_txqs { |
|---|
| 928 | + unsigned long queue_used[BITS_TO_LONGS(IWL_MAX_TVQM_QUEUES)]; |
|---|
| 929 | + unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_TVQM_QUEUES)]; |
|---|
| 930 | + struct iwl_txq *txq[IWL_MAX_TVQM_QUEUES]; |
|---|
| 931 | + struct dma_pool *bc_pool; |
|---|
| 932 | + size_t bc_tbl_size; |
|---|
| 933 | + bool bc_table_dword; |
|---|
| 934 | + u8 page_offs; |
|---|
| 935 | + u8 dev_cmd_offs; |
|---|
| 936 | + struct __percpu iwl_tso_hdr_page * tso_hdr_page; |
|---|
| 937 | + |
|---|
| 938 | + struct { |
|---|
| 939 | + u8 fifo; |
|---|
| 940 | + u8 q_id; |
|---|
| 941 | + unsigned int wdg_timeout; |
|---|
| 942 | + } cmd; |
|---|
| 943 | + |
|---|
| 944 | + struct { |
|---|
| 945 | + u8 max_tbs; |
|---|
| 946 | + u16 size; |
|---|
| 947 | + u8 addr_size; |
|---|
| 948 | + } tfd; |
|---|
| 949 | + |
|---|
| 950 | + struct iwl_dma_ptr scd_bc_tbls; |
|---|
| 951 | +}; |
|---|
| 692 | 952 | |
|---|
| 693 | 953 | /** |
|---|
| 694 | 954 | * struct iwl_trans - transport common data |
|---|
| 695 | 955 | * |
|---|
| 696 | 956 | * @ops - pointer to iwl_trans_ops |
|---|
| 697 | 957 | * @op_mode - pointer to the op_mode |
|---|
| 958 | + * @trans_cfg: the trans-specific configuration part |
|---|
| 698 | 959 | * @cfg - pointer to the configuration |
|---|
| 699 | 960 | * @drv - pointer to iwl_drv |
|---|
| 700 | 961 | * @status: a bit-mask of transport status flags |
|---|
| .. | .. |
|---|
| 719 | 980 | * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the |
|---|
| 720 | 981 | * start of the 802.11 header in the @rx_mpdu_cmd |
|---|
| 721 | 982 | * @dflt_pwr_limit: default power limit fetched from the platform (ACPI) |
|---|
| 722 | | - * @dbg_dest_tlv: points to the destination TLV for debug |
|---|
| 723 | | - * @dbg_conf_tlv: array of pointers to configuration TLVs for debug |
|---|
| 724 | | - * @dbg_trigger_tlv: array of pointers to triggers TLVs for debug |
|---|
| 725 | | - * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv |
|---|
| 726 | 983 | * @system_pm_mode: the system-wide power management mode in use. |
|---|
| 727 | 984 | * This mode is set dynamically, depending on the WoWLAN values |
|---|
| 728 | 985 | * configured from the userspace at runtime. |
|---|
| 729 | | - * @runtime_pm_mode: the runtime power management mode in use. This |
|---|
| 730 | | - * mode is set during the initialization phase and is not |
|---|
| 731 | | - * supposed to change during runtime. |
|---|
| 986 | + * @iwl_trans_txqs: transport tx queues data. |
|---|
| 732 | 987 | */ |
|---|
| 733 | 988 | struct iwl_trans { |
|---|
| 734 | 989 | const struct iwl_trans_ops *ops; |
|---|
| 735 | 990 | struct iwl_op_mode *op_mode; |
|---|
| 991 | + const struct iwl_cfg_trans_params *trans_cfg; |
|---|
| 736 | 992 | const struct iwl_cfg *cfg; |
|---|
| 737 | 993 | struct iwl_drv *drv; |
|---|
| 738 | 994 | enum iwl_trans_state state; |
|---|
| .. | .. |
|---|
| 744 | 1000 | u32 hw_rf_id; |
|---|
| 745 | 1001 | u32 hw_id; |
|---|
| 746 | 1002 | char hw_id_str[52]; |
|---|
| 1003 | + u32 sku_id[3]; |
|---|
| 747 | 1004 | |
|---|
| 748 | 1005 | u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size; |
|---|
| 749 | 1006 | |
|---|
| 750 | 1007 | bool pm_support; |
|---|
| 751 | 1008 | bool ltr_enabled; |
|---|
| 1009 | + u8 pnvm_loaded:1; |
|---|
| 752 | 1010 | |
|---|
| 753 | 1011 | const struct iwl_hcmd_arr *command_groups; |
|---|
| 754 | 1012 | int command_groups_size; |
|---|
| .. | .. |
|---|
| 769 | 1027 | struct lockdep_map sync_cmd_lockdep_map; |
|---|
| 770 | 1028 | #endif |
|---|
| 771 | 1029 | |
|---|
| 772 | | - const struct iwl_fw_dbg_dest_tlv_v1 *dbg_dest_tlv; |
|---|
| 773 | | - const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX]; |
|---|
| 774 | | - struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv; |
|---|
| 775 | | - u32 dbg_dump_mask; |
|---|
| 776 | | - u8 dbg_dest_reg_num; |
|---|
| 1030 | + struct iwl_trans_debug dbg; |
|---|
| 1031 | + struct iwl_self_init_dram init_dram; |
|---|
| 777 | 1032 | |
|---|
| 778 | 1033 | enum iwl_plat_pm_mode system_pm_mode; |
|---|
| 779 | | - enum iwl_plat_pm_mode runtime_pm_mode; |
|---|
| 780 | | - bool suspending; |
|---|
| 1034 | + |
|---|
| 1035 | + const char *name; |
|---|
| 1036 | + struct iwl_trans_txqs txqs; |
|---|
| 781 | 1037 | |
|---|
| 782 | 1038 | /* pointer to trans specific struct */ |
|---|
| 783 | 1039 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
|---|
| 784 | | - char trans_specific[0] __aligned(sizeof(void *)); |
|---|
| 1040 | + char trans_specific[] __aligned(sizeof(void *)); |
|---|
| 785 | 1041 | }; |
|---|
| 786 | 1042 | |
|---|
| 787 | 1043 | const char *iwl_get_cmd_string(struct iwl_trans *trans, u32 id); |
|---|
| .. | .. |
|---|
| 796 | 1052 | WARN_ON(iwl_cmd_groups_verify_sorted(trans_cfg)); |
|---|
| 797 | 1053 | } |
|---|
| 798 | 1054 | |
|---|
| 799 | | -static inline int _iwl_trans_start_hw(struct iwl_trans *trans, bool low_power) |
|---|
| 1055 | +static inline int iwl_trans_start_hw(struct iwl_trans *trans) |
|---|
| 800 | 1056 | { |
|---|
| 801 | 1057 | might_sleep(); |
|---|
| 802 | 1058 | |
|---|
| 803 | | - return trans->ops->start_hw(trans, low_power); |
|---|
| 804 | | -} |
|---|
| 805 | | - |
|---|
| 806 | | -static inline int iwl_trans_start_hw(struct iwl_trans *trans) |
|---|
| 807 | | -{ |
|---|
| 808 | | - return trans->ops->start_hw(trans, true); |
|---|
| 1059 | + return trans->ops->start_hw(trans); |
|---|
| 809 | 1060 | } |
|---|
| 810 | 1061 | |
|---|
| 811 | 1062 | static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans) |
|---|
| .. | .. |
|---|
| 841 | 1092 | return trans->ops->start_fw(trans, fw, run_in_rfkill); |
|---|
| 842 | 1093 | } |
|---|
| 843 | 1094 | |
|---|
| 844 | | -static inline void _iwl_trans_stop_device(struct iwl_trans *trans, |
|---|
| 845 | | - bool low_power) |
|---|
| 1095 | +static inline void iwl_trans_stop_device(struct iwl_trans *trans) |
|---|
| 846 | 1096 | { |
|---|
| 847 | 1097 | might_sleep(); |
|---|
| 848 | 1098 | |
|---|
| 849 | | - trans->ops->stop_device(trans, low_power); |
|---|
| 1099 | + trans->ops->stop_device(trans); |
|---|
| 850 | 1100 | |
|---|
| 851 | 1101 | trans->state = IWL_TRANS_NO_FW; |
|---|
| 852 | 1102 | } |
|---|
| 853 | 1103 | |
|---|
| 854 | | -static inline void iwl_trans_stop_device(struct iwl_trans *trans) |
|---|
| 855 | | -{ |
|---|
| 856 | | - _iwl_trans_stop_device(trans, true); |
|---|
| 857 | | -} |
|---|
| 858 | | - |
|---|
| 859 | | -static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test, |
|---|
| 860 | | - bool reset) |
|---|
| 1104 | +static inline int iwl_trans_d3_suspend(struct iwl_trans *trans, bool test, |
|---|
| 1105 | + bool reset) |
|---|
| 861 | 1106 | { |
|---|
| 862 | 1107 | might_sleep(); |
|---|
| 863 | | - if (trans->ops->d3_suspend) |
|---|
| 864 | | - trans->ops->d3_suspend(trans, test, reset); |
|---|
| 1108 | + if (!trans->ops->d3_suspend) |
|---|
| 1109 | + return 0; |
|---|
| 1110 | + |
|---|
| 1111 | + return trans->ops->d3_suspend(trans, test, reset); |
|---|
| 865 | 1112 | } |
|---|
| 866 | 1113 | |
|---|
| 867 | 1114 | static inline int iwl_trans_d3_resume(struct iwl_trans *trans, |
|---|
| .. | .. |
|---|
| 890 | 1137 | } |
|---|
| 891 | 1138 | |
|---|
| 892 | 1139 | static inline struct iwl_trans_dump_data * |
|---|
| 893 | | -iwl_trans_dump_data(struct iwl_trans *trans, |
|---|
| 894 | | - const struct iwl_fw_dbg_trigger_tlv *trigger) |
|---|
| 1140 | +iwl_trans_dump_data(struct iwl_trans *trans, u32 dump_mask) |
|---|
| 895 | 1141 | { |
|---|
| 896 | 1142 | if (!trans->ops->dump_data) |
|---|
| 897 | 1143 | return NULL; |
|---|
| 898 | | - return trans->ops->dump_data(trans, trigger); |
|---|
| 1144 | + return trans->ops->dump_data(trans, dump_mask); |
|---|
| 899 | 1145 | } |
|---|
| 900 | 1146 | |
|---|
| 901 | | -static inline void iwl_trans_dump_regs(struct iwl_trans *trans) |
|---|
| 902 | | -{ |
|---|
| 903 | | - if (trans->ops->dump_regs) |
|---|
| 904 | | - trans->ops->dump_regs(trans); |
|---|
| 905 | | -} |
|---|
| 906 | | - |
|---|
| 907 | | -static inline struct iwl_device_cmd * |
|---|
| 1147 | +static inline struct iwl_device_tx_cmd * |
|---|
| 908 | 1148 | iwl_trans_alloc_tx_cmd(struct iwl_trans *trans) |
|---|
| 909 | 1149 | { |
|---|
| 910 | | - return kmem_cache_alloc(trans->dev_cmd_pool, GFP_ATOMIC); |
|---|
| 1150 | + return kmem_cache_zalloc(trans->dev_cmd_pool, GFP_ATOMIC); |
|---|
| 911 | 1151 | } |
|---|
| 912 | 1152 | |
|---|
| 913 | 1153 | int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
|---|
| 914 | 1154 | |
|---|
| 915 | 1155 | static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans, |
|---|
| 916 | | - struct iwl_device_cmd *dev_cmd) |
|---|
| 1156 | + struct iwl_device_tx_cmd *dev_cmd) |
|---|
| 917 | 1157 | { |
|---|
| 918 | 1158 | kmem_cache_free(trans->dev_cmd_pool, dev_cmd); |
|---|
| 919 | 1159 | } |
|---|
| 920 | 1160 | |
|---|
| 921 | 1161 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, |
|---|
| 922 | | - struct iwl_device_cmd *dev_cmd, int queue) |
|---|
| 1162 | + struct iwl_device_tx_cmd *dev_cmd, int queue) |
|---|
| 923 | 1163 | { |
|---|
| 924 | 1164 | if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) |
|---|
| 925 | 1165 | return -EIO; |
|---|
| .. | .. |
|---|
| 941 | 1181 | } |
|---|
| 942 | 1182 | |
|---|
| 943 | 1183 | trans->ops->reclaim(trans, queue, ssn, skbs); |
|---|
| 1184 | +} |
|---|
| 1185 | + |
|---|
| 1186 | +static inline void iwl_trans_set_q_ptrs(struct iwl_trans *trans, int queue, |
|---|
| 1187 | + int ptr) |
|---|
| 1188 | +{ |
|---|
| 1189 | + if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) { |
|---|
| 1190 | + IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); |
|---|
| 1191 | + return; |
|---|
| 1192 | + } |
|---|
| 1193 | + |
|---|
| 1194 | + trans->ops->set_q_ptrs(trans, queue, ptr); |
|---|
| 944 | 1195 | } |
|---|
| 945 | 1196 | |
|---|
| 946 | 1197 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue, |
|---|
| .. | .. |
|---|
| 986 | 1237 | |
|---|
| 987 | 1238 | static inline int |
|---|
| 988 | 1239 | iwl_trans_txq_alloc(struct iwl_trans *trans, |
|---|
| 989 | | - struct iwl_tx_queue_cfg_cmd *cmd, |
|---|
| 1240 | + __le16 flags, u8 sta_id, u8 tid, |
|---|
| 990 | 1241 | int cmd_id, int size, |
|---|
| 991 | 1242 | unsigned int wdg_timeout) |
|---|
| 992 | 1243 | { |
|---|
| .. | .. |
|---|
| 1000 | 1251 | return -EIO; |
|---|
| 1001 | 1252 | } |
|---|
| 1002 | 1253 | |
|---|
| 1003 | | - return trans->ops->txq_alloc(trans, cmd, cmd_id, size, wdg_timeout); |
|---|
| 1254 | + return trans->ops->txq_alloc(trans, flags, sta_id, tid, |
|---|
| 1255 | + cmd_id, size, wdg_timeout); |
|---|
| 1004 | 1256 | } |
|---|
| 1005 | 1257 | |
|---|
| 1006 | 1258 | static inline void iwl_trans_txq_set_shared_mode(struct iwl_trans *trans, |
|---|
| .. | .. |
|---|
| 1193 | 1445 | iwl_op_mode_nic_error(trans->op_mode); |
|---|
| 1194 | 1446 | } |
|---|
| 1195 | 1447 | |
|---|
| 1448 | +static inline bool iwl_trans_fw_running(struct iwl_trans *trans) |
|---|
| 1449 | +{ |
|---|
| 1450 | + return trans->state == IWL_TRANS_FW_ALIVE; |
|---|
| 1451 | +} |
|---|
| 1452 | + |
|---|
| 1453 | +static inline void iwl_trans_sync_nmi(struct iwl_trans *trans) |
|---|
| 1454 | +{ |
|---|
| 1455 | + if (trans->ops->sync_nmi) |
|---|
| 1456 | + trans->ops->sync_nmi(trans); |
|---|
| 1457 | +} |
|---|
| 1458 | + |
|---|
| 1459 | +static inline int iwl_trans_set_pnvm(struct iwl_trans *trans, |
|---|
| 1460 | + const void *data, u32 len) |
|---|
| 1461 | +{ |
|---|
| 1462 | + if (trans->ops->set_pnvm) { |
|---|
| 1463 | + int ret = trans->ops->set_pnvm(trans, data, len); |
|---|
| 1464 | + |
|---|
| 1465 | + if (ret) |
|---|
| 1466 | + return ret; |
|---|
| 1467 | + } |
|---|
| 1468 | + |
|---|
| 1469 | + trans->pnvm_loaded = true; |
|---|
| 1470 | + |
|---|
| 1471 | + return 0; |
|---|
| 1472 | +} |
|---|
| 1473 | + |
|---|
| 1474 | +static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans) |
|---|
| 1475 | +{ |
|---|
| 1476 | + return trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED || |
|---|
| 1477 | + trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED; |
|---|
| 1478 | +} |
|---|
| 1479 | + |
|---|
| 1196 | 1480 | /***************************************************** |
|---|
| 1197 | 1481 | * transport helper functions |
|---|
| 1198 | 1482 | *****************************************************/ |
|---|
| 1199 | 1483 | struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, |
|---|
| 1200 | | - struct device *dev, |
|---|
| 1201 | | - const struct iwl_cfg *cfg, |
|---|
| 1202 | | - const struct iwl_trans_ops *ops); |
|---|
| 1484 | + struct device *dev, |
|---|
| 1485 | + const struct iwl_trans_ops *ops, |
|---|
| 1486 | + const struct iwl_cfg_trans_params *cfg_trans); |
|---|
| 1203 | 1487 | void iwl_trans_free(struct iwl_trans *trans); |
|---|
| 1204 | | -void iwl_trans_ref(struct iwl_trans *trans); |
|---|
| 1205 | | -void iwl_trans_unref(struct iwl_trans *trans); |
|---|
| 1206 | 1488 | |
|---|
| 1207 | 1489 | /***************************************************** |
|---|
| 1208 | 1490 | * driver (transport) register/unregister functions |
|---|