From patchwork Thu Apr 17 13:52:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882275 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8306C24EAA0 for ; Thu, 17 Apr 2025 13:52:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744897977; cv=none; b=c3ry3APXiLiNwLYDJpgzEFlm5jmOZNHC7vQCkuO0C+9ln2gEKf88Cv5dKHRnxsaU/XCv7y4CHM74prfFGGToRe6zfO9FsCKQcM/9wGZfxf6gy3FxGMyT9oJKPM225G686F53n/+OgRUMa6ctTOTiisq323e/gKEry0Za25DpfTU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744897977; c=relaxed/simple; bh=pDYvL20GbbhHQPz4Z0NeeVhtoq8nKSHSUt1jkOx+ieY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=U8wl+/bFrpu+ZOvXlphuYAQXpbZ3h8QHSagmGQqHboIY34ny94BNfL/T6N316UMRpr9RonOs7bQADOsHrHto/cW+RFJqMf22v2IpM7Vbr6j/dBS5zsdsRV3rszvozaLp3RNamUZ7NVIJAEWSv8hLchKfIoMVb1mQClxbPyi20WU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: /dW/BvinTO6GufxkkztNbA== X-CSE-MsgGUID: 8npkbcg3SnyEiUw827lyoA== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 17 Apr 2025 22:52:52 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 16DB04006DE8; Thu, 17 Apr 2025 22:52:48 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 02/38] renesas: add Kconfig Date: Thu, 17 Apr 2025 16:52:00 +0300 Message-Id: <20250417135236.52410-3-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/Kconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 drivers/net/wireless/renesas/Kconfig diff --git a/drivers/net/wireless/renesas/Kconfig b/drivers/net/wireless/renesas/Kconfig new file mode 100644 index 000000000000..9607b36b3d8c --- /dev/null +++ b/drivers/net/wireless/renesas/Kconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only +config WLAN_VENDOR_RENESAS + bool "Renesas devices" + default y + help + If you have a wireless card belonging to this class, say Y. + +if WLAN_VENDOR_RENESAS + +source "drivers/net/wireless/renesas/ra6w/Kconfig" + +endif # WLAN_VENDOR_RENESAS From patchwork Thu Apr 17 13:52:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882274 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A4F8224EAB6 for ; Thu, 17 Apr 2025 13:53:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744897989; cv=none; b=tRs196urj2Dv82FQBXegxajzk/rSqS/06z647xtVYL/VlpVibEcAlfBpNFdQDTYSzaXgp/OP0XbwlinTdKvzWMBA1hSqhfSQce+P51g4oDhPCwRrA7V6454pnNy6jsBM+8SusxEoy2LMk7Xyov5DNcAXrmegvyN6yj7QdOD7luw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744897989; c=relaxed/simple; bh=K3hbmSn2IEDrGLVS2GRWOhf3+NthrsVcfb1MyA7W6Rc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=n0I4bYSBsJUdslBb3d8hNRAKKVVqqkW+zj0I9eV5UR1DESF7Gx1a2OVabnJPiGohpVyfVbWLkpd67NfkmoN3ZBmodvKml1rTv4eFZsHS6QNdPfBLJi0XDN4Z9VZA7hp8HJ4Uj5HevZsGH0HG9AAzWQNsYRajq3MPP3Udg8cGA1Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: E2WY/yqhTPKLgbO9DKXgZw== X-CSE-MsgGUID: jwSxsgL6Tcu7MLCaKX5jyA== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 17 Apr 2025 22:53:03 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 6D42B4006DE8; Thu, 17 Apr 2025 22:52:57 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 04/38] ra6w: add cfg80211.c Date: Thu, 17 Apr 2025 16:52:02 +0300 Message-Id: <20250417135236.52410-5-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/cfg80211.c | 2519 ++++++++++++++++++ 1 file changed, 2519 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/cfg80211.c diff --git a/drivers/net/wireless/renesas/ra6w/cfg80211.c b/drivers/net/wireless/renesas/ra6w/cfg80211.c new file mode 100644 index 000000000000..bbe035751bf1 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/cfg80211.c @@ -0,0 +1,2519 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * This file contains communication with cfg80211 module. + * + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dbg.h" +#include "core.h" +#include "ctrl.h" +#include "cfg80211.h" +#include "dev.h" +#include "dbgfs.h" +#include "testmode.h" +#include "params.h" + +#define RATE(_bitrate, _hw_rate, _flags) { \ + .bitrate = (_bitrate), \ + .flags = (_flags), \ + .hw_value = (_hw_rate), \ +} + +#define CHAN(_band, _channel, _freq) { \ + .band = (_band), \ + .hw_value = (_channel), \ + .center_freq = (_freq), \ + .flags = 0, \ + .max_antenna_gain = 0, \ + .max_power = RA6W_CFG80211_CH_MAX_POWER, \ +} + +static const u8 ra6w_ac2hwq[IEEE80211_NUM_ACS] = { + [NL80211_TXQ_Q_VO] = RA6W_CMD_AC_VO, + [NL80211_TXQ_Q_VI] = RA6W_CMD_AC_VI, + [NL80211_TXQ_Q_BE] = RA6W_CMD_AC_BE, + [NL80211_TXQ_Q_BK] = RA6W_CMD_AC_BK +}; + +static struct ieee80211_iface_limit ra6w_if_limits[] = { + { + .max = RA6W_CFG80211_VIF_MAX, + .types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION) + } +}; + +static const struct ieee80211_iface_combination ra6w_if_comb[] = { + { + .limits = ra6w_if_limits, + .n_limits = ARRAY_SIZE(ra6w_if_limits), + .num_different_channels = RA6W_CFG80211_CHANINFO_MAX, + .max_interfaces = RA6W_CFG80211_VIF_MAX, + }, +}; + +static struct ieee80211_txrx_stypes ra6w_macm_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_P2P_GO] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_P2P_DEVICE] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, +}; + +static u32 ra6w_cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, + 0, + 0, + 0, + 0, + 0 +}; + +static struct ieee80211_rate ra6w_rate_table[] = { + RATE(10, 0x00, 0), + RATE(20, 0x01, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(55, 0x02, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(110, 0x03, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(60, 0x04, 0), + RATE(90, 0x05, 0), + RATE(120, 0x06, 0), + RATE(180, 0x07, 0), + RATE(240, 0x08, 0), + RATE(360, 0x09, 0), + RATE(480, 0x0A, 0), + RATE(540, 0x0B, 0), +}; + +static struct ieee80211_channel ra6w_chans_2g[] = { + CHAN(NL80211_BAND_2GHZ, 1, 2412), + CHAN(NL80211_BAND_2GHZ, 2, 2417), + CHAN(NL80211_BAND_2GHZ, 3, 2422), + CHAN(NL80211_BAND_2GHZ, 4, 2427), + CHAN(NL80211_BAND_2GHZ, 5, 2432), + CHAN(NL80211_BAND_2GHZ, 6, 2437), + CHAN(NL80211_BAND_2GHZ, 7, 2442), + CHAN(NL80211_BAND_2GHZ, 8, 2447), + CHAN(NL80211_BAND_2GHZ, 9, 2452), + CHAN(NL80211_BAND_2GHZ, 10, 2457), + CHAN(NL80211_BAND_2GHZ, 11, 2462), + CHAN(NL80211_BAND_2GHZ, 12, 2467), + CHAN(NL80211_BAND_2GHZ, 13, 2472), + CHAN(NL80211_BAND_2GHZ, 14, 2484), +}; + +static struct ieee80211_channel ra6w_chans_5g[] = { + CHAN(NL80211_BAND_5GHZ, 36, 5180), + CHAN(NL80211_BAND_5GHZ, 40, 5200), + CHAN(NL80211_BAND_5GHZ, 44, 5220), + CHAN(NL80211_BAND_5GHZ, 48, 5240), + CHAN(NL80211_BAND_5GHZ, 52, 5260), + CHAN(NL80211_BAND_5GHZ, 56, 5280), + CHAN(NL80211_BAND_5GHZ, 60, 5300), + CHAN(NL80211_BAND_5GHZ, 64, 5320), + CHAN(NL80211_BAND_5GHZ, 100, 5500), + CHAN(NL80211_BAND_5GHZ, 104, 5520), + CHAN(NL80211_BAND_5GHZ, 108, 5540), + CHAN(NL80211_BAND_5GHZ, 112, 5560), + CHAN(NL80211_BAND_5GHZ, 116, 5580), + CHAN(NL80211_BAND_5GHZ, 120, 5600), + CHAN(NL80211_BAND_5GHZ, 124, 5620), + CHAN(NL80211_BAND_5GHZ, 128, 5640), + CHAN(NL80211_BAND_5GHZ, 132, 5660), + CHAN(NL80211_BAND_5GHZ, 136, 5680), + CHAN(NL80211_BAND_5GHZ, 140, 5700), + CHAN(NL80211_BAND_5GHZ, 144, 5720), + CHAN(NL80211_BAND_5GHZ, 149, 5745), + CHAN(NL80211_BAND_5GHZ, 153, 5765), + CHAN(NL80211_BAND_5GHZ, 157, 5785), + CHAN(NL80211_BAND_5GHZ, 161, 5805), + CHAN(NL80211_BAND_5GHZ, 165, 5825), + CHAN(NL80211_BAND_5GHZ, 169, 5845), + CHAN(NL80211_BAND_5GHZ, 173, 5865), +}; + +static struct ieee80211_sband_iftype_data ra6w_cap_he_2g = { + .types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP), +}; + +static struct ieee80211_sband_iftype_data ra6w_cap_he_5g = { + .types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP), +}; + +static struct ieee80211_supported_band ra6w_band_2g = { + .channels = ra6w_chans_2g, + .n_channels = ARRAY_SIZE(ra6w_chans_2g), + .bitrates = ra6w_rate_table, + .n_bitrates = ARRAY_SIZE(ra6w_rate_table), + .n_iftype_data = 1, + .band = NL80211_BAND_2GHZ, +}; + +static struct ieee80211_supported_band ra6w_band_5g = { + .channels = ra6w_chans_5g, + .n_channels = ARRAY_SIZE(ra6w_chans_5g), + .bitrates = &ra6w_rate_table[4], + .n_bitrates = ARRAY_SIZE(ra6w_rate_table) - 4, + .n_iftype_data = 1, + .band = NL80211_BAND_5GHZ, +}; + +static const struct ra6w_cfg80211_legrate ra6w_legacy_rate_table[] = { + [0] = { .idx = 0, .rate = 10 }, + [1] = { .idx = 1, .rate = 20 }, + [2] = { .idx = 2, .rate = 55 }, + [3] = { .idx = 3, .rate = 110 }, + [4] = { .idx = -1, .rate = 0 }, + [5] = { .idx = -1, .rate = 0 }, + [6] = { .idx = -1, .rate = 0 }, + [7] = { .idx = -1, .rate = 0 }, + [8] = { .idx = 10, .rate = 480 }, + [9] = { .idx = 8, .rate = 240 }, + [10] = { .idx = 6, .rate = 120 }, + [11] = { .idx = 4, .rate = 60 }, + [12] = { .idx = 11, .rate = 540 }, + [13] = { .idx = 9, .rate = 360 }, + [14] = { .idx = 7, .rate = 180 }, + [15] = { .idx = 5, .rate = 90 }, +}; + +static const int ra6w_mcs_map_to_rate[] = { + [IEEE80211_VHT_MCS_SUPPORT_0_7] = 65, + [IEEE80211_VHT_MCS_SUPPORT_0_8] = 78, + [IEEE80211_VHT_MCS_SUPPORT_0_9] = 78, +}; + +static void ra6w_cfg80211_dev_init(struct net_device *ndev) +{ + ra6w_dev_init(ndev); +} + +static void ra6w_cfg80211_reg_notifier(struct wiphy *wiphy, struct regulatory_request *req) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + + ra6w_dbg("[%s] initiator=%d, alpha=%c%c\n", __func__, + req->initiator, req->alpha2[0], req->alpha2[1]); + + memcpy(priv->phy_config.country_code, req->alpha2, sizeof(req->alpha2)); + + ra6w_ctrl_chan_config(&priv->core->ctrl, wiphy); +} + +u8 *ra6w_cfg80211_create_beacon(struct ra6w_cfg80211_beacon_info *bcn, + struct cfg80211_beacon_data *new) +{ + u8 *buf = NULL; + u8 *pos = NULL; + + if (new->head) { + u8 *head = kzalloc(new->head_len, GFP_KERNEL); + + if (!head) + return NULL; + + kfree(bcn->head); + + bcn->head = head; + bcn->head_len = new->head_len; + memcpy(bcn->head, new->head, new->head_len); + } + + if (new->tail) { + u8 *tail = kzalloc(new->tail_len, GFP_KERNEL); + + if (!tail) + return NULL; + + kfree(bcn->tail); + + bcn->tail = tail; + bcn->tail_len = new->tail_len; + memcpy(bcn->tail, new->tail, new->tail_len); + } + + if (!bcn->head) + return NULL; + + bcn->tim_len = 6; + bcn->len = bcn->head_len + bcn->tail_len + bcn->ies_len + bcn->tim_len; + + buf = kzalloc(bcn->len, GFP_KERNEL); + if (!buf) + return NULL; + + pos = buf; + memcpy(pos, bcn->head, bcn->head_len); + pos += bcn->head_len; + *pos++ = WLAN_EID_TIM; + *pos++ = 4; + *pos++ = 0; + *pos++ = bcn->dtim_period; + *pos++ = 0; + *pos++ = 0; + if (bcn->tail) { + memcpy(pos, bcn->tail, bcn->tail_len); + pos += bcn->tail_len; + } + + if (bcn->ies) + memcpy(pos, bcn->ies, bcn->ies_len); + + return buf; +} + +static void ra6w_cfg80211_remove_beacon(struct ra6w_cfg80211_beacon_info *bcn) +{ + kfree(bcn->head); + bcn->head = NULL; + bcn->head_len = 0; + + kfree(bcn->tail); + bcn->tail = NULL; + bcn->tail_len = 0; + + kfree(bcn->ies); + bcn->ies = NULL; + bcn->ies_len = 0; + bcn->tim_len = 0; + bcn->dtim_period = 0; + bcn->len = 0; +} + +static void ra6w_cfg80211_csa_remove(struct ra6w_cfg80211_vif *vif) +{ + struct ra6w_cfg80211_csa_info *csa = vif->ap.csa; + + if (!csa) + return; + + ra6w_cfg80211_remove_beacon(&csa->bcn); + kfree(csa); + vif->ap.csa = NULL; +} + +struct ra6w_cfg80211_chan_info *ra6w_cfg80211_chaninfo_get(struct ra6w_cfg80211_vif *vif) +{ + struct ra6w_cfg80211_priv *priv; + + if (!vif) + return NULL; + + priv = vif->priv; + if (!priv) + return NULL; + + if (vif->ch_idx >= RA6W_CFG80211_CHANINFO_MAX || + !priv->chaninfo_table[vif->ch_idx].chan_def.chan) + return NULL; + + return &priv->chaninfo_table[vif->ch_idx]; +} + +static void ra6w_cfg80211_csa_work(struct work_struct *ws) +{ + struct ra6w_cfg80211_csa_info *csa = container_of(ws, struct ra6w_cfg80211_csa_info, + work); + struct ra6w_cfg80211_vif *vif = csa->vif; + struct ra6w_cfg80211_priv *priv = vif->priv; + + if (!priv) + goto out; + + if (csa->status) { + cfg80211_stop_iface(priv->wiphy, &vif->wdev, GFP_KERNEL); + goto out; + } + + ra6w_ctrl_change_beacon_req(&priv->core->ctrl, vif->vif_idx, + csa->buf, + csa->bcn.len, csa->bcn.head_len, + csa->bcn.tim_len, NULL); + + wiphy_lock(priv->wiphy); + ra6w_cfg80211_chaninfo_unset(vif); + ra6w_cfg80211_chaninfo_set(vif, csa->ch_idx, &csa->chandef); + cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0); + wiphy_unlock(priv->wiphy); + +out: + ra6w_cfg80211_csa_remove(vif); +} + +static int ra6w_cfg80211_station_info_fill(struct ra6w_cfg80211_sta *sta, + struct station_info *sinfo, + struct ra6w_cfg80211_vif *vif) +{ + const struct ra6w_cfg80211_sta_stats *stats = &sta->stats; + u16 format_mod = 0; + + sinfo->generation = vif->generation; + sinfo->inactive_time = jiffies_to_msecs(jiffies - stats->last_acttive_time); + sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); + sinfo->rx_bytes = sta->stats.rx_bytes; + sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES64); + sinfo->rx_packets = sta->stats.rx_packets; + sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS); + sinfo->tx_bytes = sta->stats.tx_bytes; + sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES64); + sinfo->tx_packets = sta->stats.tx_packets; + sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); + sinfo->tx_failed = sta->stats.tx_failed; + sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); + sinfo->signal = stats->last_rx_data_ext.rssi1; + sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); + + switch (stats->last_rx_data_ext.ch_bw) { + case 0: + sinfo->rxrate.bw = RATE_INFO_BW_20; + break; + case 1: + sinfo->rxrate.bw = RATE_INFO_BW_40; + break; + case 2: + sinfo->rxrate.bw = RATE_INFO_BW_80; + break; + case 3: + sinfo->rxrate.bw = RATE_INFO_BW_160; + break; + default: + sinfo->rxrate.bw = RATE_INFO_BW_HE_RU; + break; + } + + if (stats->last_rx_data_ext.pre_type) + format_mod = stats->last_rx_data_ext.format_mod + 1; + else + format_mod = stats->last_rx_data_ext.format_mod; + + if (stats->last_stats.format_mod > 1 && format_mod < 2) + format_mod = stats->last_stats.format_mod; + + switch (format_mod) { + case RA6W_CFG80211_FORMATMOD_NON_HT: + case RA6W_CFG80211_FORMATMOD_NON_HT_DUP_OFDM: + sinfo->rxrate.flags = 0; + sinfo->rxrate.legacy = + ra6w_legacy_rate_table[stats->last_rx_data_ext.leg_rate].rate; + break; + case RA6W_CFG80211_FORMATMOD_HT_MF: + case RA6W_CFG80211_FORMATMOD_HT_GF: + sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS; + if (stats->last_stats.ht.short_gi) + sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + sinfo->rxrate.mcs = stats->last_stats.ht.mcs; + break; + case RA6W_CFG80211_FORMATMOD_VHT: + sinfo->rxrate.flags = RATE_INFO_FLAGS_VHT_MCS; + if (stats->last_stats.vht.short_gi) + sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + sinfo->rxrate.mcs = stats->last_stats.vht.mcs; + sinfo->rxrate.nss = stats->last_stats.vht.nss + 1; + break; + case RA6W_CFG80211_FORMATMOD_HE_MU: + sinfo->rxrate.he_ru_alloc = stats->last_stats.he.ru_size; + fallthrough; + case RA6W_CFG80211_FORMATMOD_HE_SU: + case RA6W_CFG80211_FORMATMOD_HE_ER: + case RA6W_CFG80211_FORMATMOD_HE_TB: + sinfo->rxrate.flags = RATE_INFO_FLAGS_HE_MCS; + sinfo->rxrate.mcs = stats->last_stats.he.mcs; + sinfo->rxrate.nss = stats->last_stats.he.nss; + sinfo->rxrate.he_gi = stats->last_stats.he.gi_type; + sinfo->rxrate.he_dcm = stats->last_stats.he.dcm; + break; + default: + return -EINVAL; + } + + sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE); + + return 0; +} + +struct ra6w_cfg80211_sta *ra6w_cfg80211_sta_get(struct ra6w_cfg80211_priv *priv, u8 sta_idx) +{ + if (!priv) + return NULL; + + if (sta_idx >= RA6W_CFG80211_STA_TABLE_MAX) + return NULL; + + return &priv->sta_table[sta_idx]; +} + +void ra6w_cfg80211_sta_free(struct ra6w_cfg80211_vif *vif, u8 sta_idx) +{ + struct ra6w_cfg80211_priv *priv = vif->priv; + struct ra6w_cfg80211_sta *sta = NULL; + + if (!priv) + return; + + sta = ra6w_cfg80211_sta_get(priv, sta_idx); + if (!sta) + return; + + switch (vif->type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + list_del(&sta->list); + break; + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + vif->sta.ap = NULL; + default: + break; + } + + sta->valid = false; + sta->aid = RA6W_CFG80211_STA_IDX_INVALID; + sta->sta_idx = RA6W_CFG80211_STA_IDX_INVALID; + sta->vif_idx = RA6W_CFG80211_VIF_IDX_INVALID; + memset(sta->mac_addr, 0, ETH_ALEN); +} + +static struct ra6w_cfg80211_sta *ra6w_cfg80211_find_sta(struct ra6w_cfg80211_priv *priv, + const u8 *mac_addr) +{ + struct ra6w_cfg80211_sta *sta = NULL; + u8 i; + + for (i = 0; i < RA6W_CFG80211_STA_MAX; i++) { + sta = ra6w_cfg80211_sta_get(priv, i); + if (!sta) + continue; + + if (sta->valid && ether_addr_equal(sta->mac_addr, mac_addr)) + return sta; + } + + return NULL; +} + +static int _ra6w_cfg80211_del_station(struct ra6w_cfg80211_vif *vif, const u8 *mac) +{ + struct ra6w_cfg80211_priv *priv = vif->priv; + struct ra6w_ctrl *ctrl = &priv->core->ctrl; + struct ra6w_cfg80211_sta *sta = NULL; + struct ra6w_cfg80211_sta *tmp = NULL; + int ret = 0; + bool all_sta = false; + + if (!mac || is_broadcast_ether_addr(mac)) + all_sta = true; + + list_for_each_entry_safe(sta, tmp, &vif->ap.sta_list, list) { + if (all_sta || (mac && ether_addr_equal(sta->mac_addr, mac))) { + u8 sta_idx = sta->sta_idx; + + ra6w_cfg80211_sta_free(vif, sta_idx); + + ret = ra6w_ctrl_del_station_req(ctrl, sta_idx, false); + if (ret) + return ret; + + vif->generation++; + + if (!all_sta) + break; + } + } + + return 0; +} + +static int ra6w_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, + struct station_del_parameters *params) +{ + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + const u8 *mac = NULL; + + if (!vif->up) + return -EIO; + + if (params) + mac = params->mac; + + return _ra6w_cfg80211_del_station(vif, mac); +} + +static int ra6w_cfg80211_vif_assign(struct ra6w_cfg80211_priv *priv, enum nl80211_iftype type, + u8 *vif_idx, u8 *addr_idx) +{ + struct ra6w_cmd_add_if_rsp rsp = { 0 }; + int ret; + bool p2p = false; + unsigned long n; + + switch (type) { + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: + p2p = true; + break; + default: + break; + } + + n = find_first_zero_bit(priv->addr_map, RA6W_CFG80211_VIF_MAX); + if (n >= RA6W_CFG80211_VIF_MAX) + return -EIO; + + ret = ra6w_ctrl_if_add(&priv->core->ctrl, priv->addresses[n].addr, (u8)type, p2p, &rsp); + if (ret) + return ret; + + *addr_idx = (u8)n; + *vif_idx = rsp.vif_idx; + + return 0; +} + +static void ra6w_cfg80211_vif_unassign(struct ra6w_cfg80211_priv *priv, u8 vif_idx, u8 addr_idx) +{ + struct ra6w_cfg80211_vif *vif = ra6w_cfg80211_vif_get(priv, vif_idx); + + if (!vif) + return; + + list_del(&vif->list); + priv->vif_table[vif_idx] = NULL; + clear_bit(addr_idx, priv->addr_map); + clear_bit(vif_idx, priv->vif_map); + + ra6w_ctrl_if_remove(&priv->core->ctrl, vif_idx); +} + +static int ra6w_cfg80211_vif_type_allowed(struct ra6w_cfg80211_priv *priv, + enum nl80211_iftype type) +{ + struct ra6w_cfg80211_vif *vif = NULL; + bool mon_presents = false; + bool data_presents = false; + + switch (type) { + case NL80211_IFTYPE_MONITOR: + mon_presents = true; + break; + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_P2P_DEVICE: + case NL80211_IFTYPE_AP: + data_presents = true; + break; + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_OCB: + case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_UNSPECIFIED: + default: + return -EOPNOTSUPP; + } + + list_for_each_entry(vif, &priv->vifs, list) { + if (vif->type == NL80211_IFTYPE_MONITOR) { + mon_presents = true; + continue; + } + + data_presents = true; + } + + if (mon_presents && data_presents) { + wiphy_err(priv->wiphy, + "Can't enable monitor and data interfaces simultaneosly\n"); + return -EPERM; + } + + return 0; +} + +static struct net_device *ra6w_cfg80211_alloc_ndev(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, + u8 addr_idx, + enum nl80211_iftype type, + struct vif_params *params) +{ + struct ra6w_cfg80211_vif *vif; + struct net_device *ndev; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct sockaddr addr = { 0 }; + int ret; + + ndev = alloc_netdev_mqs(sizeof(*vif), name, name_assign_type, + ra6w_cfg80211_dev_init, + RA6W_CFG80211_NDEV_TXQ, + RA6W_CFG80211_NDEV_RXQ); + if (!ndev) + return ERR_PTR(-ENOMEM); + + vif = netdev_priv(ndev); + ndev->ieee80211_ptr = &vif->wdev; + ndev->ieee80211_ptr->iftype = type; + SET_NETDEV_DEV(ndev, wiphy_dev(wiphy)); + ether_addr_copy(addr.sa_data, priv->addresses[addr_idx].addr); + ret = eth_mac_addr(ndev, &addr); + if (ret) + return ERR_PTR(ret); + + if (params) + ndev->ieee80211_ptr->use_4addr = params->use_4addr; + + return ndev; +} + +static struct wireless_dev *ra6w_cfg80211_add_iface(struct wiphy *wiphy, + const char *name, + unsigned char name_assign_type, + enum nl80211_iftype type, + struct vif_params *params) +{ + int ret = -EFAULT; + struct net_device *ndev = NULL; + struct ra6w_cfg80211_vif *vif = NULL; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + u8 vif_idx = 0; + u8 addr_idx = 0; + + ret = ra6w_cfg80211_vif_type_allowed(priv, type); + if (ret) + return ERR_PTR(ret); + + ret = ra6w_cfg80211_vif_assign(priv, type, &vif_idx, &addr_idx); + if (ret) + return ERR_PTR(ret); + + ndev = ra6w_cfg80211_alloc_ndev(wiphy, name, name_assign_type, addr_idx, type, params); + if (IS_ERR(ndev)) + return ERR_PTR(-ENOMEM); + + vif = netdev_priv(ndev); + vif->wdev.wiphy = priv->wiphy; + vif->priv = priv; + vif->ndev = ndev; + vif->wdev.netdev = ndev; + vif->wdev.iftype = type; + vif->up = false; + vif->ch_idx = RA6W_CFG80211_CH_IDX_INVALID; + vif->generation = 0; + vif->vif_idx = vif_idx; + set_bit(vif_idx, priv->vif_map); + vif->addr_idx = addr_idx; + set_bit(addr_idx, priv->addr_map); + vif->type = type; + + switch (type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + INIT_LIST_HEAD(&vif->ap.sta_list); + memset(&vif->ap.bcn, 0, sizeof(vif->ap.bcn)); + vif->ap.ap_isolate = 0; + break; + case NL80211_IFTYPE_MONITOR: + ndev->type = ARPHRD_IEEE80211_RADIOTAP; + ra6w_dev_set_monitor_ops(ndev); + break; + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_OCB: + case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_MESH_POINT: + ret = -EOPNOTSUPP; + goto vif_unset; + case NL80211_IFTYPE_UNSPECIFIED: + ret = -EINVAL; + goto vif_unset; + default: + break; + } + + if (params) + vif->use_4addr = params->use_4addr; + + priv->vif_table[vif_idx] = vif; + list_add_tail(&vif->list, &priv->vifs); + set_bit(vif_idx, priv->vif_map); + + ret = cfg80211_register_netdevice(ndev); + if (ret) { + ra6w_err("[%s] %s not registered: %d\n", __func__, ndev->name, ret); + goto vif_unset; + } + + return &vif->wdev; + +vif_unset: + ra6w_cfg80211_vif_unassign(priv, vif_idx, addr_idx); + free_netdev(ndev); + + return ERR_PTR(ret); +} + +static void ra6w_cfg80211_vif_cleanup(struct ra6w_cfg80211_vif *vif) +{ + struct net_device *ndev = vif->ndev; + + if (ndev->reg_state == NETREG_REGISTERED) + unregister_netdevice(ndev); + + ndev->ieee80211_ptr = NULL; + vif->ndev = NULL; +} + +static int ra6w_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(wdev->netdev); + + ra6w_cfg80211_vif_cleanup(vif); + ra6w_cfg80211_vif_unassign(priv, vif->vif_idx, vif->addr_idx); + + return 0; +} + +static int ra6w_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, + enum nl80211_iftype type, struct vif_params *params) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + int ret; + u8 vif_idx; + u8 addr_idx; + + if (vif->up) + return -EBUSY; + + ret = ra6w_cfg80211_vif_type_allowed(priv, type); + if (ret) + return ret; + + ra6w_cfg80211_vif_unassign(priv, vif->vif_idx, vif->addr_idx); + + ret = ra6w_cfg80211_vif_assign(priv, type, &vif_idx, &addr_idx); + if (ret) + return ret; + + vif->type = type; + vif->vif_idx = vif_idx; + vif->addr_idx = addr_idx; + set_bit(addr_idx, priv->addr_map); + + priv->vif_table[vif->vif_idx] = vif; + list_add_tail(&vif->list, &priv->vifs); + set_bit(vif_idx, priv->vif_map); + + ndev->type = ARPHRD_ETHER; + ra6w_dev_set_ops(ndev); + + switch (type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + vif->sta.flags = 0; + vif->sta.ap = NULL; + vif->sta.tdls_sta = NULL; + break; + case NL80211_IFTYPE_MESH_POINT: + return -EOPNOTSUPP; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + INIT_LIST_HEAD(&vif->ap.sta_list); + memset(&vif->ap.bcn, 0, sizeof(vif->ap.bcn)); + vif->ap.ap_isolate = 0; + break; + case NL80211_IFTYPE_MONITOR: + ndev->type = ARPHRD_IEEE80211_RADIOTAP; + ra6w_dev_set_monitor_ops(ndev); + break; + default: + break; + } + + vif->generation = 0; + vif->wdev.iftype = type; + + if (params->use_4addr != -1) + vif->use_4addr = params->use_4addr; + + return 0; +} + +static int ra6w_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *req) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = container_of(req->wdev, struct ra6w_cfg80211_vif, wdev); + + if (!vif->up) + return -EIO; + + if (vif->type == NL80211_IFTYPE_AP) + return -EOPNOTSUPP; + + if (priv->scan_request) + return -EAGAIN; + + ret = ra6w_ctrl_scan_start(&priv->core->ctrl, req); + if (ret) + return ret; + + priv->scan_request = req; + + return 0; +} + +static void ra6w_cfg80211_scan_abort(struct wiphy *wiphy, struct wireless_dev *wdev) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = container_of(wdev, struct ra6w_cfg80211_vif, wdev); + + if (!priv->scan_request) + return; + + ra6w_ctrl_scan_cancel(&priv->core->ctrl, vif); +} + +void ra6w_cfg80211_scan_done(struct ra6w_cfg80211_priv *priv) +{ + static struct cfg80211_scan_info scan_req = { + .aborted = true, + }; + + cfg80211_scan_done(priv->scan_request, &scan_req); + priv->scan_request = NULL; +} + +static int ra6w_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + + if (!vif->up) + return -EIO; + + ra6w_stats_deinit(&vif->stats); + + return ra6w_ctrl_disconnect_req(&priv->core->ctrl, vif, reason_code); +} + +struct ra6w_cfg80211_vif *ra6w_cfg80211_vif_get(struct ra6w_cfg80211_priv *priv, u8 vif_idx) +{ + if (!priv) + return NULL; + + if (!test_bit(vif_idx, priv->vif_map)) + return NULL; + + return priv->vif_table[vif_idx]; +} + +static int ra6w_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, + int link_id, u8 key_index, bool pairwise, + const u8 *mac_addr, struct key_params *params) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_sta *sta = NULL; + struct ra6w_cfg80211_key *key = NULL; + struct ra6w_cmd_key_add_rsp rsp = { 0 }; + u8 cipher_type = 0; + u8 *tk; + + if (key_index >= RA6W_CFG80211_KEYS_MAX) { + ra6w_err("Invalid key index\n"); + return -EINVAL; + } + + if (!vif->up) + return -EIO; + + if (mac_addr) { + sta = ra6w_cfg80211_find_sta(priv, mac_addr); + if (!sta) { + ra6w_err("No STA found with MAC address\n"); + return -EINVAL; + } + key = &sta->key; + } else { + key = &vif->keys[key_index]; + } + + tk = kzalloc(params->key_len, GFP_KERNEL); + if (!tk) + return -ENOMEM; + + memcpy(tk, params->key, params->key_len); + + switch (params->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + cipher_type = RA6W_CIPHER_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + cipher_type = RA6W_CIPHER_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + cipher_type = RA6W_CIPHER_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + cipher_type = RA6W_CIPHER_CCMP; + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + cipher_type = RA6W_CIPHER_AES_CMAC_128; + break; + case WLAN_CIPHER_SUITE_SMS4: { + u8 tmp; + int i = 0; + + cipher_type = RA6W_CIPHER_SMS4; + + for (i = 0; i < RA6W_CFG80211_WPI_SUBKEY_LEN / 2; i++) { + tmp = tk[i]; + tk[i] = tk[RA6W_CFG80211_WPI_SUBKEY_LEN - 1 - i]; + tk[RA6W_CFG80211_WPI_SUBKEY_LEN - 1 - i] = tmp; + } + + for (i = 0; i < RA6W_CFG80211_WPI_SUBKEY_LEN / 2; i++) { + tmp = tk[i + RA6W_CFG80211_WPI_SUBKEY_LEN]; + tk[i + RA6W_CFG80211_WPI_SUBKEY_LEN] = + tk[RA6W_CFG80211_WPI_KEY_LEN - 1 - i]; + tk[RA6W_CFG80211_WPI_KEY_LEN - 1 - i] = tmp; + } + break; + } + case WLAN_CIPHER_SUITE_GCMP: + cipher_type = RA6W_CIPHER_GCMP_128; + break; + case WLAN_CIPHER_SUITE_GCMP_256: + cipher_type = RA6W_CIPHER_GCMP_256; + break; + case WLAN_CIPHER_SUITE_CCMP_256: + cipher_type = RA6W_CIPHER_CCMP_256; + break; + default: + ra6w_err("[%s] Unsupported cipher %d\n", __func__, params->cipher); + ret = -EINVAL; + goto free; + } + + key->cipher_type = cipher_type; + key->pairwise = pairwise; + key->sta_idx = sta ? sta->sta_idx : RA6W_CFG80211_STA_IDX_INVALID; + key->vif_idx = vif->vif_idx; + + ret = ra6w_ctrl_add_key_req(&priv->core->ctrl, key, tk, params->key_len, key_index, &rsp); + if (ret) + goto free; + + key->key_index = rsp.hw_key_index; + memcpy(key->key, tk, params->key_len); + key->key_len = params->key_len; + memcpy(key->seq, tk, params->seq_len); + key->seq_len = params->seq_len; + +free: + kfree(tk); + + return ret; +} + +static int ra6w_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, int link_id, + u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params *)) +{ + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_key *key = NULL; + struct key_params params; + + if (!vif->up) + return -EIO; + + if (key_index > RA6W_CFG80211_KEYS_MAX) { + ra6w_err("[%s] key index %d out of bounds\n", __func__, key_index); + return -ENOENT; + } + + key = &vif->keys[key_index]; + memset(¶ms, 0, sizeof(params)); + params.cipher = key->cipher; + params.key_len = key->key_len; + params.seq_len = key->seq_len; + params.seq = key->seq; + params.key = key->key; + + callback(cookie, ¶ms); + + return key->key_len ? 0 : -ENOENT; +} + +static int ra6w_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, int link_id, + u8 key_index, bool pairwise, const u8 *mac_addr) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_sta *sta = NULL; + struct ra6w_cfg80211_key *key = NULL; + + if (!vif->up) + return -EIO; + + if (key_index >= RA6W_CFG80211_KEYS_MAX) { + ra6w_err("[%s] key index %d out of bounds\n", __func__, key_index); + return -EINVAL; + } + + if (mac_addr) { + sta = ra6w_cfg80211_find_sta(priv, mac_addr); + if (!sta) + return -EINVAL; + + key = &sta->key; + } else { + key = &vif->keys[key_index]; + } + + return ra6w_ctrl_del_key_req(&priv->core->ctrl, key->key_index); +} + +static int ra6w_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, + int link_id, u8 key_index, bool unicast, bool multicast) +{ + int ret = 0; + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + + if (!vif->up) + return -EIO; + + return ret; +} + +static int ra6w_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_connect_params *sme) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cmd_sm_connect_rsp rsp = { 0 }; + int ret; + + if (!vif->up) + return -EIO; + + if ((sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40 || + sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) && + (sme->key && sme->key_len > 0)) { + struct key_params key_params; + + key_params.key = sme->key; + key_params.seq = NULL; + key_params.key_len = sme->key_len; + key_params.seq_len = 0; + key_params.cipher = sme->crypto.cipher_group; + ra6w_cfg80211_add_key(wiphy, ndev, -1, sme->key_idx, false, NULL, &key_params); + } else if ((sme->auth_type == NL80211_AUTHTYPE_SAE) && + !(sme->flags & CONNECT_REQ_EXTERNAL_AUTH_SUPPORT)) { + netdev_err(ndev, "Doesn't support SAE without external authentication\n"); + return -EINVAL; + } + + ret = ra6w_ctrl_connect(&priv->core->ctrl, ndev, sme, &rsp); + if (ret == 0) + netif_carrier_on(ndev); + + return ret; +} + +static int ra6w_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, + struct station_parameters *params) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cmd_sta_add_rsp rsp = { 0 }; + struct ra6w_cfg80211_sta *sta = NULL; + + if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) + return 0; + + ret = ra6w_ctrl_add_station_req(&priv->core->ctrl, params, mac, vif->vif_idx, &rsp); + if (ret) + return ret; + + sta = ra6w_cfg80211_sta_get(priv, rsp.sta_idx); + if (!sta) + return -EINVAL; + + sta->aid = params->aid; + sta->sta_idx = rsp.sta_idx; + sta->ch_idx = vif->ch_idx; + sta->vif_idx = vif->vif_idx; + sta->qos = (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) != 0; + sta->ht = params->link_sta_params.ht_capa ? 1 : 0; + sta->vht = params->link_sta_params.vht_capa ? 1 : 0; + sta->he = params->link_sta_params.he_capa ? 1 : 0; + sta->listen_interval = params->listen_interval; + ether_addr_copy(sta->mac_addr, mac); + list_add_tail(&sta->list, &vif->ap.sta_list); + vif->generation++; + sta->valid = true; + + return 0; +} + +static int ra6w_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, + const u8 *mac, struct station_parameters *params) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_sta *sta = NULL; + bool authorized; + + if (is_zero_ether_addr(mac)) + return 0; + + if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))) + return 0; + + sta = ra6w_cfg80211_find_sta(priv, mac); + if (!sta) + return -EINVAL; + + authorized = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED); + + return ra6w_ctrl_port_control_req(&priv->core->ctrl, authorized, sta->sta_idx); +} + +static int ra6w_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_ap_settings *settings) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_sta *sta = NULL; + struct ra6w_cmd_ap_start_rsp rsp = { 0 }; + struct ra6w_cfg80211_chan_info *chan_info = NULL; + + ret = ra6w_ctrl_ap_start_req(&priv->core->ctrl, vif, settings, &rsp); + if (ret) { + ra6w_err("Failed to start AP (%d)\n", ret); + return ret; + } + + vif->ap.bcmc_index = rsp.bcmc_idx; + vif->ap.ap_isolate = 0; + sta = ra6w_cfg80211_sta_get(priv, rsp.bcmc_idx); + if (!sta) + return -EINVAL; + + sta->valid = true; + sta->aid = 0; + sta->sta_idx = rsp.bcmc_idx; + sta->ch_idx = rsp.ch_idx; + sta->vif_idx = vif->vif_idx; + sta->qos = false; + sta->listen_interval = 5; + sta->ht = 0; + sta->vht = 0; + sta->he = 0; + + ra6w_cfg80211_chaninfo_set(vif, rsp.ch_idx, &settings->chandef); + + netif_carrier_on(ndev); + + chan_info = &priv->chaninfo_table[vif->ch_idx]; + ra6w_info("AP started: freq1 %u bcmc_idx %d\n", + chan_info->chan_def.center_freq1, vif->ap.bcmc_index); + + return 0; +} + +static int ra6w_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev, + unsigned int link_id) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + + netif_carrier_off(ndev); + _ra6w_cfg80211_del_station(vif, NULL); + ret = ra6w_ctrl_ap_stop_req(&priv->core->ctrl, vif); + ra6w_cfg80211_chaninfo_unset(vif); + + return ret; +} + +static int ra6w_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_ap_update *info) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_beacon_info *bcn = NULL; + u8 *bcn_buf; + + bcn = &vif->ap.bcn; + + bcn_buf = ra6w_cfg80211_create_beacon(bcn, &info->beacon); + if (!bcn_buf) + return -ENOMEM; + + ret = ra6w_ctrl_change_beacon_req(&priv->core->ctrl, vif->vif_idx, + bcn_buf, bcn->len, bcn->head_len, bcn->tim_len, NULL); + + kfree(bcn_buf); + + return ret; +} + +static +int ra6w_cfg80211_set_monitor_channel(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_chan_def *chandef) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = NULL; + struct ra6w_cmd_mon_mode_rsp rsp = { 0 }; + const struct ra6w_cfg80211_chan_info *chan_info = NULL; + struct cfg80211_chan_def chandef_mon; + + if (priv->mon_vif_idx == RA6W_CFG80211_VIF_IDX_INVALID) + return -EINVAL; + + vif = priv->vif_table[priv->mon_vif_idx]; + + chan_info = ra6w_cfg80211_chaninfo_get(vif); + if (chan_info && chandef && cfg80211_chandef_identical(&chan_info->chan_def, chandef)) + return 0; + + ret = ra6w_ctrl_monitor_mode_req(&priv->core->ctrl, chandef, &rsp); + if (ret) + return -EIO; + + ra6w_cfg80211_chaninfo_unset(vif); + + if (rsp.chan_index == RA6W_CFG80211_CH_IDX_INVALID) + return 0; + + if (priv->vif_started > 1) { + ra6w_cfg80211_chaninfo_set(vif, rsp.chan_index, NULL); + return -EBUSY; + } + + memset(&chandef_mon, 0, sizeof(chandef_mon)); + chandef_mon.chan = ieee80211_get_channel(wiphy, le16_to_cpu(rsp.chan.freq_prim20)); + chandef_mon.center_freq1 = le16_to_cpu(rsp.chan.freq_cen1); + chandef_mon.center_freq2 = le16_to_cpu(rsp.chan.freq_cen2); + chandef_mon.width = chnl2bw[rsp.chan.ch_bw]; + ra6w_cfg80211_chaninfo_set(vif, rsp.chan_index, &chandef_mon); + + return 0; +} + +static int ra6w_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *ndev, + const u8 *peer, u64 *cookie) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_sta *sta = NULL; + struct ra6w_cmd_probe_client_rsp rsp = { 0 }; + + if (vif->type != NL80211_IFTYPE_AP && + vif->type != NL80211_IFTYPE_P2P_GO) + return -EINVAL; + + list_for_each_entry(sta, &vif->ap.sta_list, list) { + if (sta->valid && ether_addr_equal(sta->mac_addr, peer)) + break; + } + + if (!sta) + return -EINVAL; + + ret = ra6w_ctrl_probe_client_req(&priv->core->ctrl, vif->vif_idx, sta->sta_idx, &rsp); + if (ret) + return ret; + + *cookie = (u64)le32_to_cpu(rsp.probe_id); + + return 0; +} + +static int ra6w_cfg80211_set_txq_params(struct wiphy *wiphy, struct net_device *ndev, + struct ieee80211_txq_params *params) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + u32 param; + u8 ac; + u8 aifs; + u8 cwmin; + u8 cwmax; + + ac = ra6w_ac2hwq[params->ac]; + aifs = params->aifs; + cwmin = (u8)fls(params->cwmin); + cwmax = (u8)fls(params->cwmax); + + param = (u32)(aifs << 0); + param |= (u32)(cwmin << 4); + param |= (u32)(cwmax << 8); + param |= (u32)(params->txop << 12); + + return ra6w_ctrl_edca_req(&priv->core->ctrl, ac, param, false, vif->vif_idx); +} + +static int ra6w_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, + enum nl80211_tx_power_setting type, int mbm) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = NULL; + struct ra6w_cfg80211_vif *tmp = NULL; + s8 tx_pwr = 0; + + switch (type) { + case NL80211_TX_POWER_AUTOMATIC: + tx_pwr = 0x7F; + break; + case NL80211_TX_POWER_LIMITED: + case NL80211_TX_POWER_FIXED: + tx_pwr = (s8)MBM_TO_DBM(mbm); + break; + default: + ra6w_err("[%s] Unsupported type %d\n", __func__, type); + return -EINVAL; + } + + if (wdev) { + vif = container_of(wdev, struct ra6w_cfg80211_vif, wdev); + if (!vif->up) + return -EIO; + + goto req; + } + + list_for_each_entry(tmp, &priv->vifs, list) { + if (!tmp->up) + continue; + + vif = tmp; + break; + } + +req: + if (!vif) + return -EIO; + + return ra6w_ctrl_set_tx_power_req(&priv->core->ctrl, vif->vif_idx, tx_pwr); +} + +static int ra6w_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, + bool enabled, int timeout) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + u8 ps_mode; + + if (!vif->up) + return -EIO; + + if (!ra6w_params_ps_supported()) + return -EOPNOTSUPP; + + ps_mode = enabled ? RA6W_CFG80211_PS_MODE_ON_DYN : RA6W_CFG80211_PS_MODE_OFF; + + return ra6w_ctrl_set_power_mgmt_req(&priv->core->ctrl, ps_mode); +} + +static int ra6w_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, + const u8 *mac, struct station_info *sinfo) +{ + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_sta *sta = NULL; + + if (!vif->up) + return -EIO; + + if (vif->type == NL80211_IFTYPE_MONITOR) + return -EINVAL; + + sta = ra6w_cfg80211_find_sta(vif->priv, mac); + if (!sta) + return -ENOENT; + + return ra6w_cfg80211_station_info_fill(sta, sinfo, vif); +} + +static int ra6w_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev, int idx, + u8 *mac, struct station_info *sinfo) +{ + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_sta *sta = NULL; + struct ra6w_cfg80211_sta *tmp = NULL; + int i = 0; + + if (!vif) + return -ENOENT; + + if (vif->type == NL80211_IFTYPE_MONITOR) + return -EINVAL; + + if ((vif->type == NL80211_IFTYPE_STATION || + vif->type == NL80211_IFTYPE_P2P_CLIENT) && + !idx && vif->sta.ap && vif->sta.ap->valid) { + sta = vif->sta.ap; + goto fill; + } + + list_for_each_entry(tmp, &vif->ap.sta_list, list) { + if (i == idx) { + sta = tmp; + break; + } + + i++; + } + +fill: + if (!sta) + return -ENOENT; + + ether_addr_copy(mac, (const u8 *)&sta->mac_addr); + + return ra6w_cfg80211_station_info_fill(sta, sinfo, vif); +} + +static int ra6w_cfg80211_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, + struct ieee80211_channel *chan, + unsigned int duration, u64 *cookie) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(wdev->netdev); + struct ra6w_cfg80211_remain_on_channel *roc = NULL; + + if (!priv || !vif) + return -EIO; + + if (priv->roc) + return -EBUSY; + + roc = kzalloc(sizeof(*roc), GFP_KERNEL); + if (!roc) + return -ENOMEM; + + roc->vif = vif; + roc->chan = chan; + roc->duration = duration; + roc->internal = false; + roc->on_chan = false; + roc->tx_cnt = 0; + memset(roc->tx_cookie, 0, sizeof(roc->tx_cookie)); + + priv->roc = roc; + ret = ra6w_ctrl_remain_on_channel_req(&priv->core->ctrl, vif, chan, duration); + if (ret) { + kfree(roc); + priv->roc = NULL; + + return ret; + } + + if (cookie) + *cookie = (u64)roc; + + return ret; +} + +static int ra6w_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, u64 cookie) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + + if (!priv->roc) + return 0; + + if (cookie != (u64)priv->roc) + return -EINVAL; + + return ra6w_ctrl_cancel_remain_on_channel_req(&priv->core->ctrl); +} + +static int ra6w_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_csa_settings *params) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_beacon_info *bcn; + struct ra6w_cfg80211_beacon_info *bcn_after; + struct ra6w_cfg80211_csa_info *csa; + u16 csa_oft[RA6W_CMD_BCN_MAX_CSA_CPT]; + u8 *bcn_buf; + const u8 *bcn_after_buf; + int i; + + if (vif->ap.csa) + return -EBUSY; + + if (params->n_counter_offsets_beacon > RA6W_CMD_BCN_MAX_CSA_CPT) + return -EINVAL; + + bcn = &vif->ap.bcn; + bcn_buf = ra6w_cfg80211_create_beacon(bcn, ¶ms->beacon_csa); + if (!bcn_buf) + return -ENOMEM; + + memset(csa_oft, 0, sizeof(csa_oft)); + for (i = 0; i < params->n_counter_offsets_beacon; i++) + csa_oft[i] = params->counter_offsets_beacon[i] + bcn->head_len + bcn->tim_len; + + if (params->count == 0) { + params->count = 2; + for (i = 0; i < params->n_counter_offsets_beacon; i++) + bcn_buf[csa_oft[i]] = 2; + } + + csa = kzalloc(sizeof(*csa), GFP_KERNEL); + if (!csa) { + ret = -ENOMEM; + goto free_bcn_buf; + } + + bcn_after = &csa->bcn; + bcn_after_buf = ra6w_cfg80211_create_beacon(bcn_after, ¶ms->beacon_after); + if (!bcn_after_buf) { + ret = -ENOMEM; + goto free_csa; + } + + vif->ap.csa = csa; + csa->vif = vif; + csa->chandef = params->chandef; + memcpy(csa->buf, bcn_after_buf, bcn_after->len); + kfree(bcn_after_buf); + + /* Send new Beacon. FW will extract channel and count from the beacon */ + ret = ra6w_ctrl_change_beacon_req(&priv->core->ctrl, vif->vif_idx, bcn_buf, bcn->len, + bcn->head_len, bcn->tim_len, csa_oft); + if (ret) + goto free_csa; + + INIT_WORK(&csa->work, ra6w_cfg80211_csa_work); + cfg80211_ch_switch_started_notify(ndev, &csa->chandef, params->link_id, + params->count, params->block_tx); + + kfree(bcn_buf); + + return ret; + +free_csa: + ra6w_cfg80211_csa_remove(vif); + +free_bcn_buf: + kfree(bcn_buf); + + return ret; +} + +static int ra6w_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, int idx, + struct survey_info *info) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + const struct ra6w_cfg80211_survey_info *survey_info = NULL; + struct ieee80211_supported_band *sband; + + if (idx >= ARRAY_SIZE(priv->survey_table)) + return -ENONET; + + survey_info = &priv->survey_table[idx]; + + sband = wiphy->bands[NL80211_BAND_2GHZ]; + if (!sband) + return -ENOENT; + + if (idx >= sband->n_channels) { + idx -= sband->n_channels; + sband = NULL; + } + + if (!sband) { + sband = wiphy->bands[NL80211_BAND_5GHZ]; + + if (!sband || idx >= sband->n_channels) + return -ENOENT; + } + + info->channel = &sband->channels[idx]; + info->filled = survey_info->filled; + + if (info->filled) { + info->time = (u64)survey_info->chan_dwell_ms; + info->time_busy = (u64)survey_info->chan_busy_ms; + info->noise = survey_info->chan_noise_dbm; + } + + return 0; +} + +static int ra6w_cfg80211_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, + unsigned int link_id, + struct cfg80211_chan_def *chandef) +{ + struct ra6w_cfg80211_vif *vif = container_of(wdev, struct ra6w_cfg80211_vif, wdev); + const struct ra6w_cfg80211_chan_info *chan_info = NULL; + + if (!vif->up) + return -ENODATA; + + chan_info = ra6w_cfg80211_chaninfo_get(vif); + if (!chan_info) + return -ENODATA; + + *chandef = chan_info->chan_def; + + return 0; +} + +static int ra6w_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, struct wireless_dev *wdev, + u64 cookie) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + int n_tx_cookie = 0; + int i; + + if (!priv->roc || !priv->roc->tx_cnt) + return 0; + + for (i = 0; i < RA6W_CFG80211_ROC_TX; i++) { + n_tx_cookie++; + + if (priv->roc->tx_cookie[i] == cookie) { + priv->roc->tx_cookie[i] = 0; + priv->roc->tx_cnt--; + break; + } + } + + if (i == RA6W_CFG80211_ROC_TX) { + if (n_tx_cookie != priv->roc->tx_cnt) + priv->roc->tx_cnt--; + else + return 0; + } + + if (!priv->roc->internal || priv->roc->tx_cnt > 0) + return 0; + + return ra6w_cfg80211_cancel_remain_on_channel(wiphy, wdev, (u64)priv->roc); +} + +static int ra6w_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *ndev, + s32 rssi_thold, u32 rssi_hyst) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_ctrl *ctrl = &priv->core->ctrl; + const struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + + return ra6w_ctrl_cqm_rssi_config_req(ctrl, vif->vif_idx, rssi_thold, rssi_hyst); +} + +static int ra6w_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *ndev, + struct bss_parameters *params) +{ + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_ctrl *ctrl = &priv->core->ctrl; + struct ra6w_cmd_ap_isolate_rsp rsp; + + if (params->ap_isolate < 0) + return -EINVAL; + + vif->ap.ap_isolate = params->ap_isolate; + + return ra6w_ctrl_set_ap_isolate_req(ctrl, vif->ap.ap_isolate, &rsp); +} + +static void ra6w_cfg80211_ht_set(struct ieee80211_sta_ht_cap *ht_cap) +{ + int i; + int nss; + + ht_cap->ht_supported = ra6w_params_ht_supported(); + if (!ht_cap->ht_supported) + return; + + if (ra6w_params_stbc_enabled()) + ht_cap->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; + + if (ra6w_params_ldpc_enabled()) + ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING; + + nss = ra6w_params_nss(); + ht_cap->mcs.rx_highest = cpu_to_le16(65 * nss); + + if (nss > 1) + ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC; + + ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; + + if (ra6w_params_rx_amsdu_size()) + ht_cap->cap |= IEEE80211_HT_CAP_MAX_AMSDU; + + ht_cap->mcs.rx_mask[0] = 0xff; + ht_cap->mcs.rx_highest = cpu_to_le16(65); + ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + + if (ra6w_params_use_sgi()) { + ht_cap->cap |= IEEE80211_HT_CAP_SGI_20; + ht_cap->mcs.rx_highest = cpu_to_le16(72 * nss); + } + + for (i = 0; i < nss; i++) + ht_cap->mcs.rx_mask[i] = 0xFF; +} + +static void ra6w_cfg80211_vht_set(struct ieee80211_sta_vht_cap *vht_cap) +{ + u8 nss; + u32 mcs_map; + u32 mcs_map_max_2ss_rx = IEEE80211_VHT_MCS_SUPPORT_0_9; + int mcs_map_max_2ss_tx = IEEE80211_VHT_MCS_SUPPORT_0_9; + u32 i; + + vht_cap->vht_supported = ra6w_params_vht_supported(); + if (!vht_cap->vht_supported) + return; + + vht_cap->cap = 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; + + if (ra6w_params_stbc_enabled()) + vht_cap->cap |= IEEE80211_VHT_CAP_RXSTBC_1; + + if (ra6w_params_ldpc_enabled()) + vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; + + if (ra6w_params_bfmee_enabled()) { + vht_cap->cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; + vht_cap->cap |= 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; + } + + nss = ra6w_params_nss(); + if (nss > 1) + vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; + + vht_cap->cap |= ra6w_params_rx_amsdu_size(); + + if (ra6w_params_bfmer_enabled()) { + vht_cap->cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; + vht_cap->cap |= (nss - 1) << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; + } + + if (ra6w_params_mu_mimo_rx_enabled()) + vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; + + if (ra6w_params_mu_mimo_tx_enabled()) + vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; + + mcs_map = ra6w_params_mcs_map_range(); + vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(0); + + for (i = 0; i < nss; i++) { + vht_cap->vht_mcs.rx_mcs_map |= cpu_to_le16(mcs_map << (i * 2)); + vht_cap->vht_mcs.rx_highest = cpu_to_le16(ra6w_mcs_map_to_rate[mcs_map] * nss); + mcs_map = min_t(int, mcs_map, mcs_map_max_2ss_rx); + } + + for (; i < 8; i++) + vht_cap->vht_mcs.rx_mcs_map |= + cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2)); + + mcs_map = ra6w_params_mcs_map_range(); + vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(0); + + for (i = 0; i < nss; i++) { + vht_cap->vht_mcs.tx_mcs_map |= cpu_to_le16(mcs_map << (i * 2)); + vht_cap->vht_mcs.tx_highest = cpu_to_le16(ra6w_mcs_map_to_rate[mcs_map] * nss); + mcs_map = min_t(int, mcs_map, mcs_map_max_2ss_tx); + } + + for (; i < 8; i++) + vht_cap->vht_mcs.tx_mcs_map |= + cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2)); + + vht_cap->cap &= ~IEEE80211_VHT_CAP_SHORT_GI_80; +} + +static void ra6w_cfg80211_threshold_set(struct ieee80211_sta_he_cap *he_cap) +{ + const u8 PPE_THRES_INFO_OFT = 7; + const u8 PPE_THRES_INFO_BIT_LEN = 6; + struct ppe_thres_info_tag { + u8 ppet16 : 3; + u8 ppet8 : 3; + } __packed; + + struct ppe_thres_field_tag { + u8 nsts : 3; + u8 ru_idx_bmp : 4; + }; + + struct ppe_thres_field_tag *ppe_thres_field; + struct ppe_thres_info_tag ppe_thres_info = { + .ppet16 = 0, // BPSK + .ppet8 = 7 // None + }; + + const u8 *ppe_thres_info_ptr = (u8 *)&ppe_thres_info; + u16 *ppe_thres_ptr = (u16 *)he_cap->ppe_thres; + u8 i; + u8 offset; + u8 nss; + + ppe_thres_field = (struct ppe_thres_field_tag *)he_cap->ppe_thres; + + ppe_thres_field->ru_idx_bmp = 1; + + nss = ra6w_params_nss(); + ppe_thres_field->nsts = nss - 1; + for (i = 0; i < nss; i++) { + offset = i * PPE_THRES_INFO_BIT_LEN + PPE_THRES_INFO_OFT; + ppe_thres_ptr = (u16 *)&he_cap->ppe_thres[offset / 8]; + *ppe_thres_ptr |= *ppe_thres_info_ptr << (offset % 8); + } +} + +static void ra6w_cfg80211_he_set(struct ra6w_cfg80211_priv *priv, + struct ieee80211_sband_iftype_data *ifdata) +{ + int i; + u8 nss; + struct ieee80211_sta_he_cap *he_cap = &ifdata->he_cap; + int mcs_map; + int mcs_map_max_2ss = IEEE80211_HE_MCS_SUPPORT_0_11; + u8 dcm_max_ru = IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_242; + u32 phy_vers = le32_to_cpu(priv->core->sinfo.fw_ver.phy_version); + __le16 unsup_for_ss = 0; + + he_cap->has_he = ra6w_params_he_supported(); + if (!he_cap->has_he) + return; + + if (ra6w_params_twt_enabled()) { + priv->ext_capa[9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT; + he_cap->he_cap_elem.mac_cap_info[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; + } + + he_cap->he_cap_elem.mac_cap_info[2] |= IEEE80211_HE_MAC_CAP2_ALL_ACK; + + ra6w_cfg80211_threshold_set(he_cap); + + if (ra6w_params_ldpc_enabled()) + he_cap->he_cap_elem.phy_cap_info[1] |= IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; + + he_cap->he_cap_elem.phy_cap_info[1] |= + IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US | + IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS; + he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS | + IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | + IEEE80211_HE_PHY_CAP2_DOPPLER_RX; + + if (ra6w_params_stbc_enabled()) + he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ; + + he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM | + IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU; + + nss = ra6w_params_nss(); + if (nss > 0) + he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_2; + else + he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1; + + if (ra6w_params_bfmee_enabled()) { + he_cap->he_cap_elem.phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE; + he_cap->he_cap_elem.phy_cap_info[4] |= + IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4; + } + + he_cap->he_cap_elem.phy_cap_info[5] |= IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK | + IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; + he_cap->he_cap_elem.phy_cap_info[6] |= + IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | + IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | + IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | + IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB | + IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT | + IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; + he_cap->he_cap_elem.phy_cap_info[7] |= + IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; + he_cap->he_cap_elem.phy_cap_info[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G | + dcm_max_ru; + he_cap->he_cap_elem.phy_cap_info[9] |= + IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | + IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB | + IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US; + + /* Starting from version v31 more HE_ER_SU modulations is supported */ + if (RA6W_PHY_VERSION(phy_vers) > 30) { + he_cap->he_cap_elem.phy_cap_info[6] |= IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE; + he_cap->he_cap_elem.phy_cap_info[8] |= + IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI | + IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI; + } + + mcs_map = ra6w_params_he_mcs_map_range(); + memset(&he_cap->he_mcs_nss_supp, 0, sizeof(he_cap->he_mcs_nss_supp)); + for (i = 0; i < nss; i++) { + unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2)); + he_cap->he_mcs_nss_supp.rx_mcs_80 |= cpu_to_le16(mcs_map << (i * 2)); + he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; + he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; + mcs_map = min_t(int, ra6w_params_he_mcs_map_range(), mcs_map_max_2ss); + } + + for (; i < 8; i++) { + unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2)); + he_cap->he_mcs_nss_supp.rx_mcs_80 |= unsup_for_ss; + he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; + he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; + } + + mcs_map = ra6w_params_he_mcs_map_range(); + for (i = 0; i < nss; i++) { + unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2)); + he_cap->he_mcs_nss_supp.tx_mcs_80 |= cpu_to_le16(mcs_map << (i * 2)); + he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; + he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; + mcs_map = min_t(int, ra6w_params_he_mcs_map_range(), mcs_map_max_2ss); + } + + for (; i < 8; i++) { + unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2)); + he_cap->he_mcs_nss_supp.tx_mcs_80 |= unsup_for_ss; + he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; + he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; + } +} + +static int ra6w_cfg80211_set_default_wiphy(struct ra6w_cfg80211_priv *priv, struct wiphy *wiphy) +{ + const u8 *mac_addr = priv->core->sinfo.default_mac; + int i; + + ether_addr_copy(wiphy->perm_addr, mac_addr); + for (i = 0; i < RA6W_CFG80211_VIF_MAX; i++) { + ether_addr_copy(priv->addresses[i].addr, mac_addr); + priv->addresses[i].addr[5] ^= i; + } + + wiphy->addresses = priv->addresses; + wiphy->n_addresses = RA6W_CFG80211_VIF_MAX; + + bitmap_zero(priv->addr_map, RA6W_CFG80211_VIF_MAX); + + wiphy->mgmt_stypes = ra6w_macm_stypes; + + ra6w_cfg80211_ht_set(&ra6w_band_2g.ht_cap); + if (ra6w_params_he_supported()) { + ra6w_cfg80211_he_set(priv, &ra6w_cap_he_2g); + ra6w_band_2g.iftype_data = &ra6w_cap_he_2g; + } + + wiphy->bands[NL80211_BAND_2GHZ] = &ra6w_band_2g; + + ra6w_cfg80211_ht_set(&ra6w_band_5g.ht_cap); + ra6w_cfg80211_vht_set(&ra6w_band_5g.vht_cap); + if (ra6w_params_he_supported()) { + ra6w_cfg80211_he_set(priv, &ra6w_cap_he_5g); + ra6w_band_5g.iftype_data = &ra6w_cap_he_5g; + } + + wiphy->bands[NL80211_BAND_5GHZ] = &ra6w_band_5g; + + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_MONITOR); + wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | + WIPHY_FLAG_HAS_CHANNEL_SWITCH | + WIPHY_FLAG_4ADDR_STATION | + WIPHY_FLAG_4ADDR_AP | + WIPHY_FLAG_REPORTS_OBSS | + WIPHY_FLAG_OFFCHAN_TX; + + wiphy->max_scan_ssids = RA6W_CMD_SCAN_SSID_MAX; + wiphy->max_scan_ie_len = RA6W_CMD_SCAN_MAX_IE_LEN; + + wiphy->support_mbssid = 1; + + wiphy->max_num_csa_counters = RA6W_CMD_BCN_MAX_CSA_CPT; + wiphy->max_remain_on_channel_duration = 5000; + + wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN | + NL80211_FEATURE_SK_TX_STATUS | + NL80211_FEATURE_VIF_TXPOWER | + NL80211_FEATURE_ACTIVE_MONITOR | + NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | + NL80211_FEATURE_SAE; + + wiphy->iface_combinations = ra6w_if_comb; + wiphy->n_iface_combinations = ARRAY_SIZE(ra6w_if_comb) - 1; + + if (ra6w_params_regd_mode_is_auto()) + wiphy->reg_notifier = ra6w_cfg80211_reg_notifier; + else + wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; + + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + + wiphy->extended_capabilities = priv->ext_capa; + wiphy->extended_capabilities_mask = priv->ext_capa; + wiphy->extended_capabilities_len = ARRAY_SIZE(priv->ext_capa); + + wiphy->cipher_suites = ra6w_cipher_suites; + wiphy->n_cipher_suites = + ARRAY_SIZE(ra6w_cipher_suites) - RA6W_CFG80211_RESERVED_CIPHER_NUM; + + if (ra6w_params_wapi_supported()) + ra6w_cipher_suites[wiphy->n_cipher_suites++] = WLAN_CIPHER_SUITE_SMS4; + + if (ra6w_params_mfp_supported()) + ra6w_cipher_suites[wiphy->n_cipher_suites++] = WLAN_CIPHER_SUITE_AES_CMAC; + + if (ra6w_params_ccmp256_supported()) + ra6w_cipher_suites[wiphy->n_cipher_suites++] = WLAN_CIPHER_SUITE_CCMP_256; + + if (ra6w_params_gcmp_supported()) { + ra6w_cipher_suites[wiphy->n_cipher_suites++] = WLAN_CIPHER_SUITE_GCMP; + ra6w_cipher_suites[wiphy->n_cipher_suites++] = WLAN_CIPHER_SUITE_GCMP_256; + } + + if (ra6w_params_tdls_supported()) { + wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; + wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH; + wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; + } + + if (ra6w_params_ap_uapsd_enabled()) + wiphy->flags |= WIPHY_FLAG_AP_UAPSD; + + if (ra6w_params_ps_supported()) + wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; + + strscpy(wiphy->fw_version, priv->core->sinfo.fw_version, sizeof(wiphy->fw_version)); + + return 0; +} + +static void ra6w_cfg80211_vif_del_all(struct ra6w_cfg80211_priv *priv) +{ + struct ra6w_cfg80211_vif *vif = NULL; + struct ra6w_cfg80211_vif *tmp_vif = NULL; + + rtnl_lock(); + + list_for_each_entry_safe(vif, tmp_vif, &priv->vifs, list) { + ra6w_cfg80211_vif_cleanup(vif); + ra6w_cfg80211_vif_unassign(priv, vif->vif_idx, vif->addr_idx); + } + + rtnl_unlock(); +} + +void ra6w_cfg80211_chaninfo_set(struct ra6w_cfg80211_vif *vif, u8 ch_idx, + const struct cfg80211_chan_def *chandef) +{ + struct ra6w_cfg80211_chan_info *chan_info = NULL; + struct ra6w_cfg80211_priv *priv = vif->priv; + + if (ch_idx >= RA6W_CFG80211_CHANINFO_MAX) { + ra6w_err("Invalid channel idx %d\n", ch_idx); + return; + } + + vif->ch_idx = ch_idx; + chan_info = &priv->chaninfo_table[ch_idx]; + + /* For now chandef is NULL for STATION interface */ + if (chandef && !chan_info->chan_def.chan) { + chan_info->chan_def = *chandef; + chan_info->count++; + } +} + +void ra6w_cfg80211_chaninfo_unset(struct ra6w_cfg80211_vif *vif) +{ + struct ra6w_cfg80211_chan_info *chan_info = NULL; + struct ra6w_cfg80211_priv *priv = vif->priv; + + if (vif->ch_idx == RA6W_CFG80211_CH_IDX_INVALID) + return; + + chan_info = &priv->chaninfo_table[vif->ch_idx]; + + if (chan_info->count == 0) + ra6w_dbg("Chan info ref count is already 0\n"); + else + chan_info->count--; + + if (chan_info->count == 0) + chan_info->chan_def.chan = NULL; + + vif->ch_idx = RA6W_CFG80211_CH_IDX_INVALID; +} + +static +struct ra6w_cfg80211_sta *ra6w_cfg80211_get_sta_from_fc(struct ra6w_cfg80211_priv *priv, + struct ra6w_cfg80211_vif *vif, + const u8 *addr, __le16 fc, bool ap) +{ + bool bufferable; + struct ra6w_cfg80211_sta *sta = NULL; + + if (!ap) { + if (vif->sta.ap && vif->sta.ap->valid && + ether_addr_equal(vif->sta.ap->mac_addr, addr)) + return vif->sta.ap; + + return NULL; + } + + bufferable = ieee80211_is_deauth(fc) || + ieee80211_is_disassoc(fc) || + ieee80211_is_action(fc); + + if (!bufferable) + return NULL; + + if (is_broadcast_ether_addr(addr) || is_multicast_ether_addr(addr)) { + sta = ra6w_cfg80211_sta_get(priv, vif->ap.bcmc_index); + if (!sta || !sta->valid) + return NULL; + + return sta; + } + + list_for_each_entry(sta, &vif->ap.sta_list, list) { + if (sta->valid && ether_addr_equal(sta->mac_addr, addr)) + return sta; + } + + return NULL; +} + +static int ra6w_cfg80211_offchan_proc(struct wiphy *wiphy, struct wireless_dev *wdev, + struct ra6w_cfg80211_priv *priv, + const struct ra6w_cfg80211_vif *vif, + struct cfg80211_mgmt_tx_params *params) +{ + struct ieee80211_channel *chan = params->chan; + int ret; + unsigned int duration = 30; + + if (!chan) + return -EINVAL; + + /* Offchannel transmission, need to start a RoC */ + if (priv->roc) { + /* Test if current RoC can be re-used */ + if (priv->roc->vif != vif || priv->roc->chan->center_freq != chan->center_freq) + return -EINVAL; + + return 0; + } + + /* Start a new ROC procedure */ + if (params->wait) + duration = params->wait; + + ret = ra6w_cfg80211_remain_on_channel(wiphy, wdev, chan, duration, NULL); + if (ret) + return ret; + + /* Internal RoC, no need to inform user space about it */ + priv->roc->internal = true; + + return 0; +} + +static int ra6w_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, u64 *cookie) +{ + int ret = 0; + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_cfg80211_vif *vif = container_of(wdev, struct ra6w_cfg80211_vif, wdev); + struct ra6w_cfg80211_sta *sta = NULL; + struct ra6w_tx *tx = &priv->core->tx; + const struct ieee80211_mgmt *mgmt = (const struct ieee80211_mgmt *)params->buf; + bool ap = false; + bool offchan = false; + const u8 *da; + __le16 fc; + + switch (vif->type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + ap = true; + + if (!(ieee80211_is_assoc_resp(mgmt->frame_control) || + ieee80211_is_auth(mgmt->frame_control))) + break; + + cfg80211_mgmt_tx_status(wdev, *cookie, params->buf, params->len, true, GFP_ATOMIC); + + break; + default: + break; + } + + da = mgmt->da; + fc = mgmt->frame_control; + sta = ra6w_cfg80211_get_sta_from_fc(priv, vif, da, fc, ap); + + if (params->offchan) { + const struct ra6w_cfg80211_chan_info *chan_info = ra6w_cfg80211_chaninfo_get(vif); + + if (!chan_info) + return -EINVAL; + + offchan = chan_info->chan_def.chan->center_freq == params->chan->center_freq; + + ret = ra6w_cfg80211_offchan_proc(wiphy, wdev, priv, vif, params); + if (ret) + return ret; + } + + ret = ra6w_tx_mgmt(tx, vif, sta, params, cookie); + if (offchan) { + if (priv->roc->tx_cnt < RA6W_CFG80211_ROC_TX) + priv->roc->tx_cookie[priv->roc->tx_cnt] = *cookie; + else + ra6w_warn("[%s] %d frames sent within the same Roc (> RA6W_NET_ROC_TX)", + __func__, priv->roc->tx_cnt + 1); + priv->roc->tx_cnt++; + } + + return ret; +} + +static int ra6w_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_external_auth_params *params) +{ + struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy); + struct ra6w_ctrl *ctrl = &priv->core->ctrl; + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + + if (!(vif->sta.flags & RA6W_CMD_STA_AUTH_EXT_BIT)) + return -EINVAL; + + vif->sta.flags &= ~RA6W_CMD_STA_AUTH_EXT_BIT; + + return ra6w_ctrl_sm_ext_auth_req_rsp(ctrl, vif->vif_idx, params->status); +} + +static struct cfg80211_ops ra6w_cfg80211_ops = { + .add_virtual_intf = ra6w_cfg80211_add_iface, + .del_virtual_intf = ra6w_cfg80211_del_iface, + .change_virtual_intf = ra6w_cfg80211_change_iface, + .scan = ra6w_cfg80211_scan, + .abort_scan = ra6w_cfg80211_scan_abort, + .connect = ra6w_cfg80211_connect, + .disconnect = ra6w_cfg80211_disconnect, + .add_key = ra6w_cfg80211_add_key, + .get_key = ra6w_cfg80211_get_key, + .del_key = ra6w_cfg80211_del_key, + .set_default_key = ra6w_cfg80211_set_default_key, + .add_station = ra6w_cfg80211_add_station, + .del_station = ra6w_cfg80211_del_station, + .change_station = ra6w_cfg80211_change_station, + .mgmt_tx = ra6w_cfg80211_mgmt_tx, + .mgmt_tx_cancel_wait = ra6w_cfg80211_mgmt_tx_cancel_wait, + .start_ap = ra6w_cfg80211_start_ap, + .change_beacon = ra6w_cfg80211_change_beacon, + .stop_ap = ra6w_cfg80211_stop_ap, + .set_monitor_channel = ra6w_cfg80211_set_monitor_channel, + .probe_client = ra6w_cfg80211_probe_client, + .set_txq_params = ra6w_cfg80211_set_txq_params, + .set_tx_power = ra6w_cfg80211_set_tx_power, + .set_power_mgmt = ra6w_cfg80211_set_power_mgmt, + .get_station = ra6w_cfg80211_get_station, + .dump_station = ra6w_cfg80211_dump_station, + .remain_on_channel = ra6w_cfg80211_remain_on_channel, + .cancel_remain_on_channel = ra6w_cfg80211_cancel_remain_on_channel, + .channel_switch = ra6w_cfg80211_channel_switch, + .dump_survey = ra6w_cfg80211_dump_survey, + .get_channel = ra6w_cfg80211_get_channel, + .set_cqm_rssi_config = ra6w_cfg80211_set_cqm_rssi_config, + .change_bss = ra6w_cfg80211_change_bss, + CFG80211_TESTMODE_CMD(ra6w_testmode_cmd) + .external_auth = ra6w_cfg80211_external_auth, +}; + +static int ra6w_cfg80211_register(struct ra6w_core *core, struct device *dev) +{ + int ret; + struct wiphy *wiphy = NULL; + struct ra6w_cfg80211_priv *priv = NULL; + + wiphy = wiphy_new(&ra6w_cfg80211_ops, sizeof(*priv)); + if (!wiphy) { + ra6w_err("Failed to create new wiphy\n"); + return -ENOENT; + } + + priv = wiphy_priv(wiphy); + priv->core = core; + + set_wiphy_dev(wiphy, dev); + priv->wiphy = wiphy; + core->priv = priv; + + priv->vif_started = 0; + priv->mon_vif_idx = RA6W_CFG80211_VIF_IDX_INVALID; + + bitmap_zero(priv->vif_map, RA6W_CFG80211_VIF_MAX); + + INIT_LIST_HEAD(&priv->vifs); + + priv->roc = NULL; + + priv->ext_capa[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING; + priv->ext_capa[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT; + priv->ext_capa[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF | + WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB; + priv->ext_capa[8] = WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB; + + ret = ra6w_cfg80211_set_default_wiphy(priv, wiphy); + if (ret) + goto free_wiphy; + + ret = ra6w_ctrl_me_config(&priv->core->ctrl, wiphy); + if (ret) + goto free_wiphy; + + ret = wiphy_register(wiphy); + if (ret) { + ra6w_err("register wiphy device failed: %d\n", ret); + goto free_wiphy; + } + + ret = ra6w_params_regd_set_self(wiphy); + if (ret) + goto free_wiphy; + + ra6w_dbgfs_register(priv); + + ret = ra6w_ctrl_dev_start(&priv->core->ctrl, &priv->phy_config); + if (ret) + goto free_wiphy; + + return 0; + +free_wiphy: + wiphy_free(wiphy); + priv->wiphy = NULL; + core->priv = NULL; + + return ret; +} + +void ra6w_cfg80211_deinit(struct ra6w_core *core) +{ + struct ra6w_cfg80211_priv *priv = NULL; + struct wiphy *wiphy = NULL; + + if (!core) + return; + + priv = core->priv; + if (!priv) + return; + + ra6w_cfg80211_vif_del_all(priv); + + ra6w_dbgfs_deregister(priv); + + wiphy = priv->wiphy; + if (wiphy) { + wiphy_unregister(wiphy); + wiphy_free(wiphy); + } + + priv->wiphy = NULL; + core->priv = NULL; +} + +int ra6w_cfg80211_init(struct ra6w_core *core, struct device *dev) +{ + int ret; + struct wireless_dev *wdev = NULL; + + ret = ra6w_cfg80211_register(core, dev); + if (ret) + return ret; + + rtnl_lock(); + wdev = ra6w_cfg80211_add_iface(core->priv->wiphy, "wlan%d", NET_NAME_UNKNOWN, + NL80211_IFTYPE_STATION, NULL); + rtnl_unlock(); + if (!wdev) { + ra6w_info("Failed to instantiate a network device\n"); + ret = -ENOENT; + goto cfg80211_deinit; + } + + ra6w_info("New interface created %s\n", wdev->netdev->name); + + return 0; + +cfg80211_deinit: + ra6w_cfg80211_deinit(core); + + return ret; +} From patchwork Thu Apr 17 13:52:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882273 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A7B2A24EA93 for ; Thu, 17 Apr 2025 13:53:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744897996; cv=none; b=JJsCyh1kZUDxTjQlSiL7CndoPpWA61QxWU/n0ZzQQtuUtUcXlPccFU/XkzKnnjEMeMoDIkvwsb9cwrK/uiOibITNZX2twFXfHHWONWd/sCZgk4EQkDyC500rpYZTqnDSGkLi4hS5/zEnaYaiS6vep+HEoR+BxGxyMvgO8B6RkaI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744897996; c=relaxed/simple; bh=x8ZX/qobYB6KdqWRChx5iTU+X7UCaBsbY/nJC0T3Cws=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=j1mqxzn6CZPlo9eKPXjSaWCngKynlqeP7n8QgFeggjRA80Uy6gE6CkIcrRu0aPRpK4vXqLIyV1ckH/Do5KxIrwhn8bxntsaxIFxW3l4jW9M7lNFDIuHe9mBi2eAQg8ExUxp25gP6pEaLrSNq2sIJy2CQEV/m2LT/eje7L8tQYHY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: FIdAisRdT2y1XXL5Klqatg== X-CSE-MsgGUID: lnVUS/ylQS+ItSfF30LHNg== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 17 Apr 2025 22:53:12 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 9D5734006DE8; Thu, 17 Apr 2025 22:53:08 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 06/38] ra6w: add cmd.h Date: Thu, 17 Apr 2025 16:52:04 +0300 Message-Id: <20250417135236.52410-7-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/cmd.h | 978 ++++++++++++++++++++++++ 1 file changed, 978 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/cmd.h diff --git a/drivers/net/wireless/renesas/ra6w/cmd.h b/drivers/net/wireless/renesas/ra6w/cmd.h new file mode 100644 index 000000000000..635709d05af0 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/cmd.h @@ -0,0 +1,978 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_CMD_H +#define RA6W_CMD_H + +#include + +#define RA6W_CMD_MAX_Q 4 +#define RA6W_CMD_DATA_SIZE 1700 +#define RA6W_CMD_MAX_MCS_LEN 16 + +#define RA6W_CMD_MAC_HE_MAC_CAPA_LEN 6 +#define RA6W_CMD_MAC_HE_PHY_CAPA_LEN 11 +#define RA6W_CMD_MAC_HE_PPE_THRES_MAX_LEN 25 + +#define RA6W_CMD_SCAN_SSID_MAX 2 +#define RA6W_CMD_SCAN_MAX_IE_LEN 200 +#define RA6W_CMD_SSID_LEN 32 + +#define RA6W_CMD_TX_LIFETIME_MS 100 + +#define RA6W_CMD_BT_COEX_MAX 3 +#define RA6W_CMD_BCN_MAX_CSA_CPT 2 +#define RA6W_CMD_BCN_SIZE 512 +#define RA6W_CMD_SECURY_KEY_LEN 32 + +#define RA6W_CMD_SCAN_CHANNEL_24G 14 +#define RA6W_CMD_SCAN_CHANNEL_5G 28 +#define RA6W_CMD_SCAN_CHANNEL_MAX (RA6W_CMD_SCAN_CHANNEL_24G + RA6W_CMD_SCAN_CHANNEL_5G) + +enum ra6w_cmd_data { + RA6W_CMD_DATA_START = 0, + RA6W_CMD_DATA_RX = 1, + RA6W_CMD_DATA_STATUS_RX = 2, + RA6W_CMD_DATA_TX = 5, + + RA6W_CMD_DATA_MAX, + RA6W_CMD_DATA_LAST = RA6W_CMD_DATA_MAX - 1 +}; + +enum ra6w_cmd_common { + RA6W_CMD_COMMON_START = 10, + RA6W_CMD_COMMON_RESET = 11, + RA6W_CMD_COMMON_GET_MAC_ADDR = 12, + + RA6W_CMD_COMMON_MAX, + RA6W_CMD_COMMON_LAST = RA6W_CMD_COMMON_MAX - 1 +}; + +enum ra6w_cmd_ctrl { + RA6W_CMD_FULLMAC_START = 100, + + RA6W_CMD_MM_RESET = 101, + RA6W_CMD_MM_START = 102, + RA6W_CMD_MM_GET_VER = 103, + RA6W_CMD_MM_ADD_IF = 104, + RA6W_CMD_MM_RM_IF = 105, + RA6W_CMD_MM_ADD_KEY = 106, + RA6W_CMD_MM_DEL_KEY = 107, + RA6W_CMD_MM_SET_POWER = 108, + RA6W_CMD_MM_GET_RSSI = 109, + RA6W_CMD_MM_REMAIN_ON_CHANNEL = 110, + RA6W_CMD_MM_SET_EDCA = 111, + + RA6W_CMD_ME_CONFIG = 113, + RA6W_CMD_ME_CHAN_CONFIG = 114, + RA6W_CMD_ME_SET_CONTROL_PORT = 115, + RA6W_CMD_ME_ADD_STA = 116, + RA6W_CMD_ME_DEL_STA = 117, + RA6W_CMD_ME_SET_MON_CFG = 121, + RA6W_CMD_ME_SET_PS_MODE = 122, + + RA6W_CMD_SC_START = 123, + RA6W_CMD_SC_CANCEL_CMD = 126, + + RA6W_CMD_SM_CONNECT = 127, + RA6W_CMD_SM_DISCONNECT = 128, + RA6W_CMD_SM_EXTERNAL_AUTH_REQUIRED_RSP = 129, + + RA6W_CMD_AM_START = 133, + RA6W_CMD_AM_STOP = 134, + RA6W_CMD_AM_START_CHAN_AVAIL = 135, + RA6W_CMD_AM_STOP_CHAN_AVAIL = 136, + RA6W_CMD_AM_PROBE_CLIENT = 137, + RA6W_CMD_AM_BCN_CHANGE = 138, + RA6W_CMD_AM_ISOLATE = 139, + + RA6W_CMD_FULLMAC_MAX, + RA6W_CMD_FULLMAC_LAST = RA6W_CMD_FULLMAC_MAX - 1 +}; + +enum ra6w_cmd_ind { + RA6W_CMD_IND_FULLMAC_START = 180, + + RA6W_CMD_ME_TKIP_MIC_FAILURE_IND = 181, + + RA6W_CMD_SC_RESULT_IND = 183, + RA6W_CMD_SC_COMPLETE_IND = 184, + RA6W_CMD_SC_CHANNEL_SURVEY_IND = 185, + + RA6W_CMD_SM_CONNECT_IND = 186, + RA6W_CMD_SM_DISCONNECT_IND = 187, + RA6W_CMD_SM_EXTERNAL_AUTH_REQUIRED_IND = 189, + + RA6W_CMD_TWT_SETUP_IND = 190, + + RA6W_CMD_AM_PROBE_CLIENT_IND = 191, + + RA6W_CMD_MM_CHANNEL_SWITCH_IND = 192, + RA6W_CMD_MM_CHANNEL_PRE_SWITCH_IND = 193, + RA6W_CMD_MM_REMAIN_ON_CHANNEL_EXP_IND = 194, + RA6W_CMD_MM_PS_CHANGE_IND = 195, + RA6W_CMD_MM_TRAFFIC_REQ_IND = 196, + RA6W_CMD_MM_CSA_COUNTER_IND = 198, + RA6W_CMD_MM_RSSI_STATUS_IND = 200, + RA6W_CMD_MM_CSA_FINISH_IND = 201, + RA6W_CMD_MM_CSA_TRAFFIC_IND = 202, + RA6W_CMD_MM_PACKET_LOSS_IND = 203, + + RA6W_CMD_TD_CHAN_SWITCH_IND = 204, + + RA6W_CMD_DBG_ERROR_IND = 207, + + RA6W_CMD_IND_FULLMAC_MAX, + RA6W_CMD_IND_FULLMAC_LAST = RA6W_CMD_IND_FULLMAC_MAX - 1 +}; + +enum ra6w_cmd_dbg { + RA6W_CMD_DBG_START = 220, + + RA6W_CMD_DBG_MEM_READ = 221, + RA6W_CMD_DBG_MEM_WRITE = 222, + RA6W_CMD_DBG_SET_MOD_FILTER = 223, + RA6W_CMD_DBG_SET_SEV_FILTER = 224, + RA6W_CMD_DBG_RF_TX = 227, + RA6W_CMD_DBG_RF_CW = 228, + RA6W_CMD_DBG_RF_CONT = 229, + RA6W_CMD_DBG_RF_CH = 230, + RA6W_CMD_DBG_RF_PER = 231, + RA6W_CMD_DBG_STATS_TX = 232, + + RA6W_CMD_DBG_MAX, + RA6W_CMD_DBG_LAST = RA6W_CMD_DBG_MAX - 1 +}; + +enum ra6w_cmd_ac { + RA6W_CMD_AC_BK, + RA6W_CMD_AC_BE, + RA6W_CMD_AC_VI, + RA6W_CMD_AC_VO, + + RA6W_CMD_AC_MAX, +}; + +enum ra6w_cmd_mac_chan_bandwidth { + RA6W_CMD_PHY_CHNL_BW_20, + RA6W_CMD_PHY_CHNL_BW_40, + RA6W_CMD_PHY_CHNL_BW_80, + RA6W_CMD_PHY_CHNL_BW_160, + RA6W_CMD_PHY_CHNL_BW_80P80, + + RA6W_CMD_PHY_CHNL_BW_OTHER, +}; + +enum ra6w_cmd_chan_bits { + RA6W_CMD_CHAN_NO_IR_BIT = BIT(0), + RA6W_CMD_CHAN_DISABLED_BIT = BIT(1), + RA6W_CMD_CHAN_RADAR_BIT = BIT(2), + RA6W_CMD_CHAN_HT40M_BIT = BIT(3), + RA6W_CMD_CHAN_HT40P_BIT = BIT(4), + RA6W_CMD_CHAN_VHT80_10_70_BIT = BIT(5), + RA6W_CMD_CHAN_VHT80_30_50_BIT = BIT(6), + RA6W_CMD_CHAN_VHT80_50_30_BIT = BIT(7), + RA6W_CMD_CHAN_VHT80_70_10_BIT = BIT(8) +}; + +enum ra6w_cmd_machw_version { + RA6W_CMD_MACHW_DEFAULT = 10, + RA6W_CMD_MACHW_HE = 20, + RA6W_CMD_MACHW_HE_AP = 30, +}; + +enum ra6w_cmd_connection_bits { + RA6W_CMD_CONN_CONTROL_PORT_HOST_BIT = BIT(0), + RA6W_CMD_CONN_CONTROL_PORT_NO_ENC_BIT = BIT(1), + RA6W_CMD_CONN_DISABLE_HT_BIT = BIT(2), + RA6W_CMD_CONN_USE_PAIRWISE_KEY_BIT = BIT(3), + RA6W_CMD_CONN_MFP_IN_USE_BIT = BIT(4), + RA6W_CMD_CONN_REASSOCIATION_BIT = BIT(5), + RA6W_CMD_CONN_USE_PRIVACY_BIT = BIT(7), + RA6W_CMD_CONN_REQUIRE_SPP_AMSDU_BIT = BIT(8), +}; + +enum ra6w_cmd_sm_auth_status_bits { + RA6W_CMD_STA_AUTH_EXT_BIT = BIT(0), +}; + +enum ra6w_cmd_sta_cap_bits { + RA6W_CMD_STA_CAP_QOS_BIT = BIT(0), + RA6W_CMD_STA_CAP_HT_BIT = BIT(1), + RA6W_CMD_STA_CAP_VHT_BIT = BIT(2), + RA6W_CMD_STA_CAP_MFP_BIT = BIT(3), + RA6W_CMD_STA_OP_NOT_IE_BIT = BIT(4), + RA6W_CMD_STA_CAP_HE_BIT = BIT(5), + RA6W_CMD_STA_CAP_SHORT_PREAMBLE_BIT = BIT(6), +}; + +enum ra6w_cmd_tdls_state { + RA6W_CMD_TDLS_STATE_LINK_IDLE, + RA6W_CMD_TDLS_STATE_TX_REQ, + RA6W_CMD_TDLS_STATE_TX_RSP, + RA6W_CMD_TDLS_STATE_LINK_ACTIVE, + + RA6W_CMD_TDLS_STATE_MAX +}; + +enum ra6w_cmd_roc_op_code { + RA6W_CMD_ROC_OP_CODE_START, + RA6W_CMD_ROC_OP_CODE_STOP, + + RA6W_CMD_ROC_OP_CODE_MAX +}; + +struct ra6w_cmd_hdr { + u8 cmd; + u8 ext_len; + __le16 data_len; +}; + +struct ra6w_cmd_reset_data { + __le64 time_usec; + __le32 bt_coex; +}; + +struct ra6w_cmd_reset_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_reset_data data; +} __packed; + +struct ra6w_cmd_phy_cfg { + u8 boot_mode; + u8 band; + u8 country_code[4]; +}; + +struct ra6w_cmd_mm_start_data { + struct ra6w_cmd_phy_cfg phy_cfg; + __le32 uapsd_timeout; + __le16 lp_clk_accuracy; + __le16 tx_timeout[RA6W_CMD_MAX_Q]; + __le16 rx_hostbuf_size; +}; + +struct ra6w_cmd_mm_start_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_mm_start_data data; +} __packed; + +struct ra6w_cmd_mm_common_get_mac_req { + struct ra6w_cmd_hdr hdr; +}; + +struct ra6w_cmd_fw_ver_rsp { + __le32 fw_version; + __le32 machw_features; + __le32 machw_version; + __le32 phy_feature; + __le32 phy_version; + __le32 features; + __le16 max_sta_nb; + u8 max_vif_nb; +}; + +struct ra6w_cmd_mac_addr { + u16 addr[ETH_ALEN / 2]; +}; + +struct ra6w_cmd_add_if_data { + u8 iftype; + struct ra6w_cmd_mac_addr addr; + bool p2p; + bool uf; +}; + +struct ra6w_cmd_add_if_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_add_if_data data; +} __packed; + +struct ra6w_cmd_add_if_rsp { + u8 status; + u8 vif_idx; +}; + +struct ra6w_cmd_del_if_data { + u8 vif_idx; +}; + +struct ra6w_cmd_del_if_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_del_if_data data; +} __packed; + +struct ra6w_cmd_oper_ch_info { + u8 ch_band; + u8 ch_bw; + __le16 freq_prim20; + __le16 freq_cen1; + __le16 freq_cen2; + __le16 ch_flags; + s8 tx_max_pwr; +}; + +struct ra6w_cmd_mac_htcapability { + __le16 ht_capa_info; + u8 a_mpdu_param; + u8 mcs_rate[RA6W_CMD_MAX_MCS_LEN]; + __le16 ht_extended_capa; + __le32 tx_beamforming_capa; + u8 asel_capa; +}; + +struct ra6w_cmd_mac_vhtcapability { + __le32 vht_capa_info; + __le16 rx_mcs_map; + __le16 rx_highest; + __le16 tx_mcs_map; + __le16 tx_highest; +}; + +struct ra6w_cmd_mac_he_mcs_nss_supp { + __le16 rx_mcs_80; + __le16 tx_mcs_80; + __le16 rx_mcs_160; + __le16 tx_mcs_160; + __le16 rx_mcs_80p80; + __le16 tx_mcs_80p80; +}; + +struct ra6w_cmd_mac_hecapability { + u8 mac_cap_info[RA6W_CMD_MAC_HE_MAC_CAPA_LEN]; + u8 phy_cap_info[RA6W_CMD_MAC_HE_PHY_CAPA_LEN]; + struct ra6w_cmd_mac_he_mcs_nss_supp mcs_supp; + u8 ppe_thres[RA6W_CMD_MAC_HE_PPE_THRES_MAX_LEN]; +}; + +struct ra6w_cmd_me_config_data { + struct ra6w_cmd_mac_htcapability ht_cap; + struct ra6w_cmd_mac_vhtcapability vht_cap; + struct ra6w_cmd_mac_hecapability he_cap; + __le16 tx_lft; + u8 phy_bw_max; + u8 ht_supp; + u8 vht_supp; + u8 he_supp; + u8 he_ul_on; + u8 ps_on; + u8 ant_div_on; + u8 dpsm; + u8 amsdu_tx; +}; + +struct ra6w_cmd_me_config_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_me_config_data data; +} __packed; + +struct ra6w_cmd_prim_ch_def { + __le16 ch_freq; + u8 ch_band; + s8 tx_max_pwr; + __le16 ch_flags; +}; + +struct ra6w_cmd_mac_ssid { + u8 ssid_len; + u8 ssid[RA6W_CMD_SSID_LEN]; +}; + +struct ra6w_cmd_me_chan_config_data { + struct ra6w_cmd_prim_ch_def chan24G[RA6W_CMD_SCAN_CHANNEL_24G]; + struct ra6w_cmd_prim_ch_def chan5G[RA6W_CMD_SCAN_CHANNEL_5G]; + u8 chan24G_cnt; + u8 chan5G_cnt; +}; + +struct ra6w_cmd_me_chan_config_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_me_chan_config_data data; +} __packed; + +struct ra6w_cmd_sc_start_data { + struct ra6w_cmd_prim_ch_def chan[RA6W_CMD_SCAN_CHANNEL_MAX]; + struct ra6w_cmd_mac_ssid ssid[RA6W_CMD_SCAN_SSID_MAX]; + u8 bssid[ETH_ALEN]; + __le32 ie_addr; + __le16 ie_len; + u8 vif_idx; + u8 n_channels; + u8 n_ssids; + u8 no_cck; + __le32 duration; + u8 ie[RA6W_CMD_SCAN_MAX_IE_LEN]; +}; + +struct ra6w_cmd_sc_start_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_sc_start_data data; +} __packed; + +struct ra6w_cmd_sc_cancel_data { + u8 vif_idx; +}; + +struct ra6w_cmd_sc_cancel_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_sc_cancel_data data; +} __packed; + +struct ra6w_cmd_sm_connect_data { + struct ra6w_cmd_mac_ssid ssid; + struct ra6w_cmd_mac_addr bssid; + struct ra6w_cmd_prim_ch_def chan; + __le32 flags; + __be16 ctrl_port_ethertype; + __le16 listen_interval; + u8 dont_wait_bcmc; + u8 auth_type; + u8 uapsd_queues; + u8 vif_idx; + __le16 ie_len; + u32 ie_buf[]; +}; + +struct ra6w_cmd_sm_connect_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_sm_connect_data data; +} __packed; + +struct ra6w_cmd_sm_connect_rsp { + u8 status; +}; + +struct ra6w_cmd_change_bcn_data { + u8 bcn_ptr[RA6W_CMD_BCN_SIZE]; + __le16 bcn_len; + __le16 tim_oft; + u8 tim_len; + u8 vif_id; + u8 csa_oft[RA6W_CMD_BCN_MAX_CSA_CPT]; +}; + +struct ra6w_cmd_change_bcn_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_change_bcn_data data; +} __packed; + +#define RA6W_CMD_MAC_RATESET_LEN 12 + +struct ra6w_cmd_mac_rateset { + u8 length; + u8 array[RA6W_CMD_MAC_RATESET_LEN]; +}; + +struct ra6w_cmd_sta_add_data { + struct ra6w_cmd_mac_addr mac_addr; + struct ra6w_cmd_mac_rateset rate_set; + struct ra6w_cmd_mac_htcapability ht_cap; + struct ra6w_cmd_mac_vhtcapability vht_cap; + struct ra6w_cmd_mac_hecapability he_cap; + __le32 flags; + __le16 aid; + u8 uapsd_queues; + u8 max_sp_len; + u8 opmode_notif; + u8 vif_idx; + u8 tdls_sta; + u8 tdls_sta_initiator; + u8 tdls_chsw_allowed; +}; + +struct ra6w_cmd_sta_add_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_sta_add_data data; +} __packed; + +struct ra6w_cmd_sta_del_data { + u8 sta_idx; + u8 is_tdls_sta; +}; + +struct ra6w_cmd_sta_del_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_sta_del_data data; +} __packed; + +struct ra6w_cmd_key_add_rsp { + u8 status; + u8 hw_key_index; +}; + +struct ra6w_cmd_sta_add_rsp { + u8 sta_idx; + u8 status; + u8 pm_state; +}; + +struct ra6w_cmd_ap_start_rsp { + u8 status; + u8 vif_idx; + u8 ch_idx; + u8 bcmc_idx; +}; + +struct ra6w_cmd_mon_mode_rsp { + u8 chan_index; + struct ra6w_cmd_oper_ch_info chan; +}; + +struct ra6w_cmd_probe_client_rsp { + u8 status; + __le32 probe_id; +}; + +struct ra6w_cmd_mem_read_rsp { + __le32 memaddr; + __le32 memdata; +}; + +struct ra6w_cmd_rf_per_rsp { + __le32 pass; + __le32 fcs; + __le32 phy; + __le32 overflow; +}; + +enum ra6w_cmd_stats_tx_bits { + RA6W_STATS_TX_STOP_BIT = BIT(0), + RA6W_STATS_TX_START_BIT = BIT(1), + RA6W_STATS_TX_REQ_BIT = BIT(2) +}; + +struct ra6w_cmd_stats_tx_data { + u8 req_type; +}; + +struct ra6w_cmd_stats_tx_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_stats_tx_data data; +} __packed; + +#define RA6W_CMD_CCK_OFDM_MCS_CNT 15 +#define RA6W_CMD_HT_GI_CNT 2 +#define RA6W_CMD_HT_MCS_CNT 8 +#define RA6W_CMD_VHT_GI_CNT 2 +#define RA6W_CMD_VHT_MCS_CNT 10 +#define RA6W_CMD_HE_GI_CNT 3 +#define RA6W_CMD_HE_MCS_CNT 10 + +struct ra6w_cmd_stats_tx_rsp { + u8 status; + __le64 t_success_cnt[4]; + __le64 t_fail_cnt[4]; + __le32 epr[2]; + u8 format_mod; + union { + struct { + __le64 success[RA6W_CMD_CCK_OFDM_MCS_CNT]; + __le64 fail[RA6W_CMD_CCK_OFDM_MCS_CNT]; + } non_ht; + struct { + __le64 success[RA6W_CMD_HT_GI_CNT][RA6W_CMD_HT_MCS_CNT]; + __le64 fail[RA6W_CMD_HT_GI_CNT][RA6W_CMD_HT_MCS_CNT]; + } ht; + struct { + __le64 success[RA6W_CMD_VHT_GI_CNT][RA6W_CMD_VHT_MCS_CNT]; + __le64 fail[RA6W_CMD_VHT_GI_CNT][RA6W_CMD_VHT_MCS_CNT]; + } vht; + struct { + __le64 success[RA6W_CMD_HE_GI_CNT][RA6W_CMD_HE_MCS_CNT]; + __le64 fail[RA6W_CMD_HE_GI_CNT][RA6W_CMD_HE_MCS_CNT]; + } he; + }; +}; + +struct ra6w_cmd_sc_survey_info { + __le16 freq; + s8 chan_noise_dbm; + __le32 chan_dwell_ms; + __le32 chan_busy_ms; +}; + +struct ra6w_cmd_legacy_info { + u32 format_mod : 4; + u32 ch_bw : 3; + u32 pre_type : 1; + u32 leg_length : 12; + u32 leg_rate : 4; +} __packed; + +struct ra6w_cmd_sc_result_ind { + __le16 length; + __le16 framectrl; + __le16 center_freq; + u8 band; + u8 sta_idx; + u8 inst_nbr; + s8 rssi; + struct ra6w_cmd_legacy_info legacy_info; + u32 payload[]; +}; + +#define RA6W_CMD_ASSOC_IE_SIZE 256 + +struct ra6w_cmd_sm_connect_ind { + __le16 conn_status; + struct ra6w_cmd_mac_addr bssid; + u8 is_roam; + u8 vif_idx; + u8 ap_idx; + u8 ch_idx; + u8 flag_qos; + u8 acm_bits; + __le16 assoc_req_ie_len; + __le16 assoc_rsp_ie_len; + __le16 assoc_id; + struct ra6w_cmd_oper_ch_info oper_chan; + __le32 edca_param[RA6W_CMD_AC_MAX]; + u8 assoc_ie_buf[RA6W_CMD_ASSOC_IE_SIZE]; +}; + +struct ra6w_cmd_disconnect_data { + __le16 deauth_reason; + u8 vif_idx; +}; + +struct ra6w_cmd_disconnect_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_disconnect_data data; +} __packed; + +struct ra6w_cmd_sm_disconnect_ind { + __le16 reason_code; + u8 vif_idx; + u8 reassoc; +}; + +struct ra6w_cmd_secury_key_info { + u8 length; + u32 array[RA6W_CMD_SECURY_KEY_LEN / 4]; +}; + +struct ra6w_cmd_key_add_data { + u8 key_idx; + u8 sta_id; + struct ra6w_cmd_secury_key_info key; + u8 cipher_suite; + u8 vif_idx; + u8 spp; + u8 pairwise; +}; + +struct ra6w_cmd_key_add_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_key_add_data data; +} __packed; + +struct ra6w_cmd_key_del_data { + u8 key_index; +}; + +struct ra6w_cmd_key_del_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_key_del_data data; +} __packed; + +struct ra6w_cmd_port_control_data { + u8 sta_idx; + u8 port_control_state; +}; + +struct ra6w_cmd_port_control_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_port_control_data data; +} __packed; + +struct ra6w_cmd_roc_data { + u8 op_code; + u8 vif_idx; + struct ra6w_cmd_oper_ch_info chan; + __le32 duration_ms; +}; + +struct ra6w_cmd_roc_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_roc_data data; +} __packed; + +struct ra6w_cmd_ap_start_data { + struct ra6w_cmd_mac_rateset basic_rates; + struct ra6w_cmd_oper_ch_info chan; + __le16 tim_oft; + __le16 bcn_int; + __le32 flags; + __be16 ctrl_port_ethertype; + u8 tim_len; + u8 vif_idx; + u8 beacon[RA6W_CMD_BCN_SIZE]; + __le16 bcn_len; +}; + +struct ra6w_cmd_ap_start_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_ap_start_data data; +} __packed; + +struct ra6w_cmd_ap_stop_data { + u8 vif_idx; +}; + +struct ra6w_cmd_ap_stop_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_ap_stop_data data; +} __packed; + +struct ra6w_cmd_mon_mode_data { + struct ra6w_cmd_oper_ch_info chan; + u8 ch_valid; + u8 uf_enable; +}; + +struct ra6w_cmd_mon_mode_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_mon_mode_data data; +} __packed; + +struct ra6w_cmd_probe_client_data { + u8 vif_idx; + u8 sta_idx; +}; + +struct ra6w_cmd_probe_client_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_probe_client_data data; +} __packed; + +struct ra6w_cmd_ap_isolate_data { + u8 ap_isolate; +}; + +struct ra6w_cmd_ap_isolate_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_ap_isolate_data data; +} __packed; + +struct ra6w_cmd_ap_isolate_rsp { + u8 ap_isolate; +}; + +struct ra6w_cmd_set_tx_power_data { + u8 vif_idx; + s8 tx_power; +}; + +struct ra6w_cmd_set_tx_power_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_set_tx_power_data data; +} __packed; + +struct ra6w_cmd_edca_data { + __le32 edca_param; + u8 uapsd_enabled; + u8 ac; + u8 vif_idx; +}; + +struct ra6w_cmd_edca_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_edca_data data; +} __packed; + +struct ra6w_cmd_set_power_mgmt_data { + u8 ps_mode; +}; + +struct ra6w_cmd_set_power_mgmt_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_set_power_mgmt_data data; +} __packed; + +struct ra6w_cmd_cqm_rssi_config_data { + u8 vif_idx; + s8 rssi_thold; + u8 rssi_hyst; +}; + +struct ra6w_cmd_cqm_rssi_config_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_cqm_rssi_config_data data; +} __packed; + +struct ra6w_cmd_me_mic_failure_ind { + struct ra6w_cmd_mac_addr mac_addr; + __le64 tsc; + u8 group; + u8 keyid; + u8 vif_idx; +}; + +struct ra6w_cmd_rssi_status_ind { + u8 vif_idx; + u8 rssi_status; + s8 rssi; +}; + +struct ra6w_cmd_dbg_mem_read_data { + __le32 mem_addr; +}; + +struct ra6w_cmd_dbg_mem_read_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_dbg_mem_read_data data; +} __packed; + +struct ra6w_cmd_dbg_mem_write_data { + __le32 mem_addr; + __le32 mem_value; +}; + +struct ra6w_cmd_dbg_mem_write_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_dbg_mem_write_data data; +} __packed; + +struct ra6w_cmd_dbg_mode_filter_data { + __le32 mode_filter; +}; + +struct ra6w_cmd_dbg_mode_filter_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_dbg_mode_filter_data data; +} __packed; + +struct ra6w_cmd_dbg_level_filter_data { + __le32 level_filter; +}; + +struct ra6w_cmd_dbg_level_filter_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_dbg_level_filter_data data; +} __packed; + +struct ra6w_cmd_rf_tx_data { + __le64 bssid; + __le64 dest_addr; + __le16 frequency; + __le16 num_frames; + __le16 frame_len; + u8 start; + __le32 tx_rate; + __le32 tx_power; + u8 gi; + u8 green_field; + u8 preamble_type; + u8 qos_enable; + u8 ack_policy; + u8 aifsn_val; +}; + +struct ra6w_cmd_rf_tx_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_rf_tx_data data; +} __packed; + +struct ra6w_cmd_rf_cw_data { + u8 start; + __le32 tx_power; + __le16 frequency; +}; + +struct ra6w_cmd_rf_cw_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_rf_cw_data data; +} __packed; + +struct ra6w_cmd_rf_cont_data { + __le16 frequency; + u8 start; + __le32 tx_rate; + __le32 tx_power; +}; + +struct ra6w_cmd_rf_cont_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_rf_cont_data data; +} __packed; + +struct ra6w_cmd_rf_ch_data { + __le16 frequency; +}; + +struct ra6w_cmd_rf_ch_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_rf_ch_data data; +} __packed; + +struct ra6w_cmd_rf_per_data { + u8 start; +}; + +struct ra6w_cmd_rf_per_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_rf_per_data data; +} __packed; + +struct ra6w_cmd_sm_ext_auth_req_ind { + u8 vif_idx; + struct ra6w_cmd_mac_ssid ssid; + struct ra6w_cmd_mac_addr bssid; + __le32 key_mgmt_suite; +}; + +struct ra6w_cmd_sm_ext_auth_req_rsp_data { + u8 vif_idx; + __le16 status; +}; + +struct ra6w_cmd_sm_ext_auth_req_rsp_req { + struct ra6w_cmd_hdr hdr; + struct ra6w_cmd_sm_ext_auth_req_rsp_data data; +} __packed; + +struct ra6w_cmd_channel_switch_ind { + u8 chan_index; + u8 roc_req; + u8 vif_idx; + u8 roc_tdls; + __le32 duration_us; + __le16 freq; +}; + +struct ra6w_cmd_channel_pre_switch_ind { + u8 chan_index; +}; + +struct ra6w_cmd_ap_probe_client_ind { + u8 vif_idx; + u8 sta_idx; + u8 client_present; + __le32 probe_id; +}; + +struct ra6w_cmd_pktloss_ind { + u8 vif_idx; + struct ra6w_cmd_mac_addr mac_addr; + __le32 num_packets; +}; + +struct ra6w_cmd_csa_counter_ind { + u8 vif_idx; + u8 csa_count; +}; + +struct ra6w_cmd_csa_finish_ind { + u8 vif_idx; + u8 status; + u8 chan_idx; +}; + +struct ra6w_cmd_csa_traffic_ind { + u8 vif_idx; + u8 enable; +}; + +#endif /* RA6W_CMD_H */ From patchwork Thu Apr 17 13:52:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882272 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A7F7B24E4B2 for ; Thu, 17 Apr 2025 13:53:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898003; cv=none; b=FP/rmB8Ybw15Te9VmBoAr55BAxUx3pTd3/vajRZj+fdWcGGFC18+jBuQ2hUosur4kDuKkiHih0xlvY/6r+zqz5DYt0MJVGYyX85N4nqDcL/zrqSB8uFQS9ygjNEVUOu//5gcGGgjSHWdz2RbiJ6VM5rua1fo9lJbwlrgi1IhpRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898003; c=relaxed/simple; bh=tJ07C6YZyODuHeOLhuwjyJ8CF5t/NnWhjqQ5uX/6Y5A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=AWswLau2K6aRaB357ATyzTqSQjDjkfGyyJlrBq6KyFqLsoy1Fzug+oDH3scvWFrY9+jEZpfrHQ/+hiyZNLfD5omOPk/c3JV4NlTrmWsWozZ6j2cHGlIb2GzsOBMGxl085bYKrN6hs+Lf19k1itouZ1WYn0Dzf2ofSkyGcL2uaAY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: n1TXYwYmRSiWdujinXtaYQ== X-CSE-MsgGUID: pqrHJYwKQiC1IIlqoXToLA== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 17 Apr 2025 22:53:20 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 5262D4006DE8; Thu, 17 Apr 2025 22:53:16 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 08/38] ra6w: add core.h Date: Thu, 17 Apr 2025 16:52:06 +0300 Message-Id: <20250417135236.52410-9-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/core.h | 99 ++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/core.h diff --git a/drivers/net/wireless/renesas/ra6w/core.h b/drivers/net/wireless/renesas/ra6w/core.h new file mode 100644 index 000000000000..78f7102e15f6 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/core.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_CORE_H +#define RA6W_CORE_H + +#include +#include +#include +#include +#include + +#include "status.h" +#include "cmd.h" +#include "rx.h" +#include "tx.h" +#include "indi.h" +#include "ctrl.h" +#include "sdio.h" +#include "recovery.h" + +#define RA6W_BASE_HDR_SIZE (sizeof(u8) + sizeof(u8) + sizeof(u16)) +#define RA6W_GET_DATA_SIZE(ext_len, data_len) (RA6W_BASE_HDR_SIZE + (ext_len) + (data_len)) + +struct ra6w_core_stat { + u32 packets; + u32 err; +}; + +struct ra6w_core_stats { + struct ra6w_core_stat tx; + struct ra6w_core_stat rx; +}; + +struct ra6w_sys_info { + struct ra6w_cmd_fw_ver_rsp fw_ver; + char fw_version[32]; + u8 machw_support_type; + u8 default_mac[ETH_ALEN]; +}; + +enum ra6w_core_data_event { + RA6W_CORE_EVENT_DATA, + + RA6W_CORE_EVENT_DATA_MAX, +}; + +#define RA6W_CORE_EVENT_RESET RA6W_CORE_EVENT_DATA_MAX +#define RA6W_CORE_EVENT_MASK (BIT(RA6W_CORE_EVENT_DATA) | BIT(RA6W_CORE_EVENT_RESET)) + +enum ra6w_core_handler_id { + RA6W_CORE_HNDL_RX, + RA6W_CORE_HNDL_CTRL, + RA6W_CORE_HNDL_INDI, + RA6W_CORE_HNDL_STATUS, + + RA6W_CORE_HNDL_MAX, +}; + +/* + * @priv: private cfg80211 data + * @task: main kthread task + * @event: main kthread event data + * @status: status of Tx, Rx, ctrl fw routines + * @ctrl: synchronous fw routine data + * @indi: asynchronous fw routine data + * @rx: Rx routine data + * @tx: Tx routine data + * @stats: Rx, Tx statistics + * @sinfo: fw version information + * @recovery: recovery data + */ +struct ra6w_core { + struct ra6w_cfg80211_priv *priv; + struct task_struct *task; + struct ra6w_q_event event; + struct ra6w_status status; + struct ra6w_ctrl ctrl; + struct ra6w_indi indi; + struct ra6w_rx rx; + struct ra6w_tx tx; + struct ra6w_core_stats stats; + struct ra6w_sys_info sinfo; + struct ra6w_recovery recovery; +}; + +union ra6w_core_data { + struct ra6w_rx_buf rx; + struct ra6w_indi_buf indi; + struct ra6w_ctrl_rsp ctrl; +}; + +int ra6w_core_init(struct ra6w_core *core); +void ra6w_core_deinit(struct ra6w_core *core); +int ra6w_core_post_init(struct ra6w_core *core); + +#endif /* RA6W_CORE_H */ From patchwork Thu Apr 17 13:52:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882271 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5A34024EAA4 for ; Thu, 17 Apr 2025 13:53:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898012; cv=none; b=AVHeLq6s5gmDjc5Ru8E4D9Gu2+3U7lwMbVVDnG1wOjkcDJjtLv8dQb3MflugxsEt1iIbA34n1JWSTy6+3BL4rkU+PLQ7/eRUbwaBCci8YNURounly4rLlVMmClrN6ZbnGKCq0Yfp3wnXSZmGIS06auaOwTyPcJs9V+5zymKVynw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898012; c=relaxed/simple; bh=U8E1qiaNsTXurFNMRo6kztTdOlLLEvAcaFMg0dAzIs0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=gJQOB3VrEnc2Oe8KiGXoVQt1aj8i3hK+9wNfRLkVsSlhf100mea9BudOkhLAuleD81nzZJToDknzc8smrvFw+x05dHr0Al8YWii74KqY6Xrgw4bx0FZI5jxcgMTBKh2Q1BbMxdEP3YQmJRWHZceAyZ4xOrcnbTAn+4eQ7BopAZw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: y8DCk4F4SNSPQ4drtqwDrw== X-CSE-MsgGUID: bJV5BIm0SiyeK8usPmo6sg== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 17 Apr 2025 22:53:29 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 0556E4006DE8; Thu, 17 Apr 2025 22:53:25 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 10/38] ra6w: add ctrl.h Date: Thu, 17 Apr 2025 16:52:08 +0300 Message-Id: <20250417135236.52410-11-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/ctrl.h | 100 +++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/ctrl.h diff --git a/drivers/net/wireless/renesas/ra6w/ctrl.h b/drivers/net/wireless/renesas/ra6w/ctrl.h new file mode 100644 index 000000000000..7d98251d81ae --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/ctrl.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_CTRL_H +#define RA6W_CTRL_H + +#include + +#define RA6W_CTRL_DATA_LEN 980 +#define RA6W_CTRL_RSP_EXT_LEN (sizeof(struct ra6w_ctrl_rsp_ext_hdr)) +#define RA6W_CTRL_EVENT_RESET 0 + +struct ra6w_ctrl_rsp_ext_hdr { + u32 status : 32; +}; + +struct ra6w_ctrl_rsp { + u8 cmd; + u8 ext_len; + __le16 data_len; + struct ra6w_ctrl_rsp_ext_hdr ext_hdr; + u8 data[RA6W_CTRL_DATA_LEN]; +}; + +struct ra6w_ctrl { + struct ra6w_q_event event; + u8 cmd; + void *rsp; + u16 rsp_len; +}; + +extern const int chnl2bw[]; + +struct ra6w_cfg80211_vif; +struct ra6w_cfg80211_key; + +void ra6w_ctrl_init(struct ra6w_ctrl *ctrl); +void ra6w_ctrl_event_post(struct ra6w_ctrl *ctrl, const struct sk_buff *skb); +int ra6w_ctrl_dev_hw_reset(struct ra6w_ctrl *ctrl); +int ra6w_ctrl_dev_reset(struct ra6w_ctrl *ctrl); +int ra6w_ctrl_dev_start(struct ra6w_ctrl *ctrl, const struct ra6w_cmd_phy_cfg *phy_config); +int ra6w_ctrl_otp_mac_addr_get(struct ra6w_ctrl *ctrl, u8 *mac); +int ra6w_ctrl_if_add(struct ra6w_ctrl *ctrl, const u8 *mac, u8 iftype, bool p2p, + struct ra6w_cmd_add_if_rsp *rsp); +int ra6w_ctrl_if_remove(struct ra6w_ctrl *ctrl, u8 vif_idx); +int ra6w_ctrl_me_config(struct ra6w_ctrl *ctrl, struct wiphy *wiphy); +int ra6w_ctrl_chan_config(struct ra6w_ctrl *ctrl, struct wiphy *wiphy); +int ra6w_ctrl_scan_start(struct ra6w_ctrl *ctrl, struct cfg80211_scan_request *param); +int ra6w_ctrl_scan_cancel(struct ra6w_ctrl *ctrl, const struct ra6w_cfg80211_vif *vif); +int ra6w_ctrl_connect(struct ra6w_ctrl *ctrl, const struct net_device *ndev, + struct cfg80211_connect_params *sme, + struct ra6w_cmd_sm_connect_rsp *rsp); +int ra6w_ctrl_disconnect_req(struct ra6w_ctrl *ctrl, const struct ra6w_cfg80211_vif *vif, + u16 reason); +int ra6w_ctrl_add_key_req(struct ra6w_ctrl *ctrl, const struct ra6w_cfg80211_key *key, + const u8 *key_data, u32 key_len, u8 key_index, + struct ra6w_cmd_key_add_rsp *rsp); +int ra6w_ctrl_del_key_req(struct ra6w_ctrl *ctrl, u8 key_index); +int ra6w_ctrl_add_station_req(struct ra6w_ctrl *ctrl, struct station_parameters *params, + const u8 *mac, u8 vif_idx, struct ra6w_cmd_sta_add_rsp *rsp); +int ra6w_ctrl_del_station_req(struct ra6w_ctrl *ctrl, u8 sta_idx, bool is_tdls_sta); +int ra6w_ctrl_port_control_req(struct ra6w_ctrl *ctrl, bool authorized, u8 sta_idx); +int ra6w_ctrl_remain_on_channel_req(struct ra6w_ctrl *ctrl, const struct ra6w_cfg80211_vif *vif, + struct ieee80211_channel *chan, int duration); +int ra6w_ctrl_cancel_remain_on_channel_req(struct ra6w_ctrl *ctrl); +int ra6w_ctrl_ap_start_req(struct ra6w_ctrl *ctrl, struct ra6w_cfg80211_vif *vif, + struct cfg80211_ap_settings *settings, + struct ra6w_cmd_ap_start_rsp *rsp); +int ra6w_ctrl_ap_stop_req(struct ra6w_ctrl *ctrl, const struct ra6w_cfg80211_vif *vif); +int ra6w_ctrl_change_beacon_req(struct ra6w_ctrl *ctrl, u8 vif_idx, const u8 *bcn, u16 bcn_len, + u16 tim_oft, u16 tim_len, const u16 *csa_oft); +int ra6w_ctrl_monitor_mode_req(struct ra6w_ctrl *ctrl, const struct cfg80211_chan_def *chandef, + struct ra6w_cmd_mon_mode_rsp *rsp); +int ra6w_ctrl_probe_client_req(struct ra6w_ctrl *ctrl, u8 vif_idx, u8 sta_idx, + struct ra6w_cmd_probe_client_rsp *rsp); +int ra6w_ctrl_set_ap_isolate_req(struct ra6w_ctrl *ctrl, u8 ap_isolate, + struct ra6w_cmd_ap_isolate_rsp *rsp); +int ra6w_ctrl_edca_req(struct ra6w_ctrl *ctrl, u8 ac, u32 param, bool uapsd, u8 vif_idx); +int ra6w_ctrl_set_tx_power_req(struct ra6w_ctrl *ctrl, u8 vif_idx, s8 tx_power); +int ra6w_ctrl_set_power_mgmt_req(struct ra6w_ctrl *ctrl, u8 ps_mode); +int ra6w_ctrl_cqm_rssi_config_req(struct ra6w_ctrl *ctrl, u8 vif_idx, + s32 rssi_thold, u32 rssi_hyst); +int ra6w_ctrl_mem_read_req(struct ra6w_ctrl *ctrl, u32 addr, + struct ra6w_cmd_mem_read_rsp *rsp); +int ra6w_ctrl_mem_write_req(struct ra6w_ctrl *ctrl, u32 addr, u32 value); +int ra6w_ctrl_dbg_mode_filter_req(struct ra6w_ctrl *ctrl, u32 mode); +int ra6w_ctrl_dbg_level_filter_req(struct ra6w_ctrl *ctrl, u32 level); +int ra6w_ctrl_rf_tx_req(struct ra6w_ctrl *ctrl, struct ra6w_cmd_rf_tx_data *data); +int ra6w_ctrl_rf_cw_req(struct ra6w_ctrl *ctrl, const struct ra6w_cmd_rf_cw_data *data); +int ra6w_ctrl_rf_cont_req(struct ra6w_ctrl *ctrl, const struct ra6w_cmd_rf_cont_data *data); +int ra6w_ctrl_rf_ch_req(struct ra6w_ctrl *ctrl, u16 frequency); +int ra6w_ctrl_rf_per_req(struct ra6w_ctrl *ctrl, u8 start, struct ra6w_cmd_rf_per_rsp *rsp); +int ra6w_ctrl_sm_ext_auth_req_rsp(struct ra6w_ctrl *ctrl, u8 vif_idx, u16 status); +int ra6w_ctrl_update_fw_ver(struct ra6w_ctrl *ctrl); +int ra6w_ctrl_stats_tx_req(struct ra6w_ctrl *ctrl, u8 req_type, struct ra6w_cmd_stats_tx_rsp *rsp); +int ra6w_ctrl_stats_tx_start_req(struct ra6w_ctrl *ctrl, u8 req_type); + +#endif /* RA6W_CTRL_H */ From patchwork Thu Apr 17 13:52:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882270 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D31D224EA9C for ; Thu, 17 Apr 2025 13:53:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898020; cv=none; b=KS8MLTzOcntCoKULohH10Ig3uWpkeEfwqKZHYTNs8aBiKVvNScUjCwtsXLWYONjzr+DvN1HrhTPABRTApL7+JxTWFBLN6NNz46mJpOMyo/Dqfdk3x2eBzL+fmhZT6pgF1QXs5gcDfvhXuIHMJgvVdPfHmhcP09FCLnv36Z+OuCk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898020; c=relaxed/simple; bh=seVdcN2f9FLehHM8iyNX8zksgZhOD1X2/Bgj52pP+ao=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=t5kCS4XcbGg7svG+9D7rJo1Ml261CyjHi47lAOvR9k/09PdPy7t14tMAQSffwp9g50MEkkCj1vShu3s+9Dpj9OUApeBrK2GMPmbqLP9DY0i/W+YxmfqKa8wFIfg/zaMBjMTixfSEQSqESuqEDpDrwcSy2Xn8a5whLyIRgxp0wXg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: CE6Z+OnnRYioRbDWXPLDzQ== X-CSE-MsgGUID: x46zBHQWTdewixjEtYfEWw== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 17 Apr 2025 22:53:37 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 496684006DE8; Thu, 17 Apr 2025 22:53:33 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 12/38] ra6w: add dbgfs.c Date: Thu, 17 Apr 2025 16:52:10 +0300 Message-Id: <20250417135236.52410-13-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/dbgfs.c | 201 ++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/dbgfs.c diff --git a/drivers/net/wireless/renesas/ra6w/dbgfs.c b/drivers/net/wireless/renesas/ra6w/dbgfs.c new file mode 100644 index 000000000000..9c764feebe6d --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/dbgfs.c @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * This file contains debugfs handlers. + * + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#include +#include +#include + +#include "core.h" +#include "cfg80211.h" +#include "params.h" +#include "dbg.h" +#include "dbgfs.h" + +static ssize_t ra6w_dbgfs_stats_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + const struct ra6w_cfg80211_priv *priv = file->private_data; + const struct ra6w_core_stat *tx = &priv->core->stats.tx; + const struct ra6w_core_stat *rx = &priv->core->stats.rx; + char *buf; + size_t n = 0; + size_t len = 256; + ssize_t ret = 0; + + buf = kzalloc(len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + n += scnprintf(&buf[n], len - n, "tx packets: %u\n", tx->packets); + n += scnprintf(&buf[n], len - n, "tx errors : %u\n", tx->err); + n += scnprintf(&buf[n], len - n, "rx packets: %u\n", rx->packets); + n += scnprintf(&buf[n], len - n, "rx errors : %u\n", rx->err); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, n); + + kfree(buf); + + return ret; +} + +static const struct file_operations ra6w_dbgfs_stats_ops = { + .read = ra6w_dbgfs_stats_read, + .open = simple_open, + .llseek = generic_file_llseek, +}; + +static ssize_t ra6w_dbgfs_dev_info_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ +#define FSCNPRINTF(n, len, buf, NBIT, str) \ +do { \ + bool set = test_bit(NBIT, &features); \ + (n) += scnprintf(&(buf)[n], (len) - (n), "%s : %d\n", str, set); \ +} while (0) + + struct ra6w_cfg80211_priv *priv = file->private_data; + struct ra6w_core *core = priv->core; + const struct ra6w_cmd_fw_ver_rsp *fw_ver = &core->sinfo.fw_ver; + unsigned long features; + char *buf; + size_t n = 0; + size_t len = count; + ssize_t ret = 0; + + buf = kzalloc(len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + n += scnprintf(&buf[n], len - n, "fw_version : %s\n", core->sinfo.fw_version); + n += scnprintf(&buf[n], len - n, "machw_features : 0x%X\n", + le32_to_cpu(fw_ver->machw_features)); + n += scnprintf(&buf[n], len - n, "machw_version : 0x%X\n", + le32_to_cpu(fw_ver->machw_version)); + n += scnprintf(&buf[n], len - n, "phy_feature : 0x%X\n", + le32_to_cpu(fw_ver->phy_feature)); + n += scnprintf(&buf[n], len - n, "phy_version : 0x%X\n", + le32_to_cpu(fw_ver->phy_version)); + n += scnprintf(&buf[n], len - n, "dev features : 0x%X:\n", fw_ver->features); + + features = (unsigned long)le32_to_cpu(fw_ver->features); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_BCN_BIT, " BCN "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_RADAR_BIT, " RADAR "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_PS_BIT, " PS "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_UAPSD_BIT, " UAPSD "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_AMPDU_BIT, " AMPDU "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_AMSDU_BIT, " AMSDU "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_P2P_BIT, " P2P "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_P2P_GO_BIT, " P2P_GO "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_UMAC_BIT, " UMAC "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_VHT_BIT, " VHT "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_BFMEE_BIT, " BFMEE "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_BFMER_BIT, " BFMER "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_WAPI_BIT, " WAPI "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_MFP_BIT, " MFP "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_MU_MIMO_RX_BIT, " MU_MIMO_RX "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_MU_MIMO_TX_BIT, " MU_MIMO_TX "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_MESH_BIT, " MESH "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_TDLS_BIT, " TDLS "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_ANT_DIV_BIT, " ANT_DIV "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_UF_BIT, " UF "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_AMSDU_MAX_SIZE_0_BIT, " AMSDU_MAX_SIZE_0"); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_AMSDU_MAX_SIZE_1_BIT, " AMSDU_MAX_SIZE_1"); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_HE_BIT, " HE "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_TWT_BIT, " TWT "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_FTM_INIT_BIT, " FTM_INIT "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_FAKE_FTM_RSP_BIT, " FAKE_FTM_RSP "); + FSCNPRINTF(n, len, buf, RA6W_DEV_FEAT_HW_LLCSNAP_INS_BIT, " HW_LLCSNAP_INS "); + + n += scnprintf(&buf[n], len - n, "max sta : %u\n", le16_to_cpu(fw_ver->max_sta_nb)); + n += scnprintf(&buf[n], len - n, "max vif : %u\n", fw_ver->max_vif_nb); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, n); + + kfree(buf); + + return ret; +} + +static const struct file_operations ra6w_dbgfs_dev_info_ops = { + .read = ra6w_dbgfs_dev_info_read, + .open = simple_open, + .llseek = generic_file_llseek, +}; + +static ssize_t ra6w_dbgfs_mac_info_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ +#define FSCNPRINTF(n, len, buf, NBIT, str) \ +do { \ + bool set = test_bit(NBIT, &features); \ + (n) += scnprintf(&(buf)[n], (len) - (n), "%s : %d\n", str, set); \ +} while (0) + + struct ra6w_cfg80211_priv *priv = file->private_data; + struct ra6w_core *core = priv->core; + struct ra6w_sys_info *sinfo = &core->sinfo; + u32 mac_feat = le32_to_cpu(sinfo->fw_ver.machw_features); + unsigned long features = (unsigned long)mac_feat; + char *buf; + size_t n = 0; + size_t len = count; + ssize_t ret = 0; + + buf = kzalloc(len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + n += scnprintf(&buf[n], len - n, "mac features: 0x%X:\n", mac_feat); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_QOS_BIT, " QOS "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_EDCA_BIT, " EDCA "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_SME_BIT, " SME "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_SECURITY_BIT, " SECURITY "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_TKIP_BIT, " TKIP "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_CCMP_BIT, " CCMP "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_RCE_BIT, " RCE "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_GCMP_BIT, " GCMP "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_HT_BIT, " HT "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_VHT_BIT, " VHT "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_TPC_BIT, " TPC "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_WAPI_BIT, " WAPI "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_COEX_BIT, " COEX "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_HE_BIT, " HE "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_BFMEE_BIT, " BFMEE "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_BFMER_BIT, " BFMER "); + FSCNPRINTF(n, len, buf, RA6W_MAC_FEAT_MU_MIMO_TX_BIT, " MU_MIMO_TX"); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, n); + + kfree(buf); + + return ret; +} + +static const struct file_operations ra6w_dbgfs_mac_info_ops = { + .read = ra6w_dbgfs_mac_info_read, + .open = simple_open, + .llseek = generic_file_llseek, +}; + +void ra6w_dbgfs_register(struct ra6w_cfg80211_priv *priv) +{ + struct dentry *root; + + root = debugfs_create_dir(KBUILD_MODNAME, priv->wiphy->debugfsdir); + priv->root = root; + + debugfs_create_file("stats", 0600, root, priv, &ra6w_dbgfs_stats_ops); + debugfs_create_file("dev_info", 0600, root, priv, &ra6w_dbgfs_dev_info_ops); + debugfs_create_file("mac_info", 0600, root, priv, &ra6w_dbgfs_mac_info_ops); + debugfs_create_u32("log_level", 0600, root, &ra6w_params_list.module_params.log_level); +} + +void ra6w_dbgfs_deregister(struct ra6w_cfg80211_priv *priv) +{ + debugfs_remove_recursive(priv->root); + priv->root = NULL; +} From patchwork Thu Apr 17 13:52:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882269 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 20C0E24EF65 for ; Thu, 17 Apr 2025 13:53:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898027; cv=none; b=kIFFmWNadjdklA1Hv7GXb7uIQFmYkntGD/ajc5GYEPhqvT2W2q11zQQqvwNAY7kbZZY+8qYQsJxMIeca0RhNM3nnIHavwt4h1u1NIzzdtYVo3Ds09Qii81bzSqV/grflk2xez32WMlZNIag1gM3QHdALz6tbSITCmArynGcJjBQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898027; c=relaxed/simple; bh=3+eUbsLPpjSU0tCw99VJHJrXkdBt2ZW/dgX5V02MF7g=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=XLqyrbqs8yIFAxuuxCeZNEKyed9ORtGGhT4DDKZXD6PjhgQLJ5D5SaRwstRr5gf6pg3RwjqMx7YBgL3wOwG8mr/idZPymg9jOD9uZKmEoQPaLJ5QRxi3GZaBMULTG+oArpWhVklxQ6dsdRKLnlLYVqQVJXC9eF2vSP8kt6hbSrI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: ox6e45XQSEezBZv5GAAzOw== X-CSE-MsgGUID: S08UMYjHT3yGHZ0HyyfHyA== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 17 Apr 2025 22:53:45 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 8B96F4006DE8; Thu, 17 Apr 2025 22:53:42 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 14/38] ra6w: add dev.c Date: Thu, 17 Apr 2025 16:52:12 +0300 Message-Id: <20250417135236.52410-15-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/dev.c | 233 ++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/dev.c diff --git a/drivers/net/wireless/renesas/ra6w/dev.c b/drivers/net/wireless/renesas/ra6w/dev.c new file mode 100644 index 000000000000..16716fb4fdd7 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/dev.c @@ -0,0 +1,233 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * This file contains netdevice communication. + * + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#include +#include +#include +#include + +#include "core.h" +#include "cfg80211.h" +#include "dev.h" +#include "params.h" +#include "dbg.h" + +static int ra6w_dev_ndo_open(struct net_device *ndev) +{ + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_priv *priv = vif->priv; + + vif->up = true; + priv->vif_started++; + + if (ra6w_recovery_reprobe_get()) { + ra6w_recovery_reprobe_set(false); + return 0; + } + + netif_carrier_off(ndev); + + return 0; +} + +static int ra6w_dev_ndo_close(struct net_device *ndev) +{ + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + struct ra6w_cfg80211_priv *priv = NULL; + + if (!vif) + return 0; + + priv = vif->priv; + if (!priv) + return 0; + + if (priv->scan_request) { + ra6w_ctrl_scan_cancel(&priv->core->ctrl, vif); + ra6w_cfg80211_scan_done(priv); + } + + vif->up = false; + if (netif_carrier_ok(ndev)) { + if (vif->type == NL80211_IFTYPE_STATION || + vif->type == NL80211_IFTYPE_P2P_CLIENT) + cfg80211_disconnected(ndev, WLAN_REASON_DEAUTH_LEAVING, + NULL, 0, true, GFP_ATOMIC); + + netif_carrier_off(ndev); + } + + if (vif->type == NL80211_IFTYPE_MONITOR) + priv->mon_vif_idx = RA6W_CFG80211_VIF_IDX_INVALID; + + priv->vif_started--; + + return 0; +} + +static struct ra6w_cfg80211_sta *ra6w_dev_get_sta(struct ra6w_cfg80211_vif *vif, + struct sk_buff *skb) +{ + struct ra6w_cfg80211_sta *sta = NULL; + + if (!vif) + return NULL; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + sta = vif->sta.ap; + if (sta && sta->valid) + return sta; + + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: { + const struct ethhdr *eth = (struct ethhdr *)skb->data; + + if (is_multicast_ether_addr(eth->h_dest)) { + sta = ra6w_cfg80211_sta_get(vif->priv, vif->ap.bcmc_index); + if (sta && sta->valid) + return sta; + + break; + } + + list_for_each_entry(sta, &vif->ap.sta_list, list) { + if (sta->valid && ether_addr_equal(sta->mac_addr, eth->h_dest)) + return sta; + } + } + break; + default: + break; + } + + return NULL; +} + +static netdev_tx_t ra6w_dev_tx(struct ra6w_cfg80211_vif *vif, struct sk_buff *skb) +{ + struct ra6w_cfg80211_priv *priv = vif->priv; + struct ra6w_tx *tx = &priv->core->tx; + struct ra6w_tx_buf *tx_buf = NULL; + const struct ra6w_cfg80211_sta *sta = NULL; + u8 hdr_size = RA6W_GET_DATA_SIZE(RA6W_TX_EXT_LEN, 0); + u8 tx_buf_ac = RA6W_TX_DATA_AC; + u8 sta_idx = RA6W_CFG80211_STA_IDX_INVALID; + u8 prio = skb->priority; + + if (skb->len - hdr_size > RA6W_CMD_DATA_SIZE) + return -EINVAL; + + sta = ra6w_dev_get_sta(vif, skb); + if (sta) + sta_idx = sta->sta_idx; + + if (sta_idx == RA6W_CFG80211_STA_IDX_INVALID) + return -ENXIO; + + if (skb_headroom(skb) < hdr_size) { + int ret; + + ret = pskb_expand_head(skb, hdr_size, 0, GFP_ATOMIC); + if (ret < 0) { + ra6w_err("[%s] SKB resize failed: hdr_size %u (reserved %u) ret %d\n", + __func__, hdr_size, skb_headroom(skb), ret); + + return -EFAULT; + } + } + + if (skb->priority == 0 || skb->priority > IEEE80211_QOS_CTL_TAG1D_MASK) + prio = cfg80211_classify8021d(skb, NULL); + + tx_buf = (struct ra6w_tx_buf *)skb_push(skb, hdr_size); + tx_buf->cmd = RA6W_CMD_DATA_TX; + tx_buf->ext_len = RA6W_TX_EXT_LEN; + tx_buf->ext_hdr.buf_idx = tx_buf_ac; + tx_buf->ext_hdr.tid = prio; + tx_buf->ext_hdr.vif_idx = vif->vif_idx; + tx_buf->ext_hdr.sta_idx = sta_idx; + tx_buf->ext_hdr.flags = 0; + tx_buf->ext_hdr.sn = 0; + tx_buf->data_len = cpu_to_le16(skb->len - hdr_size); + + return ra6w_tx_event_post(tx, tx_buf_ac, skb); +} + +static netdev_tx_t ra6w_dev_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + int ret; + struct ra6w_cfg80211_vif *vif = netdev_priv(ndev); + + ret = ra6w_dev_tx(vif, skb); + if (ret) { + dev_kfree_skb(skb); + ndev->stats.tx_errors++; + ndev->stats.tx_dropped++; + + return NETDEV_TX_OK; + } + + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += skb->len; + + return NETDEV_TX_OK; +} + +static const struct net_device_ops ra6w_dev_ops = { + .ndo_open = ra6w_dev_ndo_open, + .ndo_stop = ra6w_dev_ndo_close, + .ndo_start_xmit = ra6w_dev_ndo_start_xmit, + .ndo_set_mac_address = eth_mac_addr, +}; + +static const struct net_device_ops ra6w_dev_monitor_ops = { + .ndo_open = ra6w_dev_ndo_open, + .ndo_stop = ra6w_dev_ndo_close, + .ndo_set_mac_address = eth_mac_addr, +}; + +static u32 ra6w_dev_ethtool_get_link(struct net_device *ndev) +{ + return netif_carrier_ok(ndev); +} + +static const struct ethtool_ops ra6w_ethtool_ops = { + .get_link = ra6w_dev_ethtool_get_link, + .get_drvinfo = cfg80211_get_drvinfo, +}; + +void ra6w_dev_init(struct net_device *ndev) +{ + if (!ndev) + return; + + ether_setup(ndev); + + ndev->priv_flags &= ~IFF_TX_SKB_SHARING; + + ra6w_dev_set_ops(ndev); + ndev->ethtool_ops = &ra6w_ethtool_ops; + + ndev->needs_free_netdev = true; + ndev->watchdog_timeo = RA6W_CMD_TX_LIFETIME_MS; + ndev->needed_headroom += RA6W_GET_DATA_SIZE(RA6W_TX_EXT_LEN, 0); + ndev->hw_features = 0; +} + +void ra6w_dev_set_ops(struct net_device *ndev) +{ + ndev->netdev_ops = &ra6w_dev_ops; + ndev->tx_queue_len = RA6W_TX_BUF_Q_MAX; +} + +void ra6w_dev_set_monitor_ops(struct net_device *ndev) +{ + ndev->netdev_ops = &ra6w_dev_monitor_ops; +} From patchwork Thu Apr 17 13:52:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882268 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7B73324EF6A for ; Thu, 17 Apr 2025 13:53:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898036; cv=none; b=QLr68YvCMMyIMhZcpaSHvGnQT7iPbBPKyGRgxetbh9pBQXdoFuz5M1Xe5E09ULuntz7x81l2/y6ye+sRMoHuhty0ILxRijVKfGCOYrHL8pEM+PasTdvapMGEtdaGF97mHJbNypwSjI5rirV1Ndytkl2tdhl0Fsk0iOKHS63XWvU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898036; c=relaxed/simple; bh=4O/s4m3lOto2Ap8nDH6mV+g/IQN9iN+/H0DrV2Wtjw8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=VkRwvFScImwktFeWr+Gsei2L07XxWKFawa+UX3V1KEvgwHNrAyww1AIFgq9lsZnEtSJMxm5QnE9IihKrDgsuZ8y6bLBatSzd3rEFLLyKT2bIXUTnqihZOSa2NfRt5DbM4aOJhSBrtOTDXSt2JtCVJJwPI9BL/BOiR2sKiqoba4E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: xclw8bDpSvaLGOpvB4nFMg== X-CSE-MsgGUID: 8lYi64GtQHyvQC3pUW3ICA== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 17 Apr 2025 22:53:54 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id D80464005025; Thu, 17 Apr 2025 22:53:50 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 16/38] ra6w: add if.h Date: Thu, 17 Apr 2025 16:52:14 +0300 Message-Id: <20250417135236.52410-17-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/if.h | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/if.h diff --git a/drivers/net/wireless/renesas/ra6w/if.h b/drivers/net/wireless/renesas/ra6w/if.h new file mode 100644 index 000000000000..35fc7d2865d4 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/if.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_IF_H +#define RA6W_IF_H + +struct ra6w_if_ops { + int (*read)(struct sdio_func *func, void *data, int len); + int (*write)(struct sdio_func *func, void *data, int len); +}; + +struct ra6w_if_dev { + struct sdio_func *func; + bool dev_on_resume; +}; + +struct ra6w_if { + struct ra6w_core core; + struct ra6w_if_dev dev; + const struct ra6w_if_ops *ops; +}; + +static inline int ra6w_if_read(struct ra6w_if *ifp, void *buf, int len) +{ + if (ifp->core.recovery.in_recovery) + return -EINPROGRESS; + + return ifp->ops->read(ifp->dev.func, buf, len); +} + +static inline int ra6w_if_write(struct ra6w_if *ifp, void *buf, int len) +{ + if (ifp->core.recovery.in_recovery) + return -EINPROGRESS; + + return ifp->ops->write(ifp->dev.func, buf, len); +} + +#endif /* RA6W_IF_H */ From patchwork Thu Apr 17 13:52:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882267 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 217A124EAA4 for ; Thu, 17 Apr 2025 13:54:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898044; cv=none; b=AGxbKvvFeQNUvtK01RmB5PB6Nt0/bKGRlmnzo94ILdrqjhWiwaDQEI6nnrmj1o72z13Pw78+MX8iKV2YYM7XvhS4eXchcAi5hqDjaUpiabiJMqPiL8D7vVtw6f8XZJWZG4ww3wM8Q3MYEleTRxLyohjyy3Nz7okdcAqAqlHLjJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898044; c=relaxed/simple; bh=YMaLRV2UlDXx+u6uIXARxUODfFPonUWr4uQX3CuKn9s=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=Lvcp5Vj+2LILS0PROIJS+aftkOD9sY+CtxtyVDFgwkG5O/X+94J8f10Pd5Pj7d7R0FoiFQdqqN00MVfHyo129KGJitx1toT9djwMYLICCTyK//HMjD9evtL8yafIrv8RbatPkUJZmefVpIt7IfLk3Drnqw0aTd89oYn3mHSUE9s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: j4gk3zGeSY2TI4sC62KPmw== X-CSE-MsgGUID: COwuOctmSH6MAWcWPdtPwg== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 17 Apr 2025 22:54:02 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 2F75F4006DE8; Thu, 17 Apr 2025 22:53:58 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 18/38] ra6w: add indi.h Date: Thu, 17 Apr 2025 16:52:16 +0300 Message-Id: <20250417135236.52410-19-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/indi.h | 59 ++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/indi.h diff --git a/drivers/net/wireless/renesas/ra6w/indi.h b/drivers/net/wireless/renesas/ra6w/indi.h new file mode 100644 index 000000000000..ee050d086f52 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/indi.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_INDI_H +#define RA6W_INDI_H + +#include +#include + +#include "q.h" + +#define RA6W_INDI_DATA_LEN 980 +#define RA6W_INDI_EXT_LEN (sizeof(struct ra6w_indi_ext_hdr)) +#define RA6W_INDI_BUF_Q_MAX 64 + +enum ra6w_indi_disconnect_reason { + RA6W_INDI_DIS_RSN_MIN = 100, + RA6W_INDI_DIS_RSN_BEACON_MISS = RA6W_INDI_DIS_RSN_MIN, + RA6W_INDI_DIS_RSN_PS_TX_MAX_ERR, + RA6W_INDI_DIS_RSN_CHAN_SWITCH_FAIL, + + RA6W_INDI_DIS_RSN_MAX, + RA6W_INDI_DIS_RSN_LAST = RA6W_INDI_DIS_RSN_MAX - 1, +}; + +struct ra6w_indi_ext_hdr { + u32 status : 32; +}; + +struct ra6w_indi_buf { + u8 cmd; + u8 ext_len; + __le16 data_len; + struct ra6w_indi_ext_hdr ext_hdr; + u8 data[RA6W_INDI_DATA_LEN]; +}; + +enum ra6w_indi_data_event { + RA6W_INDI_EVENT, + RA6W_INDI_EVENT_RESET, + + RA6W_INDI_EVENT_MAX, +}; + +#define RA6W_INDI_EVENT_MASK (BIT(RA6W_INDI_EVENT) | BIT(RA6W_INDI_EVENT_RESET)) + +struct ra6w_indi { + struct task_struct *task; + struct ra6w_q_event event; + struct ra6w_q q; +}; + +int ra6w_indi_init(struct ra6w_indi *indi); +void ra6w_indi_deinit(struct ra6w_indi *indi); +int ra6w_indi_event_post(struct ra6w_indi *indi, struct sk_buff *skb); + +#endif /* RA6W_INDI_H */ From patchwork Thu Apr 17 13:52:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882266 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6583724EF78 for ; Thu, 17 Apr 2025 13:54:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898053; cv=none; b=jQVGhhhb/fRv4TDls2Bngk+QbNFd5vvV+u9dfJ51EKzFKh0RnrusSifjyqjVOm05FAASvOza19V4mcQ4BKcS+fGIZn6Bd6jCcZSfU0s/iQQ6ZpvClyR7bFoOumzoK4JJT2il4R/66GHg9W1psPdqsql93Y2qf+mDr50t1zUT5NY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898053; c=relaxed/simple; bh=8ZXIn7Cz7U+JCirf0fapXNBrCEverddBPeV7oVQQkTM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=SRpd14bKVk12tB1dh074q2a9pJ1aN8LKN2dOf3m+pyf27sXQaLoE7asFUHiq/E7Qa6/rNEYv22GuB5UWnNVRJHRssU6m5wxnA4NlNvCFPYBo7j361N9wrKMqaUMIlhrg6g0OX6zxnlfU6zdeI3ZccLNHr051+4+LskzcXy+KbzY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: P2vtGiINRuqwwzMWiClDLQ== X-CSE-MsgGUID: FFRJN6QkQZS3d0YiOLPp3A== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 17 Apr 2025 22:54:10 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 722D7400502F; Thu, 17 Apr 2025 22:54:07 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 20/38] ra6w: add params.h Date: Thu, 17 Apr 2025 16:52:18 +0300 Message-Id: <20250417135236.52410-21-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/params.h | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/params.h diff --git a/drivers/net/wireless/renesas/ra6w/params.h b/drivers/net/wireless/renesas/ra6w/params.h new file mode 100644 index 000000000000..c67b157e5113 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/params.h @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_PARAMS_H +#define RA6W_PARAMS_H + +#define RA6W_PHY_MINOR_VERSION(v) (((v) & 0x00FF0000) >> 16) +#define RA6W_PHY_MAJOR_VERSION(v) (((v) & 0xFF000000) >> 24) +#define RA6W_PHY_VERSION(v) \ + ((RA6W_PHY_MAJOR_VERSION(v) + 2) * 10 + RA6W_PHY_MINOR_VERSION(v)) + +enum ra6w_params_dev_feat { + RA6W_DEV_FEAT_BCN_BIT, + RA6W_DEV_FEAT_RADAR_BIT, + RA6W_DEV_FEAT_PS_BIT, + RA6W_DEV_FEAT_UAPSD_BIT, + RA6W_DEV_FEAT_AMPDU_BIT, + RA6W_DEV_FEAT_AMSDU_BIT, + RA6W_DEV_FEAT_P2P_BIT, + RA6W_DEV_FEAT_P2P_GO_BIT, + RA6W_DEV_FEAT_UMAC_BIT, + RA6W_DEV_FEAT_VHT_BIT, + RA6W_DEV_FEAT_BFMEE_BIT, + RA6W_DEV_FEAT_BFMER_BIT, + RA6W_DEV_FEAT_WAPI_BIT, + RA6W_DEV_FEAT_MFP_BIT, + RA6W_DEV_FEAT_MU_MIMO_RX_BIT, + RA6W_DEV_FEAT_MU_MIMO_TX_BIT, + RA6W_DEV_FEAT_MESH_BIT, + RA6W_DEV_FEAT_TDLS_BIT, + RA6W_DEV_FEAT_ANT_DIV_BIT, + RA6W_DEV_FEAT_UF_BIT, + RA6W_DEV_FEAT_AMSDU_MAX_SIZE_0_BIT, + RA6W_DEV_FEAT_AMSDU_MAX_SIZE_1_BIT, + RA6W_DEV_FEAT_MON_DATA_BIT, + RA6W_DEV_FEAT_HE_BIT, + RA6W_DEV_FEAT_TWT_BIT, + RA6W_DEV_FEAT_FTM_INIT_BIT, + RA6W_DEV_FEAT_FAKE_FTM_RSP_BIT, + RA6W_DEV_FEAT_HW_LLCSNAP_INS_BIT, + RA6W_DEV_FEAT_MAX +}; + +enum ra6w_params_mac_feat { + RA6W_MAC_FEAT_QOS_BIT, + RA6W_MAC_FEAT_EDCA_BIT, + RA6W_MAC_FEAT_SME_BIT, + RA6W_MAC_FEAT_SECURITY_BIT, + RA6W_MAC_FEAT_WEP_BIT, + RA6W_MAC_FEAT_TKIP_BIT, + RA6W_MAC_FEAT_CCMP_BIT, + RA6W_MAC_FEAT_RCE_BIT, + RA6W_MAC_FEAT_GCMP_BIT, + RA6W_MAC_FEAT_HT_BIT, + RA6W_MAC_FEAT_VHT_BIT, + RA6W_MAC_FEAT_TPC_BIT, + RA6W_MAC_FEAT_WAPI_BIT, + RA6W_MAC_FEAT_COEX_BIT, + RA6W_MAC_FEAT_HE_BIT, + RA6W_MAC_FEAT_RESERVED_BIT, + RA6W_MAC_FEAT_BFMEE_BIT, + RA6W_MAC_FEAT_BFMER_BIT, + RA6W_MAC_FEAT_MU_MIMO_TX_BIT, + + RA6W_MAC_FEAT_MAX, +}; + +struct ra6w_params_dev_features { + bool tdls_supported; + bool amsdu_supported; + bool vht_supported; + bool he_supported; + bool he_ul_on; + bool bfmee_enabled; + bool ps_supported; + bool wapi_supported; + bool mfp_supported; + bool gcmp_supported; + bool radar_supported; + bool mu_mimo_rx_enabled; + bool mu_mimo_tx_enabled; + bool twt_enabled; + u8 nss; + u32 uapsd_threshold; + u8 bw_max; +}; + +struct ra6w_params_module_params { + bool stbc_enabled; + bool ldpc_enabled; + bool ant_div; + bool ht_supported; + bool amsdu_require_spp; + bool bfmer_enabled; + bool dpsm_enabled; + bool ap_uapsd_enabled; + bool use_sgi; + bool ccmp256_supported; + char *regdom_mode; + u8 mcs_map_range; + u8 he_mcs_map_range; + u8 rx_amsdu_size; + u32 log_level; +}; + +struct ra6w_params { + struct ra6w_params_dev_features features; + struct ra6w_params_module_params module_params; +}; + +extern struct ra6w_params ra6w_params_list; + +int ra6w_params_init(struct ra6w_core *core); +bool ra6w_params_regd_mode_is_auto(void); +int ra6w_params_regd_set_self(struct wiphy *wiphy); +bool ra6w_params_ps_supported(void); +bool ra6w_params_dpsm_enabled(void); +bool ra6w_params_amsdu_require_spp(void); +bool ra6w_params_ht_supported(void); +bool ra6w_params_vht_supported(void); +bool ra6w_params_he_supported(void); +bool ra6w_params_he_ul_on(void); +bool ra6w_params_wapi_supported(void); +bool ra6w_params_mfp_supported(void); +bool ra6w_params_ap_uapsd_enabled(void); +bool ra6w_params_tdls_supported(void); +bool ra6w_params_gcmp_supported(void); +bool ra6w_params_ccmp256_supported(void); +bool ra6w_params_bfmee_enabled(void); +bool ra6w_params_bfmer_enabled(void); +bool ra6w_params_ldpc_enabled(void); +bool ra6w_params_stbc_enabled(void); +u8 ra6w_params_bw_max_get(void); +bool ra6w_params_use_sgi(void); +bool ra6w_params_mu_mimo_rx_enabled(void); +bool ra6w_params_mu_mimo_tx_enabled(void); +bool ra6w_params_twt_enabled(void); +bool ra6w_params_ant_div(void); +u32 ra6w_params_log_level(void); +void ra6w_params_log_level_set(u32 log_level); +u8 ra6w_params_nss(void); +u8 ra6w_params_rx_amsdu_size(void); +u8 ra6w_params_mcs_map_range(void); +u8 ra6w_params_he_mcs_map_range(void); +u32 ra6w_params_uapsd_threshold(void); + +#endif /* RA6W_PARAMS_H */ From patchwork Thu Apr 17 13:52:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882265 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 536B624EAAE for ; Thu, 17 Apr 2025 13:54:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898061; cv=none; b=h8ddBqDzyuVY5WeToLJeHonn/MAxziujmxw17Nk1qOVskEepAo5suPNKV6+Ux7l7c8KddcU9ulJWQZOnJa2qYpGGlUsW57fWxCHEefU3DpLHlfuDZsI05ZPe1RF4VOlfcKinklGobo2EWDLJf//Za3iH4EHWAi4NIyFjBHawzZY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898061; c=relaxed/simple; bh=NSOjeTQzrSHltDuz0G3J6cqJ6L1wwx55nF/bgrlu4EU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=BgL/1KQH4Vcsx81oxsv8rOSxlFGFCUKQvfHugu7/Uz34cFxFe1XnZYBA7s/dWMeCioQBVB0a8P3lI1u9+Dkc3S7AEukuaeJs/dtH7c7SPsLvGDnURxMhJDUaUdg22Io75MXdwm9OKeNh27HYvQ1u7OH5Kj2LvauvrnXO3Ti9nXg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: m35NB3JERCK0sq45yyLlqg== X-CSE-MsgGUID: DMu9qfs7Si6kkMXp1EJs6g== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 17 Apr 2025 22:54:19 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id BB54D400E4E9; Thu, 17 Apr 2025 22:54:15 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 22/38] ra6w: add q.h Date: Thu, 17 Apr 2025 16:52:20 +0300 Message-Id: <20250417135236.52410-23-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/q.h | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/q.h diff --git a/drivers/net/wireless/renesas/ra6w/q.h b/drivers/net/wireless/renesas/ra6w/q.h new file mode 100644 index 000000000000..5f8a165ae84d --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/q.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_Q_H +#define RA6W_Q_H + +#include +#include +#include +#include +#include + +struct ra6w_q { + size_t max_count; + unsigned long head; + unsigned long tail; + spinlock_t lock; + void **buf; +}; + +struct ra6w_q_event { + atomic_t condition; + wait_queue_head_t wait_queue; + u32 timeout; +}; + +int ra6w_q_init(struct ra6w_q *q, size_t max_count, size_t buf_size); +bool ra6w_q_empty(struct ra6w_q *q); +int ra6w_q_push(struct ra6w_q *q, void *buf); +void *ra6w_q_pop(struct ra6w_q *q); +void ra6w_q_event_set(struct ra6w_q_event *event, int event_val); +bool ra6w_q_event_condition(const struct ra6w_q_event *event, int event_mask, int *ret_event); +int ra6w_q_wait(struct ra6w_q_event *event, int event_mask); +int ra6w_q_wait_timeout(struct ra6w_q_event *event, int event_mask); +void ra6w_q_deinit(struct ra6w_q *q); + +#endif /* RA6W_Q_H */ From patchwork Thu Apr 17 13:52:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882264 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 687D724EAA4 for ; Thu, 17 Apr 2025 13:54:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898069; cv=none; b=LMkbhl3FTXjlg6atsO8/6KQ4qZPir4vwxL9sYsyiqeO7gDnWYsQEfPk7podpzQrw11XxzfndKFaUaq+TDu8K4YmOsDq3j2pkqOsved1ktzLf6Ao6Cv/oi0AkUJqK3YNRIxdmsMBqphG1y9x9FPNZi4elmlJFTh+vw7MhJYtZwJk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898069; c=relaxed/simple; bh=jh8/0RPh0B4eDJn5iKI1DI3xPFh4teWxL6+cEnSCIRY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=N6nmHpIa1wcVxWOaw4nKwHovoX/bYmzrkwylQI7HTjFlA7/kmQFLNYJfgXMURQ+xWkwJduvshxeb/SpcV9XzZm9bHHAspuQ6yGVz3npCNKnZIARYoQe1OcloYqC1wO1Iz8+6TnjUCH40w5Vp43tQ2UDXEx91xxJBFPTihbY971E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: 76p1aJRtTVaq9MpVra/QAw== X-CSE-MsgGUID: w2X5boaPSzSO2pRuY1rWGQ== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 17 Apr 2025 22:54:27 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 0986B400502F; Thu, 17 Apr 2025 22:54:23 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 24/38] ra6w: add recovery.h Date: Thu, 17 Apr 2025 16:52:22 +0300 Message-Id: <20250417135236.52410-25-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/recovery.h | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/recovery.h diff --git a/drivers/net/wireless/renesas/ra6w/recovery.h b/drivers/net/wireless/renesas/ra6w/recovery.h new file mode 100644 index 000000000000..bffe16d6e919 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/recovery.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_RECOVERY_H +#define RA6W_RECOVERY_H + +struct ra6w_recovery { + struct workqueue_struct *wq; + struct work_struct work; + bool in_recovery; +}; + +int ra6w_recovery_init(struct ra6w_recovery *recovery); +void ra6w_recovery_deinit(struct ra6w_recovery *recovery); +void ra6w_recovery_event_post(struct ra6w_recovery *recovery); +void ra6w_recovery_reprobe_set(bool set); +bool ra6w_recovery_reprobe_get(void); + +#endif /* RA6W_RECOVERY_H */ From patchwork Thu Apr 17 13:52:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882263 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6B64324EF68 for ; Thu, 17 Apr 2025 13:54:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898078; cv=none; b=NCTIz01JIO5Al4zbHnTb7Ekh+GNLAZXFh0acAYnEWgpqhbGuOCA/hg5Q2od/cIf88R2MawoBgehi/RD5WR8AS+khdO0D1uSK+o9EQKG7Z+fDaS9F0CZ4CjHe6zSMNhYqClSqHCZImjGQcmWj/e84JPkEnWFmrMqXFojr+ikExck= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898078; c=relaxed/simple; bh=0XKVgpu8jNkoQSoN0pPT9F308cU1ywVApeYhChk4NDs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=k9/Mc4itLF0CwExXY9qCXZT/+h53Fc3cNhhq+ohaGivWN/mDqrt3/5GN6gCCXIUN8R+VKTE3mVrIKAq00XAWelIvtV974AlaArKch52fez4mr4q0jVi10WjBPFj9YZD+O5MIp4U67b/r8RI9XoBzAP5JUndX9oQ7YFNrIiCgcAA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: 0AoczfFCSd6x9Z/aVSHsBg== X-CSE-MsgGUID: IM3ez+KcQM6SO6j3zVWP1A== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 17 Apr 2025 22:54:35 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 521AC401009B; Thu, 17 Apr 2025 22:54:31 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 26/38] ra6w: add rx.h Date: Thu, 17 Apr 2025 16:52:24 +0300 Message-Id: <20250417135236.52410-27-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/rx.h | 105 +++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/rx.h diff --git a/drivers/net/wireless/renesas/ra6w/rx.h b/drivers/net/wireless/renesas/ra6w/rx.h new file mode 100644 index 000000000000..10ee61b3ed6f --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/rx.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_RX_H +#define RA6W_RX_H + +#include + +#include "q.h" + +#define RA6W_RX_EXT_LEN (sizeof(struct ra6w_rx_ext_hdr)) +#define RA6W_RX_BUF_Q_MAX 64 + +enum ra6w_rx_ext_hdr_flags { + RA6W_EXT_FLAGS_MGMT_BIT = BIT(1), + RA6W_EXT_FLAGS_MGMT_NO_CCK_BIT = BIT(2), + RA6W_EXT_FLAGS_AMSDU_BIT = BIT(3), + RA6W_EXT_FLAGS_MGMT_ROBUST_BIT = BIT(4), + RA6W_EXT_FLAGS_4ADDR_BIT = BIT(5), + RA6W_EXT_FLAGS_EOSP_BIT = BIT(6), + RA6W_EXT_FLAGS_MESH_FWD_BIT = BIT(7), + RA6W_EXT_FLAGS_TDLS_BIT = BIT(8), + RA6W_EXT_FLAGS_SN_BIT = BIT(9) +}; + +struct ra6w_rx_ext_ht { + u16 short_gi : 1; + u16 mcs : 7; + u16 num_extn_ss : 2; + u16 reserved : 6; +}; + +struct ra6w_rx_ext_vht { + u16 short_gi : 1; + u16 mcs : 7; + u16 nss : 3; + u16 reserved : 5; +}; + +struct ra6w_rx_ext_he { + u16 ru_size : 3; + u16 mcs : 7; + u16 nss : 3; + u16 gi_type : 2; + u16 dcm : 1; +}; + +struct ra6w_rx_ext_hdr { + u32 status : 32; + u32 amsdu : 1; + u32 mpdu : 1; + u32 addr_4 : 1; + u32 mesh_peer_new : 1; + u32 priority : 3; + u32 vif_idx : 8; + u32 sta_idx : 8; + u32 dest_sta_idx : 8; + u32 ch_bw : 2; + u32 rssi1 : 8; + u32 band : 4; + u32 channel_type : 8; + u32 prim20_freq : 16; + u32 center1_freq : 16; + u32 center2_freq : 16; + u32 format_mod : 4; + u32 pre_type : 1; + u32 leg_rate : 4; + + union { + struct ra6w_rx_ext_ht ht; + struct ra6w_rx_ext_vht vht; + struct ra6w_rx_ext_he he; + }; +}; + +struct ra6w_rx_buf { + u8 cmd; + u8 ext_len; + __le16 data_len; + struct ra6w_rx_ext_hdr ext_hdr; + u8 data[RA6W_CMD_DATA_SIZE]; +}; + +enum ra6w_rx_data_event { + RA6W_RX_DATA_EVENT, + + RA6W_RX_DATA_EVENT_MAX, +}; + +#define RA6W_RX_EVENT_RESET RA6W_RX_DATA_EVENT_MAX +#define RA6W_RX_EVENT_MASK (BIT(RA6W_RX_DATA_EVENT) | BIT(RA6W_RX_EVENT_RESET)) + +struct ra6w_rx { + struct task_struct *task; + struct ra6w_q_event event; + struct ra6w_q q; +}; + +int ra6w_rx_init(struct ra6w_rx *rx); +void ra6w_rx_deinit(struct ra6w_rx *rx); +int ra6w_rx_event_post(struct ra6w_rx *rx, struct sk_buff *skb); + +#endif /* RA6W_RX_H */ From patchwork Thu Apr 17 13:52:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882262 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9D6B824EABF for ; Thu, 17 Apr 2025 13:54:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898086; cv=none; b=BhWSuAADSEq1GrTfTqcWNamD0vK4TSo+8zxFqiP7aZnV+K26AhUBFGBV65OfSdz7CDAnaNxt3LxbiwNvnRldCRbHQfzDQasvdG3fBsbyJLVrttCbbVKXExGf9dGPbLOIfwGdOv88c5+jR20TnifvHQy0CNLNuxO/Ip7x+AmdLzQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898086; c=relaxed/simple; bh=CSv+Y7Ei5d0ps/8dtEgtZloQ+D8G/rpyNduaZ4hDX0Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=dslbqLKogncMnjapB2fXsW8GE1Ld9KkQ0/PWpveH37Avx2PgzY4xsX3mH5M6ExyYuL8p3h4GxdAstLHSA+1E+EJQS6HBIz/iLufAXrj9Zk0LfNeYC+ecBxkeaWCjD7nsWRKcgW6yHqXDY7/ZsdcOvIMyDSnMQ+No+2h0aehzeWA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: iG2QPO3NQYiM1oKaC5dFWw== X-CSE-MsgGUID: WbAol+0DSPaG4HCLU8t37Q== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 17 Apr 2025 22:54:44 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 9F61F401009B; Thu, 17 Apr 2025 22:54:40 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 28/38] ra6w: add sdio.h Date: Thu, 17 Apr 2025 16:52:26 +0300 Message-Id: <20250417135236.52410-29-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/sdio.h | 38 ++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/sdio.h diff --git a/drivers/net/wireless/renesas/ra6w/sdio.h b/drivers/net/wireless/renesas/ra6w/sdio.h new file mode 100644 index 000000000000..6b7d0c7d7bbc --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/sdio.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_SDIO_H +#define RA6W_SDIO_H + +#include + +#define RA6W_SDIO_VENDOR_ID_RENESAS 0x5245 +#define RA6W_SDIO_DEVICE_ID_RA6W 0x4154 +#define RA6W_SDIO_MAX_BLOCK_CNT 5 +#define RA6W_SDIO_BLOCK_SIZE 512 +#define RA6W_SDIO_HOST_GP_REG 0x24 +#define RA6W_SDIO_CHIP_GP_REG 0x28 +#define RA6W_SDIO_CODE_SUCCESS 0x00022000 +#define RA6W_SDIO_CODE_CRC_CHECKING 0xf0f0f0f0 +#define RA6W_SDIO_CODE_BOOT_NG 0x20000002 +#define RA6W_SDIO_ADDR_RESET 0xdeadffff +#define RA6W_SDIO_ADDR_READ 0x0001 +#define RA6W_SDIO_ADDR_WRITE 0x0002 +#define RA6W_SDIO_ADDR_STATUS 0x0010 + +#define RA6W_SDIO_FW_NAME "fmacfw_sdio.bin" + +#define RA6W_SDIO_GET_CNT(len, blk_size) (((u32)(len)) / (blk_size)) +#define RA6W_SDIO_GET_REMAIN(len, blk_size) (((u32)(len)) % (blk_size)) + +#define RA6W_SDIO_ACK_CNT_MAX 10 +#define RA6W_SDIO_WAIT_SYNC_CNT_MAX 20 +#define RA6W_SDIO_CRC_CHECK_RETRY_MAX 20 +#define RA6W_SDIO_CRC_CHECK_SLEEP_MIN_US 10000 +#define RA6W_SDIO_CRC_CHECK_SLEEP_MAX_US 11000 + +void ra6w_sdio_reprobe(struct sdio_func *func); + +#endif /* RA6W_SDIO_H */ From patchwork Thu Apr 17 13:52:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882261 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8097624EA9C for ; Thu, 17 Apr 2025 13:54:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898094; cv=none; b=bmdRdSSrA9Ung9U8UStrJu6UnKyjGdI9aWTU15xuWmdU7tTcHVzCdJmFOTWkFBhYMrbUMCB4js1oemLHAS19cBxzJmB+gFITrLnhGkx1J8D2+HVeeSMvhaeuOc+C2rzrRj8AeCYcxke80/aGpSb12UDj/MdSHFACFhfYosv+iEY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898094; c=relaxed/simple; bh=Z91kGV9gdbQ/5EAiACcYSnbvvRe9vnRkY0c8b91p5aM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=XOlpitXWYiOb2apWJ2+Vvj75o7DVmjYYy3rQRCa/BqV7G9OWCsk/rKNRIfTh3wZEtwmbp3x4JGadmaUyGibCsnT8d6/X/UobT0KP1sD3ipopTfTBFAybSophl1KoDTCBsPqZ7PdOMkG6JGg/gEKQ9xiVq5a/EXrzO02sTRmoSAA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: PwBmrmkyRpiTD8CChsf7EA== X-CSE-MsgGUID: 34EwP5IjQXaOfn0nWY6xig== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 17 Apr 2025 22:54:52 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id E09AD40103D5; Thu, 17 Apr 2025 22:54:48 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 30/38] ra6w: add stats.h Date: Thu, 17 Apr 2025 16:52:28 +0300 Message-Id: <20250417135236.52410-31-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/stats.h | 100 ++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/stats.h diff --git a/drivers/net/wireless/renesas/ra6w/stats.h b/drivers/net/wireless/renesas/ra6w/stats.h new file mode 100644 index 000000000000..06e870f6ae0f --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/stats.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_STATS_H +#define RA6W_STATS_H + +#define RA6W_MCS_MAX_HT 8 +#define RA6W_MCS_MAX_VHT 9 +#define RA6W_MCS_MAX_HE 12 +#define RA6W_GI_MAX_HT 2 +#define RA6W_GI_MAX_VHT 2 +#define RA6W_GI_MAX_HE 3 + +enum ra6w_stats_bits { + RA6W_STATS_RX_CCK_BIT = BIT(0), + RA6W_STATS_RX_OFDM_BIT = BIT(1), + RA6W_STATS_RX_HT_BIT = BIT(2), + RA6W_STATS_RX_VHT_BIT = BIT(3), + RA6W_STATS_RX_HE_SU_BIT = BIT(4), + RA6W_STATS_RX_HE_MU_BIT = BIT(5), + RA6W_STATS_RX_HE_EXT_BIT = BIT(6), + RA6W_STATS_RX_HE_TRIGFLAG_LONG_BIT = BIT(7) +}; + +enum ra6w_stats_status { + RA6W_STATS_STATUS_DISABLED, + RA6W_STATS_STATUS_ENABLED, + + RA6W_STATS_STATUS_MAX +}; + +struct ra6w_stats_non_ht { + u8 bw; + u64 ofdm; + u64 cck; +}; + +struct ra6w_stats_rx { + u8 format_mode; + u8 flags; + struct ra6w_stats_non_ht non_ht; + struct { + u8 bw; + u8 mcs; + u8 gi; + u8 nss; + u64 ht[RA6W_GI_MAX_HT][RA6W_MCS_MAX_HT]; + } ht; + struct { + u8 bw; + u8 mcs; + u8 gi; + u8 nss; + u64 vht[RA6W_GI_MAX_VHT][RA6W_MCS_MAX_VHT]; + } vht; + struct { + u8 bw; + u8 mcs; + u8 gi; + u8 nss; + u64 he[RA6W_GI_MAX_HE][RA6W_MCS_MAX_HE]; + } he_su; +}; + +struct ra6w_stats { + struct ra6w_stats_rx *rx_stats; + bool stats_enabled; +}; + +struct ra6w_cfg80211_sta_stats; + +#ifdef CONFIG_NL80211_TESTMODE + +int ra6w_stats_init(struct ra6w_stats *stats); +void ra6w_stats_deinit(struct ra6w_stats *stats); +void ra6w_stats_rx_update(struct ra6w_stats *stats, + const struct ra6w_cfg80211_sta_stats *sta_stats); + +#else + +static inline int ra6w_stats_init(struct ra6w_stats *stats) +{ + return 0; +} + +static inline void ra6w_stats_deinit(struct ra6w_stats *stats) +{ +} + +static inline +void ra6w_stats_rx_update(struct ra6w_stats *stats, + const struct ra6w_cfg80211_sta_stats *sta_stats) +{ +} + +#endif /* CONFIG_NL80211_TESTMODE */ + +#endif /* RA6W_STATS_H */ From patchwork Thu Apr 17 13:52:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882260 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9C82C24EF6B for ; Thu, 17 Apr 2025 13:55:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898103; cv=none; b=Rt54ChP6kZzRvWGprrQdZqWaKoc51pEgT3VUhy2Zi0EwXz86OvZOj+HCgOO0gt7KWH5rEAHibB3QjDGonCtBruVUAenFiXi/pJl0pcUo17mVr2s2fgRapX4FJpMIz+6XDdo2doheMPewts+M1yOx06YqWcJRs4p01TnK25i42/U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898103; c=relaxed/simple; bh=RMviJYm8lGQtJAHfpndeBCfJuNWB5H4Utvn2Inw5vkc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=tlUQjGoNVxVM2xBF6ef8gAT6eLA1yMRcqmNtuenW5z9KeY/P1LAavCnmiV40ZYDGMw/Qo3BGjysYz4Mt2F0OTW4xBLKk7kQmAs9HElGVLVwgLvzqLipNydvisoTvUqMp4s4+xcvlrpAwzRtiLTg1Eg3BZNZYT3CSRPlTTLoHH/Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: +SUrNCTBRTWk3uAG3RDIRA== X-CSE-MsgGUID: 21RCBnHSQBCpoOa5dJqa9g== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 17 Apr 2025 22:55:00 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 4F7E8401009B; Thu, 17 Apr 2025 22:54:56 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 32/38] ra6w: add status.h Date: Thu, 17 Apr 2025 16:52:30 +0300 Message-Id: <20250417135236.52410-33-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/status.h | 73 ++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/status.h diff --git a/drivers/net/wireless/renesas/ra6w/status.h b/drivers/net/wireless/renesas/ra6w/status.h new file mode 100644 index 000000000000..3736e2a2fdb7 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/status.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_STATUS_H +#define RA6W_STATUS_H + +#include +#include + +enum ra6w_status_code { + RA6W_STATUS_CODE_SUCCESS = 0, + RA6W_STATUS_CODE_FAIL, + RA6W_STATUS_CODE_EMPTY, + RA6W_STATUS_CODE_FULL, + RA6W_STATUS_CODE_INVALID_PARAM, + RA6W_STATUS_CODE_NOT_FOUND, + RA6W_STATUS_CODE_NO_MORE, + RA6W_STATUS_CODE_NOT_IN_USE, + RA6W_STATUS_CODE_BUSY, + RA6W_STATUS_CODE_IN_PROGRESS, + RA6W_STATUS_CODE_MEMORY_FAIL, + RA6W_STATUS_CODE_NOT_SUPPORT, + RA6W_STATUS_CODE_EXIST, + + RA6W_STATUS_CODE_MAX +}; + +enum ra6w_status_byte { + RA6W_STATUS_BYTE_STATUS, + RA6W_STATUS_BYTE_TX_AVAIL_CNT, + RA6W_STATUS_BYTE_TX_POWER_AVAIL_CNT, + RA6W_STATUS_BYTE_RESERVED, + + RA6W_STATUS_BYTE_MAX +}; + +enum ra6w_status_byte_bits { + RA6W_STATUS_BIT_RX_EMPTY, + RA6W_STATUS_BIT_TX_AC_FULL, + RA6W_STATUS_BIT_TX_POWER_FULL, + + RA6W_STATUS_BITS_MAX +}; + +struct ra6w_status { + u8 value[RA6W_STATUS_BYTE_MAX]; + spinlock_t lock; +}; + +struct ra6w_status_ext_hdr { + u32 status : 32; +}; + +struct ra6w_status_buf { + u8 cmd; + u8 ext_len; + __le16 data_len; + struct ra6w_status_ext_hdr ext_hdr; +}; + +#define RA6W_STATUS_EXT_LEN (sizeof(struct ra6w_status_ext_hdr)) + +void ra6w_status_init(struct ra6w_status *status); +void ra6w_status_set(struct ra6w_status *status, u32 value); +u8 ra6w_status_rx_get(struct ra6w_status *status); +u8 ra6w_status_tx_get(struct ra6w_status *status, u8 ac); +u8 ra6w_status_tx_avail_cnt_get(struct ra6w_status *status, u8 ac); +int ra6w_status_err_code_to_errno(u8 err); +void ra6w_status_event_post(struct ra6w_status *status, const struct sk_buff *skb); + +#endif /* RA6W_STATUS_H */ From patchwork Thu Apr 17 13:52:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882259 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BF7B024EA9C for ; Thu, 17 Apr 2025 13:55:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898111; cv=none; b=QhZ2ly+KBY+dioVTnNVuHuEjDO/pwsp78aYBxXkRXWV1LVIq7ZeHzY8jQt4lr8a9V7f3SRTAaApPk9Y9+L4Sb4Ft37k7q77D59fbPa0L+yHZHweYa9p3LA5Gk88Ae57y823vFKkAsvUmcH5RbiuS+dXutjcnSj/G2UFfuSeMoVQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898111; c=relaxed/simple; bh=amMD0tJarLEqIXW32riiTY3aTRG7oz5LqE4fSq3LO4k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=lKX+PEgS0S6XKCWeX/Rq9qVwCpei2gGIIKHjtAuhwjwrLgoSjmyVqp0mzpADUXgjaK8+XJlOqL+IdjAt7w8CySsMuxAh/OEX8zNam6h5YKCrXUWYYEM7d5vvlqTfOXAYI+Nb7AT5lbWwKGL7XNEG0Yj+FgMt7WdfJX2mpR5uRMg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: Q1SvfPQ2QzmJVAb/2tnSBg== X-CSE-MsgGUID: Pj1qgTh4QeWhjw0jtIFbVQ== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 17 Apr 2025 22:55:09 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 34470401009B; Thu, 17 Apr 2025 22:55:05 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 34/38] ra6w: add testmode.h Date: Thu, 17 Apr 2025 16:52:32 +0300 Message-Id: <20250417135236.52410-35-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/testmode.h | 150 +++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/testmode.h diff --git a/drivers/net/wireless/renesas/ra6w/testmode.h b/drivers/net/wireless/renesas/ra6w/testmode.h new file mode 100644 index 000000000000..eb4907137761 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/testmode.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ +#ifndef RA6W_TESTMODE_H +#define RA6W_TESTMODE_H + +#ifdef CONFIG_NL80211_TESTMODE + +enum ra6w_testmode_cmd { + RA6W_TESTMODE_CMD_READ_REG = 1, + RA6W_TESTMODE_CMD_WRITE_REG, + RA6W_TESTMODE_CMD_LOGMODEFILTER_SET, + RA6W_TESTMODE_CMD_DBGLEVELFILTER_SET, + RA6W_TESTMODE_CMD_TX, + RA6W_TESTMODE_CMD_CW, + RA6W_TESTMODE_CMD_CONT, + RA6W_TESTMODE_CMD_CHANNEL, + RA6W_TESTMODE_CMD_PER, + RA6W_TESTMODE_CMD_RESET_HW, + RA6W_TESTMODE_CMD_HOST_LOG_LEVEL, + RA6W_TESTMODE_CMD_DBGOUTDIR_SET, + RA6W_TESTMODE_CMD_TX_POWER, + RA6W_TESTMODE_CMD_STATS_START, + RA6W_TESTMODE_CMD_STATS_STOP, + RA6W_TESTMODE_CMD_STATS_TX, + RA6W_TESTMODE_CMD_STATS_RX, + RA6W_TESTMODE_CMD_STATS_RSSI, + RA6W_TESTMODE_CMD_MAX, +}; + +enum ra6w_testmode_attr { + RA6W_TESTMODE_ATTR_NOT_APPLICABLE = 0, + RA6W_TESTMODE_ATTR_CMD, + RA6W_TESTMODE_ATTR_REG_OFFSET, + RA6W_TESTMODE_ATTR_REG_VALUE32, + RA6W_TESTMODE_ATTR_REG_FILTER, + RA6W_TESTMODE_ATTR_START, + RA6W_TESTMODE_ATTR_CH, + RA6W_TESTMODE_ATTR_FRAMES_NUM, + RA6W_TESTMODE_ATTR_FRAMES_LEN, + RA6W_TESTMODE_ATTR_RATE, + RA6W_TESTMODE_ATTR_POWER, + RA6W_TESTMODE_ATTR_ADDR_DEST, + RA6W_TESTMODE_ATTR_BSSID, + RA6W_TESTMODE_ATTR_GI, + RA6W_TESTMODE_ATTR_GREEN, + RA6W_TESTMODE_ATTR_PREAMBLE, + RA6W_TESTMODE_ATTR_QOS, + RA6W_TESTMODE_ATTR_ACK, + RA6W_TESTMODE_ATTR_AIFSN, + RA6W_TESTMODE_ATTR_PER_PASS, + RA6W_TESTMODE_ATTR_PER_FCS, + RA6W_TESTMODE_ATTR_PER_PHY, + RA6W_TESTMODE_ATTR_PER_OVERFLOW, + RA6W_TESTMODE_ATTR_HOST_LOG_LEVEL, + RA6W_TESTMODE_ATTR_STATS_READY, + RA6W_TESTMODE_ATTR_STATS_RSSI, + RA6W_TESTMODE_ATTR_STATS_BSSID, + RA6W_TESTMODE_ATTR_STATS_STAIDX, + RA6W_TESTMODE_ATTR_STATS_OWN_MAC, + RA6W_TESTMODE_ATTR_STATS_FLAGS, + RA6W_TESTMODE_ATTR_STATS_RX_BW, + RA6W_TESTMODE_ATTR_STATS_RX_MCS, + RA6W_TESTMODE_ATTR_STATS_RX_GI, + RA6W_TESTMODE_ATTR_STATS_RX_NSS, + RA6W_TESTMODE_ATTR_STATS_RX_CCK, + RA6W_TESTMODE_ATTR_STATS_RX_OFDM, + RA6W_TESTMODE_ATTR_STATS_RX_HT, + RA6W_TESTMODE_ATTR_STATS_RX_VHT, + RA6W_TESTMODE_ATTR_STATS_RX_HE_SU, + RA6W_TESTMODE_ATTR_STATS_RX_HE_MU, + RA6W_TESTMODE_ATTR_STATS_RX_HE_EXT, + RA6W_TESTMODE_ATTR_STATS_RX_HE_TRIG, + RA6W_TESTMODE_ATTR_STATS_TX_CCK, + RA6W_TESTMODE_ATTR_STATS_TX_CCK_FAIL, + RA6W_TESTMODE_ATTR_STATS_TX_OFDM, + RA6W_TESTMODE_ATTR_STATS_TX_OFDM_FAIL, + RA6W_TESTMODE_ATTR_STATS_TX_HT, + RA6W_TESTMODE_ATTR_STATS_TX_HT_FAIL, + RA6W_TESTMODE_ATTR_STATS_TX_VHT, + RA6W_TESTMODE_ATTR_STATS_TX_VHT_FAIL, + RA6W_TESTMODE_ATTR_STATS_TX_HE, + RA6W_TESTMODE_ATTR_STATS_TX_HE_FAIL, + RA6W_TESTMODE_ATTR_STATS_TX_EPR, + RA6W_TESTMODE_ATTR_MAX, +}; + +enum { + RA6W_TESTMODE_VALUE_STOP = 0, + RA6W_TESTMODE_VALUE_START, +}; + +enum ra6w_testmode_value_per { + RA6W_TESTMODE_VALUE_PER_STOP = 0, + RA6W_TESTMODE_VALUE_PER_START, + RA6W_TESTMODE_VALUE_PER_GET, + RA6W_TESTMODE_VALUE_PER_RESET, +}; + +enum ra6w_testmode_rate { + RA6W_TESTMODE_RATE_B1 = 0, + RA6W_TESTMODE_RATE_B2, + RA6W_TESTMODE_RATE_B5_5, + RA6W_TESTMODE_RATE_B11, + RA6W_TESTMODE_RATE_G6, + RA6W_TESTMODE_RATE_G9, + RA6W_TESTMODE_RATE_G12, + RA6W_TESTMODE_RATE_G18, + RA6W_TESTMODE_RATE_G24, + RA6W_TESTMODE_RATE_G36, + RA6W_TESTMODE_RATE_G48, + RA6W_TESTMODE_RATE_G54, + RA6W_TESTMODE_RATE_N6_5, + RA6W_TESTMODE_RATE_N13, + RA6W_TESTMODE_RATE_N19_5, + RA6W_TESTMODE_RATE_N26, + RA6W_TESTMODE_RATE_N39, + RA6W_TESTMODE_RATE_N52, + RA6W_TESTMODE_RATE_N58_5, + RA6W_TESTMODE_RATE_N65, +}; + +enum { + RA6W_TESTMODE_VALUE_SHORT = 0, + RA6W_TESTMODE_VALUE_LONG, +}; + +enum { + RA6W_TESTMODE_VALUE_OFF = 0, + RA6W_TESTMODE_VALUE_ON, +}; + +enum { + RA6W_TESTMODE_VALUE_NO = 0, + RA6W_TESTMODE_VALUE_NORM, + RA6W_TESTMODE_VALUE_BA, + RA6W_TESTMODE_VALUE_CBA, +}; + +int ra6w_testmode_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, void *data, int len); +#else +static inline int ra6w_testmode_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, + void *data, int len) +{ + return 0; +} +#endif /* CONFIG_NL80211_TESTMODE */ + +#endif // RA6W_TESTMODE_H From patchwork Thu Apr 17 13:52:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882258 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1FFC5250BF1 for ; Thu, 17 Apr 2025 13:55:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898119; cv=none; b=XaNfmdsseToF9woTz19KEUXVpV3WUDqstxdrqyrOh2OjlrF73F7WpYCIAUmJvZD+yKsODlZTcC+OQ6s7TCPYcw/Ed0I9kXqNbDvKePEXujl7kYEvxMagkssdGFeo/+y1U5DPjtJPYxkjPisLYFvlK0O2Xktef9MsmFDj6gWkCHg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898119; c=relaxed/simple; bh=31NH0et9RAe2gDQ31TIsRvUnTSYSaDHQ/G8scXU+RUE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=EZw5BDqR2vvunNjlbtyYz7x/wN2Ed5Jjmjk8OgqHztTbdIreNjNWSPcKYaDM3IGNr15r1+Rtzp4Mps06cBCi5Ri8KO+rqsunE4ryPTt4HsD5kt8CECXYsvxIbnjGOmagYaNkAhZP47GgiSArE5vNq4NVQC3sRHNTEF0QI57HdJo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: ZJEW6XKmQWOfqIPPs03Z4A== X-CSE-MsgGUID: ugTnYJXpTfyPPSCKaolA4Q== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 17 Apr 2025 22:55:17 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 76CD240103A8; Thu, 17 Apr 2025 22:55:14 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 36/38] ra6w: add tx.h Date: Thu, 17 Apr 2025 16:52:34 +0300 Message-Id: <20250417135236.52410-37-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/tx.h | 69 ++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/tx.h diff --git a/drivers/net/wireless/renesas/ra6w/tx.h b/drivers/net/wireless/renesas/ra6w/tx.h new file mode 100644 index 000000000000..3020946468af --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/tx.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates. + */ + +#ifndef RA6W_TX_H +#define RA6W_TX_H + +#include + +#include "q.h" + +#define RA6W_TX_EXT_LEN (sizeof(struct ra6w_tx_ext_hdr)) +#define RA6W_TX_BUF_Q_MAX 128 +#define RA6W_TX_POWER_BUF_Q_MAX 32 + +enum ra6w_tx_data_ac { + RA6W_TX_DATA_AC, + RA6W_TX_DATA_AC_POWER, + + RA6W_TX_DATA_AC_MAX, +}; + +#define RA6W_TX_EVENT_RESET RA6W_TX_DATA_AC_MAX +#define RA6W_TX_EVENT_MASK (BIT(RA6W_TX_DATA_AC) | \ + BIT(RA6W_TX_DATA_AC_POWER) | \ + BIT(RA6W_TX_EVENT_RESET)) + +#define RA6W_TX_EVENT_TIMEOUT_MS 100 + +struct ra6w_tx_ext_hdr { + u32 buf_idx : 3; + u32 tid : 5; + u32 vif_idx : 8; + u32 sta_idx : 8; + u32 flags : 10; + u32 sn : 24; +}; + +struct ra6w_tx_buf { + u8 cmd; + u8 ext_len; + __le16 data_len; + struct ra6w_tx_ext_hdr ext_hdr; + u8 data[RA6W_CMD_DATA_SIZE]; +}; + +struct ra6w_tx_q_ac { + struct ra6w_q q; +}; + +struct ra6w_tx { + struct task_struct *task; + struct ra6w_q_event event; + struct ra6w_tx_q_ac q_ac[RA6W_TX_DATA_AC_MAX]; +}; + +struct ra6w_cfg80211_vif; +struct ra6w_cfg80211_sta; + +int ra6w_tx_init(struct ra6w_tx *tx); +void ra6w_tx_deinit(struct ra6w_tx *tx); +int ra6w_tx_event_post(struct ra6w_tx *tx, u8 ac, struct sk_buff *skb); +int ra6w_tx_mgmt(struct ra6w_tx *tx, const struct ra6w_cfg80211_vif *vif, + const struct ra6w_cfg80211_sta *sta, + const struct cfg80211_mgmt_tx_params *params, + u64 *cookie); + +#endif /* RA6W_TX_H */ From patchwork Thu Apr 17 13:52:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Savchenko X-Patchwork-Id: 882257 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7596024EF6D for ; Thu, 17 Apr 2025 13:55:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.160.252.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898127; cv=none; b=iyn4jV2F1VPK5n2R6c5bCoHOarDlJStR0YGQjvQCPEUDokZQrxUL6/TyyIgkv6/b3VNvDl/Ei5MK5hbK92xF9BqT4QN1+bW28o+f0IGm2B1Y5hNsskzILbYRzLqQCVW3gAn7i0nUcZsufVW4OhH2l4TRoCM9xx7Bu7L5aTQh0BY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744898127; c=relaxed/simple; bh=IPo7jDqI6XbpqGyVrtjredTl/bL6IIEv1D0mztFgZOI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=a1IR/pbXv/U4VOX2kC9tzy8XWZWzG+QOO7kh+fqAPqcn10Xr/wAqRwxRH3awFS0MZ6OeGOlE9PSonoP00YXCCh/xMfm/bQofO7Sf8euBIxh1/57GUEWXfz8caZFUTSegr5I7fFMUTlMZSeTgue6a1X+JVBlisZ2w/h75GYFai4U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com; spf=pass smtp.mailfrom=bp.renesas.com; arc=none smtp.client-ip=210.160.252.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=bp.renesas.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bp.renesas.com X-CSE-ConnectionGUID: 7kv0lfjQSROFsR9aD23CmQ== X-CSE-MsgGUID: 1CYehWLCSqO28JZlqpNDXQ== Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 17 Apr 2025 22:55:26 +0900 Received: from localhost.localdomain (unknown [10.14.100.3]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id D814D401009B; Thu, 17 Apr 2025 22:55:22 +0900 (JST) From: Alexander Savchenko To: linux-wireless@vger.kernel.org, Johannes Berg Cc: Sergiy Petrov , Viktor Barna , Gal Gur , Alexander Savchenko Subject: [PATCH 38/38] ra6w: add Kconfig Date: Thu, 17 Apr 2025 16:52:36 +0300 Message-Id: <20250417135236.52410-39-oleksandr.savchenko.dn@bp.renesas.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> References: <20250417135236.52410-1-oleksandr.savchenko.dn@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Part of the split. Please, take a look at the cover letter for more details Reviewed-by: Viktor Barna Reviewed-by: Gal Gur Signed-off-by: Alexander Savchenko --- drivers/net/wireless/renesas/ra6w/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 drivers/net/wireless/renesas/ra6w/Kconfig diff --git a/drivers/net/wireless/renesas/ra6w/Kconfig b/drivers/net/wireless/renesas/ra6w/Kconfig new file mode 100644 index 000000000000..d23b5a5ef469 --- /dev/null +++ b/drivers/net/wireless/renesas/ra6w/Kconfig @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0-only +config RA6W + tristate "Renesas 802.11ax wireless chips support" + depends on CFG80211 && MMC + help + This module adds support for wireless adapters based on + Renesas RA6W IEEE 802.11ax (Dual-band Wi-Fi6) family of chipsets. + Select M (recommended), if you have a wireless module.