Search Linux Wireless

Re: [RFC v2 38/96] cl8k: add mac80211.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2022-05-24 at 14:34 +0300, viktor.barna@xxxxxxxxxx wrote:
> 
> +static void cl_ops_tx_single(struct cl_hw *cl_hw,
> +			     struct sk_buff *skb,
> +			     struct ieee80211_tx_info *tx_info,
> +			     struct cl_sta *cl_sta,
> +			     struct ieee80211_sta *sta)
> +{

...

> +	if (sta) {
> +		u32 sta_vht_cap = sta->vht_cap.cap;
> +		struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
> +
> +		if (!(sta_vht_cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK))
> +			goto out_tx;
> +
> +		if (ieee80211_is_assoc_resp(mgmt->frame_control)) {
> +			int len = skb->len - (mgmt->u.assoc_resp.variable - skb->data);
> +			const u8 *vht_cap_addr = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY,
> +								 mgmt->u.assoc_resp.variable,
> +								 len);
> +
> +			if (vht_cap_addr) {
> +				struct ieee80211_vht_cap *vht_cap =
> +					(struct ieee80211_vht_cap *)(2 + vht_cap_addr);
> +
> +				vht_cap->vht_cap_info &=
> +					~(cpu_to_le32(IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK |
> +						      IEEE80211_VHT_CAP_SHORT_GI_160));
> +			}

Huh??


> +int cl_ops_config(struct ieee80211_hw *hw, u32 changed)
> +{
> +	/*
> +	 * Handler for configuration requests. IEEE 802.11 code calls this
> +	 * function to change hardware configuration, e.g., channel.
> +	 * This function should never fail but returns a negative error code
> +	 * if it does. The callback can sleep
> +	 */
> +	int error = 0;
> +
> +	if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
> +		error = cl_ops_conf_change_channel(hw);

I'm really surprised to see this callback in a modern driver - wouldn't
you want to support some form of multi-channel operation? Even just
using the chanctx callbacks might make some of the DFS things you have
there easier?


> 
> +void cl_ops_bss_info_changed(struct ieee80211_hw *hw,
> +			     struct ieee80211_vif *vif,
> +			     struct ieee80211_bss_conf *info,
> +			     u32 changed)
> +{

...

> +		if (beacon) {
> +			size_t ies_len = beacon->tail_len;
> +			const u8 *ies = beacon->tail;
> +			const u8 *cap =  NULL;
> +			int var_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
> +			int len = beacon->head_len - var_offset;
> +			const u8 *var_pos = beacon->head + var_offset;
> +			const u8 *rate_ie = NULL;
> +
> +			cl_vif->wmm_enabled = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
> +								      WLAN_OUI_TYPE_MICROSOFT_WMM,
> +								      ies,
> +								      ies_len);
> +			cl_dbg_info(cl_hw, "vif=%d wmm_enabled=%d\n",
> +				    cl_vif->vif_index,
> +				    cl_vif->wmm_enabled);
> +
> +			cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
> +			if (cap && cap[1] >= sizeof(*ht_cap)) {
> +				ht_cap = (void *)(cap + 2);
> +				sgi_en |= (le16_to_cpu(ht_cap->cap_info) &
> +					   IEEE80211_HT_CAP_SGI_20) ||
> +					  (le16_to_cpu(ht_cap->cap_info) &
> +					   IEEE80211_HT_CAP_SGI_40);
> +			}
> +
> +			cap = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
> +			if (cap && cap[1] >= sizeof(*vht_cap)) {
> +				vht_cap = (void *)(cap + 2);
> +				sgi_en |= (le32_to_cpu(vht_cap->vht_cap_info) &
> +					   IEEE80211_VHT_CAP_SHORT_GI_80) ||
> +					  (le32_to_cpu(vht_cap->vht_cap_info) &
> +					   IEEE80211_VHT_CAP_SHORT_GI_160);
> +			}
> +
> +			cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len);
> +			if (cap && cap[1] >= sizeof(*he_cap) + 1)
> +				he_cap = (void *)(cap + 3);
> +
> +			rate_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len);
> +			if (rate_ie) {
> +				if (cl_band_is_24g(cl_hw))
> +					if (cl_is_valid_g_rates(rate_ie))
> +						hw_mode = cl_hw->conf->ci_cck_in_hw_mode ?
> +							     HW_MODE_BG : HW_MODE_G;
> +					else
> +						hw_mode = HW_MODE_B;
> +				else
> +					hw_mode = HW_MODE_A;
> +			}
> +		} else {
> +			cl_dbg_warn(cl_hw, "beacon_data not set!\n");
> +		}
> +

This feels ... odd. You really shouldn't have to look into the beacon to
figure out these things?

And SGI etc. are per-STA rate control parameters anyway? Hmm.

> +/* This function is required for PS flow - do not remove */
> +int cl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
> +{
> +	return 0;
> +}

You have all this hardware/firmware and you implement this? Interesting
design choice. One that I'm sure you'll revisit for WiFi 7 ;-)

johannes




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux