Message ID | 20231204081323.5582-1-quic_bqiang@quicinc.com |
---|---|
Headers | show |
Series | wifi: ath11k: add support for 6 GHz station for various modes : LPI, SP and VLP | expand |
On 12/4/2023 11:53 PM, Aditya Kumar Singh wrote: > On 12/4/23 13:43, Baochen Qiang wrote: >> From: Wen Gong <quic_wgong@quicinc.com> >> >> When station is connected to a 6 GHz AP, it has 2 ways to configure >> the power limit to firmware. The first way is to send 2 WMI commands >> WMI_PDEV_PARAM_TXPOWER_LIMIT2G/WMI_PDEV_PARAM_TXPOWER_LIMIT5G to >> firmware, the second way is to send WMI_VDEV_SET_TPC_POWER_CMDID to >> firmware which include more parameters for power control. >> >> When firmware support SERVICE_EXT_TPC_REG, it means firmware support >> the second way for WMI_VDEV_SET_TPC_POWER_CMDID, then ath11k discard >> BSS_CHANGED_TXPOWER flag from mac80211 which is used to the first way >> for 6 GHz band and select the second way. >> >> Tested-on: WCN6855 hw2.0 PCI >> WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 >> >> Signed-off-by: Wen Gong <quic_wgong@quicinc.com> >> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com> >> --- > ...snip... >> @@ -3596,9 +3608,13 @@ static void >> ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, >> if (changed & BSS_CHANGED_TXPOWER) { >> ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev_id %i txpower %d\n", >> arvif->vdev_id, info->txpower); >> - >> - arvif->txpower = info->txpower; >> - ath11k_mac_txpower_recalc(ar); >> + if (ath11k_mac_supports_station_tpc(ar, arvif, >> &info->chandef)) { >> + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, >> + "discard tx power, change to set TPC power\n"); >> + } else { >> + arvif->txpower = info->txpower; >> + ath11k_mac_txpower_recalc(ar); >> + } > > Could you check v6 once? I remember Wen told he would drop this check > and let FW take the min value. If we do like this, then user could not > set his own desired value even if that is well inside the reg limits. I did notice this comment in V6, but came out of a different opinion: it is OK to discard the TX power here, because that will be sent to firmware using WMI_VDEV_SET_TPC_POWER_CMDID command in another patch. Please correct me if wrong. >
On 12/4/23 13:43, Baochen Qiang wrote: > --- a/drivers/net/wireless/ath/ath11k/mac.h > +++ b/drivers/net/wireless/ath/ath11k/mac.h > @@ -159,7 +159,6 @@ struct ath11k_vif *ath11k_mac_get_vif_up(struct ath11k_base *ab); > > struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, u32 vdev_id); > struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id); > - Irrelevant change w.r.t commit message? > void ath11k_mac_drain_tx(struct ath11k *ar); > void ath11k_mac_peer_cleanup_all(struct ath11k *ar); > int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); ... > @@ -4749,6 +4749,11 @@ static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc, > soc->pdevs[0].pdev_id = 0; > } > > + if (!soc->reg_info_store) > + soc->reg_info_store = kcalloc(soc->num_radios, > + sizeof(*soc->reg_info_store), > + GFP_ATOMIC); What if this memory allocation request fails? Any negative case check should be present? > + > return 0; > } > > @@ -7071,33 +7076,54 @@ static bool ath11k_reg_is_world_alpha(char *alpha) > return false; > } > > -static int ath11k_reg_chan_list_event(struct ath11k_base *ab, > - struct sk_buff *skb, > - enum wmi_reg_chan_list_cmd_type id) > +void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info) > { > - struct cur_regulatory_info *reg_info = NULL; > - struct ieee80211_regdomain *regd = NULL; > - bool intersect = false; > - int ret = 0, pdev_idx, i, j; > - struct ath11k *ar; > + int i, j; > > - reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); > - if (!reg_info) { > - ret = -ENOMEM; > - goto fallback; > - } > + if (reg_info) { > + kfree(reg_info->reg_rules_2ghz_ptr); > > - if (id == WMI_REG_CHAN_LIST_CC_ID) > - ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); > - else > - ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info); > + kfree(reg_info->reg_rules_5ghz_ptr); > > - if (ret) { > - ath11k_warn(ab, "failed to extract regulatory info from received event\n"); > - goto fallback; > + for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { > + kfree(reg_info->reg_rules_6ghz_ap_ptr[i]); > + for (j = 0; j < WMI_REG_MAX_CLIENT_TYPE; j++) > + kfree(reg_info->reg_rules_6ghz_client_ptr[i][j]); > + } > + > + memset(reg_info, 0, sizeof(*reg_info)); > } > +} > + > +static > +enum wmi_vdev_type ath11k_reg_get_ar_vdev_type(struct ath11k *ar) > +{ > + struct ath11k_vif *arvif; > + > + /* Currently each struct ath11k maps to one struct ieee80211_hw/wiphy > + * and one struct ieee80211_regdomain, so it could only store one group > + * reg rules. It means muti-interface concurrency in the same ath11k is > + * not support for the regdomain. So get the vdev type of the first entry > + * now. After concurrency support for the regdomain, this should change. > + */ > + arvif = list_first_entry_or_null(&ar->arvifs, struct ath11k_vif, list); > + if (arvif) > + return arvif->vdev_type; > + > + return WMI_VDEV_TYPE_UNSPEC; > +} > + > +int ath11k_reg_handle_chan_list(struct ath11k_base *ab, > + struct cur_regulatory_info *reg_info, > + enum ieee80211_ap_reg_power power_type) > +{ > + struct ieee80211_regdomain *regd; > + bool intersect = false; > + int pdev_idx; > + struct ath11k *ar; > + enum wmi_vdev_type vdev_type; > > - ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg chan list id %d", id); > + ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg handle chan list"); I believe this debug was helpful in the sense it showed which type of event came. Can't we still print this somehow? Or may be somewhere else?
On 12/4/23 13:43, Baochen Qiang wrote: > --- a/drivers/net/wireless/ath/ath11k/mac.h > +++ b/drivers/net/wireless/ath/ath11k/mac.h > @@ -156,7 +156,6 @@ struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, > u8 ath11k_mac_get_target_pdev_id(struct ath11k *ar); > u8 ath11k_mac_get_target_pdev_id_from_vif(struct ath11k_vif *arvif); > struct ath11k_vif *ath11k_mac_get_vif_up(struct ath11k_base *ab); > - Irrelevant change? > struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, u32 vdev_id); > struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id); > void ath11k_mac_drain_tx(struct ath11k *ar); > diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c > index 6f0a35fcc9c1..9a0568676a74 100644 > --- a/drivers/net/wireless/ath/ath11k/wmi.c > +++ b/drivers/net/wireless/ath/ath11k/wmi.c > @@ -9858,3 +9858,9 @@ int ath11k_wmi_sta_keepalive(struct ath11k *ar, > > return ath11k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID); > } > + > +bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar) > +{ > + return (test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT, > + ar->ab->wmi_ab.svc_map)) && ar->supports_6ghz; What is the use of first parenthesis? I don't see a closing one after ar->supports_6ghz so its just guarding test_bit() which is not required. I believe intention here was to guard whole expression?
On 12/6/23 11:04, Baochen Qiang wrote: > > > On 12/4/2023 11:53 PM, Aditya Kumar Singh wrote: >> On 12/4/23 13:43, Baochen Qiang wrote: >>> From: Wen Gong <quic_wgong@quicinc.com> >>> >>> When station is connected to a 6 GHz AP, it has 2 ways to configure >>> the power limit to firmware. The first way is to send 2 WMI commands >>> WMI_PDEV_PARAM_TXPOWER_LIMIT2G/WMI_PDEV_PARAM_TXPOWER_LIMIT5G to >>> firmware, the second way is to send WMI_VDEV_SET_TPC_POWER_CMDID to >>> firmware which include more parameters for power control. >>> >>> When firmware support SERVICE_EXT_TPC_REG, it means firmware support >>> the second way for WMI_VDEV_SET_TPC_POWER_CMDID, then ath11k discard >>> BSS_CHANGED_TXPOWER flag from mac80211 which is used to the first way >>> for 6 GHz band and select the second way. >>> >>> Tested-on: WCN6855 hw2.0 PCI >>> WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 >>> >>> Signed-off-by: Wen Gong <quic_wgong@quicinc.com> >>> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com> >>> --- >> ...snip... >>> @@ -3596,9 +3608,13 @@ static void >>> ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, >>> if (changed & BSS_CHANGED_TXPOWER) { >>> ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev_id %i txpower %d\n", >>> arvif->vdev_id, info->txpower); >>> - >>> - arvif->txpower = info->txpower; >>> - ath11k_mac_txpower_recalc(ar); >>> + if (ath11k_mac_supports_station_tpc(ar, arvif, >>> &info->chandef)) { >>> + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, >>> + "discard tx power, change to set TPC power\n"); >>> + } else { >>> + arvif->txpower = info->txpower; >>> + ath11k_mac_txpower_recalc(ar); >>> + } >> >> Could you check v6 once? I remember Wen told he would drop this check >> and let FW take the min value. If we do like this, then user could not >> set his own desired value even if that is well inside the reg limits. > I did notice this comment in V6, but came out of a different opinion: it > is OK to discard the TX power here, because that will be sent to > firmware using WMI_VDEV_SET_TPC_POWER_CMDID command in another patch. > Please correct me if wrong. Yeah that is correct but applies only during initial bring up. What if after client gets connected and user still wants to lower power level by giving command "iw wlanX set txpower fixed 1000" something like this? This time again it will be ignored but it won't be sent to FW.
On 12/7/2023 11:31 AM, Aditya Kumar Singh wrote: > On 12/6/23 11:04, Baochen Qiang wrote: >> >> >> On 12/4/2023 11:53 PM, Aditya Kumar Singh wrote: >>> On 12/4/23 13:43, Baochen Qiang wrote: >>>> From: Wen Gong <quic_wgong@quicinc.com> >>>> >>>> When station is connected to a 6 GHz AP, it has 2 ways to configure >>>> the power limit to firmware. The first way is to send 2 WMI commands >>>> WMI_PDEV_PARAM_TXPOWER_LIMIT2G/WMI_PDEV_PARAM_TXPOWER_LIMIT5G to >>>> firmware, the second way is to send WMI_VDEV_SET_TPC_POWER_CMDID to >>>> firmware which include more parameters for power control. >>>> >>>> When firmware support SERVICE_EXT_TPC_REG, it means firmware support >>>> the second way for WMI_VDEV_SET_TPC_POWER_CMDID, then ath11k discard >>>> BSS_CHANGED_TXPOWER flag from mac80211 which is used to the first way >>>> for 6 GHz band and select the second way. >>>> >>>> Tested-on: WCN6855 hw2.0 PCI >>>> WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 >>>> >>>> Signed-off-by: Wen Gong <quic_wgong@quicinc.com> >>>> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com> >>>> --- >>> ...snip... >>>> @@ -3596,9 +3608,13 @@ static void >>>> ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, >>>> if (changed & BSS_CHANGED_TXPOWER) { >>>> ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev_id %i txpower %d\n", >>>> arvif->vdev_id, info->txpower); >>>> - >>>> - arvif->txpower = info->txpower; >>>> - ath11k_mac_txpower_recalc(ar); >>>> + if (ath11k_mac_supports_station_tpc(ar, arvif, >>>> &info->chandef)) { >>>> + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, >>>> + "discard tx power, change to set TPC power\n"); >>>> + } else { >>>> + arvif->txpower = info->txpower; >>>> + ath11k_mac_txpower_recalc(ar); >>>> + } >>> >>> Could you check v6 once? I remember Wen told he would drop this check >>> and let FW take the min value. If we do like this, then user could >>> not set his own desired value even if that is well inside the reg >>> limits. >> I did notice this comment in V6, but came out of a different opinion: >> it is OK to discard the TX power here, because that will be sent to >> firmware using WMI_VDEV_SET_TPC_POWER_CMDID command in another patch. >> Please correct me if wrong. > Yeah that is correct but applies only during initial bring up. What if > after client gets connected and user still wants to lower power level by > giving command "iw wlanX set txpower fixed 1000" something like this? > This time again it will be ignored but it won't be sent to FW. Exactly, will drop this patch in V9. >
On 12/7/2023 11:15 AM, Aditya Kumar Singh wrote: > On 12/4/23 13:43, Baochen Qiang wrote: > >> --- a/drivers/net/wireless/ath/ath11k/mac.h >> +++ b/drivers/net/wireless/ath/ath11k/mac.h >> @@ -156,7 +156,6 @@ struct ath11k_vif >> *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, >> u8 ath11k_mac_get_target_pdev_id(struct ath11k *ar); >> u8 ath11k_mac_get_target_pdev_id_from_vif(struct ath11k_vif *arvif); >> struct ath11k_vif *ath11k_mac_get_vif_up(struct ath11k_base *ab); >> - > > Irrelevant change? > >> struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, >> u32 vdev_id); >> struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, >> u32 pdev_id); >> void ath11k_mac_drain_tx(struct ath11k *ar); >> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c >> b/drivers/net/wireless/ath/ath11k/wmi.c >> index 6f0a35fcc9c1..9a0568676a74 100644 >> --- a/drivers/net/wireless/ath/ath11k/wmi.c >> +++ b/drivers/net/wireless/ath/ath11k/wmi.c >> @@ -9858,3 +9858,9 @@ int ath11k_wmi_sta_keepalive(struct ath11k *ar, >> return ath11k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID); >> } >> + >> +bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar) >> +{ >> + return (test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT, >> + ar->ab->wmi_ab.svc_map)) && ar->supports_6ghz; > > What is the use of first parenthesis? I don't see a closing one after > ar->supports_6ghz so its just guarding test_bit() which is not required. > I believe intention here was to guard whole expression? I don't see an need to guard the whole expression or the test_bit(), so will drop extra parenthesis in V9.
On 12/7/2023 11:15 AM, Aditya Kumar Singh wrote: > On 12/4/23 13:43, Baochen Qiang wrote: >> --- a/drivers/net/wireless/ath/ath11k/mac.h >> +++ b/drivers/net/wireless/ath/ath11k/mac.h >> @@ -159,7 +159,6 @@ struct ath11k_vif *ath11k_mac_get_vif_up(struct >> ath11k_base *ab); >> struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, >> u32 vdev_id); >> struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, >> u32 pdev_id); >> - > > Irrelevant change w.r.t commit message? > > >> void ath11k_mac_drain_tx(struct ath11k *ar); >> void ath11k_mac_peer_cleanup_all(struct ath11k *ar); >> int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); > ... >> @@ -4749,6 +4749,11 @@ static int >> ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc, >> soc->pdevs[0].pdev_id = 0; >> } >> + if (!soc->reg_info_store) >> + soc->reg_info_store = kcalloc(soc->num_radios, >> + sizeof(*soc->reg_info_store), >> + GFP_ATOMIC); > What if this memory allocation request fails? Any negative case check > should be present? > > >> + >> return 0; >> } >> @@ -7071,33 +7076,54 @@ static bool ath11k_reg_is_world_alpha(char >> *alpha) >> return false; >> } >> -static int ath11k_reg_chan_list_event(struct ath11k_base *ab, >> - struct sk_buff *skb, >> - enum wmi_reg_chan_list_cmd_type id) >> +void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info) >> { >> - struct cur_regulatory_info *reg_info = NULL; >> - struct ieee80211_regdomain *regd = NULL; >> - bool intersect = false; >> - int ret = 0, pdev_idx, i, j; >> - struct ath11k *ar; >> + int i, j; >> - reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); >> - if (!reg_info) { >> - ret = -ENOMEM; >> - goto fallback; >> - } >> + if (reg_info) { >> + kfree(reg_info->reg_rules_2ghz_ptr); >> - if (id == WMI_REG_CHAN_LIST_CC_ID) >> - ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); >> - else >> - ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, >> reg_info); >> + kfree(reg_info->reg_rules_5ghz_ptr); >> - if (ret) { >> - ath11k_warn(ab, "failed to extract regulatory info from >> received event\n"); >> - goto fallback; >> + for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { >> + kfree(reg_info->reg_rules_6ghz_ap_ptr[i]); >> + for (j = 0; j < WMI_REG_MAX_CLIENT_TYPE; j++) >> + kfree(reg_info->reg_rules_6ghz_client_ptr[i][j]); >> + } >> + >> + memset(reg_info, 0, sizeof(*reg_info)); >> } >> +} >> + >> +static >> +enum wmi_vdev_type ath11k_reg_get_ar_vdev_type(struct ath11k *ar) >> +{ >> + struct ath11k_vif *arvif; >> + >> + /* Currently each struct ath11k maps to one struct >> ieee80211_hw/wiphy >> + * and one struct ieee80211_regdomain, so it could only store one >> group >> + * reg rules. It means muti-interface concurrency in the same >> ath11k is >> + * not support for the regdomain. So get the vdev type of the >> first entry >> + * now. After concurrency support for the regdomain, this should >> change. >> + */ >> + arvif = list_first_entry_or_null(&ar->arvifs, struct ath11k_vif, >> list); >> + if (arvif) >> + return arvif->vdev_type; >> + >> + return WMI_VDEV_TYPE_UNSPEC; >> +} >> + >> +int ath11k_reg_handle_chan_list(struct ath11k_base *ab, >> + struct cur_regulatory_info *reg_info, >> + enum ieee80211_ap_reg_power power_type) >> +{ >> + struct ieee80211_regdomain *regd; >> + bool intersect = false; >> + int pdev_idx; >> + struct ath11k *ar; >> + enum wmi_vdev_type vdev_type; >> - ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg chan list id %d", id); >> + ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg handle chan list"); > > I believe this debug was helpful in the sense it showed which type of > event came. Can't we still print this somehow? Or may be somewhere else?You can check the event type from logs of ath11k_pull_reg_chan_list_update_ev() and ath11k_pull_reg_chan_list_ext_update_ev().
Baochen Qiang <quic_bqiang@quicinc.com> writes: > On 12/7/2023 11:15 AM, Aditya Kumar Singh wrote: >> On 12/4/23 13:43, Baochen Qiang wrote: >>> --- a/drivers/net/wireless/ath/ath11k/mac.h >>> +++ b/drivers/net/wireless/ath/ath11k/mac.h >>> @@ -159,7 +159,6 @@ struct ath11k_vif *ath11k_mac_get_vif_up(struct >>> ath11k_base *ab); >>> struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base >>> *ab, u32 vdev_id); >>> struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base >>> *ab, u32 pdev_id); >>> - >> Irrelevant change w.r.t commit message? >> >>> void ath11k_mac_drain_tx(struct ath11k *ar); >>> void ath11k_mac_peer_cleanup_all(struct ath11k *ar); >>> int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); >> ... >>> @@ -4749,6 +4749,11 @@ static int >>> ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc, >>> soc->pdevs[0].pdev_id = 0; >>> } >>> + if (!soc->reg_info_store) >>> + soc->reg_info_store = kcalloc(soc->num_radios, >>> + sizeof(*soc->reg_info_store), >>> + GFP_ATOMIC); >> What if this memory allocation request fails? Any negative case >> check should be present? >> >>> + >>> return 0; >>> } >>> @@ -7071,33 +7076,54 @@ static bool ath11k_reg_is_world_alpha(char >>> *alpha) >>> return false; >>> } >>> -static int ath11k_reg_chan_list_event(struct ath11k_base *ab, >>> - struct sk_buff *skb, >>> - enum wmi_reg_chan_list_cmd_type id) >>> +void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info) >>> { >>> - struct cur_regulatory_info *reg_info = NULL; >>> - struct ieee80211_regdomain *regd = NULL; >>> - bool intersect = false; >>> - int ret = 0, pdev_idx, i, j; >>> - struct ath11k *ar; >>> + int i, j; >>> - reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); >>> - if (!reg_info) { >>> - ret = -ENOMEM; >>> - goto fallback; >>> - } >>> + if (reg_info) { >>> + kfree(reg_info->reg_rules_2ghz_ptr); >>> - if (id == WMI_REG_CHAN_LIST_CC_ID) >>> - ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); >>> - else >>> - ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, >>> reg_info); >>> + kfree(reg_info->reg_rules_5ghz_ptr); >>> - if (ret) { >>> - ath11k_warn(ab, "failed to extract regulatory info from >>> received event\n"); >>> - goto fallback; >>> + for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { >>> + kfree(reg_info->reg_rules_6ghz_ap_ptr[i]); >>> + for (j = 0; j < WMI_REG_MAX_CLIENT_TYPE; j++) >>> + kfree(reg_info->reg_rules_6ghz_client_ptr[i][j]); >>> + } >>> + >>> + memset(reg_info, 0, sizeof(*reg_info)); >>> } >>> +} >>> + >>> +static >>> +enum wmi_vdev_type ath11k_reg_get_ar_vdev_type(struct ath11k *ar) >>> +{ >>> + struct ath11k_vif *arvif; >>> + >>> + /* Currently each struct ath11k maps to one struct >>> ieee80211_hw/wiphy >>> + * and one struct ieee80211_regdomain, so it could only store >>> one group >>> + * reg rules. It means muti-interface concurrency in the same >>> ath11k is >>> + * not support for the regdomain. So get the vdev type of the >>> first entry >>> + * now. After concurrency support for the regdomain, this >>> should change. >>> + */ >>> + arvif = list_first_entry_or_null(&ar->arvifs, struct >>> ath11k_vif, list); >>> + if (arvif) >>> + return arvif->vdev_type; >>> + >>> + return WMI_VDEV_TYPE_UNSPEC; >>> +} >>> + >>> +int ath11k_reg_handle_chan_list(struct ath11k_base *ab, >>> + struct cur_regulatory_info *reg_info, >>> + enum ieee80211_ap_reg_power power_type) >>> +{ >>> + struct ieee80211_regdomain *regd; >>> + bool intersect = false; >>> + int pdev_idx; >>> + struct ath11k *ar; >>> + enum wmi_vdev_type vdev_type; >>> - ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg chan list id %d", id); >>> + ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg handle chan list"); >> I believe this debug was helpful in the sense it showed which type >> of event came. Can't we still print this somehow? Or may be >> somewhere else?You can check the event type from logs of > ath11k_pull_reg_chan_list_update_ev() and > ath11k_pull_reg_chan_list_ext_update_ev(). Baochen, I didn't see any comments from you. Did you send an empty mail by accident?
On 12/11/2023 11:18 PM, Kalle Valo wrote: > Baochen Qiang <quic_bqiang@quicinc.com> writes: > >> On 12/7/2023 11:15 AM, Aditya Kumar Singh wrote: >>> On 12/4/23 13:43, Baochen Qiang wrote: >>>> --- a/drivers/net/wireless/ath/ath11k/mac.h >>>> +++ b/drivers/net/wireless/ath/ath11k/mac.h >>>> @@ -159,7 +159,6 @@ struct ath11k_vif *ath11k_mac_get_vif_up(struct >>>> ath11k_base *ab); >>>> struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base >>>> *ab, u32 vdev_id); >>>> struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base >>>> *ab, u32 pdev_id); >>>> - >>> Irrelevant change w.r.t commit message? >>> >>>> void ath11k_mac_drain_tx(struct ath11k *ar); >>>> void ath11k_mac_peer_cleanup_all(struct ath11k *ar); >>>> int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); >>> ... >>>> @@ -4749,6 +4749,11 @@ static int >>>> ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc, >>>> soc->pdevs[0].pdev_id = 0; >>>> } >>>> + if (!soc->reg_info_store) >>>> + soc->reg_info_store = kcalloc(soc->num_radios, >>>> + sizeof(*soc->reg_info_store), >>>> + GFP_ATOMIC); >>> What if this memory allocation request fails? Any negative case >>> check should be present? >>> >>>> + >>>> return 0; >>>> } >>>> @@ -7071,33 +7076,54 @@ static bool ath11k_reg_is_world_alpha(char >>>> *alpha) >>>> return false; >>>> } >>>> -static int ath11k_reg_chan_list_event(struct ath11k_base *ab, >>>> - struct sk_buff *skb, >>>> - enum wmi_reg_chan_list_cmd_type id) >>>> +void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info) >>>> { >>>> - struct cur_regulatory_info *reg_info = NULL; >>>> - struct ieee80211_regdomain *regd = NULL; >>>> - bool intersect = false; >>>> - int ret = 0, pdev_idx, i, j; >>>> - struct ath11k *ar; >>>> + int i, j; >>>> - reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); >>>> - if (!reg_info) { >>>> - ret = -ENOMEM; >>>> - goto fallback; >>>> - } >>>> + if (reg_info) { >>>> + kfree(reg_info->reg_rules_2ghz_ptr); >>>> - if (id == WMI_REG_CHAN_LIST_CC_ID) >>>> - ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); >>>> - else >>>> - ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, >>>> reg_info); >>>> + kfree(reg_info->reg_rules_5ghz_ptr); >>>> - if (ret) { >>>> - ath11k_warn(ab, "failed to extract regulatory info from >>>> received event\n"); >>>> - goto fallback; >>>> + for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { >>>> + kfree(reg_info->reg_rules_6ghz_ap_ptr[i]); >>>> + for (j = 0; j < WMI_REG_MAX_CLIENT_TYPE; j++) >>>> + kfree(reg_info->reg_rules_6ghz_client_ptr[i][j]); >>>> + } >>>> + >>>> + memset(reg_info, 0, sizeof(*reg_info)); >>>> } >>>> +} >>>> + >>>> +static >>>> +enum wmi_vdev_type ath11k_reg_get_ar_vdev_type(struct ath11k *ar) >>>> +{ >>>> + struct ath11k_vif *arvif; >>>> + >>>> + /* Currently each struct ath11k maps to one struct >>>> ieee80211_hw/wiphy >>>> + * and one struct ieee80211_regdomain, so it could only store >>>> one group >>>> + * reg rules. It means muti-interface concurrency in the same >>>> ath11k is >>>> + * not support for the regdomain. So get the vdev type of the >>>> first entry >>>> + * now. After concurrency support for the regdomain, this >>>> should change. >>>> + */ >>>> + arvif = list_first_entry_or_null(&ar->arvifs, struct >>>> ath11k_vif, list); >>>> + if (arvif) >>>> + return arvif->vdev_type; >>>> + >>>> + return WMI_VDEV_TYPE_UNSPEC; >>>> +} >>>> + >>>> +int ath11k_reg_handle_chan_list(struct ath11k_base *ab, >>>> + struct cur_regulatory_info *reg_info, >>>> + enum ieee80211_ap_reg_power power_type) >>>> +{ >>>> + struct ieee80211_regdomain *regd; >>>> + bool intersect = false; >>>> + int pdev_idx; >>>> + struct ath11k *ar; >>>> + enum wmi_vdev_type vdev_type; >>>> - ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg chan list id %d", id); >>>> + ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg handle chan list"); >>> I believe this debug was helpful in the sense it showed which type >>> of event came. Can't we still print this somehow? Or may be >>> somewhere else?You can check the event type from logs of >> ath11k_pull_reg_chan_list_update_ev() and >> ath11k_pull_reg_chan_list_ext_update_ev(). > > Baochen, I didn't see any comments from you. Did you send an empty mail > by accident? I did have comments, but some how, I don't know why, it gets merged in Aditya's comments. Will repost it here: You can check the event type from logs of ath11k_pull_reg_chan_list_update_ev() and ath11k_pull_reg_chan_list_ext_update_ev(). >