mbox series

[0/6] wifi: ath11k: P2P support for QCA6390/WCN6855/QCA2066

Message ID 20240226060203.2040444-1-quic_kangyang@quicinc.com
Headers show
Series wifi: ath11k: P2P support for QCA6390/WCN6855/QCA2066 | expand

Message

Kang Yang Feb. 26, 2024, 6:01 a.m. UTC
Add P2P support for QCA6390/WCN6855/QCA2066.

Kang Yang (6):
  wifi: ath11k: change interface combination for P2P mode
  wifi: ath11k: add P2P IE in beacon template
  wifi: ath11k: implement handling of P2P NoA event
  wifi: ath11k: change WLAN_SCAN_PARAMS_MAX_IE_LEN from 256 to 512
  wifi: ath11k: invert scan flag WMI_SCAN_FILTER_PROBE_REQ for
    QCA6390/WCN6855/QCA2066
  wifi: ath11k: advertise P2P dev support for QCA6390/WCN6855/QCA2066

 drivers/net/wireless/ath/ath11k/Makefile |   3 +-
 drivers/net/wireless/ath/ath11k/core.c   |  20 ++-
 drivers/net/wireless/ath/ath11k/mac.c    | 159 ++++++++++++++++++-----
 drivers/net/wireless/ath/ath11k/p2p.c    | 145 +++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/p2p.h    |  23 ++++
 drivers/net/wireless/ath/ath11k/wmi.c    |  99 +++++++++++++-
 drivers/net/wireless/ath/ath11k/wmi.h    |  42 +++++-
 7 files changed, 454 insertions(+), 37 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath11k/p2p.c
 create mode 100644 drivers/net/wireless/ath/ath11k/p2p.h


base-commit: c39a5cfa0448f3afbee78373f16d87815a674f11

Comments

Jeff Johnson Feb. 26, 2024, 7:05 p.m. UTC | #1
On 2/25/2024 10:01 PM, Kang Yang wrote:
> P2P Element is a necessary component of P2P protocol communication.
> It contains the Vendor Specific Information Element which includes
> the WFA OUI and an OUI Type indicating P2P.
> 
> Add P2P IE in beacon template, and implement WMI interface for it.
> 
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
> 
> Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
> ---
>  drivers/net/wireless/ath/ath11k/mac.c | 103 ++++++++++++++++++++++++--
>  drivers/net/wireless/ath/ath11k/wmi.c |  39 ++++++++++
>  drivers/net/wireless/ath/ath11k/wmi.h |   9 +++
>  3 files changed, 143 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
> index 9240dedf3217..f52dd52dabbb 100644
> --- a/drivers/net/wireless/ath/ath11k/mac.c
> +++ b/drivers/net/wireless/ath/ath11k/mac.c
> @@ -1430,10 +1430,67 @@ static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
>  	return false;
>  }
>  
> -static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
> -				      struct sk_buff *bcn)
> +static int ath11k_mac_setup_bcn_p2p_ie(struct ath11k_vif *arvif,
> +				       struct sk_buff *bcn)
>  {
> +	struct ath11k *ar = arvif->ar;
> +	struct ieee80211_mgmt *mgmt;
> +	const u8 *p2p_ie;
> +	int ret = 0;
> +
> +	mgmt = (void *)bcn->data;
> +	p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
> +					 mgmt->u.beacon.variable,
> +					 bcn->len - (mgmt->u.beacon.variable -
> +						     bcn->data));
> +	if (!p2p_ie)
> +		return -ENOENT;
> +
> +	ret = ath11k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
> +	if (ret) {
> +		ath11k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n",
> +			    arvif->vdev_id, ret);
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +static int ath11k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
> +				       u8 oui_type, size_t ie_offset)
> +{
> +	size_t len;
> +	const u8 *next, *end;
> +	u8 *ie;
> +
> +	if (WARN_ON(skb->len < ie_offset))
> +		return -EINVAL;
> +
> +	ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
> +					   skb->data + ie_offset,
> +					   skb->len - ie_offset);
> +	if (!ie)
> +		return -ENOENT;
> +
> +	len = ie[1] + 2;
> +	end = skb->data + skb->len;
> +	next = ie + len;
> +
> +	if (WARN_ON(next > end))
> +		return -EINVAL;
> +
> +	memmove(ie, next, end - next);
> +	skb_trim(skb, skb->len - len);
> +
> +	return 0;
> +}
> +
> +static int ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
> +				     struct sk_buff *bcn)
> +{
> +	struct ath11k_base *ab = arvif->ar->ab;
>  	struct ieee80211_mgmt *mgmt;
> +	int ret = 0;
>  	u8 *ies;
>  
>  	ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
> @@ -1451,6 +1508,32 @@ static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
>  		arvif->wpaie_present = true;
>  	else
>  		arvif->wpaie_present = false;
> +
> +	if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)

