openwrt-ipq-breeze303/package/kernel/mac80211/patches/nss/ath11k/211-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch
Qosmio 858bb6da15 ath11k_nss: squash and refactor patches
ath11k_nss: fix build for 256/1G mem, and ath10k

ath11k_nss: bump release version '8'

mac80211: refactor NSS patches

Since NSS requires patches to subsys, and ath*k directories. Move
patches into a subset of nss for better tracking against QSDK,
and modularization.

ath11k_nss: rename patches

ath11k_nss: clean up optional patches

To reduce bug tracking headaches, I've remove the following patches, as
they are not required for NSS offload and have been around the last 2-3
years without ever being upstreamed.

nss/ath11k/235-001-ath11k-Add-support-for-beacon-tx-mode.patch
nss/ath11k/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch
nss/ath11k/902-020-ath11k-add-btcoex-config.patch
nss/ath11k/902-022-ath11k-add-ap-ps-support.patch
nss/ath11k/907-068-ath11k-add-rx-histogram-stats.patch
nss/ath11k/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch
nss/ath11k/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch
nss/ath11k/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch
nss/ath11k/913-356-ath11k-invalid-desc-sanity-check.patch
nss/ath11k/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch
nss/ath11k/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch
nss/subsys/235-002-mac80211-Add-support-for-beacon-tx-mode.patch
nss/subsys/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch

ath11k_nss: Remove superfluous patches

Remove patches unrelated to NSS offloading to minimize bloat and better
track NSS related issues.

ath11k_nss: Refactor patches to use upstream names

Reworked patches to use upstream QSDK names. Allows for better tracking

ath11k_nss: align wifi offload with qca-nss-drv

The option in qca-nss-drv is actually 'NSS_DRV_WIFIOFFLOAD_ENABLE' use
the same syntax.

ath10k-ct: fix compile with NSS wifi

ath11k_nss: Merge every NSS related feature + more

* Added macro to disable NSS mesh offload
* Added menuconfig option "ATH11K_NSS_MESH_SUPPORT" to selectivley build mesh support,
	as well it's depenacndy on nss-drv-wifimeshmgr.
* Added option to disable HTT Stats, and STA stats (stations).
* Reducing footprint by ~210KB. Debugfs minimal is still enabled.
* Reworked a TON of patches, some my own, hopefully there should be a far less amount of WOA2/WPA3 connection issues.
* Updated the /etc/init.d/pbuf script to be more robust. (handles tweaking ath11k and NSS settings better)

NOTES: Although mesh package builds (nss-drv-wifimeshmgr), ath11k doesn't seem to support it yet.
Not sure if NSS requires 3 radios to work, I'm at a dead end currently with that route.

ATTENTION:
the ptch `37-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch`
works well on nss with frame_mode=2.
And on `ath11k frame_mode=1 nss_offload=0`

And on `ath11k frame_mode=2 nss_offload=1`

if you set nss_offload=off and frame_mode=2, it will CRASH
if you set nss_offload=on and frame_mode=2, it will  RUN
if you set nss_offload=off and frame_mode=1, it will RUN

ath11k_nss: fix n2h high_water_core0/wifi_pool_buf

These were commented out, but looks like they are needed to prevent lock
ups with heavy usage apps (users report in torrenting)

ath11k_nss: Renumber ath11k patches in the range

commit 3c7cc4b725ea406f19b736427034e3bdb436aedc
Author:     Yuvasree Sivasankaran <quic_ysivasan@quicinc.com>
AuthorDate: Thu Jan 4 11:25:56 2024 +0530
Commit:     Yuvasree Sivasankaran <quic_ysivasan@quicinc.com>
CommitDate: Wed Jan 3 22:53:51 2024 -0800

    wifi: ath11k: Renumber ath11k patches in the range

    In ath11k, patches are not maintained in the range and not sequential.
    Renumber the patches sequential and in the range.

    Change-Id: I77c51c0f5bf9f94863db4ef364b156e14465a60c
    Signed-off-by: Yuvasree Sivasankaran <quic_ysivasan@quicinc.com>

ath11k_nss: Add mac hw flag to avoid tx queue in mac80211

commit 4e9b5f7f0d1ed40dbf3208f7ed4448e49b4a4ac1
Author:     Yuvasree Sivasankaran <quic_ysivasan@quicinc.com>
AuthorDate: Wed Dec 6 12:20:59 2023 +0530
Commit:     Yuvasree Sivasankaran <quic_ysivasan@quicinc.com>
CommitDate: Mon Dec 18 12:52:33 2023 +0530

    wifi: mac80211: Add mac hw flag to avoid tx queue in mac80211

    Queue SKB in mac80211 become mandatory from latest 6.1 kernel. Because of
    this queuing, there will be performance degradation. Add hw flag option
    to enable tx queue in Driver/Hardware.

    Driver/hardware can register for HAS_TX_QUEUE HW flag and avoid tx queuing
    in mac80211.

    Add same HW flag checks to avoid accessing skb queues which will be
    NULL or invalid and also NULL checks for sta txqs for NULL or invalid
    access.

