iwlwifi: split fw-error-dump between transport and mvm
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-trans.h
index 1f065cf4a4baeb09fc4c4288be705dbe0772fe64..656371a668daa5e2325e45fe0b576fc3e13bd307 100644 (file)
@@ -189,16 +189,25 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt)
 /**
  * enum CMD_MODE - how to send the host commands ?
  *
- * @CMD_SYNC: The caller will be stalled until the fw responds to the command
  * @CMD_ASYNC: Return right away and don't wait for the response
- * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
- *     response. The caller needs to call iwl_free_resp when done.
+ * @CMD_WANT_SKB: Not valid with CMD_ASYNC. The caller needs the buffer of
+ *     the response. The caller needs to call iwl_free_resp when done.
+ * @CMD_HIGH_PRIO: The command is high priority - it goes to the front of the
+ *     command queue, but after other high priority commands. valid only
+ *     with CMD_ASYNC.
+ * @CMD_SEND_IN_IDLE: The command should be sent even when the trans is idle.
+ * @CMD_MAKE_TRANS_IDLE: The command response should mark the trans as idle.
+ * @CMD_WAKE_UP_TRANS: The command response should wake up the trans
+ *     (i.e. mark it as non-idle).
  */
 enum CMD_MODE {
-       CMD_SYNC                = 0,
        CMD_ASYNC               = BIT(0),
        CMD_WANT_SKB            = BIT(1),
        CMD_SEND_IN_RFKILL      = BIT(2),
+       CMD_HIGH_PRIO           = BIT(3),
+       CMD_SEND_IN_IDLE        = BIT(4),
+       CMD_MAKE_TRANS_IDLE     = BIT(5),
+       CMD_WAKE_UP_TRANS       = BIT(6),
 };
 
 #define DEF_CMD_PAYLOAD_SIZE 320
