rtw89: support AP mode
Ping-Ke Shih
maintainercover rtw89: support AP mode
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.
Ping-Ke Shih (19):
rtw89: configure rx_filter according to FIF_PROBE_REQ
rtw89: use hardware SSN to TX management frame
rtw89: download beacon content to firmware
rtw89: add C2H handle of BCN_CNT
rtw89: implement mac80211_ops::set_tim to indicate STA to receive
packets
rtw89: allocate mac_id for each station in AP mode
rtw89: extend firmware commands on states of sta_assoc and
sta_disconnect
rtw89: rename vif_maintain to role_maintain
rtw89: configure mac port HIQ registers
rtw89: send broadcast/multicast packets via HIQ if STAs are in sleep
mode
rtw89: set mac_id and port ID to TXWD
rtw89: separate {init,deinit}_addr_cam functions
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 | 40 +++--- drivers/net/wireless/realtek/rtw89/cam.h | 5 + drivers/net/wireless/realtek/rtw89/core.c | 107 ++++++++++++++-- drivers/net/wireless/realtek/rtw89/core.h | 83 ++++++++----- drivers/net/wireless/realtek/rtw89/debug.c | 71 +++++++++++ drivers/net/wireless/realtek/rtw89/fw.c | 110 ++++++++++++++--- drivers/net/wireless/realtek/rtw89/fw.h | 115 +++++++++++++++++- drivers/net/wireless/realtek/rtw89/mac.c | 50 +++++++- drivers/net/wireless/realtek/rtw89/mac.h | 2 + drivers/net/wireless/realtek/rtw89/mac80211.c | 67 +++++++++- drivers/net/wireless/realtek/rtw89/reg.h | 14 ++- drivers/net/wireless/realtek/rtw89/txrx.h | 3 + 12 files changed, 575 insertions(+), 92 deletions(-)
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 1/19 rtw89: configure rx_filter according to FIF_PROBE_REQ
With this patch, we can receive probe_req and reply probe_resp, and STA can find us.
--- drivers/net/wireless/realtek/rtw89/mac80211.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw89/mac80211.c +10 -1
@@ -161,7 +161,7 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,rtw89_leave_ps_mode (rtwdev); *new_flags &=FIF_ALLMULTI |FIF_OTHER_BSS |FIF_FCSFAIL | -FIF_BCN_PRBRESP_PROMISC ; +FIF_BCN_PRBRESP_PROMISC |FIF_PROBE_REQ ;if (changed_flags &FIF_ALLMULTI ) {if (*new_flags &FIF_ALLMULTI )
@@ -192,6 +192,15 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, rtwdev->hal.rx_fltr |=B_AX_A_A1_MATCH ; } } +if (changed_flags &FIF_PROBE_REQ ) { +if (*new_flags &FIF_PROBE_REQ ) { + rtwdev->hal.rx_fltr &= ~B_AX_A_BC_CAM_MATCH ; + rtwdev->hal.rx_fltr &= ~B_AX_A_UC_CAM_MATCH ; + }else { + rtwdev->hal.rx_fltr |=B_AX_A_BC_CAM_MATCH ; + rtwdev->hal.rx_fltr |=B_AX_A_UC_CAM_MATCH ; + } + } rtw89_write32_mask(rtwdev, rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
Signature · 1 line
2.25.1
Re: [PATCH 01/19] rtw89: configure rx_filter according to FIF_PROBE_REQ
Quoted 4 lines · Ping-Ke Shih
With this patch, we can receive
probe_reqand replyprobe_resp, and STA can find us.Signed-off-by Ping-Ke Shih <[email protected]>
12 patches applied to wireless-next.git, thanks.
6629dc5697cc rtw89: configure rx_filter according to FIF_PROBE_REQ 91644020dbd9 rtw89: use hardware SSN to TX management framef7e76d13bb2b rtw89: download beacon content to firmwarefccca9345b25 rtw89: add C2H handle of BCN_CNTd62816b4a44e rtw89: implement mac80211_ops::set_tim to indicate STA to receive packets c7df64c194f6 rtw89: allocate mac_id for each station in AP mode 742c470b5773 rtw89: extend firmware commands on states of sta_assoc and sta_disconnect 8b252070d790 rtw89: rename vif_maintain to role_maintain283c3d886fdf rtw89: configure mac port HIQ registers11d261f24be6 rtw89: send broadcast/multicast packets via HIQ if STAs are in sleep mode 9eecaec238c8 rtw89: set mac_id and port ID to TXWD14f0999d49e7 rtw89: separate {init,deinit}_addr_cam functions
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Ping-Ke Shih
maintainerPATCH 2/19 rtw89: use hardware SSN to TX management frame
In reply to Ping-Ke ShihSince firmware transmits beacon by hardware SSN, driver does it with the same setting, then packets in the air have continual sequence number.
--- drivers/net/wireless/realtek/rtw89/core.c | 6 +++++- drivers/net/wireless/realtek/rtw89/core.h | 4 ++++ drivers/net/wireless/realtek/rtw89/txrx.h | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw89/core.c +5 -1
@@ -383,6 +383,8 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, desc_info->qsel =RTW89_TX_QSEL_B0_MGMT ; desc_info->ch_dma = ch_dma; + desc_info->hw_ssn_sel =RTW89_MGMT_HW_SSN_SEL ; + desc_info->hw_seq_mode =RTW89_MGMT_HW_SEQ_MODE ;/* fixed data rate for mgmt frames */ desc_info->en_wd_info = true;
@@ -708,7 +710,9 @@ static __le32 rtw89_build_txwd_body0(struct rtw89_tx_desc_info *desc_info)FIELD_PREP (RTW89_TXWD_BODY0_CHANNEL_DMA , desc_info->ch_dma) |FIELD_PREP (RTW89_TXWD_BODY0_HDR_LLC_LEN , desc_info->hdr_llc_len) |FIELD_PREP (RTW89_TXWD_BODY0_WD_PAGE , desc_info->wd_page) | -FIELD_PREP (RTW89_TXWD_BODY0_FW_DL , desc_info->fw_dl); +FIELD_PREP (RTW89_TXWD_BODY0_FW_DL , desc_info->fw_dl) | +FIELD_PREP (RTW89_TXWD_BODY0_HW_SSN_SEL , desc_info->hw_ssn_sel) | +FIELD_PREP (RTW89_TXWD_BODY0_HW_SSN_MODE , desc_info->hw_seq_mode);return cpu_to_le32 (dword); }
drivers/net/wireless/realtek/rtw89/core.h +4 -0
@@ -691,6 +691,10 @@ struct rtw89_tx_desc_info {bool fw_dl;u16 seq;bool a_ctrl_bsr; +u8 hw_ssn_sel; +#define RTW89_MGMT_HW_SSN_SEL 1 +u8 hw_seq_mode; +#define RTW89_MGMT_HW_SEQ_MODE 1 };struct rtw89_core_tx_request {
drivers/net/wireless/realtek/rtw89/txrx.h +2 -0
@@ -31,6 +31,8 @@#define RTW89_TXWD_BODY0_HDR_LLC_LEN GENMASK(15, 11)#define RTW89_TXWD_BODY0_WD_PAGE BIT(7)#define RTW89_TXWD_BODY0_HW_AMSDU BIT(5) +#define RTW89_TXWD_BODY0_HW_SSN_SEL GENMASK(3, 2) +#define RTW89_TXWD_BODY0_HW_SSN_MODE GENMASK(1, 0)/* TX WD BODY DWORD 1 */ #define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16)
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 3/19 rtw89: download beacon content to firmware
In reply to Ping-Ke ShihFirmware sends out beacon content generated by mac80211, and then stations can receive beacon and work with this AP properly. Also, we download beacon content again if TIM is changed.
--- drivers/net/wireless/realtek/rtw89/fw.c | 53 +++++++++ drivers/net/wireless/realtek/rtw89/fw.h | 103 ++++++++++++++++++ drivers/net/wireless/realtek/rtw89/mac80211.c | 3 + 3 files changed, 159 insertions(+)
drivers/net/wireless/realtek/rtw89/fw.c +53 -0
@@ -928,6 +928,59 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,return -EBUSY ; } +#define H2C_BCN_BASE_LEN 12 +int rtw89_fw_h2c_update_beacon (struct rtw89_dev *rtwdev, +struct rtw89_vif *rtwvif) +{ +struct rtw89_hal *hal = &rtwdev->hal; +struct ieee80211_vif *vif =rtwvif_to_vif (rtwvif); +struct sk_buff *skb; +struct sk_buff *skb_beacon; +u16 tim_offset; +int bcn_total_len; + + skb_beacon =ieee80211_beacon_get_tim (rtwdev->hw, vif, &tim_offset,NULL ); +if (!skb_beacon) { +rtw89_err (rtwdev,"failed to get beacon skb\n" ); +return -ENOMEM ; + } + + bcn_total_len =H2C_BCN_BASE_LEN + skb_beacon->len; + skb =rtw89_fw_h2c_alloc_skb_with_hdr (bcn_total_len); +if (!skb) { +rtw89_err (rtwdev,"failed to alloc skb for fw dl\n" ); +dev_kfree_skb_any (skb_beacon); +return -ENOMEM ; + } +skb_put (skb,H2C_BCN_BASE_LEN ); + +SET_BCN_UPD_PORT (skb->data, rtwvif->port); +SET_BCN_UPD_MBSSID (skb->data,0 ); +SET_BCN_UPD_BAND (skb->data, rtwvif->mac_idx); +SET_BCN_UPD_GRP_IE_OFST (skb->data, tim_offset); +SET_BCN_UPD_MACID (skb->data, rtwvif->mac_id); +SET_BCN_UPD_SSN_SEL (skb->data,RTW89_MGMT_HW_SSN_SEL ); +SET_BCN_UPD_SSN_MODE (skb->data,RTW89_MGMT_HW_SEQ_MODE ); +SET_BCN_UPD_RATE (skb->data, hal->current_band_type ==RTW89_BAND_2G ? +RTW89_HW_RATE_CCK1 :RTW89_HW_RATE_OFDM6 ); + +skb_put_data (skb, skb_beacon->data, skb_beacon->len); +dev_kfree_skb_any (skb_beacon); + +rtw89_h2c_pkt_set_hdr (rtwdev, skb,FWCMD_TYPE_H2C , +H2C_CAT_MAC ,H2C_CL_MAC_FR_EXCHG , +H2C_FUNC_MAC_BCN_UPD ,0 ,1 , + bcn_total_len); + +if (rtw89_h2c_tx (rtwdev, skb, false)) { +rtw89_err (rtwdev,"failed to send h2c\n" ); +dev_kfree_skb_any (skb); +return -EBUSY ; + } + +return 0 ; +} +#define H2C_VIF_MAINTAIN_LEN 4 int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
drivers/net/wireless/realtek/rtw89/fw.h +103 -0
121 lines not on this page · raw message
drivers/net/wireless/realtek/rtw89/mac80211.c +3 -0
@@ -349,6 +349,9 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,rtw89_fw_h2c_cam (rtwdev, rtwvif,NULL ,NULL ); } +if (changed &BSS_CHANGED_BEACON ) +rtw89_fw_h2c_update_beacon (rtwdev, rtwvif); +if (changed &BSS_CHANGED_ERP_SLOT )rtw89_conf_tx (rtwdev, rtwvif);
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 4/19 rtw89: add C2H handle of BCN_CNT
In reply to Ping-Ke ShihThis C2H notify driver the beacon count we send out. We don't handle the content for now, so add a dummy handler to avoid messages, like
rtw89_pci 0000:03:00.0: c2h class 0 func 3 not support
C2H: 00000000: 01 03 01 3f 0f 00 00 00 80 0a 00 00 00 00 a0 rtw89_pci 0000:03:00.0: c2h class 0 func 3 not support
C2H: 00000000: 01 03 01 40 0f 00 00 00 00 03 20 00 00 00 a5
--- drivers/net/wireless/realtek/rtw89/mac.c | 6 ++++++ drivers/net/wireless/realtek/rtw89/mac.h | 1 + 2 files changed, 7 insertions(+)
drivers/net/wireless/realtek/rtw89/mac.c +6 -0
@@ -3114,6 +3114,11 @@ rtw89_mac_c2h_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) RTW89_GET_C2H_LOG_SRT_PRT(c2h->data)); } +static void +rtw89_mac_c2h_bcn_cnt (struct rtw89_dev *rtwdev,struct sk_buff *c2h,u32 len) +{ +} +static void (*const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev,struct sk_buff *c2h,u32 len) = {
@@ -3130,6 +3135,7 @@ void (* const rtw89_mac_c2h_info_handler[])(struct rtw89_dev *rtwdev, [RTW89_MAC_C2H_FUNC_REC_ACK] = rtw89_mac_c2h_rec_ack, [RTW89_MAC_C2H_FUNC_DONE_ACK] = rtw89_mac_c2h_done_ack, [RTW89_MAC_C2H_FUNC_C2H_LOG] = rtw89_mac_c2h_log, + [RTW89_MAC_C2H_FUNC_BCN_CNT] = rtw89_mac_c2h_bcn_cnt, }; void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
drivers/net/wireless/realtek/rtw89/mac.h +1 -0
@@ -308,6 +308,7 @@ enum rtw89_mac_c2h_info_func {RTW89_MAC_C2H_FUNC_REC_ACK ,RTW89_MAC_C2H_FUNC_DONE_ACK ,RTW89_MAC_C2H_FUNC_C2H_LOG , +RTW89_MAC_C2H_FUNC_BCN_CNT , RTW89_MAC_C2H_FUNC_INFO_MAX, };
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 5/19 rtw89: implement mac80211_ops::set_tim to indicate STA to receive packets
In reply to Ping-Ke ShihUpdate beacon content if TIM bitmap maintained by mac80211 is changed. Since .set_tim must be atomic but driver uses mutex lock, we add a work. Otherwise, kernel says "sched: RT throttling activated" and lock down.
--- drivers/net/wireless/realtek/rtw89/core.c | 15 +++++++++++++++ drivers/net/wireless/realtek/rtw89/core.h | 3 +++ drivers/net/wireless/realtek/rtw89/mac80211.c | 17 +++++++++++++++++ 3 files changed, 35 insertions(+)
drivers/net/wireless/realtek/rtw89/core.c +15 -0
@@ -2238,6 +2238,21 @@ static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev) rtwdev->ppdu_sts.curr_rx_ppdu_cnt[i] =U8_MAX ; } +void rtw89_core_update_beacon_work (struct work_struct *work) +{ +struct rtw89_dev *rtwdev; + struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif, + update_beacon_work); + +if (rtwvif->net_type !=RTW89_NET_TYPE_AP_MODE ) +return ; + + rtwdev = rtwvif->rtwdev; +mutex_lock (&rtwdev->mutex); +rtw89_fw_h2c_update_beacon (rtwdev, rtwvif); +mutex_unlock (&rtwdev->mutex); +} +int rtw89_core_start (struct rtw89_dev *rtwdev) {int ret;
drivers/net/wireless/realtek/rtw89/core.h +3 -0
@@ -1928,6 +1928,7 @@ struct rtw89_phy_rate_pattern {struct rtw89_vif {struct list_head list; +struct rtw89_dev *rtwdev;u8 mac_id;u8 port;u8 mac_addr[ETH_ALEN ];
@@ -1949,6 +1950,7 @@ struct rtw89_vif {bool wowlan_magic;bool is_hesta;bool last_a_ctrl; +struct work_struct update_beacon_work;struct rtw89_addr_cam_entry addr_cam;struct rtw89_bssid_cam_entry bssid_cam;struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS ];
@@ -3396,5 +3398,6 @@ void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, struct rtw89_traffic_stats *stats);int rtw89_core_start (struct rtw89_dev *rtwdev);void rtw89_core_stop (struct rtw89_dev *rtwdev); +void rtw89_core_update_beacon_work (struct work_struct *work);#endif
drivers/net/wireless/realtek/rtw89/mac80211.c +17 -0
@@ -102,7 +102,9 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,int ret =0 ;mutex_lock (&rtwdev->mutex); + rtwvif->rtwdev = rtwdev;list_add_tail (&rtwvif->list, &rtwdev->rtwvifs_list); +INIT_WORK (&rtwvif->update_beacon_work, rtw89_core_update_beacon_work);rtw89_leave_ps_mode (rtwdev);rtw89_traffic_stats_init (rtwdev, &rtwvif->stats);
@@ -141,6 +143,8 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,struct rtw89_dev *rtwdev = hw->priv;struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; +cancel_work_sync (&rtwvif->update_beacon_work); +mutex_lock (&rtwdev->mutex);rtw89_leave_ps_mode (rtwdev);rtw89_btc_ntfy_role_info (rtwdev, rtwvif,NULL ,BTC_ROLE_STOP );
@@ -364,6 +368,18 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,mutex_unlock (&rtwdev->mutex); } +static int rtw89_ops_set_tim (struct ieee80211_hw *hw,struct ieee80211_sta *sta, +bool set) +{ +struct rtw89_dev *rtwdev = hw->priv; +struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; +struct rtw89_vif *rtwvif = rtwsta->rtwvif; + +ieee80211_queue_work (rtwdev->hw, &rtwvif->update_beacon_work); + +return 0 ; +} +static int rtw89_ops_conf_tx (struct ieee80211_hw *hw,struct ieee80211_vif *vif,u16 ac,const struct ieee80211_tx_queue_params *params)
@@ -680,6 +696,7 @@ 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, + .set_tim = rtw89_ops_set_tim, .conf_tx = rtw89_ops_conf_tx, .sta_state = rtw89_ops_sta_state, .set_key = rtw89_ops_set_key,
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 6/19 rtw89: allocate mac_id for each station in AP mode
In reply to Ping-Ke ShihIn station mode, mac_id of station is the same as rtwvif's one. In AP mode, each station uses individual mac_id.
--- drivers/net/wireless/realtek/rtw89/core.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/wireless/realtek/rtw89/core.c +5 -0
@@ -1885,6 +1885,9 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev,rtw89_btc_ntfy_role_info (rtwdev, rtwvif, rtwsta,BTC_ROLE_MSTS_STA_CONN_START );rtw89_chip_rfk_channel (rtwdev); + }else if (vif->type ==NL80211_IFTYPE_AP ) { + rtwsta->mac_id =rtw89_core_acquire_bit_map (rtwdev->mac_id_map, +RTW89_MAX_MAC_ID_NUM ); }return 0 ;
@@ -1997,6 +2000,8 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,if (vif->type ==NL80211_IFTYPE_STATION )rtw89_btc_ntfy_role_info (rtwdev, rtwvif, rtwsta,BTC_ROLE_MSTS_STA_DIS_CONN ); +else if (vif->type ==NL80211_IFTYPE_AP ) +rtw89_core_release_bit_map (rtwdev->mac_id_map, rtwsta->mac_id);return 0 ; }
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 7/19 rtw89: extend firmware commands on states of sta_assoc and sta_disconnect
In reply to Ping-Ke ShihThe h2c_join firmware command is used to indicate a station is connected, and the assoc_cmac_tbl firmware command is used to set CMAC table corresponding to a mac_id. Both commands must work in both station and AP modes. Use the mac_id of rtw89_sta naturally and intuitively.
--- drivers/net/wireless/realtek/rtw89/core.c | 4 +-- drivers/net/wireless/realtek/rtw89/fw.c | 35 +++++++++++++++++------ drivers/net/wireless/realtek/rtw89/fw.h | 5 ++-- drivers/net/wireless/realtek/rtw89/mac.c | 2 +- 4 files changed, 32 insertions(+), 14 deletions(-)
drivers/net/wireless/realtek/rtw89/core.c +2 -2
@@ -1925,7 +1925,7 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,return ret; } - ret =rtw89_fw_h2c_join_info (rtwdev, rtwvif,1 ); + ret =rtw89_fw_h2c_join_info (rtwdev, rtwvif, rtwsta, true);if (ret) {rtw89_warn (rtwdev,"failed to send h2c join info\n" );return ret;
@@ -1957,7 +1957,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,return ret; } - ret =rtw89_fw_h2c_join_info (rtwdev, rtwvif,0 ); + ret =rtw89_fw_h2c_join_info (rtwdev, rtwvif, rtwsta, false);if (ret) {rtw89_warn (rtwdev,"failed to send h2c join info\n" );return ret;
drivers/net/wireless/realtek/rtw89/fw.c +26 -9
@@ -733,12 +733,14 @@ int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, }#define H2C_CMC_TBL_LEN 68 -int rtw89_fw_h2c_default_cmac_tbl (struct rtw89_dev *rtwdev,u8 macid) +int rtw89_fw_h2c_default_cmac_tbl (struct rtw89_dev *rtwdev, +struct rtw89_vif *rtwvif) {struct rtw89_hal *hal = &rtwdev->hal;struct sk_buff *skb;u8 ntx_path = hal->antenna_tx ? hal->antenna_tx :RF_B ;u8 map_b = hal->antenna_tx ==RF_AB ?1 :0 ; +u8 macid = rtwvif->mac_id; skb =rtw89_fw_h2c_alloc_skb_with_hdr (H2C_CMC_TBL_LEN );if (!skb) {
@@ -760,6 +762,8 @@ int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, u8 macid)SET_CMC_TBL_ANTSEL_D (skb->data,0 );SET_CMC_TBL_DOPPLER_CTRL (skb->data,0 );SET_CMC_TBL_TXPWR_TOLERENCE (skb->data,0 ); +if (rtwvif->net_type ==RTW89_NET_TYPE_AP_MODE ) +SET_CMC_TBL_DATA_DCM (skb->data,0 ); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
@@ -838,13 +842,15 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) {struct rtw89_hal *hal = &rtwdev->hal; -struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; +struct rtw89_sta *rtwsta =sta_to_rtwsta_safe (sta);struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;struct sk_buff *skb;u8 pads[RTW89_PPE_BW_NUM ]; +u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;memset (pads,0 ,sizeof (pads)); -__get_sta_he_pkt_padding (rtwdev, sta, pads); +if (sta) +__get_sta_he_pkt_padding (rtwdev, sta, pads); skb =rtw89_fw_h2c_alloc_skb_with_hdr (H2C_CMC_TBL_LEN );if (!skb) {
@@ -852,7 +858,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,return -ENOMEM ; }skb_put (skb,H2C_CMC_TBL_LEN ); -SET_CTRL_INFO_MACID (skb->data, rtwsta->mac_id); +SET_CTRL_INFO_MACID (skb->data, mac_id);SET_CTRL_INFO_OPERATION (skb->data,1 );SET_CMC_TBL_DISRTSFB (skb->data,1 );SET_CMC_TBL_DISDATAFB (skb->data,1 );
@@ -870,7 +876,10 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,SET_CMC_TBL_NOMINAL_PKT_PADDING (skb->data, pads[RTW89_CHANNEL_WIDTH_20 ]);SET_CMC_TBL_NOMINAL_PKT_PADDING40 (skb->data, pads[RTW89_CHANNEL_WIDTH_40 ]);SET_CMC_TBL_NOMINAL_PKT_PADDING80 (skb->data, pads[RTW89_CHANNEL_WIDTH_80 ]); -SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT (skb->data, sta->he_cap.has_he); +if (sta) +SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT (skb->data, sta->he_cap.has_he); +if (rtwvif->net_type ==RTW89_NET_TYPE_AP_MODE ) +SET_CMC_TBL_DATA_DCM (skb->data,0 ); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
@@ -1018,9 +1027,17 @@ int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev,#define H2C_JOIN_INFO_LEN 4int rtw89_fw_h2c_join_info (struct rtw89_dev *rtwdev,struct rtw89_vif *rtwvif, -u8 dis_conn) +struct rtw89_sta *rtwsta,bool dis_conn) {struct sk_buff *skb; +u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id; +u8 self_role = rtwvif->self_role; +u8 net_type = rtwvif->net_type; + +if (net_type ==RTW89_NET_TYPE_AP_MODE && rtwsta) { + self_role =RTW89_SELF_ROLE_AP_CLIENT ; + net_type = dis_conn ?RTW89_NET_TYPE_NO_LINK : net_type; + } skb =rtw89_fw_h2c_alloc_skb_with_hdr (H2C_JOIN_INFO_LEN );if (!skb) {
@@ -1028,7 +1045,7 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,return -ENOMEM ; }skb_put (skb,H2C_JOIN_INFO_LEN ); -SET_JOININFO_MACID (skb->data, rtwvif->mac_id); +SET_JOININFO_MACID (skb->data, mac_id);SET_JOININFO_OP (skb->data, dis_conn);SET_JOININFO_BAND (skb->data, rtwvif->mac_idx);SET_JOININFO_WMM (skb->data, rtwvif->wmm);
@@ -1038,9 +1055,9 @@ int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,SET_JOININFO_TF_MAC_PAD (skb->data,0 );SET_JOININFO_DL_T_PE (skb->data,0 );SET_JOININFO_PORT_ID (skb->data, rtwvif->port); -SET_JOININFO_NET_TYPE (skb->data, rtwvif->net_type); +SET_JOININFO_NET_TYPE (skb->data, net_type);SET_JOININFO_WIFI_ROLE (skb->data, rtwvif->wifi_role); -SET_JOININFO_SELF_ROLE (skb->data, rtwvif->self_role); +SET_JOININFO_SELF_ROLE (skb->data, self_role); rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT,
drivers/net/wireless/realtek/rtw89/fw.h +3 -2
@@ -1871,7 +1871,8 @@ int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev);void rtw89_h2c_pkt_set_hdr (struct rtw89_dev *rtwdev,struct sk_buff *skb,u8 type,u8 cat,u8 class,u8 func,bool rack,bool dack,u32 len); -int rtw89_fw_h2c_default_cmac_tbl (struct rtw89_dev *rtwdev,u8 macid); +int rtw89_fw_h2c_default_cmac_tbl (struct rtw89_dev *rtwdev, +struct rtw89_vif *rtwvif);int rtw89_fw_h2c_assoc_cmac_tbl (struct rtw89_dev *rtwdev,struct ieee80211_vif *vif,struct ieee80211_sta *sta);
@@ -1887,7 +1888,7 @@ int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev,struct rtw89_vif *rtwvif, enum rtw89_upd_mode upd_mode);int rtw89_fw_h2c_join_info (struct rtw89_dev *rtwdev,struct rtw89_vif *rtwvif, -u8 dis_conn); +struct rtw89_sta *rtwsta,bool dis_conn);int rtw89_fw_h2c_macid_pause (struct rtw89_dev *rtwdev,u8 sh,u8 grp,bool pause); int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
drivers/net/wireless/realtek/rtw89/mac.c +1 -1
@@ -2994,7 +2994,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)if (ret)return ret; - ret =rtw89_fw_h2c_default_cmac_tbl (rtwdev, rtwvif->mac_id); + ret =rtw89_fw_h2c_default_cmac_tbl (rtwdev, rtwvif);if (ret)return ret;
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 8/19 rtw89: rename vif_maintain to role_maintain
In reply to Ping-Ke ShihThe H2C_FUNC_MAC_FWROLE_MAINTAIN also maintains the roles of all connected stations; not just the role of VIF. So, I correct the name, but don't change the logic at all.
--- drivers/net/wireless/realtek/rtw89/core.h | 10 +++++----- drivers/net/wireless/realtek/rtw89/fw.c | 14 +++++++------- drivers/net/wireless/realtek/rtw89/fw.h | 6 +++--- drivers/net/wireless/realtek/rtw89/mac.c | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-)
drivers/net/wireless/realtek/rtw89/core.h +5 -5
@@ -140,11 +140,11 @@ enum rtw89_wifi_role { };enum rtw89_upd_mode { -RTW89_VIF_CREATE , -RTW89_VIF_REMOVE , -RTW89_VIF_TYPE_CHANGE , -RTW89_VIF_INFO_CHANGE , -RTW89_VIF_CON_DISCONN +RTW89_ROLE_CREATE , +RTW89_ROLE_REMOVE , +RTW89_ROLE_TYPE_CHANGE , +RTW89_ROLE_INFO_CHANGE , +RTW89_ROLE_CON_DISCONN };enum rtw89_self_role {
drivers/net/wireless/realtek/rtw89/fw.c +7 -7
@@ -990,19 +990,19 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,return 0 ; } -#define H2C_VIF_MAINTAIN_LEN 4 -int rtw89_fw_h2c_vif_maintain (struct rtw89_dev *rtwdev, -struct rtw89_vif *rtwvif, -enum rtw89_upd_mode upd_mode) +#define H2C_ROLE_MAINTAIN_LEN 4 +int rtw89_fw_h2c_role_maintain (struct rtw89_dev *rtwdev, +struct rtw89_vif *rtwvif, +enum rtw89_upd_mode upd_mode) {struct sk_buff *skb; - skb =rtw89_fw_h2c_alloc_skb_with_hdr (H2C_VIF_MAINTAIN_LEN ); + skb =rtw89_fw_h2c_alloc_skb_with_hdr (H2C_ROLE_MAINTAIN_LEN );if (!skb) {rtw89_err (rtwdev,"failed to alloc skb for h2c join\n" );return -ENOMEM ; } -skb_put (skb,H2C_VIF_MAINTAIN_LEN ); +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_UPD_MODE (skb->data, upd_mode);
@@ -1011,7 +1011,7 @@ int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev,rtw89_h2c_pkt_set_hdr (rtwdev, skb,FWCMD_TYPE_H2C ,H2C_CAT_MAC ,H2C_CL_MAC_MEDIA_RPT ,H2C_FUNC_MAC_FWROLE_MAINTAIN ,0 ,1 , -H2C_VIF_MAINTAIN_LEN ); +H2C_ROLE_MAINTAIN_LEN );if (rtw89_h2c_tx (rtwdev, skb, false)) {rtw89_err (rtwdev,"failed to send h2c\n" );
drivers/net/wireless/realtek/rtw89/fw.h +3 -3
@@ -1884,9 +1884,9 @@ int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *vif, struct rtw89_sta *rtwsta, const u8 *scan_mac_addr);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_vif_maintain (struct rtw89_dev *rtwdev, -struct rtw89_vif *rtwvif, -enum rtw89_upd_mode upd_mode); +int rtw89_fw_h2c_role_maintain (struct rtw89_dev *rtwdev, +struct rtw89_vif *rtwvif, +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); int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
drivers/net/wireless/realtek/rtw89/mac.c +2 -2
@@ -2982,7 +2982,7 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)if (ret)return ret; - ret =rtw89_fw_h2c_vif_maintain (rtwdev, rtwvif,RTW89_VIF_CREATE ); + ret =rtw89_fw_h2c_role_maintain (rtwdev, rtwvif,RTW89_ROLE_CREATE );if (ret)return ret;
@@ -3005,7 +3005,7 @@ int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) {int ret; - ret =rtw89_fw_h2c_vif_maintain (rtwdev, rtwvif,RTW89_VIF_REMOVE ); + ret =rtw89_fw_h2c_role_maintain (rtwdev, rtwvif,RTW89_ROLE_REMOVE );if (ret)return ret;
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 9/19 rtw89: configure mac port HIQ registers
In reply to Ping-Ke ShihHIQ is short for high queue that is used to send broadcast/multicast packets right after TBTT in AP mode. Two registers, DTIM and window size, are configured accordingly.
--- drivers/net/wireless/realtek/rtw89/mac.c | 34 +++++++++++++++++++++++- drivers/net/wireless/realtek/rtw89/reg.h | 14 +++++++++- 2 files changed, 46 insertions(+), 2 deletions(-)
drivers/net/wireless/realtek/rtw89/mac.c +33 -1
@@ -2864,6 +2864,36 @@ static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev, bcn_int); } +static void rtw89_mac_port_cfg_hiq_win (struct rtw89_dev *rtwdev, +struct rtw89_vif *rtwvif) +{ +static const u32 hiq_win_addr[RTW89_PORT_NUM ] = { +R_AX_P0MB_HGQ_WINDOW_CFG_0 ,R_AX_PORT_HGQ_WINDOW_CFG , +R_AX_PORT_HGQ_WINDOW_CFG +1 ,R_AX_PORT_HGQ_WINDOW_CFG +2 , +R_AX_PORT_HGQ_WINDOW_CFG +3 , + }; +u8 win = rtwvif->net_type ==RTW89_NET_TYPE_AP_MODE ?16 :0 ; +u8 port = rtwvif->port; +u32 reg; + + reg =rtw89_mac_reg_by_idx (hiq_win_addr[port], rtwvif->mac_idx); +rtw89_write8 (rtwdev, reg, win); +} + +static void rtw89_mac_port_cfg_hiq_dtim (struct rtw89_dev *rtwdev, +struct rtw89_vif *rtwvif) +{ +struct ieee80211_vif *vif =rtwvif_to_vif (rtwvif); +const struct rtw89_port_reg *p = &rtw_port_base; +u32 addr; + + addr =rtw89_mac_reg_by_idx (R_AX_MD_TSFT_STMP_CTL , rtwvif->mac_idx); +rtw89_write8_set (rtwdev, addr,B_AX_UPD_HGQMD |B_AX_UPD_TIMIE ); + +rtw89_write16_port_mask (rtwdev, rtwvif, p->dtim_ctrl,B_AX_DTIM_NUM_MASK , + vif->bss_conf.dtim_period); +} +static void rtw89_mac_port_cfg_bcn_setup_time (struct rtw89_dev *rtwdev,struct rtw89_vif *rtwvif) {
@@ -3034,13 +3064,15 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)rtw89_mac_port_cfg_rx_sync (rtwdev, rtwvif);rtw89_mac_port_cfg_tx_sw (rtwdev, rtwvif);rtw89_mac_port_cfg_bcn_intv (rtwdev, rtwvif); +rtw89_mac_port_cfg_hiq_win (rtwdev, rtwvif); +rtw89_mac_port_cfg_hiq_dtim (rtwdev, rtwvif); +rtw89_mac_port_cfg_hiq_drop (rtwdev, rtwvif);rtw89_mac_port_cfg_bcn_setup_time (rtwdev, rtwvif);rtw89_mac_port_cfg_bcn_hold_time (rtwdev, rtwvif);rtw89_mac_port_cfg_bcn_mask_area (rtwdev, rtwvif);rtw89_mac_port_cfg_tbtt_early (rtwdev, rtwvif);rtw89_mac_port_cfg_bss_color (rtwdev, rtwvif);rtw89_mac_port_cfg_mbssid (rtwdev, rtwvif); -rtw89_mac_port_cfg_hiq_drop (rtwdev, rtwvif);rtw89_mac_port_cfg_func_en (rtwdev, rtwvif);fsleep (BCN_ERLY_SET_DLY );rtw89_mac_port_cfg_bcn_early (rtwdev, rtwvif);
drivers/net/wireless/realtek/rtw89/reg.h +13 -1
@@ -913,7 +913,7 @@#define R_AX_DTIM_CTRL_P2 0xC4A6#define R_AX_DTIM_CTRL_P3 0xC4E6#define R_AX_DTIM_CTRL_P4 0xC526 -#define B_AX_DTIM_NUM_MASK GENMASK(15, 0) +#define B_AX_DTIM_NUM_MASK GENMASK(15, 8)#define B_AX_DTIM_CURRCNT_MASK GENMASK(7, 0)#define R_AX_TBTT_SHIFT_P0 0xC428
@@ -964,6 +964,11 @@#define B_AX_P0MB2_EN BIT(2)#define B_AX_P0MB1_EN BIT(1) +#define R_AX_P0MB_HGQ_WINDOW_CFG_0 0xC590 +#define R_AX_P0MB_HGQ_WINDOW_CFG_0_C1 0xE590 +#define R_AX_PORT_HGQ_WINDOW_CFG 0xC5A0 +#define R_AX_PORT_HGQ_WINDOW_CFG_C1 0xE5A0 +#define R_AX_AMPDU_AGG_LIMIT 0xC610#define B_AX_AMPDU_MAX_TIME_MASK GENMASK(31, 24)#define B_AX_RA_TRY_RATE_AGG_LMT_MASK GENMASK(23, 16)
@@ -1080,6 +1085,13 @@#define B_AX_TCR_ZLD_USTIME_AFTERPHYTXON GENMASK(11, 8)#define B_AX_TCR_TXTIMEOUT GENMASK(7, 0) +#define R_AX_MD_TSFT_STMP_CTL 0xCA08 +#define R_AX_MD_TSFT_STMP_CTL_C1 0xEA08 +#define B_AX_TSFT_OFS_MASK GENMASK(31, 16) +#define B_AX_STMP_THSD_MASK GENMASK(15, 8) +#define B_AX_UPD_HGQMD BIT(1) +#define B_AX_UPD_TIMIE BIT(0) +#define R_AX_PPWRBIT_SETTING 0xCA0C#define R_AX_PPWRBIT_SETTING_C1 0xEA0C
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 10/19 rtw89: send broadcast/multicast packets via HIQ if STAs are in sleep mode
In reply to Ping-Ke ShihIf a packet we are going to send is broadcast/multicast and certain STAs are in sleep mode, a flag IEEE80211_TX_CTL_SEND_AFTER_DTIM is added to txinfo. Then, this kind of packets must be sent via HIQ instead of regular AC queues, because they should be sent right after beacon.
--- drivers/net/wireless/realtek/rtw89/core.c | 8 +++++--- drivers/net/wireless/realtek/rtw89/core.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-)
drivers/net/wireless/realtek/rtw89/core.c +5 -3
@@ -378,10 +378,10 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;u8 qsel, ch_dma; - qsel =RTW89_TX_QSEL_B0_MGMT ; + qsel = desc_info->hiq ?RTW89_TX_QSEL_B0_HI :RTW89_TX_QSEL_B0_MGMT ; ch_dma =rtw89_core_get_ch_dma (rtwdev, qsel); - desc_info->qsel =RTW89_TX_QSEL_B0_MGMT ; + desc_info->qsel = qsel; desc_info->ch_dma = ch_dma; desc_info->hw_ssn_sel =RTW89_MGMT_HW_SSN_SEL ; desc_info->hw_seq_mode =RTW89_MGMT_HW_SEQ_MODE ;
@@ -535,7 +535,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, tid = skb->priority &IEEE80211_QOS_CTL_TAG1D_MASK ; tid_indicate =rtw89_core_get_tid_indicate (rtwdev, tid); - qsel =rtw89_core_get_qsel (rtwdev, tid); + qsel = desc_info->hiq ?RTW89_TX_QSEL_B0_HI :rtw89_core_get_qsel (rtwdev, tid); ch_dma =rtw89_core_get_ch_dma (rtwdev, qsel); desc_info->ch_dma = ch_dma;
@@ -601,6 +601,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev, {struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;struct sk_buff *skb = tx_req->skb; +struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);struct ieee80211_hdr *hdr = (void *)skb->data;enum rtw89_core_tx_type tx_type;enum btc_pkt_type pkt_type;
@@ -619,6 +620,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev, desc_info->pkt_size = skb->len; desc_info->is_bmc = is_bmc; desc_info->wd_page = true; + desc_info->hiq = info->flags &IEEE80211_TX_CTL_SEND_AFTER_DTIM ;switch (tx_req->tx_type) {case RTW89_CORE_TX_TYPE_MGMT :
drivers/net/wireless/realtek/rtw89/core.h +1 -0
@@ -695,6 +695,7 @@ struct rtw89_tx_desc_info {#define RTW89_MGMT_HW_SSN_SEL 1u8 hw_seq_mode;#define RTW89_MGMT_HW_SEQ_MODE 1 +bool hiq; };struct rtw89_core_tx_request {
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 11/19 rtw89: set mac_id and port ID to TXWD
In reply to Ping-Ke ShihOne mac_id is corresponding to one connected station, and port ID is a ID of virtual interfaces. With proper mac_id and port ID, firmware and hardware can handle a packet with correct context.
--- drivers/net/wireless/realtek/rtw89/core.c | 26 +++++++++++++++++++++-- drivers/net/wireless/realtek/rtw89/core.h | 2 ++ drivers/net/wireless/realtek/rtw89/txrx.h | 1 + 3 files changed, 27 insertions(+), 2 deletions(-)
drivers/net/wireless/realtek/rtw89/core.c +24 -2
@@ -375,6 +375,8 @@ static void rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) { + struct ieee80211_vif *vif = tx_req->vif; +struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;u8 qsel, ch_dma;
@@ -383,6 +385,7 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, desc_info->qsel = qsel; desc_info->ch_dma = ch_dma; + desc_info->port = desc_info->hiq ? rtwvif->port :0 ; desc_info->hw_ssn_sel =RTW89_MGMT_HW_SSN_SEL ; desc_info->hw_seq_mode =RTW89_MGMT_HW_SEQ_MODE ;
@@ -520,6 +523,21 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev, desc_info->bk = true; } +static u8 rtw89_core_tx_get_mac_id (struct rtw89_dev *rtwdev, +struct rtw89_core_tx_request *tx_req) +{ +struct ieee80211_vif *vif = tx_req->vif; +struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; +struct ieee80211_sta *sta = tx_req->sta; +struct rtw89_sta *rtwsta; + +if (!sta) +return rtwvif->mac_id; + + rtwsta = (struct rtw89_sta *)sta->drv_priv; +return rtwsta->mac_id; +} +static void rtw89_core_tx_update_data_info (struct rtw89_dev *rtwdev,struct rtw89_core_tx_request *tx_req)
@@ -541,6 +559,8 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, desc_info->ch_dma = ch_dma; desc_info->tid_indicate = tid_indicate; desc_info->qsel = qsel; + desc_info->mac_id =rtw89_core_tx_get_mac_id (rtwdev, tx_req); + desc_info->port = desc_info->hiq ? rtwvif->port :0 ;/* enable wd_info for AMPDU */ desc_info->en_wd_info = true;
@@ -723,7 +743,8 @@ static __le32 rtw89_build_txwd_body2(struct rtw89_tx_desc_info *desc_info) {u32 dword =FIELD_PREP (RTW89_TXWD_BODY2_TID_INDICATE , desc_info->tid_indicate) |FIELD_PREP (RTW89_TXWD_BODY2_QSEL , desc_info->qsel) | -FIELD_PREP (RTW89_TXWD_BODY2_TXPKT_SIZE , desc_info->pkt_size); +FIELD_PREP (RTW89_TXWD_BODY2_TXPKT_SIZE , desc_info->pkt_size) | +FIELD_PREP (RTW89_TXWD_BODY2_MACID , desc_info->mac_id);return cpu_to_le32 (dword); }
@@ -741,7 +762,8 @@ static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info) {u32 dword =FIELD_PREP (RTW89_TXWD_INFO0_USE_RATE , desc_info->use_rate) |FIELD_PREP (RTW89_TXWD_INFO0_DATA_RATE , desc_info->data_rate) | -FIELD_PREP (RTW89_TXWD_INFO0_DISDATAFB , desc_info->dis_data_fb); +FIELD_PREP (RTW89_TXWD_INFO0_DISDATAFB , desc_info->dis_data_fb) | +FIELD_PREP (RTW89_TXWD_INFO0_MULTIPORT_ID , desc_info->port);return cpu_to_le32 (dword); }
drivers/net/wireless/realtek/rtw89/core.h +2 -0
@@ -670,6 +670,7 @@ struct rtw89_rxdesc_long {struct rtw89_tx_desc_info {u16 pkt_size;u8 wp_offset; +u8 mac_id;u8 qsel;u8 ch_dma;u8 hdr_llc_len;
@@ -696,6 +697,7 @@ struct rtw89_tx_desc_info {u8 hw_seq_mode;#define RTW89_MGMT_HW_SEQ_MODE 1bool hiq; +u8 port; };struct rtw89_core_tx_request {
drivers/net/wireless/realtek/rtw89/txrx.h +1 -0
@@ -58,6 +58,7 @@#define RTW89_TXWD_INFO0_GI_LTF GENMASK(27, 25)#define RTW89_TXWD_INFO0_DATA_RATE GENMASK(24, 16)#define RTW89_TXWD_INFO0_DISDATAFB BIT(10) +#define RTW89_TXWD_INFO0_MULTIPORT_ID GENMASK(6, 4)/* TX WD INFO DWORD 1 */ #define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16)
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 12/19 rtw89: separate {init,deinit}_addr_cam functions
In reply to Ping-Ke ShihEach stations connected to AP needs to set an address CAM, so don't combine address and BSSID CAM.
--- drivers/net/wireless/realtek/rtw89/cam.c | 34 ++++++++++++++--------- drivers/net/wireless/realtek/rtw89/cam.h | 5 ++++ drivers/net/wireless/realtek/rtw89/core.h | 1 - 3 files changed, 26 insertions(+), 14 deletions(-)
drivers/net/wireless/realtek/rtw89/cam.c +21 -13
@@ -427,15 +427,23 @@ static void rtw89_cam_reset_key_iter(struct ieee80211_hw *hw,rtw89_cam_deinit (rtwdev, rtwvif); } +void rtw89_cam_deinit_addr_cam (struct rtw89_dev *rtwdev, +struct rtw89_addr_cam_entry *addr_cam) +{ +struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + + addr_cam->valid = false; +clear_bit (addr_cam->addr_cam_idx, cam_info->addr_cam_map); +} +void rtw89_cam_deinit (struct rtw89_dev *rtwdev,struct rtw89_vif *rtwvif) {struct rtw89_cam_info *cam_info = &rtwdev->cam_info;struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam; - addr_cam->valid = false; +rtw89_cam_deinit_addr_cam (rtwdev, addr_cam); bssid_cam->valid = false; -clear_bit (addr_cam->addr_cam_idx, cam_info->addr_cam_map);clear_bit (bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map); }
@@ -464,10 +472,10 @@ static int rtw89_cam_get_avail_addr_cam(struct rtw89_dev *rtwdev,return 0 ; } -static int rtw89_cam_init_addr_cam (struct rtw89_dev *rtwdev, -struct rtw89_vif *rtwvif) +int rtw89_cam_init_addr_cam (struct rtw89_dev *rtwdev, +struct rtw89_addr_cam_entry *addr_cam, +const struct rtw89_bssid_cam_entry *bssid_cam) { -struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;u8 addr_cam_idx;int i;int ret;
@@ -484,14 +492,17 @@ static int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev, addr_cam->valid = true; addr_cam->addr_mask =0 ; addr_cam->mask_sel =RTW89_NO_MSK ; + addr_cam->sec_ent_mode =RTW89_ADDR_CAM_SEC_NORMAL ;bitmap_zero (addr_cam->sec_cam_map,RTW89_SEC_CAM_IN_ADDR_CAM ); -ether_addr_copy (addr_cam->sma, rtwvif->mac_addr);for (i =0 ; i <RTW89_SEC_CAM_IN_ADDR_CAM ; i++) { addr_cam->sec_ent_keyid[i] =0 ; addr_cam->sec_ent[i] =0 ; } +/* associate addr cam with bssid cam */ + addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx; +return 0 ; }
@@ -549,21 +560,18 @@ int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;int ret; - ret =rtw89_cam_init_addr_cam (rtwdev, rtwvif); + ret =rtw89_cam_init_bssid_cam (rtwdev, rtwvif);if (ret) { -rtw89_err (rtwdev,"failed to init addr cam\n" ); +rtw89_err (rtwdev,"failed to init bssid cam\n" );return ret; } - ret =rtw89_cam_init_bssid_cam (rtwdev, rtwvif); + ret =rtw89_cam_init_addr_cam (rtwdev, addr_cam, bssid_cam);if (ret) { -rtw89_err (rtwdev,"failed to init bssid cam\n" ); +rtw89_err (rtwdev,"failed to init addr cam\n" );return ret; } -/* associate addr cam with bssid cam */ - addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx; -return 0 ; }
drivers/net/wireless/realtek/rtw89/cam.h +5 -0
@@ -346,6 +346,11 @@ static inline void FWCMD_SET_ADDR_BSSID_BSSID5(void *cmd, u32 value)int rtw89_cam_init (struct rtw89_dev *rtwdev,struct rtw89_vif *vif);void rtw89_cam_deinit (struct rtw89_dev *rtwdev,struct rtw89_vif *vif); +int rtw89_cam_init_addr_cam (struct rtw89_dev *rtwdev, +struct rtw89_addr_cam_entry *addr_cam, +const struct rtw89_bssid_cam_entry *bssid_cam); +void rtw89_cam_deinit_addr_cam (struct rtw89_dev *rtwdev, +struct rtw89_addr_cam_entry *addr_cam); void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, struct rtw89_vif *vif, struct rtw89_sta *rtwsta,
drivers/net/wireless/realtek/rtw89/core.h +0 -1
@@ -1884,7 +1884,6 @@ struct rtw89_addr_cam_entry { u8 wapi : 1; u8 mask_sel : 2; u8 bssid_cam_idx: 6; -u8 sma[ETH_ALEN ];u8 sec_ent_mode;DECLARE_BITMAP (sec_cam_map,RTW89_SEC_CAM_IN_ADDR_CAM );
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 13/19 rtw89: extend role_maintain to support AP mode
In reply to Ping-Ke ShihFill 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,
--- drivers/net/wireless/realtek/rtw89/fw.c | 8 ++++++-- drivers/net/wireless/realtek/rtw89/fw.h | 1 + drivers/net/wireless/realtek/rtw89/mac.c | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-)
drivers/net/wireless/realtek/rtw89/fw.c +6 -2
@@ -993,9 +993,13 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,#define H2C_ROLE_MAINTAIN_LEN 4int 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 = rtwvif->net_type ==RTW89_NET_TYPE_AP_MODE && rtwsta ? +RTW89_SELF_ROLE_AP_CLIENT : rtwvif->self_role; skb =rtw89_fw_h2c_alloc_skb_with_hdr (H2C_ROLE_MAINTAIN_LEN );if (!skb) {
@@ -1003,8 +1007,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);
drivers/net/wireless/realtek/rtw89/fw.h +1 -0
@@ -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);
drivers/net/wireless/realtek/rtw89/mac.c +2 -2
@@ -3012,7 +3012,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;
@@ -3035,7 +3035,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;
Signature · 1 line
2.25.1
Re: [PATCH 13/19] rtw89: extend role_maintain to support AP mode
Quoted 20 lines · Ping-Ke Shih
Fill
mac_idandself_roledepends on the operation mode.In AP mode, echo connected station has an unique
mac_id, and each vif also has onemac_idto represent itself.The
self_roleis assigned to vif if the operation mode is decided, andRTW89_SELF_ROLE_AP_CLIENTis assigned to the connected STA in AP mode,Signed-off-by Ping-Ke Shih <[email protected]>--- drivers/net/wireless/realtek/rtw89/fw.c | 8 ++++++-- drivers/net/wireless/realtek/rtw89/fw.h | 1 + drivers/net/wireless/realtek/rtw89/mac.c | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-)drivers/net/wireless/realtek/rtw89/fw.c +0
-0
drivers/net/wireless/realtek/rtw89/fw.c int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, · line 1002
Quoted 10 lines
drivers/net/wireless/realtek/rtw89/fw.c +4
-0@@ -993,9 +993,13 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,#define H2C_ROLE_MAINTAIN_LEN 4int 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 = rtwvif->net_type ==RTW89_NET_TYPE_AP_MODE && rtwsta ? +RTW89_SELF_ROLE_AP_CLIENT : rtwvif->self_role;
It seems you like '?' operator more than I do, and it's ok to use in simple cases. But the latter statement is not really readable, something like this is so much easier to read:
if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta)
self_role = RTW89_SELF_ROLE_AP_CLIENT
else
self_role = rtwvif->self_role;
But should there a parenthesis around the == operator? I cannot now recall what's the preference in the kernel, can someone help on that?
Maybe I also move check for rtwsta first?
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Pkshih
maintainerRe: [PATCH 13/19] rtw89: extend role_maintain to support AP mode
Quoted 37 lines · Kalle Valo
Quoted 20 lines · Ping-Ke Shih
Fill
mac_idandself_roledepends on the operation mode.In AP mode, echo connected station has an unique
mac_id, and each vif also has onemac_idto represent itself.The
self_roleis assigned to vif if the operation mode is decided, andRTW89_SELF_ROLE_AP_CLIENTis assigned to the connected STA in AP mode,Signed-off-by Ping-Ke Shih <[email protected]>--- drivers/net/wireless/realtek/rtw89/fw.c | 8 ++++++-- drivers/net/wireless/realtek/rtw89/fw.h | 1 + drivers/net/wireless/realtek/rtw89/mac.c | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-)drivers/net/wireless/realtek/rtw89/fw.c +0
-0drivers/net/wireless/realtek/rtw89/fw.c int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, · line 1002
Quoted 10 lines
drivers/net/wireless/realtek/rtw89/fw.c +4
-0@@ -993,9 +993,13 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,#define H2C_ROLE_MAINTAIN_LEN 4int 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 = rtwvif->net_type ==RTW89_NET_TYPE_AP_MODE && rtwsta ? +RTW89_SELF_ROLE_AP_CLIENT : rtwvif->self_role;It seems you like '?' operator more than I do, and it's ok to use in simple cases. But the latter statement is not really readable, something like this is so much easier to read:
Quoted 5 lines
if (
rtwvif->net_type==RTW89_NET_TYPE_AP_MODE&& rtwsta)
self_role=RTW89_SELF_ROLE_AP_CLIENT
elseself_role = rtwvif->self_role;
I use '?' to make code shorter, but your sugeestion would be eaiser to reviewer. I will send v2 after the Lunar New Year.
Quoted 2 lines
But should there a parenthesis around the == operator? I cannot now recall what's the preference in the kernel, can someone help on that?
The checkpatch will warn this if we add parenthesis, so preence is not to use parenthesis.
CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'rtwvif->net_type == RTW89_NET_TYPE_AP_MODE'
#9: FILE: fw.c:1004:
+ if ((rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) && rtwsta)
Quoted 3 lines
Maybe I also move check for rtwsta first?
The full logic is
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;
}And, the meaning of 'rtwsta' here is to indicate we are going to setup a connected station that connects to this AP, but not check if the pointer is NULL. To emphasis the case is only existing in AP_MODE, I prefer to check net_type ahead. Or, this full logic is preferred?
Ping-Ke
Re: [PATCH 13/19] rtw89: extend role_maintain to support AP mode
Quoted 38 lines · Pkshih
Quoted 37 lines · Kalle Valo
Quoted 20 lines · Ping-Ke Shih
Fill
mac_idandself_roledepends on the operation mode.In AP mode, echo connected station has an unique
mac_id, and each vif also has onemac_idto represent itself.The
self_roleis assigned to vif if the operation mode is decided, andRTW89_SELF_ROLE_AP_CLIENTis assigned to the connected STA in AP mode,Signed-off-by Ping-Ke Shih <[email protected]>--- drivers/net/wireless/realtek/rtw89/fw.c | 8 ++++++-- drivers/net/wireless/realtek/rtw89/fw.h | 1 + drivers/net/wireless/realtek/rtw89/mac.c | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-)drivers/net/wireless/realtek/rtw89/fw.c +0
-0drivers/net/wireless/realtek/rtw89/fw.c int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev, · line 1002
Quoted 10 lines
drivers/net/wireless/realtek/rtw89/fw.c +4
-0@@ -993,9 +993,13 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,#define H2C_ROLE_MAINTAIN_LEN 4int 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 = rtwvif->net_type ==RTW89_NET_TYPE_AP_MODE && rtwsta ? +RTW89_SELF_ROLE_AP_CLIENT : rtwvif->self_role;It seems you like '?' operator more than I do, and it's ok to use in simple cases. But the latter statement is not really readable, something like this is so much easier to read:
Quoted 8 lines
Quoted 5 lines
if (
rtwvif->net_type==RTW89_NET_TYPE_AP_MODE&& rtwsta)
self_role=RTW89_SELF_ROLE_AP_CLIENT
elseself_role = rtwvif->self_role;I use '?' to make code shorter, but your sugeestion would be eaiser to reviewer. I will send v2 after the Lunar New Year.
Happy New Year :)
Review
Quoted 10 lines
Quoted 2 lines
But should there a parenthesis around the == operator? I cannot now recall what's the preference in the kernel, can someone help on that?
The checkpatch will warn this if we add parenthesis, so preence is not to use parenthesis.
CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around '
rtwvif->net_type==RTW89_NET_TYPE_AP_MODE'
#9: FILE: fw.c:1004:(quoted diff) +1
-0+ if ((rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) && rtwsta)
Ok, I need to remember that :)
Quoted 10 lines
Quoted 2 lines
Maybe I also move check for rtwsta first?
The full logic is
if (
rtwvif->net_type==RTW89_NET_TYPE_AP_MODE) {
if (rtwsta)
self_role=RTW89_SELF_ROLE_AP_CLIENT
else
self_role=rtwvif->self_role;
Quoted 8 lines
} else { self_role = rtwvif->self_role; }And, the meaning of 'rtwsta' here is to indicate we are going to setup a connected station that connects to this AP, but not check if the pointer is NULL. To emphasis the case is only existing in
AP_MODE, I prefer to checknet_typeahead. Or, this full logic is preferred?
I don't know what others think, but I find this full logic style most readable.
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Pkshih
maintainerRe: [PATCH 13/19] rtw89: extend role_maintain to support AP mode
Quoted 18 lines · Kalle Valo
Quoted 16 lines · Pkshih
Quoted 3 lines · Kalle Valo
Maybe I also move check for rtwsta first?
The full logic is
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; }
Quoted 8 lines
Quoted 4 lines
And, the meaning of 'rtwsta' here is to indicate we are going to setup a connected station that connects to this AP, but not check if the pointer is NULL. To emphasis the case is only existing in
AP_MODE, I prefer to checknet_typeahead. Or, this full logic is preferred?I don't know what others think, but I find this full logic style most readable.
Maybe, a static analysis tool warns two else branches are the same. If so, we can make a decision at that time.
I will send v2 next week, and wait for people who have other ideas.
Happy New Year.
--
Ping-Ke
Re: [PATCH 13/19] rtw89: extend role_maintain to support AP mode
In reply to Ping-Ke ShihQuoted 9 lines · Ping-Ke Shih
Fill
mac_idandself_roledepends on the operation mode.In AP mode, echo connected station has an unique
mac_id, and each vif also has onemac_idto represent itself.The
self_roleis assigned to vif if the operation mode is decided, andRTW89_SELF_ROLE_AP_CLIENTis assigned to the connected STA in AP mode,Signed-off-by Ping-Ke Shih <[email protected]>
Dropping rest of the patches due to my comment.
7 patches set to Changes Requested.
12706170 [13/19] rtw89: extend role_maintain to support AP mode 12706171 [14/19] rtw89: add addr_cam field to sta to support AP mode 12706172 [15/19] rtw89: only STA mode change vif_type mapping dynamically 12706173 [16/19] rtw89: maintain assoc/disassoc STA states of firmware and hardware 12706174 [17/19] rtw89: implement ieee80211_ops::start_ap and stop_ap 12706175 [18/19] rtw89: debug: add stations entry to show ID assignment 12706176 [19/19] rtw89: declare AP mode support
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Ping-Ke Shih
maintainerPATCH 14/19 rtw89: add addr_cam field to sta to support AP mode
In reply to Ping-Ke ShihIn 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.
--- 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(-)
drivers/net/wireless/realtek/rtw89/cam.c +3 -3
@@ -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;
drivers/net/wireless/realtek/rtw89/core.c +4 -1
@@ -2,6 +2,7 @@/* Copyright(c) 2019-2020 Realtek Corporation */ +#include "cam.h" #include "coex.h" #include "core.h" #include "efuse.h"
@@ -298,9 +299,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;
@@ -313,7 +316,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;
drivers/net/wireless/realtek/rtw89/core.h +36 -26
80 lines not on this page · raw message
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 15/19 rtw89: only STA mode change vif_type mapping dynamically
In reply to Ping-Ke Shihvif_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.
--- drivers/net/wireless/realtek/rtw89/core.c | 4 ++-- drivers/net/wireless/realtek/rtw89/mac80211.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-)
drivers/net/wireless/realtek/rtw89/core.c +2 -2
@@ -1944,7 +1944,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) {
@@ -1976,7 +1977,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) {
drivers/net/wireless/realtek/rtw89/mac80211.c +3 -0
@@ -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); }
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 16/19 rtw89: maintain assoc/disassoc STA states of firmware and hardware
In reply to Ping-Ke ShihIn 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.
--- 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(-)
drivers/net/wireless/realtek/rtw89/core.c +30 -1
@@ -1943,6 +1943,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);
@@ -1959,8 +1961,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;
@@ -1977,6 +1987,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) {
drivers/net/wireless/realtek/rtw89/mac.c +2 -2
@@ -2705,7 +2705,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 ;
@@ -3008,7 +3008,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;
drivers/net/wireless/realtek/rtw89/mac.h +1 -0
@@ -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) {
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 17/19 rtw89: implement ieee80211_ops::start_ap and stop_ap
In reply to Ping-Ke ShihConfigure 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.
--- drivers/net/wireless/realtek/rtw89/mac80211.c | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+)
drivers/net/wireless/realtek/rtw89/mac80211.c +33 -0
@@ -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,
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 18/19 rtw89: debug: add stations entry to show ID assignment
In reply to Ping-Ke ShihIn 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--- drivers/net/wireless/realtek/rtw89/debug.c | 71 ++++++++++++++++++++++ 1 file changed, 71 insertions(+)
drivers/net/wireless/realtek/rtw89/debug.c +71 -0
@@ -2364,6 +2364,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,
@@ -2430,6 +2496,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; \
@@ -2468,6 +2538,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
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH 19/19 rtw89: declare AP mode support
In reply to Ping-Ke ShihThings are ready for AP mode, so declare this driver can support it.
--- drivers/net/wireless/realtek/rtw89/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw89/core.c +2 -1
@@ -2561,7 +2561,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 ;
Signature · 1 line
2.25.1