this logic isn't applicable for NL80211_IFTYPE_P2P_GO ?

> +		return ret;
> +
> +	ret = ath11k_mac_setup_bcn_p2p_ie(arvif, bcn);
> +	if (ret) {
> +		ath11k_warn(ab, "failed to setup P2P GO bcn ie: %d\n",
> +			    ret);
> +		return ret;
> +	}
> +
> +	/* P2P IE is inserted by firmware automatically (as
> +	 * configured above) so remove it from the base beacon
> +	 * template to avoid duplicate P2P IEs in beacon frames.
> +	 */
> +	ret = ath11k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA,
> +					  WLAN_OUI_TYPE_WFA_P2P,
> +					  offsetof(struct ieee80211_mgmt,
> +						   u.beacon.variable));
> +	if (ret) {
> +		ath11k_warn(ab, "failed to remove P2P vendor ie: %d\n",
> +			    ret);
> +		return ret;
> +	}
> +
> +	return ret;
>  }
>  
>  static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
> @@ -1472,10 +1555,12 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
>  		return -EPERM;
>  	}
>  
> -	if (tx_arvif == arvif)
> -		ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb);
> -	else
> +	if (tx_arvif == arvif) {
> +		if (ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb))
> +			return -EINVAL;
> +	} else {
>  		arvif->wpaie_present = tx_arvif->wpaie_present;
> +	}
>  
>  	for (i = 0; i < beacons->cnt; i++) {
>  		if (tx_arvif != arvif && !nontx_vif_params_set)
> @@ -1534,10 +1619,12 @@ static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
>  		return -EPERM;
>  	}
>  
> -	if (tx_arvif == arvif)
> -		ath11k_mac_set_vif_params(tx_arvif, bcn);
> -	else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
> +	if (tx_arvif == arvif) {
> +		if (ath11k_mac_set_vif_params(tx_arvif, bcn))
> +			return -EINVAL;
> +	} else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) {
>  		return -EINVAL;
> +	}
>  
>  	ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0);
>  	kfree_skb(bcn);
> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
> index 34ab9631ff36..d86fcdd374c6 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.c
> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
> @@ -1704,6 +1704,45 @@ int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
>  	return ret;
>  }
>  
> +int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
> +			     const u8 *p2p_ie)
> +{
> +	struct ath11k_pdev_wmi *wmi = ar->wmi;
> +	struct wmi_p2p_go_set_beacon_ie_cmd *cmd;
> +	size_t p2p_ie_len, aligned_len;
> +	struct wmi_tlv *tlv;
> +	struct sk_buff *skb;
> +	int ret, len;
> +
> +	p2p_ie_len = p2p_ie[1] + 2;
> +	aligned_len = roundup(p2p_ie_len, 4);
> +
> +	len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len;
> +
> +	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
> +	if (!skb)
> +		return -ENOMEM;
> +
> +	cmd = (struct wmi_p2p_go_set_beacon_ie_cmd *)skb->data;
> +	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_P2P_GO_SET_BEACON_IE) |
> +			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
> +	cmd->vdev_id = vdev_id;
> +	cmd->ie_buf_len = p2p_ie_len;
> +
> +	tlv = (struct wmi_tlv *)cmd->tlv;
> +	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
> +		      FIELD_PREP(WMI_TLV_LEN, aligned_len);
> +	memcpy(tlv->value, p2p_ie, p2p_ie_len);
> +
> +	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE);
> +	if (ret) {
> +		ath11k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
> +		dev_kfree_skb(skb);
> +	}
> +
> +	return ret;
> +}
> +
>  int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
>  			struct ieee80211_mutable_offsets *offs,
>  			struct sk_buff *bcn, u32 ema_params)
> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
> index bb419e3abb00..4c20202947c7 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.h
> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
> @@ -3653,6 +3653,13 @@ struct wmi_bcn_tmpl_cmd {
>  	u32 ema_params;
>  } __packed;
>  
> +struct wmi_p2p_go_set_beacon_ie_cmd {
> +	u32 tlv_header;
> +	u32 vdev_id;
> +	u32 ie_buf_len;
> +	u8 tlv[];
> +} __packed;
> +
>  struct wmi_key_seq_counter {
>  	u32 key_seq_counter_l;
>  	u32 key_seq_counter_h;
> @@ -6349,6 +6356,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
>  struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len);
>  int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
>  			 struct sk_buff *frame);
> +int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
> +			     const u8 *p2p_ie);
>  int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
>  			struct ieee80211_mutable_offsets *offs,
>  			struct sk_buff *bcn, u32 ema_param);
Jeff Johnson Feb. 26, 2024, 7:54 p.m. UTC | #2
On 2/25/2024 10:02 PM, Kang Yang wrote:
> Mac80211 needs more space for P2P scan ie in P2P mode, 256 is not
> enough, resize it to 512.
> 
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
> 
> Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Kang Yang Feb. 27, 2024, 3:15 a.m. UTC | #3
On 2/27/2024 4:40 AM, Jeff Johnson wrote:
> On 2/25/2024 10:02 PM, Kang Yang wrote:
>> Current ROC scan will filter probe request. But probe request is
>> necessary for P2P mode. A P2P device cannot be discovered by others if
>> it doesn't respond to others' probe request.
>>
>> So invert scan flag WMI_SCAN_FILTER_PROBE_REQ for
>> QCA6390/WCN6855/QCA2066.
>>
>> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
>> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>>
>> Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
>> ---
>>   drivers/net/wireless/ath/ath11k/wmi.c | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
>> index bbccddd7d729..1dd0cbdda199 100644
>> --- a/drivers/net/wireless/ath/ath11k/wmi.c
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
>> @@ -2317,6 +2317,9 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
>>   	ether_addr_copy(cmd->mac_addr.addr, params->mac_addr.addr);
>>   	ether_addr_copy(cmd->mac_mask.addr, params->mac_mask.addr);
>>   
>> +	if (ar->ab->hw_params.single_pdev_only)
>> +		cmd->scan_ctrl_flags ^=  WMI_SCAN_FILTER_PROBE_REQ;
>> +
> 
> Why is this being done in WMI? Ideally WMI should just be doing host to
> firmware translation, so seems this should be further up the stack, i.e.
> in ath11k_mac_op_hw_scan() / ath11k_mac_op_remain_on_channel()
> 