ath11k_nss: add the HTC+ / iPhone fix

commit ccdca73cd65723c3cb63c17edc95c4c43318cb38
Author:     John Crispin <john@phrozen.org>
AuthorDate: Sun Jul 9 17:12:34 2023 +0200
Commit:     John Crispin <john@phrozen.org>
CommitDate: Thu Aug 31 16:08:34 2023 +0200

    mac80211: add the HTC+ / iPhone fix

    Signed-off-by: John Crispin <john@phrozen.org>

ath11k_nss: ath-next fix connection failure due to unexpected peer delete

Currently ath11k_mac_op_unassign_vif_chanctx() deletes peer but
ath11k_mac_op_assign_vif_chanctx() doesn't create it. This results in
connection failure if MAC80211 calls drv_unassign_vif_chanctx() and
drv_assign_vif_chanctx() during AUTH and ASSOC, see below log:

[  102.372431] wlan0: authenticated
[  102.372585] ath11k_pci 0000:01:00.0: wlan0: disabling HT/VHT/HE as WMM/QoS is not supported by the AP
[  102.372593] ath11k_pci 0000:01:00.0: mac chanctx unassign ptr ffff895084638598 vdev_id 0
[  102.372808] ath11k_pci 0000:01:00.0: WMI vdev stop id 0x0
[  102.383114] ath11k_pci 0000:01:00.0: vdev stopped for vdev id 0
[  102.384689] ath11k_pci 0000:01:00.0: WMI peer delete vdev_id 0 peer_addr 20:e5:2a:21:c4:51
[  102.396676] ath11k_pci 0000:01:00.0: htt peer unmap vdev 0 peer 20:e5:2a:21:c4:51 id 3
[  102.396711] ath11k_pci 0000:01:00.0: peer delete resp for vdev id 0 addr 20:e5:2a:21:c4:51
[  102.396722] ath11k_pci 0000:01:00.0: mac removed peer 20:e5:2a:21:c4:51  vdev 0 after vdev stop
[  102.396780] ath11k_pci 0000:01:00.0: mac chanctx assign ptr ffff895084639c18 vdev_id 0
[  102.400628] wlan0: associate with 20:e5:2a:21:c4:51 (try 1/3)
[  102.508864] wlan0: associate with 20:e5:2a:21:c4:51 (try 2/3)
[  102.612815] wlan0: associate with 20:e5:2a:21:c4:51 (try 3/3)
[  102.720846] wlan0: association with 20:e5:2a:21:c4:51 timed out