@@ -335,6 +344,9 @@ enum iwl_d3_status {
  * @STATUS_INT_ENABLED: interrupts are enabled
  * @STATUS_RFKILL: the HW RFkill switch is in KILL position
  * @STATUS_FW_ERROR: the fw is in error state
+ * @STATUS_TRANS_GOING_IDLE: shutting down the trans, only special commands
+ *     are sent
+ * @STATUS_TRANS_IDLE: the trans is idle - general commands are not to be sent
  */
 enum iwl_trans_status {
        STATUS_SYNC_HCMD_ACTIVE,
@@ -343,6 +355,8 @@ enum iwl_trans_status {
        STATUS_INT_ENABLED,
        STATUS_RFKILL,
        STATUS_FW_ERROR,
+       STATUS_TRANS_GOING_IDLE,
+       STATUS_TRANS_IDLE,
 };
 
 /**
@@ -377,7 +391,12 @@ struct iwl_trans_config {
        bool rx_buf_size_8k;
        bool bc_table_dword;
        unsigned int queue_watchdog_timeout;
-       const char **command_names;
+       const char *const *command_names;
+};
+
+struct iwl_trans_dump_data {
+       u32 len;
+       u8 data[];
 };
 
 struct iwl_trans;
@@ -411,7 +430,7 @@ struct iwl_trans;
  * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted.
  *     If RFkill is asserted in the middle of a SYNC host command, it must
  *     return -ERFKILL straight away.
- *     May sleep only if CMD_SYNC is set
+ *     May sleep only if CMD_ASYNC is not set
  * @tx: send an skb
  *     Must be atomic
  * @reclaim: free packet until ssn. Returns a list of freed packets.
@@ -421,8 +440,7 @@ struct iwl_trans;
  *     this one. The op_mode must not configure the HCMD queue. May sleep.
  * @txq_disable: de-configure a Tx queue to send AMPDUs
  *     Must be atomic
- * @wait_tx_queue_empty: wait until all tx queues are empty
- *     May sleep
+ * @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
  * @dbgfs_register: add the dbgfs files under this directory. Files will be
  *     automatically deleted.
  * @write8: write a u8 to a register at offset ofs from the BAR
@@ -443,6 +461,14 @@ struct iwl_trans;
  * @release_nic_access: let the NIC go to sleep. The "flags" parameter
  *     must be the same one that was sent before to the grab_nic_access.
  * @set_bits_mask - set SRAM register according to value and mask.
+ * @ref: grab a reference to the transport/FW layers, disallowing
+ *     certain low power states
+ * @unref: release a reference previously taken with @ref. Note that
+ *     initially the reference count is 1, making an initial @unref
+ *     necessary to allow low power states.
+ * @dump_data: return a vmalloc'ed buffer with debug data, maybe containing last
+ *     TX'ed commands and similar. The buffer will be vfree'd by the caller.
+ *     Note that the transport must fill in the proper file headers.
  */
 struct iwl_trans_ops {
 
@@ -450,6 +476,8 @@ struct iwl_trans_ops {
        void (*op_mode_leave)(struct iwl_trans *iwl_trans);
        int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw,
                        bool run_in_rfkill);
+       int (*update_sf)(struct iwl_trans *trans,
+                        struct iwl_sf_region *st_fwrd_space);
        void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
        void (*stop_device)(struct iwl_trans *trans);
 
@@ -469,7 +497,7 @@ struct iwl_trans_ops {
        void (*txq_disable)(struct iwl_trans *trans, int queue);
 
        int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
-       int (*wait_tx_queue_empty)(struct iwl_trans *trans);
+       int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
 
        void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
        void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
@@ -489,6 +517,12 @@ struct iwl_trans_ops {
                                   unsigned long *flags);
        void (*set_bits_mask)(struct iwl_trans *trans, u32 reg, u32 mask,
                              u32 value);
+       void (*ref)(struct iwl_trans *trans);
+       void (*unref)(struct iwl_trans *trans);
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+       struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans);
+#endif
 };
 
 /**
@@ -523,6 +557,7 @@ enum iwl_trans_state {
  *     starting the firmware, used for tracing
  * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the
  *     start of the 802.11 header in the @rx_mpdu_cmd
+ * @dflt_pwr_limit: default power limit fetched from the platform (ACPI)
  */
 struct iwl_trans {
        const struct iwl_trans_ops *ops;
@@ -551,6 +586,8 @@ struct iwl_trans {
        struct lockdep_map sync_cmd_lockdep_map;
 #endif
 
+       u64 dflt_pwr_limit;
+
        /* pointer to trans specific struct */
        /*Ensure that this pointer will always be aligned to sizeof pointer */
        char trans_specific[0] __aligned(sizeof(void *));
@@ -604,6 +641,17 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans,
        return trans->ops->start_fw(trans, fw, run_in_rfkill);
 }
 
+static inline int iwl_trans_update_sf(struct iwl_trans *trans,
+                                     struct iwl_sf_region *st_fwrd_space)
+{
+       might_sleep();
+
+       if (trans->ops->update_sf)
+               return trans->ops->update_sf(trans, st_fwrd_space);
+
+       return 0;
+}
+
 static inline void iwl_trans_stop_device(struct iwl_trans *trans)
 {
        might_sleep();
@@ -627,6 +675,28 @@ static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
        return trans->ops->d3_resume(trans, status, test);
 }
 
+static inline void iwl_trans_ref(struct iwl_trans *trans)
+{
+       if (trans->ops->ref)
+               trans->ops->ref(trans);
+}
+
+static inline void iwl_trans_unref(struct iwl_trans *trans)
+{
+       if (trans->ops->unref)
+               trans->ops->unref(trans);
+}
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+static inline struct iwl_trans_dump_data *
+iwl_trans_dump_data(struct iwl_trans *trans)
+{
+       if (!trans->ops->dump_data)
+               return NULL;
+       return trans->ops->dump_data(trans);
+}
+#endif
+
 static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
                                     struct iwl_host_cmd *cmd)
 {
@@ -640,7 +710,7 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
                return -EIO;
 
        if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) {
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+               IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
                return -EIO;
        }
 
@@ -682,7 +752,7 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
                return -EIO;
 
        if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+               IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
 
        return trans->ops->tx(trans, skb, dev_cmd, queue);
 }
@@ -691,7 +761,7 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
                                     int ssn, struct sk_buff_head *skbs)
 {
        if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+               IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
 
        trans->ops->reclaim(trans, queue, ssn, skbs);
 }
@@ -708,7 +778,7 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
        might_sleep();
 
        if (unlikely((trans->state != IWL_TRANS_FW_ALIVE)))
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+               IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
 
        trans->ops->txq_enable(trans, queue, fifo, sta_id, tid,
                                 frame_limit, ssn);
@@ -721,12 +791,13 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
                             IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0);
 }
 
-static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
+static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
+                                               u32 txq_bm)
 {
        if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+               IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
 
-       return trans->ops->wait_tx_queue_empty(trans);
+       return trans->ops->wait_tx_queue_empty(trans, txq_bm);
 }
 
 static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
This page took 0.034675 seconds and 5 git commands to generate.