I referred to ath10k
you are right, i will move to hw_scan().


> It also seems strange to invert the flag (which assumes a known starting
> value) instead of just explicitly setting it to the required value.
> 

When work as P2P, will call remain_on_channel(), then hw_scan().
scan_ctrl_flags will set WMI_SCAN_FILTER_PROBE_REQ in 
remain_on_channel(). so later should reset this flag to 0 (1 -> 0, 
accept probe request).

When work as station, won't call remain_on_channel(). There is no need 
to accept probe request for station(i should also explain this point), 
so need to set this flag to 1 (0 -> 1).

That's why i invert this flag here, but move to hw_scan() is better.



>>   	ptr += sizeof(*cmd);
>>   
>>   	len = params->num_chan * sizeof(u32);
>
Kang Yang Feb. 27, 2024, 6:58 a.m. UTC | #4
On 2/27/2024 3:05 AM, Jeff Johnson wrote:
> On 2/25/2024 10:01 PM, Kang Yang wrote:
>> P2P Element is a necessary component of P2P protocol communication.
>> It contains the Vendor Specific Information Element which includes
>> the WFA OUI and an OUI Type indicating P2P.
>>
>> Add P2P IE in beacon template, and implement WMI interface for it.
>>
>> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
>> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>>
>> Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
>> ---
>>   drivers/net/wireless/ath/ath11k/mac.c | 103 ++++++++++++++++++++++++--
>>   drivers/net/wireless/ath/ath11k/wmi.c |  39 ++++++++++
>>   drivers/net/wireless/ath/ath11k/wmi.h |   9 +++
>>   3 files changed, 143 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
>> index 9240dedf3217..f52dd52dabbb 100644
>> --- a/drivers/net/wireless/ath/ath11k/mac.c
>> +++ b/drivers/net/wireless/ath/ath11k/mac.c
>> @@ -1430,10 +1430,67 @@ static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
>>   	return false;
>>   }
>>   
>> -static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
>> -				      struct sk_buff *bcn)
>> +static int ath11k_mac_setup_bcn_p2p_ie(struct ath11k_vif *arvif,
>> +				       struct sk_buff *bcn)
>>   {
>> +	struct ath11k *ar = arvif->ar;
>> +	struct ieee80211_mgmt *mgmt;
>> +	const u8 *p2p_ie;
>> +	int ret = 0;
>> +
>> +	mgmt = (void *)bcn->data;
>> +	p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
>> +					 mgmt->u.beacon.variable,
>> +					 bcn->len - (mgmt->u.beacon.variable -
>> +						     bcn->data));
>> +	if (!p2p_ie)
>> +		return -ENOENT;
>> +
>> +	ret = ath11k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
>> +	if (ret) {
>> +		ath11k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n",
>> +			    arvif->vdev_id, ret);
>> +		return ret;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static int ath11k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
>> +				       u8 oui_type, size_t ie_offset)
>> +{
>> +	size_t len;
>> +	const u8 *next, *end;
>> +	u8 *ie;
>> +
>> +	if (WARN_ON(skb->len < ie_offset))
>> +		return -EINVAL;
>> +
>> +	ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
>> +					   skb->data + ie_offset,
>> +					   skb->len - ie_offset);
>> +	if (!ie)
>> +		return -ENOENT;
>> +
>> +	len = ie[1] + 2;
>> +	end = skb->data + skb->len;
>> +	next = ie + len;
>> +
>> +	if (WARN_ON(next > end))
>> +		return -EINVAL;
>> +
>> +	memmove(ie, next, end - next);
>> +	skb_trim(skb, skb->len - len);
>> +
>> +	return 0;
>> +}
>> +
>> +static int ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
>> +				     struct sk_buff *bcn)
>> +{
>> +	struct ath11k_base *ab = arvif->ar->ab;
>>   	struct ieee80211_mgmt *mgmt;
>> +	int ret = 0;
>>   	u8 *ies;
>>   
>>   	ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
>> @@ -1451,6 +1508,32 @@ static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
>>   		arvif->wpaie_present = true;
>>   	else
>>   		arvif->wpaie_present = false;
>> +
>> +	if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
> 
> this logic isn't applicable for NL80211_IFTYPE_P2P_GO ?

The original intention here is to determine if it is P2P GO, if yes, 
continue, otherwise return.


Maybe this judgment is a bit misleading, let me replace with
if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) ?