The peer delete logic in ath11k_mac_op_unassign_vif_chanctx() is
introduced by commit b4a0f54156ac ("ath11k: move peer delete after
vdev stop of station for QCA6390 and WCN6855") to fix firmware
crash issue caused by unexpected vdev stop/peer delete sequence.

Actually for a STA interface peer should be deleted in
ath11k_mac_op_sta_state() when STA's state changes from
IEEE80211_STA_NONE to IEEE80211_STA_NOTEXIST, which also coincides
with current peer creation design that peer is created during
IEEE80211_STA_NOTEXIST -> IEEE80211_STA_NONE transition. So move
peer delete back to ath11k_mac_op_sta_state(), also stop vdev before
deleting peer to fix the firmware crash issue mentioned there. In
this way the connection failure mentioned here is also fixed.

Also do some cleanups in patch "wifi: ath11k: remove invalid peer
create logic", and refactor in patches "wifi: ath11k: rename
ath11k_start_vdev_delay()" and "wifi: ath11k: avoid forward declaration
of ath11k_mac_start_vdev_delay()".

Tested this patch set using QCA6390 and WCN6855 on both STA and SAP
interfaces. Basic connection and ping work well.

Baochen Qiang (4):
  wifi: ath11k: remove invalid peer create logic
  wifi: ath11k: rename ath11k_start_vdev_delay()
  wifi: ath11k: avoid forward declaration of
    ath11k_mac_start_vdev_delay()
  wifi: ath11k: fix connection failure due to unexpected peer delete

 drivers/net/wireless/ath/ath11k/mac.c | 564 +++++++++++++-------------
 1 file changed, 288 insertions(+), 276 deletions(-)

ath11k_nss: Revert support for beacon_tx_mode

ath11k_nss: Update release fix dependancies

ath11k_nss: mgmt and data ack rssi update

Data ACK RSSI :

      Advertise NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT feature support
for accounting and notifying "last ack signal" and "avg ack signal" to
user space through NL interface.

      Enabled data ack rssi support for ethernet mode.

Mgmt ACK RSSI:

      Enabled support for Tx-ACK RSSI in HTT over Management packets.

ath11k_nss: add missing support to enable/disable bss color collision detection

ath11k_nss: FW Initiated Dynamic MU-EDCA

Implementing the updating of firmware initiated dynamic MU-EDCA
parameters in Beacon IE. Firmware routinely checks its clients and
updates its MU-EDCA values every 3 seconds. Firmware is tuning
MU-EDCA parameters to improve performance. As part of this process,
the firmware informs host about new MU-EDCA values utilizing
WMI_MUEDCA_PARAMS_CONFIG_EVENTID. FW expectation is that host will
update MU-EDCA parameters in the Beacon IE.

ath11k_nss: refresh patches + cleanup Makefile

ath11k_nss: Set correct pbufs for 1GB profile

ath11k_nss: Revert setting fw_mem_mode for IPQ807x

Leave it set to '0', as it will kernel panic with 2K skb patch. This
flag was incorrectly assumed to save memory on 1G platforms.

ath11k_nss: remove leftover max_tx_ring

it was not removed when applying patch to replace it with 'max_tx_ring =
DP_TCL_NUM_RING_MAX +1'

ath11k_nss: Import bugfix patches

ath11k_nss: Experimental build for IPQ6018

This will require setting the correct `ATH11K_MEM_PROFILE_XXX` for your
platform. Setting it to value lower/higher than physically available
will cause NULL virtual address kernel panics.

I believe this setting was not originally meant to reduce memory
footprint of 1G+ platforms, but to account for platforms that were
512M or less.

Will require tweaking to allow for the old behvaior on 1G+ IPQ807x,
while still saving memory for platforms <= 512M.

commit d2d5a0d1f9ce668f92a22eb45279c6c4c3bf7a4f
Author:     Qosmio <datapronix@protonmail.com>
AuthorDate: Sat Mar 9 11:59:20 2024 -0500
Commit:     Sean Khan <datapronix@protonmail.com>
CommitDate: Fri Oct 11 11:13:03 2024 -0400

ath11k_nss: fix typo in 512M memory profile

ath11k_nss: remove SFE patch 718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly

It is not relevant to NSS builds and only meant for SFE.

ath11k_nss: remove unecessary patches

Color collision should be left on by default, as it's a primary feature
of 802.11AX.

ath11k_nss: fix spacing

ath11k_nss: Remove unnecessary TKIP bloat

Remove TKIP patches that are not being used as 99% of folks are running
modern encryption (AES-CCMP,SAE,etc).

ath11k_nss: parameterize DP_RXDMA_REFILL_RING_SIZE memory profile

ath11k_nss: Remove SFE related code

Cleanup SFE (shortcut fe) related code as we're not using it on NSS

ath11k_nss: idr, ampdu, and skb headroom check optimizations

ath11k_nss: get valid last_rate for rx_bitrate from cpu stats

ath11k_nss: Fix BCCA counter for EMA

Currently BCCA counter is updated to FW via csa counter offs and
beacon with new countdown is updated for every beacon tx completion event.
For EMA, all EMA beacons are updated in one shot, and counter update for
every tx event will mess up the actual sequence of countdown sent over the air.

Allow FW to update the countdown till 1 and finalize the color
change.

ath11k_nss: Fix compile for TRACE feature
2024-10-11 19:19:03 -04:00

689 lines
21 KiB
Diff

From d4c3b17e66243a2d6d8845192453ef7da568bac2 Mon Sep 17 00:00:00 2001
From: Sathishkumar Muruganandam <murugana@codeaurora.org>
Date: Thu, 10 Sep 2020 15:58:53 +0530
Subject: [PATCH 1/2] ath11k: add WDS offload changes to NSS driver interface
add WDS and MEC AST handling to NSS
Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
---
drivers/net/wireless/ath/ath11k/nss.c | 465 ++++++++++++++++++++++++++++++++--
drivers/net/wireless/ath/ath11k/nss.h | 36 ++-
2 files changed, 473 insertions(+), 28 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/nss.c
+++ b/drivers/net/wireless/ath/ath11k/nss.c
@@ -307,6 +307,22 @@ void ath11k_nss_wifili_event_receive(str
case NSS_WIFILI_TID_REOQ_SETUP_MSG:
/* TODO setup tidq */
break;
+ case NSS_WIFILI_WDS_PEER_ADD_MSG:
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili wds peer add event received %d response %d error %d\n",
+ msg_type, response, error);
+ break;
+ case NSS_WIFILI_WDS_PEER_UPDATE_MSG:
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili wds peer update event received %d response %d error %d\n",
+ msg_type, response, error);
+ break;
+ case NSS_WIFILI_WDS_PEER_MAP_MSG:
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili wds peer map event received %d response %d error %d\n",
+ msg_type, response, error);
+ break;
+ case NSS_WIFILI_WDS_PEER_DEL_MSG:
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili wds peer del event received %d response %d error %d\n",
+ msg_type, response, error);
+ break;
default:
ath11k_dbg(ab, ATH11K_DBG_NSS, "unhandled event %d\n", msg_type);
break;
@@ -417,13 +433,6 @@ static void ath11k_nss_vdev_event_receiv
/*TODO*/
}
-static void
-ath11k_nss_vdev_special_data_receive(struct net_device *dev, struct sk_buff *skb,
- __attribute__((unused)) struct napi_struct *napi)
-{
- /* TODO */
-}
-
/* TODO: move to mac80211 after cleanups/refactoring required after feature completion */
static int ath11k_nss_deliver_rx(struct ieee80211_vif *vif, struct sk_buff *skb,
bool eth, int data_offs, struct napi_struct *napi)
@@ -547,11 +556,239 @@ static int ath11k_nss_undecap_nwifi(stru
return 0;
}
+static void ath11k_nss_wds_type_rx(struct ath11k *ar, u8* src_mac, u8 is_sa_valid,
+ u8 addr4_valid, u16 peer_id)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct ath11k_ast_entry *ast_entry = NULL;
+ struct ath11k_peer *ta_peer = NULL;
+
+ spin_lock_bh(&ab->base_lock);
+ ta_peer = ath11k_peer_find_by_id(ab, peer_id);
+
+ if (!ta_peer) {
+ spin_unlock_bh(&ab->base_lock);
+ return;
+ }
+
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,"ath11k_nss_wds_type_rx ta_peer %pM\n",
+ ta_peer->addr);
+
+ if (addr4_valid) {
+ ast_entry = ath11k_peer_ast_find_by_addr(ab, src_mac);
+ if (!is_sa_valid) {
+ ath11k_peer_add_ast(ar, ta_peer, src_mac,
+ ATH11K_AST_TYPE_WDS);
+ ath11k_nss_add_wds_peer(ar, ta_peer,
+ src_mac, ATH11K_AST_TYPE_WDS);
+ } else {
+ if (!ast_entry) {
+ ath11k_peer_add_ast(ar, ta_peer, src_mac,
+ ATH11K_AST_TYPE_WDS);
+ ath11k_nss_add_wds_peer(ar, ta_peer, src_mac,
+ ATH11K_AST_TYPE_WDS);
+ } else {
+ ath11k_peer_update_ast(ar, ta_peer, ast_entry);
+ ath11k_nss_update_wds_peer(ar, ta_peer, src_mac);
+ }
+ }
+ }
+
+ spin_unlock_bh(&ab->base_lock);
+}
+
+static void ath11k_nss_mec_handler(struct ath11k *ar, u8* mec_mac_addr)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct ath11k_peer *peer = ar->bss_peer;
+ u8 mac_addr[ETH_ALEN];
+ u32 *mac_addr_l32;
+ u16 *mac_addr_h16;
+
+ if (!peer)
+ return;
+
+ /* mec_mac_addr has the swapped mac_addr after 4 bytes (sizeof(u32))
+ * mec_mac_addr[0]
+ * |
+ * 03:0a:00:00:2d:15:22:f0:fd:8c
+ * ^
+ * Swapped MAC address present after 4 bytes
+ * MAC address after swapping is 8c:fd:f0:22:15:2d */
+
+ mac_addr_l32 = (u32 *) (mec_mac_addr + sizeof(u32));
+ mac_addr_h16 = (u16 *) (mec_mac_addr + sizeof(u32) + sizeof(u32));
+
+ *mac_addr_l32 = swab32(*mac_addr_l32);
+ *mac_addr_h16 = swab16(*mac_addr_h16);
+
+ memcpy(mac_addr, mac_addr_h16, ETH_ALEN - 4);
+ memcpy(mac_addr + 2, mac_addr_l32, 4);
+
+ if (!ether_addr_equal(ar->mac_addr, mac_addr)) {
+ spin_lock_bh(&ab->base_lock);
+ ath11k_peer_add_ast(ar, peer, mac_addr,
+ ATH11K_AST_TYPE_MEC);
+ spin_unlock_bh(&ab->base_lock);
+ }
+}
+
+static void ath11k_nss_vdev_spl_receive_ext_wdsdata(struct ath11k_vif *arvif,
+ struct sk_buff *skb,
+ struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata)
+{
+ struct ath11k *ar = arvif->ar;
+ struct ath11k_base *ab = ar->ab;
+ enum wifi_vdev_ext_wds_info_type wds_type;
+ u8 is_sa_valid = 0, addr4_valid = 0;
+ u16 peer_id;
+ u8 src_mac[ETH_ALEN];
+
+ is_sa_valid = wds_metadata->is_sa_valid;
+ addr4_valid = wds_metadata->addr4_valid;
+ wds_type = wds_metadata->wds_type;
+ peer_id = wds_metadata->peer_id;
+
+ memcpy(src_mac, ((struct ethhdr *)skb->data)->h_source, ETH_ALEN);
+
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,"receive_ext_wdsdata wds_type %d peer id %u sa_valid %d addr4_valid %d src_mac %pM\n",
+ wds_type, peer_id, is_sa_valid, addr4_valid, src_mac);
+
+ switch (wds_type) {
+ case NSS_WIFI_VDEV_WDS_TYPE_RX:
+ ath11k_nss_wds_type_rx(ar, src_mac, is_sa_valid,
+ addr4_valid, peer_id);
+ break;
+ case NSS_WIFI_VDEV_WDS_TYPE_MEC:
+ ath11k_nss_mec_handler(ar, (u8 *)(skb->data));
+ break;
+ default:
+ ath11k_warn(ab, "unsupported wds_type %d\n", wds_type);
+ break;
+ }
+}
+
+static bool ath11k_nss_vdev_data_receive_mec_check(struct ath11k *ar,
+ struct sk_buff *skb)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct ath11k_ast_entry *ast_entry = NULL;
+ u8 src_mac[ETH_ALEN];
+
+ memcpy(src_mac, ((struct ethhdr *)skb->data)->h_source, ETH_ALEN);
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,
+ "ath11k_nss_vdev_data_receive_mec_check src mac %pM\n",
+ src_mac);
+
+ spin_lock_bh(&ab->base_lock);
+ ast_entry = ath11k_peer_ast_find_by_addr(ab, src_mac);
+
+ if (ast_entry && ast_entry->type == ATH11K_AST_TYPE_MEC) {
+ spin_unlock_bh(&ab->base_lock);
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,
+ "dropping mec traffic from %pM\n", ast_entry->addr);
+ return true;
+ }
+
+ spin_unlock_bh(&ab->base_lock);
+ return false;
+}
+
+static int ath11k_nss_undecap(struct ath11k_vif *arvif, struct sk_buff *skb,
+ int *data_offs, bool *eth_decap)
+{
+ enum ath11k_hw_txrx_mode decap_type;
+
+ decap_type = arvif->nss.decap;
+
+ switch (decap_type) {
+ case ATH11K_HW_TXRX_RAW:
+ return ath11k_nss_undecap_raw(arvif, skb, data_offs);
+ case ATH11K_HW_TXRX_NATIVE_WIFI:
+ return ath11k_nss_undecap_nwifi(arvif, skb, data_offs);
+ case ATH11K_HW_TXRX_ETHERNET:
+ *eth_decap = true;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static void
+ath11k_nss_vdev_special_data_receive(struct net_device *dev, struct sk_buff *skb,
+ __attribute__((unused)) struct napi_struct *napi)
+{
+ struct nss_wifi_vdev_per_packet_metadata *wifi_metadata = NULL;
+ struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata = NULL;
+ struct wireless_dev *wdev;
+ struct ieee80211_vif *vif;
+ struct ath11k_vif *arvif;
+ struct ath11k_base *ab;
+ bool eth_decap = false;
+ int data_offs = 0;
+ int ret = 0;
+
+ if (!dev) {
+ dev_kfree_skb_any(skb);
+ return;
+ }
+
+ wdev = dev->ieee80211_ptr;
+ if (!wdev) {
+ dev_kfree_skb_any(skb);
+ return;
+ }
+
+ vif = wdev_to_ieee80211_vif(wdev);
+ if (!vif) {
+ dev_kfree_skb_any(skb);
+ return;
+ }
+
+ arvif = (struct ath11k_vif *)vif->drv_priv;
+ if (!arvif) {
+ dev_kfree_skb_any(skb);
+ return;
+ }
+
+ ab = arvif->ar->ab;
+
+ skb->dev = dev;
+
+ dma_unmap_single(ab->dev, virt_to_phys(skb->head),
+ NSS_WIFI_VDEV_PER_PACKET_METADATA_OFFSET +
+ sizeof(struct nss_wifi_vdev_per_packet_metadata),
+ DMA_FROM_DEVICE);
+
+ wifi_metadata = (struct nss_wifi_vdev_per_packet_metadata *)(skb->head +
+ NSS_WIFI_VDEV_PER_PACKET_METADATA_OFFSET);
+
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,
+ "dp special data from nss: wifi_metadata->pkt_type %d",
+ wifi_metadata->pkt_type);
+
+ ret = ath11k_nss_undecap(arvif, skb, &data_offs, &eth_decap);
+ if (ret) {
+ ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n",
+ arvif->nss.decap, ret);
+ dev_kfree_skb_any(skb);
+ return;
+ }
+
+ if (eth_decap && wifi_metadata->pkt_type ==
+ NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WDS_LEARN) {
+ wds_metadata = &wifi_metadata->metadata.wds_metadata;
+ ath11k_nss_vdev_spl_receive_ext_wdsdata(arvif, skb,
+ wds_metadata);
+ }
+
+ ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi);
+}
+
static void
ath11k_nss_vdev_data_receive(struct net_device *dev, struct sk_buff *skb,
__attribute__((unused)) struct napi_struct *napi)
{
- enum ath11k_hw_txrx_mode decap_type;
struct wireless_dev *wdev = NULL;
struct ieee80211_vif *vif = NULL;
struct ath11k_vif *arvif;
@@ -591,28 +828,16 @@ ath11k_nss_vdev_data_receive(struct net_
ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", "dp rx msdu from nss: ",
skb->data, skb->len);
- decap_type = arvif->nss.decap;
-
- switch (decap_type) {
- case ATH11K_HW_TXRX_RAW:
- ret = ath11k_nss_undecap_raw(arvif, skb, &data_offs);
- break;
- case ATH11K_HW_TXRX_NATIVE_WIFI:
- ret = ath11k_nss_undecap_nwifi(arvif, skb, &data_offs);
- break;
- case ATH11K_HW_TXRX_ETHERNET:
- /* no changes required for ethernet decap */
- ret = 0;
- eth_decap = true;
- break;
- default:
- ret = -EINVAL;
- break;
+ if ((vif->type == NL80211_IFTYPE_STATION && wdev->use_4addr) &&
+ ath11k_nss_vdev_data_receive_mec_check(arvif->ar, skb)) {
+ dev_kfree_skb_any(skb);
+ return;
}
+ ret = ath11k_nss_undecap(arvif, skb, &data_offs, &eth_decap);
if (ret) {
- ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n", decap_type,
- ret);
+ ath11k_warn(ab, "error in nss rx undecap, type %d err %d\n",
+ arvif->nss.decap, ret);
dev_kfree_skb_any(skb);
return;
}
@@ -1321,7 +1546,7 @@ void ath11k_nss_update_sta_rxrate(struct
peer->nss.nss_stats->rxrate.bw = ath11k_mac_bw_to_mac80211_bw(ppdu_info->bw);
}
-int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr)
+int ath11k_nss_peer_delete(struct ath11k_base *ab, u32 vdev_id, const u8 *addr)
{
struct nss_wifili_peer_msg *peer_msg;
struct nss_wifili_msg *wlmsg = NULL;
@@ -1335,9 +1560,10 @@ int ath11k_nss_peer_delete(struct ath11k
spin_lock_bh(&ab->base_lock);
- peer = ath11k_peer_find_by_addr(ab, addr);
+ peer = ath11k_peer_find(ab, vdev_id, addr);
if (!peer) {
- ath11k_warn(ab, "peer (%pM) not found for nss peer delete\n", addr);
+ ath11k_warn(ab, "peer (%pM) not found on vdev_id %d for nss peer delete\n",
+ addr, vdev_id);
spin_unlock_bh(&ab->base_lock);
return -EINVAL;
}
@@ -1410,8 +1636,9 @@ free_peer:
return ret;
}
-int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer)
+int ath11k_nss_peer_create(struct ath11k *ar, struct ath11k_peer *peer)
{
+ struct ath11k_base *ab = ar->ab;
struct nss_wifili_peer_msg *peer_msg;
struct nss_wifili_msg *wlmsg = NULL;
nss_wifili_msg_callback_t msg_cb;
@@ -1468,17 +1695,23 @@ int ath11k_nss_peer_create(struct ath11k
status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg);
if (status != NSS_TX_SUCCESS) {
ret = -EINVAL;
- ath11k_warn(ab, "nss send peer (%pM) create msg tx error\n",
- peer->addr);
+ ath11k_warn(ab, "nss send peer (%pM) create msg tx error: %d\n",
+ peer->addr, status);
goto peer_mem_free;
}
- ret = 0;
ath11k_dbg(ab, ATH11K_DBG_NSS,
"nss peer_create msg success mac:%pM vdev:%d peer_id:%d hw_ast_idx:%d ast_hash:%d\n",
peer_msg->peer_mac_addr, peer_msg->vdev_id, peer_msg->peer_id,
peer_msg->hw_ast_idx, peer_msg->tx_ast_hash);
+ ret = ath11k_peer_add_ast(ar, peer, peer->addr,
+ ATH11K_AST_TYPE_STATIC);
+ if (ret) {
+ ath11k_warn(ab, "failed to add STATIC ast: %d\n", ret);
+ goto peer_mem_free;
+ }
+
peer->nss.nss_stats = kzalloc(sizeof(*peer->nss.nss_stats), GFP_ATOMIC);
if (!peer->nss.nss_stats) {
ret = -ENOMEM;
@@ -1497,6 +1730,199 @@ msg_free:
return ret;
}
+int ath11k_nss_add_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac, enum ath11k_ast_entry_type type)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct nss_wifili_wds_peer_msg *wds_peer_msg;
+ struct nss_wifili_msg *wlmsg = NULL;
+ nss_wifili_msg_callback_t msg_cb;
+ nss_tx_status_t status;
+ int ret = 0;
+
+ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC);
+ if (wlmsg == NULL)
+ return -ENOMEM;
+
+ wds_peer_msg = &wlmsg->msg.wdspeermsg;
+
+ wds_peer_msg->pdev_id = ar->pdev->pdev_id;
+ wds_peer_msg->ast_type = type;
+ wds_peer_msg->peer_id = peer->peer_id;
+
+ if (type == ATH11K_AST_TYPE_MEC)
+ ether_addr_copy(wds_peer_msg->peer_mac, ar->mac_addr);
+ else
+ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr);
+
+ ether_addr_copy(wds_peer_msg->dest_mac, dest_mac);
+
+ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive;
+
+ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num,
+ NSS_WIFILI_WDS_PEER_ADD_MSG,
+ sizeof(struct nss_wifili_wds_peer_msg),
+ msg_cb, NULL);
+
+ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg);
+ if (status != NSS_TX_SUCCESS) {
+ ret = -EINVAL;
+ ath11k_warn(ab, "nss send wds add peer msg tx error: %d\n",
+ status);
+ goto msg_free;
+ }
+
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,
+ "nss add wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n",
+ wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id);
+
+msg_free:
+ kfree(wlmsg);
+ return ret;
+}
+
+int ath11k_nss_update_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct nss_wifili_wds_peer_msg *wds_peer_msg;
+ struct nss_wifili_msg *wlmsg = NULL;
+ nss_wifili_msg_callback_t msg_cb;
+ nss_tx_status_t status;
+ int ret = 0;
+
+ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC);
+ if (wlmsg == NULL)
+ return -ENOMEM;
+
+ wds_peer_msg = &wlmsg->msg.wdspeermsg;
+
+ wds_peer_msg->pdev_id = ar->pdev->pdev_id;
+ wds_peer_msg->ast_type = ATH11K_AST_TYPE_WDS;
+ wds_peer_msg->peer_id = peer->peer_id;
+ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr);
+ ether_addr_copy(wds_peer_msg->dest_mac, dest_mac);
+
+ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive;
+
+ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num,
+ NSS_WIFILI_WDS_PEER_UPDATE_MSG,
+ sizeof(struct nss_wifili_wds_peer_msg),
+ msg_cb, NULL);
+
+ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg);
+ if (status != NSS_TX_SUCCESS) {
+ ret = -EINVAL;
+ ath11k_warn(ab, "nss send wds update peer msg tx error: %d\n",
+ status);
+ goto msg_free;
+ }
+
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,
+ "nss update wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n",
+ wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id);
+
+msg_free:
+ kfree(wlmsg);
+ return ret;
+}
+
+int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac, enum ath11k_ast_entry_type type)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct nss_wifili_wds_peer_map_msg *wds_peer_map_msg;
+ struct nss_wifili_msg *wlmsg = NULL;
+ nss_wifili_msg_callback_t msg_cb;
+ nss_tx_status_t status;
+ int ret = 0;
+
+ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC);
+ if (wlmsg == NULL)
+ return -ENOMEM;
+
+ wds_peer_map_msg = &wlmsg->msg.wdspeermapmsg;
+
+ wds_peer_map_msg->vdev_id = peer->vdev_id;
+ wds_peer_map_msg->ast_idx = peer->hw_peer_id;
+
+ if (type == ATH11K_AST_TYPE_MEC)
+ wds_peer_map_msg->peer_id = NSS_WIFILI_MEC_PEER_ID;
+ else
+ wds_peer_map_msg->peer_id = peer->peer_id;
+
+ ether_addr_copy(wds_peer_map_msg->dest_mac, dest_mac);
+
+ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive;
+
+ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num,
+ NSS_WIFILI_WDS_PEER_MAP_MSG,
+ sizeof(struct nss_wifili_wds_peer_map_msg),
+ msg_cb, NULL);
+
+ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg);
+ if (status != NSS_TX_SUCCESS) {
+ ret = -EINVAL;
+ ath11k_warn(ab, "nss send wds peer map msg tx error: %d\n",
+ status);
+ goto msg_free;
+ }
+
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,
+ "nss wds peer map success mac:%pM hw_ast_idx:%d peer_id:%d\n",
+ wds_peer_map_msg->dest_mac, wds_peer_map_msg->ast_idx, wds_peer_map_msg->peer_id);
+
+msg_free:
+ kfree(wlmsg);
+ return ret;
+}
+
+int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct nss_wifili_wds_peer_msg *wds_peer_msg;
+ struct nss_wifili_msg *wlmsg = NULL;
+ nss_wifili_msg_callback_t msg_cb;
+ nss_tx_status_t status;
+ int ret = 0;
+
+ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC);
+ if (wlmsg == NULL)
+ return -ENOMEM;
+
+ wds_peer_msg = &wlmsg->msg.wdspeermsg;
+
+ wds_peer_msg->pdev_id = ar->pdev->pdev_id;
+ wds_peer_msg->ast_type = ATH11K_AST_TYPE_NONE;
+ wds_peer_msg->peer_id = peer->peer_id;
+ ether_addr_copy(wds_peer_msg->peer_mac, peer->addr);
+ ether_addr_copy(wds_peer_msg->dest_mac, dest_mac);
+
+ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive;
+
+ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num,
+ NSS_WIFILI_WDS_PEER_DEL_MSG,
+ sizeof(struct nss_wifili_wds_peer_msg),
+ msg_cb, NULL);
+
+ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg);
+ if (status != NSS_TX_SUCCESS) {
+ ret = -EINVAL;
+ ath11k_warn(ab, "nss send wds del peer msg tx error: %d\n",
+ status);
+ goto msg_free;
+ }
+
+ ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,
+ "nss del wds peer success peer mac:%pM dest mac:%pM peer_id:%d\n",
+ wds_peer_msg->peer_mac, wds_peer_msg->dest_mac, wds_peer_msg->peer_id);
+
+msg_free:
+ kfree(wlmsg);
+ return ret;
+}
+
/*-------------------------------INIT/DEINIT---------------------------------*/
static int ath11k_nss_radio_buf_cfg(struct ath11k *ar, int range, int buf_sz)
@@ -1890,7 +2316,7 @@ static int ath11k_nss_init(struct ath11k
status = nss_wifili_tx_msg(nss_contex, wlmsg);
if (status != NSS_TX_SUCCESS) {
- ath11k_warn(ab, "failure to send nss init msg\n");
+ ath11k_warn(ab, "failure to send nss init msg: %d \n", status);
goto unregister;
}
@@ -1944,7 +2370,8 @@ static int ath11k_nss_stats_cfg(struct a
status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg);
if (status != NSS_TX_SUCCESS) {
- ath11k_warn(ab, "nss stats cfg %d msg tx failure\n", nss_msg);
+ ath11k_warn(ab, "nss stats cfg %d msg tx failure: %d\n",
+ nss_msg, status);
ret = -EINVAL;
goto free;
}
--- a/drivers/net/wireless/ath/ath11k/nss.h
+++ b/drivers/net/wireless/ath/ath11k/nss.h
@@ -17,12 +17,14 @@ struct ath11k_base;
struct ath11k_vif;
struct ath11k_peer;
struct ath11k_sta;
+enum ath11k_ast_entry_type;
struct hal_rx_mon_ppdu_info;
struct hal_rx_user_status;
/* NSS DBG macro is not included as part of debug enum to avoid
* frequent changes during upgrade*/
-#define ATH11K_DBG_NSS 0x80000000
+#define ATH11K_DBG_NSS 0x40000000
+#define ATH11K_DBG_NSS_WDS 0x80000000
/* WIFILI Supported Target Types */
#define ATH11K_WIFILI_TARGET_TYPE_UNKNOWN 0xFF
@@ -205,11 +207,19 @@ int ath11k_nss_vdev_create(struct ath11k
void ath11k_nss_vdev_delete(struct ath11k_vif *arvif);
int ath11k_nss_vdev_up(struct ath11k_vif *arvif);
int ath11k_nss_vdev_down(struct ath11k_vif *arvif);
-int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr);
+int ath11k_nss_peer_delete(struct ath11k_base *ab, u32 vdev_id, const u8 *addr);
int ath11k_nss_set_peer_authorize(struct ath11k *ar, u16 peer_id);
-int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer);
+int ath11k_nss_peer_create(struct ath11k *ar, struct ath11k_peer *peer);
void ath11k_nss_peer_stats_enable(struct ath11k *ar);
void ath11k_nss_peer_stats_disable(struct ath11k *ar);
+int ath11k_nss_add_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac, enum ath11k_ast_entry_type type);
+int ath11k_nss_update_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac);
+int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac, enum ath11k_ast_entry_type type);
+int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac);
int ath11k_nss_set_peer_sec_type(struct ath11k *ar, struct ath11k_peer *peer,
struct ieee80211_key_conf *key_conf);
void ath11k_nss_update_sta_stats(struct station_info *sinfo,
@@ -271,12 +281,37 @@ static inline int ath11k_nss_vdev_down(s
return 0;
}
-static inline int ath11k_nss_peer_delete(struct ath11k_base *ab, const u8 *addr)
+static inline int ath11k_nss_peer_delete(struct ath11k_base *ab, u32 vdev_id,
+ const u8 *addr)
{
return 0;
}
-static inline int ath11k_nss_peer_create(struct ath11k_base *ab, struct ath11k_peer *peer)
+static inline int ath11k_nss_add_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac, int type)
+{
+ return 0;
+}
+
+static inline int ath11k_nss_update_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac)
+{
+ return 0;
+}
+
+static inline int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer,
+ u8 *dest_mac, int type)
+{
+ return 0;
+}
+
+static inline int ath11k_nss_del_wds_peer(struct ath11k_vif *arvif, struct ath11k_peer *peer,
+ u8 *dest_mac)
+{
+ return 0;
+}
+
+static inline int ath11k_nss_peer_create(struct ath11k *ar, struct ath11k_peer *peer)
{
return 0;
}