* [PATCH v2 0/7] rtw89: support AP mode
@ 2022-02-07 6:38 Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 1/7] rtw89: extend role_maintain to " Ping-Ke Shih
` (6 more replies)
0 siblings, 7 replies; 9+ messages in thread
From: Ping-Ke Shih @ 2022-02-07 6:38 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
To support AP mode, we implement ::start_ap and ::stop_ap to configure
firmware and hardware to play an AP. Then, we download beacon content to
firmware, so firmware can send out periodically the frames that must have
continual sequence number with other management frames.
When mac80211 buffers unicast packets for certain STAs, it tells driver via
::set_tim, and then we download the beacon content to firmware again. On the
other hand, if a broadcast packet is going to send out, it should go via
HIQ (HI queue) that hardware will raise group frame bit in TIM of beacon
frame. But if no STA sleeps, a broadcast packet is sent via AC queue.
When a STA is going to connect, it issues a probe request frame and then
auth/assoc frames. To receive these frames before it is connected, we need
to consider more RX filter flags to set registers properly.
When a connection is established, we need to assign a mac_id as a behalf of
this peer in firmware and hardware, and then use this mac_id to initialize
an instance in firmware via H2C(s). The most important part is to add a
corresponding address CAM entry that contains peer's MAC address and BSSID,
so hardware can determine a packet is belong to which peer. If it is a
security connection, keys will be filled to security CAM as well.
Since there are many CAM ID(s), I add a debugfs entry to see if the
relations between ID(s) and STA(s) are expected.
v2:
- use full logic style of 'self_role'
- 1~13/19 patches of patchset v1 are merged, so v2 contains remaining
7 patches.
Ping-Ke Shih (7):
rtw89: extend role_maintain to support AP mode
rtw89: add addr_cam field to sta to support AP mode
rtw89: only STA mode change vif_type mapping dynamically
rtw89: maintain assoc/disassoc STA states of firmware and hardware
rtw89: implement ieee80211_ops::start_ap and stop_ap
rtw89: debug: add stations entry to show ID assignment
rtw89: declare AP mode support
drivers/net/wireless/realtek/rtw89/cam.c | 6 +-
drivers/net/wireless/realtek/rtw89/core.c | 43 +++++++++--
drivers/net/wireless/realtek/rtw89/core.h | 62 +++++++++-------
drivers/net/wireless/realtek/rtw89/debug.c | 71 +++++++++++++++++++
drivers/net/wireless/realtek/rtw89/fw.c | 16 ++++-
drivers/net/wireless/realtek/rtw89/fw.h | 1 +
drivers/net/wireless/realtek/rtw89/mac.c | 8 +--
drivers/net/wireless/realtek/rtw89/mac.h | 1 +
drivers/net/wireless/realtek/rtw89/mac80211.c | 36 ++++++++++
9 files changed, 204 insertions(+), 40 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/7] rtw89: extend role_maintain to support AP mode
2022-02-07 6:38 [PATCH v2 0/7] rtw89: support AP mode Ping-Ke Shih
@ 2022-02-07 6:38 ` Ping-Ke Shih
2022-02-10 8:41 ` Kalle Valo
2022-02-07 6:38 ` [PATCH 2/7] rtw89: add addr_cam field to sta " Ping-Ke Shih
` (5 subsequent siblings)
6 siblings, 1 reply; 9+ messages in thread
From: Ping-Ke Shih @ 2022-02-07 6:38 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
Fill mac_id and self_role depends on the operation mode.
In AP mode, echo connected station has an unique mac_id, and each vif also
has one mac_id to represent itself.
The self_role is assigned to vif if the operation mode is decided, and
RTW89_SELF_ROLE_AP_CLIENT is assigned to the connected STA in AP mode,
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 16 ++++++++++++++--
drivers/net/wireless/realtek/rtw89/fw.h | 1 +
drivers/net/wireless/realtek/rtw89/mac.c | 4 ++--
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 2d5b6323b607d..7fa60fd00143a 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -993,9 +993,21 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
#define H2C_ROLE_MAINTAIN_LEN 4
int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
+ struct rtw89_sta *rtwsta,
enum rtw89_upd_mode upd_mode)
{
struct sk_buff *skb;
+ u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
+ u8 self_role;
+
+ if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) {
+ if (rtwsta)
+ self_role = RTW89_SELF_ROLE_AP_CLIENT;
+ else
+ self_role = rtwvif->self_role;
+ } else {
+ self_role = rtwvif->self_role;
+ }
skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_ROLE_MAINTAIN_LEN);
if (!skb) {
@@ -1003,8 +1015,8 @@ int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
skb_put(skb, H2C_ROLE_MAINTAIN_LEN);
- SET_FWROLE_MAINTAIN_MACID(skb->data, rtwvif->mac_id);
- SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, rtwvif->self_role);
+ SET_FWROLE_MAINTAIN_MACID(skb->data, mac_id);
+ SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, self_role);
SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode);
SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role);
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index b30cf0a2cc1e0..83f4eaaf90f3b 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -1886,6 +1886,7 @@ void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h);
void rtw89_fw_c2h_work(struct work_struct *work);
int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
+ struct rtw89_sta *rtwsta,
enum rtw89_upd_mode upd_mode);
int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta, bool dis_conn);
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 2e95d9007c41d..2ced6a8b36c2d 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -3025,7 +3025,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
if (ret)
return ret;
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, RTW89_ROLE_CREATE);
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_CREATE);
if (ret)
return ret;
@@ -3048,7 +3048,7 @@ int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
int ret;
- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, RTW89_ROLE_REMOVE);
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_REMOVE);
if (ret)
return ret;
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/7] rtw89: add addr_cam field to sta to support AP mode
2022-02-07 6:38 [PATCH v2 0/7] rtw89: support AP mode Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 1/7] rtw89: extend role_maintain to " Ping-Ke Shih
@ 2022-02-07 6:38 ` Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 3/7] rtw89: only STA mode change vif_type mapping dynamically Ping-Ke Shih
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Ping-Ke Shih @ 2022-02-07 6:38 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In AP mode, each connected station needs an entry of address CAM. The
address CAM of vif is still needed to assit in AP itself.
For station mode, it still uses vif's address CAM.
Add a help macro rtw89_get_addr_cam_of() to get addr_cam from vif or sta
for all use cases.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/cam.c | 6 +--
drivers/net/wireless/realtek/rtw89/core.c | 5 +-
drivers/net/wireless/realtek/rtw89/core.h | 62 +++++++++++++----------
3 files changed, 43 insertions(+), 30 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c
index 2114d117b603d..305dbbebff6bb 100644
--- a/drivers/net/wireless/realtek/rtw89/cam.c
+++ b/drivers/net/wireless/realtek/rtw89/cam.c
@@ -231,7 +231,7 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
}
rtwvif = (struct rtw89_vif *)vif->drv_priv;
- addr_cam = &rtwvif->addr_cam;
+ addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
ret = rtw89_cam_get_addr_cam_key_idx(addr_cam, sec_cam, key, &key_idx);
if (ret) {
rtw89_err(rtwdev, "failed to get addr cam key idx %d, %d\n",
@@ -387,7 +387,7 @@ int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
}
rtwvif = (struct rtw89_vif *)vif->drv_priv;
- addr_cam = &rtwvif->addr_cam;
+ addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
sec_cam = addr_cam->sec_entries[key_idx];
if (!sec_cam)
return -EINVAL;
@@ -617,7 +617,7 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
u8 *cmd)
{
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
+ struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr;
u8 sma_hash, tma_hash, addr_msk_start;
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 490f5d86eeb2e..81575463a833f 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -4,6 +4,7 @@
#include <linux/ip.h>
#include <linux/udp.h>
+#include "cam.h"
#include "coex.h"
#include "core.h"
#include "efuse.h"
@@ -399,9 +400,11 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
struct ieee80211_vif *vif = tx_req->vif;
+ struct ieee80211_sta *sta = tx_req->sta;
struct ieee80211_tx_info *info;
struct ieee80211_key_conf *key;
struct rtw89_vif *rtwvif;
+ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
struct rtw89_addr_cam_entry *addr_cam;
struct rtw89_sec_cam_entry *sec_cam;
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
@@ -414,7 +417,7 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev,
}
rtwvif = (struct rtw89_vif *)vif->drv_priv;
- addr_cam = &rtwvif->addr_cam;
+ addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
info = IEEE80211_SKB_CB(skb);
key = info->control.hw_key;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index cb71dfca9341c..deb91f6b67375 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1842,32 +1842,6 @@ struct rtw89_ba_cam_entry {
u8 tid;
};
-struct rtw89_sta {
- u8 mac_id;
- bool disassoc;
- struct rtw89_vif *rtwvif;
- struct rtw89_ra_info ra;
- struct rtw89_ra_report ra_report;
- int max_agg_wait;
- u8 prev_rssi;
- struct ewma_rssi avg_rssi;
- struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
- struct ieee80211_rx_status rx_status;
- u16 rx_hw_rate;
- __le32 htc_template;
-
- bool use_cfg_mask;
- struct cfg80211_bitrate_mask mask;
-
- bool cctl_tx_time;
- u32 ampdu_max_time:4;
- bool cctl_tx_retry_limit;
- u32 data_tx_cnt_lmt:6;
-
- DECLARE_BITMAP(ba_cam_map, RTW89_BA_CAM_NUM);
- struct rtw89_ba_cam_entry ba_cam_entry[RTW89_BA_CAM_NUM];
-};
-
#define RTW89_MAX_ADDR_CAM_NUM 128
#define RTW89_MAX_BSSID_CAM_NUM 20
#define RTW89_MAX_SEC_CAM_NUM 128
@@ -1911,6 +1885,33 @@ struct rtw89_sec_cam_entry {
u8 key[32];
};
+struct rtw89_sta {
+ u8 mac_id;
+ bool disassoc;
+ struct rtw89_vif *rtwvif;
+ struct rtw89_ra_info ra;
+ struct rtw89_ra_report ra_report;
+ int max_agg_wait;
+ u8 prev_rssi;
+ struct ewma_rssi avg_rssi;
+ struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
+ struct ieee80211_rx_status rx_status;
+ u16 rx_hw_rate;
+ __le32 htc_template;
+ struct rtw89_addr_cam_entry addr_cam; /* AP mode only */
+
+ bool use_cfg_mask;
+ struct cfg80211_bitrate_mask mask;
+
+ bool cctl_tx_time;
+ u32 ampdu_max_time:4;
+ bool cctl_tx_retry_limit;
+ u32 data_tx_cnt_lmt:6;
+
+ DECLARE_BITMAP(ba_cam_map, RTW89_BA_CAM_NUM);
+ struct rtw89_ba_cam_entry ba_cam_entry[RTW89_BA_CAM_NUM];
+};
+
struct rtw89_efuse {
bool valid;
u8 xtal_cap;
@@ -3149,6 +3150,15 @@ static inline struct rtw89_sta *sta_to_rtwsta_safe(struct ieee80211_sta *sta)
return sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
}
+static inline
+struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif *rtwvif,
+ struct rtw89_sta *rtwsta)
+{
+ if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta)
+ return &rtwsta->addr_cam;
+ return &rtwvif->addr_cam;
+}
+
static inline
void rtw89_chip_set_channel_prepare(struct rtw89_dev *rtwdev,
struct rtw89_channel_help_params *p)
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/7] rtw89: only STA mode change vif_type mapping dynamically
2022-02-07 6:38 [PATCH v2 0/7] rtw89: support AP mode Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 1/7] rtw89: extend role_maintain to " Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 2/7] rtw89: add addr_cam field to sta " Ping-Ke Shih
@ 2022-02-07 6:38 ` Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 4/7] rtw89: maintain assoc/disassoc STA states of firmware and hardware Ping-Ke Shih
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Ping-Ke Shih @ 2022-02-07 6:38 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
vif_type mapping indicates hardware operating mode corresponding to vif
type. In STA mode, hardware mode should be INFRA or NO_LINK mode
dynamically according to association status. Since AP mode don't need to
change this by association status intuitively, just do the mapping in
STA mode.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 4 ++--
drivers/net/wireless/realtek/rtw89/mac80211.c | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 81575463a833f..8849f3172a341 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2047,7 +2047,8 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
rtw89_mac_bf_disassoc(rtwdev, vif, sta);
rtw89_core_free_sta_pending_ba(rtwdev, sta);
- rtw89_vif_type_mapping(vif, false);
+ if (vif->type == NL80211_IFTYPE_STATION)
+ rtw89_vif_type_mapping(vif, false);
ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
if (ret) {
@@ -2079,7 +2080,6 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
int ret;
- rtw89_vif_type_mapping(vif, true);
ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
if (ret) {
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 02480a6bdf4c0..295d54c0fc94a 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -324,6 +324,9 @@ static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
rtw89_err(rtwdev, "can't find sta to set sta_assoc state\n");
return;
}
+
+ rtw89_vif_type_mapping(vif, true);
+
rtw89_core_sta_assoc(rtwdev, vif, sta);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/7] rtw89: maintain assoc/disassoc STA states of firmware and hardware
2022-02-07 6:38 [PATCH v2 0/7] rtw89: support AP mode Ping-Ke Shih
` (2 preceding siblings ...)
2022-02-07 6:38 ` [PATCH 3/7] rtw89: only STA mode change vif_type mapping dynamically Ping-Ke Shih
@ 2022-02-07 6:38 ` Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 5/7] rtw89: implement ieee80211_ops::start_ap and stop_ap Ping-Ke Shih
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Ping-Ke Shih @ 2022-02-07 6:38 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In AP mode, when a STA associate to us, we need to create an entry in
firmware and hardware, and then they can transmit data properly.
The entry index called mac_id which is assigned when sta_add, and we ask
firmware to create an entry for an associated station. Also, the address
CAM should be filled so hardware can know which packet is ours, and lookup
the mac_id for further use.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 31 ++++++++++++++++++++++-
drivers/net/wireless/realtek/rtw89/mac.c | 4 +--
drivers/net/wireless/realtek/rtw89/mac.h | 1 +
3 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 8849f3172a341..413bb391c21e3 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2046,6 +2046,8 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
rtw89_mac_bf_monitor_calc(rtwdev, sta, true);
rtw89_mac_bf_disassoc(rtwdev, vif, sta);
rtw89_core_free_sta_pending_ba(rtwdev, sta);
+ if (vif->type == NL80211_IFTYPE_AP)
+ rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
if (vif->type == NL80211_IFTYPE_STATION)
rtw89_vif_type_mapping(vif, false);
@@ -2062,8 +2064,16 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
return ret;
}
+ if (vif->type == NL80211_IFTYPE_AP) {
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, RTW89_ROLE_REMOVE);
+ if (ret) {
+ rtw89_warn(rtwdev, "failed to send h2c role info\n");
+ return ret;
+ }
+ }
+
/* update cam aid mac_id net_type */
- rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
@@ -2080,6 +2090,25 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
int ret;
+ if (vif->type == NL80211_IFTYPE_AP) {
+ ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta->mac_id, false);
+ if (ret) {
+ rtw89_warn(rtwdev, "failed to send h2c macid pause\n");
+ return ret;
+ }
+
+ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, RTW89_ROLE_CREATE);
+ if (ret) {
+ rtw89_warn(rtwdev, "failed to send h2c role info\n");
+ return ret;
+ }
+
+ ret = rtw89_cam_init_addr_cam(rtwdev, &rtwsta->addr_cam, &rtwvif->bssid_cam);
+ if (ret) {
+ rtw89_warn(rtwdev, "failed to send h2c init addr cam\n");
+ return ret;
+ }
+ }
ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
if (ret) {
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 2ced6a8b36c2d..3cd208d05c7c0 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -2718,7 +2718,7 @@ static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 28, 0xB8109);
}
-static int rtw89_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause)
+int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause)
{
u8 sh = FIELD_GET(GENMASK(4, 0), macid);
u8 grp = macid >> 5;
@@ -3021,7 +3021,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_mac_dmac_tbl_init(rtwdev, rtwvif->mac_id);
rtw89_mac_cmac_tbl_init(rtwdev, rtwvif->mac_id);
- ret = rtw89_set_macid_pause(rtwdev, rtwvif->mac_id, false);
+ ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif->mac_id, false);
if (ret)
return ret;
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 9fe7629f1da16..e5db0a2eb9c29 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -811,6 +811,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool en);
+int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause);
static inline void rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
{
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/7] rtw89: implement ieee80211_ops::start_ap and stop_ap
2022-02-07 6:38 [PATCH v2 0/7] rtw89: support AP mode Ping-Ke Shih
` (3 preceding siblings ...)
2022-02-07 6:38 ` [PATCH 4/7] rtw89: maintain assoc/disassoc STA states of firmware and hardware Ping-Ke Shih
@ 2022-02-07 6:38 ` Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 6/7] rtw89: debug: add stations entry to show ID assignment Ping-Ke Shih
2022-02-07 6:39 ` [PATCH 7/7] rtw89: declare AP mode support Ping-Ke Shih
6 siblings, 0 replies; 9+ messages in thread
From: Ping-Ke Shih @ 2022-02-07 6:38 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
Configure firmware and hardware to run AP mode. The start_ap() setup
bssid, mac port, mac_id entry, and does RFK. The stop_ap() reset the
state.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/mac80211.c | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 295d54c0fc94a..5df7aceabdf5e 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -371,6 +371,37 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&rtwdev->mutex);
}
+static int rtw89_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+
+ mutex_lock(&rtwdev->mutex);
+ ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid);
+ rtw89_cam_bssid_changed(rtwdev, rtwvif);
+ rtw89_mac_port_update(rtwdev, rtwvif);
+ rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
+ rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_TYPE_CHANGE);
+ rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
+ rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
+ rtw89_chip_rfk_channel(rtwdev);
+ mutex_unlock(&rtwdev->mutex);
+
+ return 0;
+}
+
+static
+void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct rtw89_dev *rtwdev = hw->priv;
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+
+ mutex_lock(&rtwdev->mutex);
+ rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
+ rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
+ mutex_unlock(&rtwdev->mutex);
+}
+
static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
bool set)
{
@@ -699,6 +730,8 @@ const struct ieee80211_ops rtw89_ops = {
.remove_interface = rtw89_ops_remove_interface,
.configure_filter = rtw89_ops_configure_filter,
.bss_info_changed = rtw89_ops_bss_info_changed,
+ .start_ap = rtw89_ops_start_ap,
+ .stop_ap = rtw89_ops_stop_ap,
.set_tim = rtw89_ops_set_tim,
.conf_tx = rtw89_ops_conf_tx,
.sta_state = rtw89_ops_sta_state,
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/7] rtw89: debug: add stations entry to show ID assignment
2022-02-07 6:38 [PATCH v2 0/7] rtw89: support AP mode Ping-Ke Shih
` (4 preceding siblings ...)
2022-02-07 6:38 ` [PATCH 5/7] rtw89: implement ieee80211_ops::start_ap and stop_ap Ping-Ke Shih
@ 2022-02-07 6:38 ` Ping-Ke Shih
2022-02-07 6:39 ` [PATCH 7/7] rtw89: declare AP mode support Ping-Ke Shih
6 siblings, 0 replies; 9+ messages in thread
From: Ping-Ke Shih @ 2022-02-07 6:38 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In order to trace the relation of IDs, we add this debugfs entry to make
them clear.
The output looks like:
map:
mac_id: 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
addr_cam: 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bssid_cam: 01 00 00 00 00 00 00 00
sec_cam: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
VIF [0] 94:08:53:8e:ef:21
bssid_cam_idx=0
addr_cam_idx=0
-> bssid_cam_idx=0
sec_cam_bitmap=00 00 00 00 00 00 00 00
STA [1] 58:00:e3:bb:9c:4f
addr_cam_idx=1
-> bssid_cam_idx=0
sec_cam_bitmap=00 00 00 00 00 00 00 00
STA [2] 94:08:53:8e:ef:75
addr_cam_idx=2
-> bssid_cam_idx=0
sec_cam_bitmap=00 00 00 00 00 00 00 00
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/debug.c | 71 ++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index b25d88d508553..b73cc03cecfd7 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -2372,6 +2372,72 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
return 0;
}
+static void rtw89_dump_addr_cam(struct seq_file *m,
+ struct rtw89_addr_cam_entry *addr_cam)
+{
+ struct rtw89_sec_cam_entry *sec_entry;
+ int i;
+
+ seq_printf(m, "\taddr_cam_idx=%u\n", addr_cam->addr_cam_idx);
+ seq_printf(m, "\t-> bssid_cam_idx=%u\n", addr_cam->bssid_cam_idx);
+ seq_printf(m, "\tsec_cam_bitmap=%*ph\n", (int)sizeof(addr_cam->sec_cam_map),
+ addr_cam->sec_cam_map);
+ for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) {
+ sec_entry = addr_cam->sec_entries[i];
+ if (!sec_entry)
+ continue;
+ seq_printf(m, "\tsec[%d]: sec_cam_idx %u", i, sec_entry->sec_cam_idx);
+ if (sec_entry->ext_key)
+ seq_printf(m, ", %u", sec_entry->sec_cam_idx + 1);
+ seq_puts(m, "\n");
+ }
+}
+
+static
+void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ struct seq_file *m = (struct seq_file *)data;
+ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
+
+ seq_printf(m, "VIF [%d] %pM\n", rtwvif->mac_id, rtwvif->mac_addr);
+ seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx);
+ rtw89_dump_addr_cam(m, &rtwvif->addr_cam);
+}
+
+static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ struct seq_file *m = (struct seq_file *)data;
+
+ seq_printf(m, "STA [%d] %pM\n", rtwsta->mac_id, sta->addr);
+ rtw89_dump_addr_cam(m, &rtwsta->addr_cam);
+}
+
+static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)
+{
+ struct rtw89_debugfs_priv *debugfs_priv = m->private;
+ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
+
+ seq_puts(m, "map:\n");
+ seq_printf(m, "\tmac_id: %*ph\n", (int)sizeof(rtwdev->mac_id_map),
+ rtwdev->mac_id_map);
+ seq_printf(m, "\taddr_cam: %*ph\n", (int)sizeof(cam_info->addr_cam_map),
+ cam_info->addr_cam_map);
+ seq_printf(m, "\tbssid_cam: %*ph\n", (int)sizeof(cam_info->bssid_cam_map),
+ cam_info->bssid_cam_map);
+ seq_printf(m, "\tsec_cam: %*ph\n", (int)sizeof(cam_info->sec_cam_map),
+ cam_info->sec_cam_map);
+
+ ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,
+ IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m);
+
+ ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, m);
+
+ return 0;
+}
+
static struct rtw89_debugfs_priv rtw89_debug_priv_read_reg = {
.cb_read = rtw89_debug_priv_read_reg_get,
.cb_write = rtw89_debug_priv_read_reg_select,
@@ -2438,6 +2504,10 @@ static struct rtw89_debugfs_priv rtw89_debug_priv_phy_info = {
.cb_read = rtw89_debug_priv_phy_info_get,
};
+static struct rtw89_debugfs_priv rtw89_debug_priv_stations = {
+ .cb_read = rtw89_debug_priv_stations_get,
+};
+
#define rtw89_debugfs_add(name, mode, fopname, parent) \
do { \
rtw89_debug_priv_ ##name.rtwdev = rtwdev; \
@@ -2476,6 +2546,7 @@ void rtw89_debugfs_init(struct rtw89_dev *rtwdev)
rtw89_debugfs_add_w(btc_manual);
rtw89_debugfs_add_w(fw_log_manual);
rtw89_debugfs_add_r(phy_info);
+ rtw89_debugfs_add_r(stations);
}
#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 7/7] rtw89: declare AP mode support
2022-02-07 6:38 [PATCH v2 0/7] rtw89: support AP mode Ping-Ke Shih
` (5 preceding siblings ...)
2022-02-07 6:38 ` [PATCH 6/7] rtw89: debug: add stations entry to show ID assignment Ping-Ke Shih
@ 2022-02-07 6:39 ` Ping-Ke Shih
6 siblings, 0 replies; 9+ messages in thread
From: Ping-Ke Shih @ 2022-02-07 6:39 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
Things are ready for AP mode, so declare this driver can support it.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 413bb391c21e3..a9544b006f0b4 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2696,7 +2696,8 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
ieee80211_hw_set(hw, SUPPORTS_PS);
ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
- hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_AP);
hw->wiphy->available_antennas_tx = BIT(rtwdev->chip->rf_path_num) - 1;
hw->wiphy->available_antennas_rx = BIT(rtwdev->chip->rf_path_num) - 1;
--
2.25.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/7] rtw89: extend role_maintain to support AP mode
2022-02-07 6:38 ` [PATCH 1/7] rtw89: extend role_maintain to " Ping-Ke Shih
@ 2022-02-10 8:41 ` Kalle Valo
0 siblings, 0 replies; 9+ messages in thread
From: Kalle Valo @ 2022-02-10 8:41 UTC (permalink / raw)
To: Ping-Ke Shih; +Cc: linux-wireless
Ping-Ke Shih <pkshih@realtek.com> wrote:
> Fill mac_id and self_role depends on the operation mode.
>
> In AP mode, echo connected station has an unique mac_id, and each vif also
> has one mac_id to represent itself.
>
> The self_role is assigned to vif if the operation mode is decided, and
> RTW89_SELF_ROLE_AP_CLIENT is assigned to the connected STA in AP mode,
>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
7 patches applied to wireless-next.git, thanks.
ff66964a9467 rtw89: extend role_maintain to support AP mode
2ab856cc3a6c rtw89: add addr_cam field to sta to support AP mode
fd7ee4c8ac14 rtw89: only STA mode change vif_type mapping dynamically
1b73e77db1d0 rtw89: maintain assoc/disassoc STA states of firmware and hardware
a52e4f2ce0f5 rtw89: implement ieee80211_ops::start_ap and stop_ap
d95d8d6bba72 rtw89: debug: add stations entry to show ID assignment
b478ff6bcb2d rtw89: declare AP mode support
--
https://patchwork.kernel.org/project/linux-wireless/patch/20220207063900.43643-2-pkshih@realtek.com/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-02-10 8:41 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-07 6:38 [PATCH v2 0/7] rtw89: support AP mode Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 1/7] rtw89: extend role_maintain to " Ping-Ke Shih
2022-02-10 8:41 ` Kalle Valo
2022-02-07 6:38 ` [PATCH 2/7] rtw89: add addr_cam field to sta " Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 3/7] rtw89: only STA mode change vif_type mapping dynamically Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 4/7] rtw89: maintain assoc/disassoc STA states of firmware and hardware Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 5/7] rtw89: implement ieee80211_ops::start_ap and stop_ap Ping-Ke Shih
2022-02-07 6:38 ` [PATCH 6/7] rtw89: debug: add stations entry to show ID assignment Ping-Ke Shih
2022-02-07 6:39 ` [PATCH 7/7] rtw89: declare AP mode support Ping-Ke Shih
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).