From: Jérôme Pouiller <jerome.pouil...@silabs.com>

Signed-off-by: Jérôme Pouiller <jerome.pouil...@silabs.com>
---
 drivers/net/wireless/silabs/wfx/data_rx.c | 93 +++++++++++++++++++++++
 drivers/net/wireless/silabs/wfx/data_rx.h | 18 +++++
 2 files changed, 111 insertions(+)
 create mode 100644 drivers/net/wireless/silabs/wfx/data_rx.c
 create mode 100644 drivers/net/wireless/silabs/wfx/data_rx.h

diff --git a/drivers/net/wireless/silabs/wfx/data_rx.c 
b/drivers/net/wireless/silabs/wfx/data_rx.c
new file mode 100644
index 000000000000..385f2d42a0e2
--- /dev/null
+++ b/drivers/net/wireless/silabs/wfx/data_rx.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Datapath implementation.
+ *
+ * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+
+#include "data_rx.h"
+#include "wfx.h"
+#include "bh.h"
+#include "sta.h"
+
+static void wfx_rx_handle_ba(struct wfx_vif *wvif, struct ieee80211_mgmt *mgmt)
+{
+       int params, tid;
+
+       if (wfx_api_older_than(wvif->wdev, 3, 6))
+               return;
+
+       switch (mgmt->u.action.u.addba_req.action_code) {
+       case WLAN_ACTION_ADDBA_REQ:
+               params = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+               tid = (params & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
+               ieee80211_start_rx_ba_session_offl(wvif->vif, mgmt->sa, tid);
+               break;
+       case WLAN_ACTION_DELBA:
+               params = le16_to_cpu(mgmt->u.action.u.delba.params);
+               tid = (params &  IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
+               ieee80211_stop_rx_ba_session_offl(wvif->vif, mgmt->sa, tid);
+               break;
+       }
+}
+
+void wfx_rx_cb(struct wfx_vif *wvif,
+              const struct hif_ind_rx *arg, struct sk_buff *skb)
+{
+       struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb);
+       struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+
+       memset(hdr, 0, sizeof(*hdr));
+
+       if (arg->status == HIF_STATUS_RX_FAIL_MIC)
+               hdr->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_IV_STRIPPED;
+       else if (arg->status)
+               goto drop;
+
+       if (skb->len < sizeof(struct ieee80211_pspoll)) {
+               dev_warn(wvif->wdev->dev, "malformed SDU received\n");
+               goto drop;
+       }
+
+       hdr->band = NL80211_BAND_2GHZ;
+       hdr->freq = ieee80211_channel_to_frequency(arg->channel_number,
+                                                  hdr->band);
+
+       if (arg->rxed_rate >= 14) {
+               hdr->encoding = RX_ENC_HT;
+               hdr->rate_idx = arg->rxed_rate - 14;
+       } else if (arg->rxed_rate >= 4) {
+               hdr->rate_idx = arg->rxed_rate - 2;
+       } else {
+               hdr->rate_idx = arg->rxed_rate;
+       }
+
+       if (!arg->rcpi_rssi) {
+               hdr->flag |= RX_FLAG_NO_SIGNAL_VAL;
+               dev_info(wvif->wdev->dev, "received frame without RSSI data\n");
+       }
+       hdr->signal = arg->rcpi_rssi / 2 - 110;
+       hdr->antenna = 0;
+
+       if (arg->encryp)
+               hdr->flag |= RX_FLAG_DECRYPTED;
+
+       // Block ack negotiation is offloaded by the firmware. However,
+       // re-ordering must be done by the mac80211.
+       if (ieee80211_is_action(frame->frame_control) &&
+           mgmt->u.action.category == WLAN_CATEGORY_BACK &&
+           skb->len > IEEE80211_MIN_ACTION_SIZE) {
+               wfx_rx_handle_ba(wvif, mgmt);
+               goto drop;
+       }
+
+       ieee80211_rx_irqsafe(wvif->wdev->hw, skb);
+       return;
+
+drop:
+       dev_kfree_skb(skb);
+}
diff --git a/drivers/net/wireless/silabs/wfx/data_rx.h 
b/drivers/net/wireless/silabs/wfx/data_rx.h
new file mode 100644
index 000000000000..4c0da37f2084
--- /dev/null
+++ b/drivers/net/wireless/silabs/wfx/data_rx.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Datapath implementation.
+ *
+ * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#ifndef WFX_DATA_RX_H
+#define WFX_DATA_RX_H
+
+struct wfx_vif;
+struct sk_buff;
+struct hif_ind_rx;
+
+void wfx_rx_cb(struct wfx_vif *wvif,
+              const struct hif_ind_rx *arg, struct sk_buff *skb);
+
+#endif /* WFX_DATA_RX_H */
-- 
2.28.0

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to