wil6210: support 8KB RX buffers
authorLior David <qca_liord@qca.qualcomm.com>
Wed, 5 Apr 2017 11:58:06 +0000 (14:58 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Thu, 13 Apr 2017 12:45:48 +0000 (15:45 +0300)
The 11ad spec requires 11ad devices to be able to receive 8KB
packets over the air. Currently this is only possible by
loading the driver with mtu_max=7912 but this also forces
a smaller block ACK window size which reduces performance
for stations which transmit normal sized packets (<2KB).
Fix this problem as follows:
1. Add a module parameter rx_large_buf that when set,
will allocate 8KB RX buffers regardless of mtu_max
setting.
2. When receiving block ACK request agree to any window
size not above our maximum, regardless of the mtu_max setting.
This means if the other side transmits small packets (2KB)
it can still set up block ACK with a large window size,
and get better performance.

Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/wil6210/rx_reorder.c
drivers/net/wireless/ath/wil6210/txrx.c
drivers/net/wireless/ath/wil6210/wil6210.h
drivers/net/wireless/ath/wil6210/wmi.c

index 7404b6f39c6aff08495dd53c6f463d5c20f0e15c..a43cffcf1bbf7aa4b10d039ae364cf2b82f732f1 100644 (file)
@@ -343,8 +343,16 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
                wil_err(wil, "BACK requested unsupported ba_policy == 1\n");
                status = WLAN_STATUS_INVALID_QOS_PARAM;
        }
-       if (status == WLAN_STATUS_SUCCESS)
-               agg_wsize = wil_agg_size(wil, req_agg_wsize);
+       if (status == WLAN_STATUS_SUCCESS) {
+               if (req_agg_wsize == 0) {
+                       wil_dbg_misc(wil, "Suggest BACK wsize %d\n",
+                                    WIL_MAX_AGG_WSIZE);
+                       agg_wsize = WIL_MAX_AGG_WSIZE;
+               } else {
+                       agg_wsize = min_t(u16,
+                                         WIL_MAX_AGG_WSIZE, req_agg_wsize);
+               }
+       }
 
        rc = wmi_addba_rx_resp(wil, cid, tid, dialog_token, status,
                               agg_amsdu, agg_wsize, agg_timeout);
index 67f50ae17cd3fdb8d5c5ff816e994e41f846c262..edab4c0a900ff9ab0a022465002690bc5e3f7017 100644 (file)
@@ -37,6 +37,10 @@ bool rx_align_2;
 module_param(rx_align_2, bool, 0444);
 MODULE_PARM_DESC(rx_align_2, " align Rx buffers on 4*n+2, default - no");
 
+bool rx_large_buf;
+module_param(rx_large_buf, bool, 0444);
+MODULE_PARM_DESC(rx_large_buf, " allocate 8KB RX buffers, default - no");
+
 static inline uint wil_rx_snaplen(void)
 {
        return rx_align_2 ? 6 : 0;
@@ -255,7 +259,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
                               u32 i, int headroom)
 {
        struct device *dev = wil_to_dev(wil);
-       unsigned int sz = mtu_max + ETH_HLEN + wil_rx_snaplen();
+       unsigned int sz = wil->rx_buf_len + ETH_HLEN + wil_rx_snaplen();
        struct vring_rx_desc dd, *d = &dd;
        volatile struct vring_rx_desc *_d = &vring->va[i].rx;
        dma_addr_t pa;
@@ -419,7 +423,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
        struct sk_buff *skb;
        dma_addr_t pa;
        unsigned int snaplen = wil_rx_snaplen();
-       unsigned int sz = mtu_max + ETH_HLEN + snaplen;
+       unsigned int sz = wil->rx_buf_len + ETH_HLEN + snaplen;
        u16 dmalen;
        u8 ftype;
        int cid;
@@ -780,6 +784,20 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota)
        wil_rx_refill(wil, v->size);
 }
 
+static void wil_rx_buf_len_init(struct wil6210_priv *wil)
+{
+       wil->rx_buf_len = rx_large_buf ?
+               WIL_MAX_ETH_MTU : TXRX_BUF_LEN_DEFAULT - WIL_MAX_MPDU_OVERHEAD;
+       if (mtu_max > wil->rx_buf_len) {
+               /* do not allow RX buffers to be smaller than mtu_max, for
+                * backward compatibility (mtu_max parameter was also used
+                * to support receiving large packets)
+                */
+               wil_info(wil, "Override RX buffer to mtu_max(%d)\n", mtu_max);
+               wil->rx_buf_len = mtu_max;
+       }
+}
+
 int wil_rx_init(struct wil6210_priv *wil, u16 size)
 {
        struct vring *vring = &wil->vring_rx;
@@ -792,6 +810,8 @@ int wil_rx_init(struct wil6210_priv *wil, u16 size)
                return -EINVAL;
        }
 
+       wil_rx_buf_len_init(wil);
+
        vring->size = size;
        rc = wil_vring_alloc(wil, vring);
        if (rc)
index 9cedc2d642bab2329708e7b39601e1c57e3bed35..2af4a643bd0319fd825f81bfdf485b60f29a0b06 100644 (file)
@@ -32,6 +32,7 @@ extern unsigned short rx_ring_overflow_thrsh;
 extern int agg_wsize;
 extern u32 vring_idle_trsh;
 extern bool rx_align_2;
+extern bool rx_large_buf;
 extern bool debug_fw;
 extern bool disable_ap_sme;
 
@@ -656,6 +657,7 @@ struct wil6210_priv {
        struct work_struct probe_client_worker;
        /* DMA related */
        struct vring vring_rx;
+       unsigned int rx_buf_len;
        struct vring vring_tx[WIL6210_MAX_TX_RINGS];
        struct vring_tx_data vring_tx_data[WIL6210_MAX_TX_RINGS];
        u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */
index 9255c47af15a8d941577f7049cd6b612cb63e8dc..e6c249d47487b732fc97bc2789bb40c36a45efa4 100644 (file)
@@ -1398,7 +1398,8 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
        struct wmi_cfg_rx_chain_cmd cmd = {
                .action = WMI_RX_CHAIN_ADD,
                .rx_sw_ring = {
-                       .max_mpdu_size = cpu_to_le16(wil_mtu2macbuf(mtu_max)),
+                       .max_mpdu_size = cpu_to_le16(
+                               wil_mtu2macbuf(wil->rx_buf_len)),
                        .ring_mem_base = cpu_to_le64(vring->pa),
                        .ring_size = cpu_to_le16(vring->size),
                },