> 
>> +		return ret;
>> +
>> +	ret = ath11k_mac_setup_bcn_p2p_ie(arvif, bcn);
>> +	if (ret) {
>> +		ath11k_warn(ab, "failed to setup P2P GO bcn ie: %d\n",
>> +			    ret);
>> +		return ret;
>> +	}
>> +
>> +	/* P2P IE is inserted by firmware automatically (as
>> +	 * configured above) so remove it from the base beacon
>> +	 * template to avoid duplicate P2P IEs in beacon frames.
>> +	 */
>> +	ret = ath11k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA,
>> +					  WLAN_OUI_TYPE_WFA_P2P,
>> +					  offsetof(struct ieee80211_mgmt,
>> +						   u.beacon.variable));
>> +	if (ret) {
>> +		ath11k_warn(ab, "failed to remove P2P vendor ie: %d\n",
>> +			    ret);
>> +		return ret;
>> +	}
>> +
>> +	return ret;
>>   }
>>   
>>   static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
>> @@ -1472,10 +1555,12 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
>>   		return -EPERM;
>>   	}
>>   
>> -	if (tx_arvif == arvif)
>> -		ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb);
>> -	else
>> +	if (tx_arvif == arvif) {
>> +		if (ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb))
>> +			return -EINVAL;
>> +	} else {
>>   		arvif->wpaie_present = tx_arvif->wpaie_present;
>> +	}
>>   
>>   	for (i = 0; i < beacons->cnt; i++) {
>>   		if (tx_arvif != arvif && !nontx_vif_params_set)
>> @@ -1534,10 +1619,12 @@ static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
>>   		return -EPERM;
>>   	}
>>   
>> -	if (tx_arvif == arvif)
>> -		ath11k_mac_set_vif_params(tx_arvif, bcn);
>> -	else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
>> +	if (tx_arvif == arvif) {
>> +		if (ath11k_mac_set_vif_params(tx_arvif, bcn))
>> +			return -EINVAL;
>> +	} else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) {
>>   		return -EINVAL;
>> +	}
>>   
>>   	ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0);
>>   	kfree_skb(bcn);
>> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
>> index 34ab9631ff36..d86fcdd374c6 100644
>> --- a/drivers/net/wireless/ath/ath11k/wmi.c
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
>> @@ -1704,6 +1704,45 @@ int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
>>   	return ret;
>>   }
>>   
>> +int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
>> +			     const u8 *p2p_ie)
>> +{
>> +	struct ath11k_pdev_wmi *wmi = ar->wmi;
>> +	struct wmi_p2p_go_set_beacon_ie_cmd *cmd;
>> +	size_t p2p_ie_len, aligned_len;
>> +	struct wmi_tlv *tlv;
>> +	struct sk_buff *skb;
>> +	int ret, len;
>> +
>> +	p2p_ie_len = p2p_ie[1] + 2;
>> +	aligned_len = roundup(p2p_ie_len, 4);
>> +
>> +	len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len;
>> +
>> +	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
>> +	if (!skb)
>> +		return -ENOMEM;
>> +
>> +	cmd = (struct wmi_p2p_go_set_beacon_ie_cmd *)skb->data;
>> +	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_P2P_GO_SET_BEACON_IE) |
>> +			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
>> +	cmd->vdev_id = vdev_id;
>> +	cmd->ie_buf_len = p2p_ie_len;
>> +
>> +	tlv = (struct wmi_tlv *)cmd->tlv;
>> +	tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
>> +		      FIELD_PREP(WMI_TLV_LEN, aligned_len);
>> +	memcpy(tlv->value, p2p_ie, p2p_ie_len);
>> +
>> +	ret = ath11k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE);
>> +	if (ret) {
>> +		ath11k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
>> +		dev_kfree_skb(skb);
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>>   int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
>>   			struct ieee80211_mutable_offsets *offs,
>>   			struct sk_buff *bcn, u32 ema_params)
>> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
>> index bb419e3abb00..4c20202947c7 100644
>> --- a/drivers/net/wireless/ath/ath11k/wmi.h
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
>> @@ -3653,6 +3653,13 @@ struct wmi_bcn_tmpl_cmd {
>>   	u32 ema_params;
>>   } __packed;
>>   
>> +struct wmi_p2p_go_set_beacon_ie_cmd {
>> +	u32 tlv_header;
>> +	u32 vdev_id;
>> +	u32 ie_buf_len;
>> +	u8 tlv[];
>> +} __packed;
>> +
>>   struct wmi_key_seq_counter {
>>   	u32 key_seq_counter_l;
>>   	u32 key_seq_counter_h;
>> @@ -6349,6 +6356,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
>>   struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len);
>>   int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
>>   			 struct sk_buff *frame);
>> +int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
>> +			     const u8 *p2p_ie);
>>   int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
>>   			struct ieee80211_mutable_offsets *offs,
>>   			struct sk_buff *bcn, u32 ema_param);
>
Johannes Berg Feb. 27, 2024, 7:32 a.m. UTC | #5
On Tue, 2024-02-27 at 14:58 +0800, Kang Yang wrote:
> 
> > > +	if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
> > 
> > this logic isn't applicable for NL80211_IFTYPE_P2P_GO ?
> 
> The original intention here is to determine if it is P2P GO, if yes, 
> continue, otherwise return.
> 
> 
> Maybe this judgment is a bit misleading, let me replace with
> if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) ?

