wil6210: add advanced interrupt moderation
[cascardo/linux.git] / drivers / net / wireless / ath / wil6210 / wil6210.h
index c6ec5b9..a6d63c1 100644 (file)
 
 extern bool no_fw_recovery;
 extern unsigned int mtu_max;
+extern int agg_wsize;
 
 #define WIL_NAME "wil6210"
 #define WIL_FW_NAME "wil6210.fw"
 
 #define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
 
-struct wil_board {
-       int board;
-#define WIL_BOARD_MARLON       (1)
-#define WIL_BOARD_SPARROW      (2)
-       const char * const name;
-};
-
 /**
  * extract bits [@b0:@b1] (inclusive) from the value @x
  * it should be @b0 <= @b1, or result is incorrect
@@ -57,9 +51,35 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
 #define WIL6210_MAX_TX_RINGS   (24) /* HW limit */
 #define WIL6210_MAX_CID                (8) /* HW limit */
 #define WIL6210_NAPI_BUDGET    (16) /* arbitrary */
+#define WIL_MAX_AMPDU_SIZE     (64 * 1024) /* FW/HW limit */
+#define WIL_MAX_AGG_WSIZE      (32) /* FW/HW limit */
+/* Hardware offload block adds the following:
+ * 26 bytes - 3-address QoS data header
+ *  8 bytes - IV + EIV (for GCMP)
+ *  8 bytes - SNAP
+ * 16 bytes - MIC (for GCMP)
+ *  4 bytes - CRC
+ */
+#define WIL_MAX_MPDU_OVERHEAD  (62)
+
+/* Calculate MAC buffer size for the firmware. It includes all overhead,
+ * as it will go over the air, and need to be 8 byte aligned
+ */
+static inline u32 wil_mtu2macbuf(u32 mtu)
+{
+       return ALIGN(mtu + WIL_MAX_MPDU_OVERHEAD, 8);
+}
+
+/* MTU for Ethernet need to take into account 8-byte SNAP header
+ * to be added when encapsulating Ethernet frame into 802.11
+ */
+#define WIL_MAX_ETH_MTU                (IEEE80211_MAX_DATA_LEN_DMG - 8)
 /* Max supported by wil6210 value for interrupt threshold is 5sec. */
 #define WIL6210_ITR_TRSH_MAX (5000000)
-#define WIL6210_ITR_TRSH_DEFAULT       (300) /* usec */
+#define WIL6210_ITR_TX_INTERFRAME_TIMEOUT_DEFAULT (15) /* usec */
+#define WIL6210_ITR_RX_INTERFRAME_TIMEOUT_DEFAULT (15) /* usec */
+#define WIL6210_ITR_TX_MAX_BURST_DURATION_DEFAULT (500) /* usec */
+#define WIL6210_ITR_RX_MAX_BURST_DURATION_DEFAULT (500) /* usec */
 #define WIL6210_FW_RECOVERY_RETRIES    (5) /* try to recover this many times */
 #define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000)
 #define WIL6210_SCAN_TO                msecs_to_jiffies(10000)
