]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Thu, 4 Mar 2021 20:46:01 +0000 (15:46 -0500)
committerSasha Levin <sashal@kernel.org>
Thu, 4 Mar 2021 20:46:01 +0000 (15:46 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.10/rsi-fix-tx-eapol-packet-handling-against-iwlwifi-ap.patch [new file with mode: 0644]
queue-5.10/rsi-move-card-interrupt-handling-to-rx-thread.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/rsi-fix-tx-eapol-packet-handling-against-iwlwifi-ap.patch b/queue-5.10/rsi-fix-tx-eapol-packet-handling-against-iwlwifi-ap.patch
new file mode 100644 (file)
index 0000000..e0ac8ae
--- /dev/null
@@ -0,0 +1,71 @@
+From 18e3171b0b120efc80ac2d5670a5829efbdc5f2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Oct 2020 13:16:16 +0200
+Subject: rsi: Fix TX EAPOL packet handling against iwlwifi AP
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 65277100caa2f2c62b6f3c4648b90d6f0435f3bc ]
+
+In case RSI9116 SDIO WiFi operates in STA mode against Intel 9260 in AP mode,
+the association fails. The former is using wpa_supplicant during association,
+the later is set up using hostapd:
+
+iwl$ cat hostapd.conf
+interface=wlp1s0
+ssid=test
+country_code=DE
+hw_mode=g
+channel=1
+wpa=2
+wpa_passphrase=test
+wpa_key_mgmt=WPA-PSK
+iwl$ hostapd -d hostapd.conf
+
+rsi$ wpa_supplicant -i wlan0 -c <(wpa_passphrase test test)
+
+The problem is that the TX EAPOL data descriptor RSI_DESC_REQUIRE_CFM_TO_HOST
+flag and extended descriptor EAPOL4_CONFIRM frame type are not set in case the
+AP is iwlwifi, because in that case the TX EAPOL packet is 2 bytes shorter.
+
+The downstream vendor driver has this change in place already [1], however
+there is no explanation for it, neither is there any commit history from which
+such explanation could be obtained.
+
+[1] https://github.com/SiliconLabs/RS911X-nLink-OSD/blob/master/rsi/rsi_91x_hal.c#L238
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Cc: Angus Ainslie <angus@akkea.ca>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Kalle Valo <kvalo@codeaurora.org>
+Cc: Lee Jones <lee.jones@linaro.org>
+Cc: Martin Kepplinger <martink@posteo.de>
+Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Cc: Siva Rebbagondla <siva8118@gmail.com>
+Cc: linux-wireless@vger.kernel.org
+Cc: netdev@vger.kernel.org
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20201015111616.429220-1-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/rsi/rsi_91x_hal.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
+index 3f7e3cfb6f00..ce9892152f4d 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
++++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
+@@ -248,7 +248,8 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
+                       rsi_set_len_qno(&data_desc->len_qno,
+                                       (skb->len - FRAME_DESC_SZ),
+                                       RSI_WIFI_MGMT_Q);
+-              if ((skb->len - header_size) == EAPOL4_PACKET_LEN) {
++              if (((skb->len - header_size) == EAPOL4_PACKET_LEN) ||
++                  ((skb->len - header_size) == EAPOL4_PACKET_LEN - 2)) {
+                       data_desc->misc_flags |=
+                               RSI_DESC_REQUIRE_CFM_TO_HOST;
+                       xtend_desc->confirm_frame_type = EAPOL4_CONFIRM;
+-- 
+2.30.1
+
diff --git a/queue-5.10/rsi-move-card-interrupt-handling-to-rx-thread.patch b/queue-5.10/rsi-move-card-interrupt-handling-to-rx-thread.patch
new file mode 100644 (file)
index 0000000..0459cbe
--- /dev/null
@@ -0,0 +1,217 @@
+From 28c3535abaa95ff162d669e9ec246deaa92523a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Nov 2020 19:09:40 +0100
+Subject: rsi: Move card interrupt handling to RX thread
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 287431463e786766e05e4dc26d0a11d5f8ac8815 ]
+
+The interrupt handling of the RS911x is particularly heavy. For each RX
+packet, the card does three SDIO transactions, one to read interrupt
+status register, one to RX buffer length, one to read the RX packet(s).
+This translates to ~330 uS per one cycle of interrupt handler. In case
+there is more incoming traffic, this will be more.
+
+The drivers/mmc/core/sdio_irq.c has the following comment, quote "Just
+like traditional hard IRQ handlers, we expect SDIO IRQ handlers to be
+quick and to the point, so that the holding of the host lock does not
+cover too much work that doesn't require that lock to be held."
+
+The RS911x interrupt handler does not fit that. This patch therefore
+changes it such that the entire IRQ handler is moved to the RX thread
+instead, and the interrupt handler only wakes the RX thread.
+
+This is OK, because the interrupt handler only does things which can
+also be done in the RX thread, that is, it checks for firmware loading
+error(s), it checks buffer status, it checks whether a packet arrived
+and if so, reads out the packet and passes it to network stack.
+
+Moreover, this change permits removal of a code which allocated an
+skbuff only to get 4-byte-aligned buffer, read up to 8kiB of data
+into the skbuff, queue this skbuff into local private queue, then in
+RX thread, this buffer is dequeued, the data in the skbuff as passed
+to the RSI driver core, and the skbuff is deallocated. All this is
+replaced by directly calling the RSI driver core with local buffer.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Cc: Angus Ainslie <angus@akkea.ca>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Kalle Valo <kvalo@codeaurora.org>
+Cc: Lee Jones <lee.jones@linaro.org>
+Cc: Martin Kepplinger <martink@posteo.de>
+Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Cc: Siva Rebbagondla <siva8118@gmail.com>
+Cc: linux-wireless@vger.kernel.org
+Cc: netdev@vger.kernel.org
+Tested-by: Martin Kepplinger <martin.kepplinger@puri.sm>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20201103180941.443528-1-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/rsi/rsi_91x_sdio.c     |  6 +--
+ drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 52 ++++++---------------
+ drivers/net/wireless/rsi/rsi_sdio.h         |  8 +---
+ 3 files changed, 15 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
+index a7b8684143f4..592e9dadcb55 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
++++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
+@@ -153,9 +153,7 @@ static void rsi_handle_interrupt(struct sdio_func *function)
+       if (adapter->priv->fsm_state == FSM_FW_NOT_LOADED)
+               return;
+-      dev->sdio_irq_task = current;
+-      rsi_interrupt_handler(adapter);
+-      dev->sdio_irq_task = NULL;
++      rsi_set_event(&dev->rx_thread.event);
+ }
+ /**
+@@ -1058,8 +1056,6 @@ static int rsi_probe(struct sdio_func *pfunction,
+               rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
+               goto fail_kill_thread;
+       }
+-      skb_queue_head_init(&sdev->rx_q.head);
+-      sdev->rx_q.num_rx_pkts = 0;
+       sdio_claim_host(pfunction);
+       if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
+diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
+index 7825c9a889d3..23e709aabd1f 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
++++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
+@@ -60,39 +60,20 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word)
+       return status;
+ }
++static void rsi_rx_handler(struct rsi_hw *adapter);
++
+ void rsi_sdio_rx_thread(struct rsi_common *common)
+ {
+       struct rsi_hw *adapter = common->priv;
+       struct rsi_91x_sdiodev *sdev = adapter->rsi_dev;
+-      struct sk_buff *skb;
+-      int status;
+       do {
+               rsi_wait_event(&sdev->rx_thread.event, EVENT_WAIT_FOREVER);
+               rsi_reset_event(&sdev->rx_thread.event);
++              rsi_rx_handler(adapter);
++      } while (!atomic_read(&sdev->rx_thread.thread_done));
+-              while (true) {
+-                      if (atomic_read(&sdev->rx_thread.thread_done))
+-                              goto out;
+-
+-                      skb = skb_dequeue(&sdev->rx_q.head);
+-                      if (!skb)
+-                              break;
+-                      if (sdev->rx_q.num_rx_pkts > 0)
+-                              sdev->rx_q.num_rx_pkts--;
+-                      status = rsi_read_pkt(common, skb->data, skb->len);
+-                      if (status) {
+-                              rsi_dbg(ERR_ZONE, "Failed to read the packet\n");
+-                              dev_kfree_skb(skb);
+-                              break;
+-                      }
+-                      dev_kfree_skb(skb);
+-              }
+-      } while (1);
+-
+-out:
+       rsi_dbg(INFO_ZONE, "%s: Terminated SDIO RX thread\n", __func__);
+-      skb_queue_purge(&sdev->rx_q.head);
+       atomic_inc(&sdev->rx_thread.thread_done);
+       complete_and_exit(&sdev->rx_thread.completion, 0);
+ }
+@@ -113,10 +94,6 @@ static int rsi_process_pkt(struct rsi_common *common)
+       u32 rcv_pkt_len = 0;
+       int status = 0;
+       u8 value = 0;
+-      struct sk_buff *skb;
+-
+-      if (dev->rx_q.num_rx_pkts >= RSI_MAX_RX_PKTS)
+-              return 0;
+       num_blks = ((adapter->interrupt_status & 1) |
+                       ((adapter->interrupt_status >> RECV_NUM_BLOCKS) << 1));
+@@ -144,22 +121,19 @@ static int rsi_process_pkt(struct rsi_common *common)
+       rcv_pkt_len = (num_blks * 256);
+-      skb = dev_alloc_skb(rcv_pkt_len);
+-      if (!skb)
+-              return -ENOMEM;
+-
+-      status = rsi_sdio_host_intf_read_pkt(adapter, skb->data, rcv_pkt_len);
++      status = rsi_sdio_host_intf_read_pkt(adapter, dev->pktbuffer,
++                                           rcv_pkt_len);
+       if (status) {
+               rsi_dbg(ERR_ZONE, "%s: Failed to read packet from card\n",
+                       __func__);
+-              dev_kfree_skb(skb);
+               return status;
+       }
+-      skb_put(skb, rcv_pkt_len);
+-      skb_queue_tail(&dev->rx_q.head, skb);
+-      dev->rx_q.num_rx_pkts++;
+-      rsi_set_event(&dev->rx_thread.event);
++      status = rsi_read_pkt(common, dev->pktbuffer, rcv_pkt_len);
++      if (status) {
++              rsi_dbg(ERR_ZONE, "Failed to read the packet\n");
++              return status;
++      }
+       return 0;
+ }
+@@ -251,12 +225,12 @@ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
+ }
+ /**
+- * rsi_interrupt_handler() - This function read and process SDIO interrupts.
++ * rsi_rx_handler() - Read and process SDIO interrupts.
+  * @adapter: Pointer to the adapter structure.
+  *
+  * Return: None.
+  */
+-void rsi_interrupt_handler(struct rsi_hw *adapter)
++static void rsi_rx_handler(struct rsi_hw *adapter)
+ {
+       struct rsi_common *common = adapter->priv;
+       struct rsi_91x_sdiodev *dev =
+diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
+index 9afc1d0d2684..1c756263cf15 100644
+--- a/drivers/net/wireless/rsi/rsi_sdio.h
++++ b/drivers/net/wireless/rsi/rsi_sdio.h
+@@ -107,11 +107,6 @@ struct receive_info {
+       u32 buf_available_counter;
+ };
+-struct rsi_sdio_rx_q {
+-      u8 num_rx_pkts;
+-      struct sk_buff_head head;
+-};
+-
+ struct rsi_91x_sdiodev {
+       struct sdio_func *pfunction;
+       struct task_struct *sdio_irq_task;
+@@ -124,11 +119,10 @@ struct rsi_91x_sdiodev {
+       u16 tx_blk_size;
+       u8 write_fail;
+       bool buff_status_updated;
+-      struct rsi_sdio_rx_q rx_q;
+       struct rsi_thread rx_thread;
++      u8 pktbuffer[8192] __aligned(4);
+ };
+-void rsi_interrupt_handler(struct rsi_hw *adapter);
+ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter);
+ int rsi_sdio_read_register(struct rsi_hw *adapter, u32 addr, u8 *data);
+ int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter, u8 *pkt, u32 length);
+-- 
+2.30.1
+
index 022809e3f3cbb88d2bdae4ac72e250e815f083f3..63b095b0f44cd350c5cd0336f971d9883cd8215e 100644 (file)
@@ -33,3 +33,5 @@ dt-bindings-ethernet-controller-fix-fixed-link-specification.patch
 dt-bindings-net-btusb-dt-fix-s-interrupt-name-interrupt-names.patch
 asoc-qcom-remove-useless-debug-print.patch
 soundwire-debugfs-use-controller-id-instead-of-link_id.patch
+rsi-fix-tx-eapol-packet-handling-against-iwlwifi-ap.patch
+rsi-move-card-interrupt-handling-to-rx-thread.patch