There's also

	ieee80211_vif_type_p2p(arvif->vif) != NL80211_IFTYPE_P2P_GO

if you wanted to write it that way.

@Jeff: NL80211_IFTYPE_P2P_GO is not used by mac80211 internally, it
translates that to vif->type==NL80211_IFTYPE_AP && vif->p2p==true.

johannes
Jeff Johnson Feb. 27, 2024, 3:05 p.m. UTC | #6
On 2/26/2024 11:32 PM, Johannes Berg wrote:
> @Jeff: NL80211_IFTYPE_P2P_GO is not used by mac80211 internally, it
> translates that to vif->type==NL80211_IFTYPE_AP && vif->p2p==true.

Yesterday I was looking at another patch and while doing so noticed this
as well. Too many years of working with our downstream Android driver
where we use the P2P iftypes directly...

/jeff
Johannes Berg Feb. 27, 2024, 3:11 p.m. UTC | #7
On Tue, 2024-02-27 at 07:05 -0800, Jeff Johnson wrote:
> On 2/26/2024 11:32 PM, Johannes Berg wrote:
> > @Jeff: NL80211_IFTYPE_P2P_GO is not used by mac80211 internally, it
> > translates that to vif->type==NL80211_IFTYPE_AP && vif->p2p==true.
> 
> Yesterday I was looking at another patch and while doing so noticed this
> as well. Too many years of working with our downstream Android driver
> where we use the P2P iftypes directly...

I do sometimes wonder if this was the right decision ... but I think
it'll be quite difficult to change it now.

johannes