@@ -135,7 +155,7 @@ struct RGF_ICR {
        #define BIT_DMA_EP_MISC_ICR_TX_NO_ACT   BIT(1)
        #define BIT_DMA_EP_MISC_ICR_FW_INT(n)   BIT(28+n) /* n = [0..3] */
 
-/* Interrupt moderation control */
+/* Legacy interrupt moderation control (before Sparrow v2)*/
 #define RGF_DMA_ITR_CNT_TRSH           (0x881c5c)
 #define RGF_DMA_ITR_CNT_DATA           (0x881c60)
 #define RGF_DMA_ITR_CNT_CRL            (0x881c64)
@@ -145,6 +165,46 @@ struct RGF_ICR {
        #define BIT_DMA_ITR_CNT_CRL_CLR         BIT(3)
        #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH  BIT(4)
 
+/* New (sparrow v2+) interrupt moderation control */
+#define RGF_DMA_ITR_TX_DESQ_NO_MOD             (0x881d40)
+#define RGF_DMA_ITR_TX_CNT_TRSH                        (0x881d34)
+#define RGF_DMA_ITR_TX_CNT_DATA                        (0x881d38)
+#define RGF_DMA_ITR_TX_CNT_CTL                 (0x881d3c)
+       #define BIT_DMA_ITR_TX_CNT_CTL_EN               BIT(0)
+       #define BIT_DMA_ITR_TX_CNT_CTL_EXT_TIC_SEL      BIT(1)
+       #define BIT_DMA_ITR_TX_CNT_CTL_FOREVER          BIT(2)
+       #define BIT_DMA_ITR_TX_CNT_CTL_CLR              BIT(3)
+       #define BIT_DMA_ITR_TX_CNT_CTL_REACHED_TRESH    BIT(4)
+       #define BIT_DMA_ITR_TX_CNT_CTL_CROSS_EN         BIT(5)
+       #define BIT_DMA_ITR_TX_CNT_CTL_FREE_RUNNIG      BIT(6)
+#define RGF_DMA_ITR_TX_IDL_CNT_TRSH                    (0x881d60)
+#define RGF_DMA_ITR_TX_IDL_CNT_DATA                    (0x881d64)
+#define RGF_DMA_ITR_TX_IDL_CNT_CTL                     (0x881d68)
+       #define BIT_DMA_ITR_TX_IDL_CNT_CTL_EN                   BIT(0)
+       #define BIT_DMA_ITR_TX_IDL_CNT_CTL_EXT_TIC_SEL          BIT(1)
+       #define BIT_DMA_ITR_TX_IDL_CNT_CTL_FOREVER              BIT(2)
+       #define BIT_DMA_ITR_TX_IDL_CNT_CTL_CLR                  BIT(3)
+       #define BIT_DMA_ITR_TX_IDL_CNT_CTL_REACHED_TRESH        BIT(4)
+#define RGF_DMA_ITR_RX_DESQ_NO_MOD             (0x881d50)
+#define RGF_DMA_ITR_RX_CNT_TRSH                        (0x881d44)
+#define RGF_DMA_ITR_RX_CNT_DATA                        (0x881d48)
+#define RGF_DMA_ITR_RX_CNT_CTL                 (0x881d4c)
+       #define BIT_DMA_ITR_RX_CNT_CTL_EN               BIT(0)
+       #define BIT_DMA_ITR_RX_CNT_CTL_EXT_TIC_SEL      BIT(1)
+       #define BIT_DMA_ITR_RX_CNT_CTL_FOREVER          BIT(2)
+       #define BIT_DMA_ITR_RX_CNT_CTL_CLR              BIT(3)
+       #define BIT_DMA_ITR_RX_CNT_CTL_REACHED_TRESH    BIT(4)
+       #define BIT_DMA_ITR_RX_CNT_CTL_CROSS_EN         BIT(5)
+       #define BIT_DMA_ITR_RX_CNT_CTL_FREE_RUNNIG      BIT(6)
+#define RGF_DMA_ITR_RX_IDL_CNT_TRSH                    (0x881d54)
+#define RGF_DMA_ITR_RX_IDL_CNT_DATA                    (0x881d58)
+#define RGF_DMA_ITR_RX_IDL_CNT_CTL                     (0x881d5c)
+       #define BIT_DMA_ITR_RX_IDL_CNT_CTL_EN                   BIT(0)
+       #define BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL          BIT(1)
+       #define BIT_DMA_ITR_RX_IDL_CNT_CTL_FOREVER              BIT(2)
+       #define BIT_DMA_ITR_RX_IDL_CNT_CTL_CLR                  BIT(3)
+       #define BIT_DMA_ITR_RX_IDL_CNT_CTL_REACHED_TRESH        BIT(4)
+
 #define RGF_DMA_PSEUDO_CAUSE           (0x881c68)
 #define RGF_DMA_PSEUDO_CAUSE_MASK_SW   (0x881c6c)
 #define RGF_DMA_PSEUDO_CAUSE_MASK_FW   (0x881c70)
@@ -164,6 +224,20 @@ struct RGF_ICR {
 #define RGF_CAF_PLL_LOCK_STATUS                (0x88afec)
        #define BIT_CAF_OSC_DIG_XTAL_STABLE     BIT(0)
 
+#define RGF_USER_JTAG_DEV_ID   (0x880b34) /* device ID */
+       #define JTAG_DEV_ID_MARLON_B0   (0x0612072f)
+       #define JTAG_DEV_ID_SPARROW_A0  (0x0632072f)
+       #define JTAG_DEV_ID_SPARROW_A1  (0x1632072f)
+       #define JTAG_DEV_ID_SPARROW_B0  (0x2632072f)
+
+enum {
+       HW_VER_UNKNOWN,
+       HW_VER_MARLON_B0,  /* JTAG_DEV_ID_MARLON_B0  */
+       HW_VER_SPARROW_A0, /* JTAG_DEV_ID_SPARROW_A0 */
+       HW_VER_SPARROW_A1, /* JTAG_DEV_ID_SPARROW_A1 */
+       HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */
+};
+
 /* popular locations */
 #define HOST_MBOX   HOSTADDR(RGF_USER_USER_SCRATCH_PAD)
 #define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \
@@ -303,6 +377,10 @@ struct vring {
 struct vring_tx_data {
        int enabled;
        cycles_t idle, last_idle, begin;
+       u8 agg_wsize; /* agreed aggregation window, 0 - no agg */
+       u16 agg_timeout;
+       u8 agg_amsdu;
+       bool addba_in_progress; /* if set, agg_xxx is for request in progress */
 };
 
 enum { /* for wil6210_priv.status */
@@ -313,6 +391,7 @@ enum { /* for wil6210_priv.status */
        wil_status_reset_done,
        wil_status_irqen, /* FIXME: interrupts enabled - for debug */
        wil_status_napi_en, /* NAPI enabled protected by wil->mutex */
+       wil_status_last /* keep last */
 };
 
 struct pci_dev;
@@ -397,15 +476,40 @@ enum {
        fw_recovery_running = 2,
 };
 
+enum {
+       hw_capability_reset_v2 = 0,
+       hw_capability_advanced_itr_moderation = 1,
+       hw_capability_last
+};
+
+struct wil_back_rx {
+       struct list_head list;
+       /* request params, converted to CPU byte order - what we asked for */
+       u8 cidxtid;
+       u8 dialog_token;
+       u16 ba_param_set;
+       u16 ba_timeout;
+       u16 ba_seq_ctrl;
+};
+
+struct wil_back_tx {
+       struct list_head list;
+       /* request params, converted to CPU byte order - what we asked for */
+       u8 ringid;
+       u8 agg_wsize;
+       u16 agg_timeout;
+};
+
 struct wil6210_priv {
        struct pci_dev *pdev;
        int n_msi;
        struct wireless_dev *wdev;
        void __iomem *csr;
-       ulong status;
+       DECLARE_BITMAP(status, wil_status_last);
        u32 fw_version;
        u32 hw_version;
-       struct wil_board *board;
+       const char *hw_name;
+       DECLARE_BITMAP(hw_capabilities, hw_capability_last);
        u8 n_mids; /* number of additional MIDs as reported by FW */
        u32 recovery_count; /* num of FW recovery attempts in a short time */
        u32 recovery_state; /* FW recovery state machine */
@@ -415,7 +519,11 @@ struct wil6210_priv {
        u32 monitor_flags;
        u32 secure_pcp; /* create secure PCP? */
        int sinfo_gen;
-       u32 itr_trsh;
+       /* interrupt moderation */
+       u32 tx_max_burst_duration;
+       u32 tx_interframe_timeout;
+       u32 rx_max_burst_duration;
+       u32 rx_interframe_timeout;
        /* cached ISR registers */
        u32 isr_misc;
        /* mailbox related */
@@ -429,7 +537,7 @@ struct wil6210_priv {
        u16 reply_size;
        struct workqueue_struct *wmi_wq; /* for deferred calls */
        struct work_struct wmi_event_worker;
-       struct workqueue_struct *wmi_wq_conn; /* for connect worker */
+       struct workqueue_struct *wq_service;
        struct work_struct connect_worker;
        struct work_struct disconnect_worker;
        struct work_struct fw_error_worker;     /* for FW error recovery */
@@ -445,6 +553,13 @@ struct wil6210_priv {
        spinlock_t wmi_ev_lock;
        struct napi_struct napi_rx;
        struct napi_struct napi_tx;
+       /* BACK */
+       struct list_head back_rx_pending;
+       struct mutex back_rx_mutex; /* protect @back_rx_pending */
+       struct work_struct back_rx_worker;
+       struct list_head back_tx_pending;
+       struct mutex back_tx_mutex; /* protect @back_tx_pending */
+       struct work_struct back_tx_worker;
        /* DMA related */
        struct vring vring_rx;
        struct vring vring_tx[WIL6210_MAX_TX_RINGS];
@@ -529,7 +644,6 @@ void wil_if_remove(struct wil6210_priv *wil);
 int wil_priv_init(struct wil6210_priv *wil);
 void wil_priv_deinit(struct wil6210_priv *wil);
 int wil_reset(struct wil6210_priv *wil);
-void wil_set_itr_trsh(struct wil6210_priv *wil);
 void wil_fw_error_recovery(struct wil6210_priv *wil);
 void wil_set_recovery_state(struct wil6210_priv *wil, int state);
 void wil_link_on(struct wil6210_priv *wil);
@@ -567,12 +681,26 @@ int wmi_p2p_cfg(struct wil6210_priv *wil, int channel);
 int wmi_rxon(struct wil6210_priv *wil, bool on);
 int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
 int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason);
+int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout);
+int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason);
+int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason);
+int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
+                     u16 status, bool amsdu, u16 agg_wsize, u16 timeout);
+int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
+                        u8 dialog_token, __le16 ba_param_set,
+                        __le16 ba_timeout, __le16 ba_seq_ctrl);
+void wil_back_rx_worker(struct work_struct *work);
+void wil_back_rx_flush(struct wil6210_priv *wil);
+int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize);
+void wil_back_tx_worker(struct work_struct *work);
+void wil_back_tx_flush(struct wil6210_priv *wil);
 
 void wil6210_clear_irq(struct wil6210_priv *wil);
 int wil6210_init_irq(struct wil6210_priv *wil, int irq);
 void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
 void wil_mask_irq(struct wil6210_priv *wil);
 void wil_unmask_irq(struct wil6210_priv *wil);
+void wil_configure_interrupt_moderation(struct wil6210_priv *wil);
 void wil_disable_irq(struct wil6210_priv *wil);
 void wil_enable_irq(struct wil6210_priv *wil);
 int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,