diff --git a/feeds/ipq807x/ath11k-firmware/Makefile b/feeds/ipq807x/ath11k-firmware/Makefile index 70380d996..5cfd8b2c2 100644 --- a/feeds/ipq807x/ath11k-firmware/Makefile +++ b/feeds/ipq807x/ath11k-firmware/Makefile @@ -45,8 +45,8 @@ define Package/ath11k-firmware-ipq60xx/install $(INSTALL_DIR) $(1)/lib/firmware/IPQ6018 $(INSTALL_DATA) $(PKG_BUILD_DIR)/IPQ6018/hw1.0/2.1.0.1/WLAN.HK.2.1.0.1-01238-QCAHKSWPL_SILICONZ-2/* \ $(1)/lib/firmware/IPQ6018 - $(INSTALL_DATA) $(PKG_BUILD_DIR)/IPQ6018/hw1.0/board-2.bin \ - $(1)/lib/firmware/IPQ6018 +# $(INSTALL_DATA) $(PKG_BUILD_DIR)/IPQ6018/hw1.0/board-2.bin \ +# $(1)/lib/firmware/IPQ6018 endef define Package/ath11k-firmware-ipq807x/install diff --git a/feeds/ipq807x/ath11k-wifi/Makefile b/feeds/ipq807x/ath11k-wifi/Makefile new file mode 100644 index 000000000..fbae09fb0 --- /dev/null +++ b/feeds/ipq807x/ath11k-wifi/Makefile @@ -0,0 +1,81 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/version.mk + +PKG_NAME:=ath11k-wifi +PKG_RELEASE:=1 +PKG_FLAGS:=nonshared + +include $(INCLUDE_DIR)/package.mk + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Compile +endef + +# +# This is intended to be used on an interim basis until device-specific +# board data for new devices is available through the upstream compilation +# +# Please send a mail with your device-specific board files upstream. +# You can find instructions and examples on the linux-wireless wiki: +# +# + +ALLWIFIBOARDS:= \ + cig-wf188 + +ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ath11k-wifi-$(BOARD)) + +define Package/ath11k-wifi-default + SUBMENU:=ath11k Board-Specific Overrides + SECTION:=firmware + CATEGORY:=Firmware + DEPENDS:=@TARGET_ipq807x + TITLE:=Custom Board +endef + +define ath11k-wifi-install-one-to + $(INSTALL_DIR) $(2)/lib/firmware/$(3)/ + $(INSTALL_DATA) $(1) $(2)/lib/firmware/$(3)/bdwlan.bin +endef + +define ath11k-wifi-install-one + $(if $(filter $(suffix $(1)),.IPQ6018),\ + $(call ath11k-wifi-install-one-to,$(1),$(2),IPQ6018),\ + ) + +endef +# Blank line required at end of above define due to foreach context + +define generate-ath11k-wifi-package + define Package/ath11k-wifi-$(1) + $(call Package/ath11k-wifi-default) + TITLE:=bdwlan.bin Overrides for $(2) + CONFLICTS:=$(PREV_BOARD) + endef + + define Package/ath11k-wifi-$(1)/description +The $(2) requires board-specific, reference ("cal") data +that is not yet present in the upstream wireless firmware distribution. + +This package supplies bdwlan.bin file(s) that, in the interim, +overwrite those supplied by the ath11k-firmware-* packages. + +This is package is only necessary for the $(2). + +Do not install it for any other device! + endef + + define Package/ath11k-wifi-$(1)/install-overlay + $$$$(foreach ATH11K_WIFI_BOARD_FILE,$$$$(wildcard board-$(1).*),\ + $$$$(call ath11k-wifi-install-one,$$$$(ATH11K_WIFI_BOARD_FILE),$$(1))) + endef + + PREV_BOARD+=ath11k-wifi-$(1) +endef + +$(eval $(call generate-ath11k-wifi-package,cig-wf188,Cigtech WF188)) + +$(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE)))) diff --git a/feeds/ipq807x/ath11k-wifi/board-cig-wf188.bin.IPQ6018 b/feeds/ipq807x/ath11k-wifi/board-cig-wf188.bin.IPQ6018 new file mode 100644 index 000000000..58e9f75ef Binary files /dev/null and b/feeds/ipq807x/ath11k-wifi/board-cig-wf188.bin.IPQ6018 differ diff --git a/feeds/ipq807x/hostapd/files/hostapd.sh b/feeds/ipq807x/hostapd/files/hostapd.sh index 10fd06c98..ceffe16e3 100644 --- a/feeds/ipq807x/hostapd/files/hostapd.sh +++ b/feeds/ipq807x/hostapd/files/hostapd.sh @@ -136,8 +136,8 @@ hostapd_prepare_device_config() { } [ -n "$acs_chan_bias" ] && append base_cfg "acs_chan_bias=$acs_chan_bias" "$N" - append base_cfg "multiple_bssid=$multiple_bssid" "$N" - append base_cfg "rnr_beacon=$rnr_beacon" "$N" + #append base_cfg "multiple_bssid=$multiple_bssid" "$N" + #append base_cfg "rnr_beacon=$rnr_beacon" "$N" local brlist= br json_get_values basic_rate_list basic_rate diff --git a/feeds/ipq807x/hostapd/src/src/drivers/nl80211_copy.h b/feeds/ipq807x/hostapd/src/src/drivers/nl80211_copy.h index 22d24dc11..d99e017ff 100644 --- a/feeds/ipq807x/hostapd/src/src/drivers/nl80211_copy.h +++ b/feeds/ipq807x/hostapd/src/src/drivers/nl80211_copy.h @@ -1384,13 +1384,6 @@ enum nl80211_commands { NL80211_CMD_PROBE_MESH_LINK, - NL80211_CMD_OBSS_COLOR_COLLISION, - - NL80211_CMD_COLOR_CHANGE, - NL80211_CMD_CCA_STARTED_NOTIFY, - NL80211_CMD_CCA_ABORTED_NOTIFY, - NL80211_CMD_CCA_NOTIFY, - NL80211_CMD_SET_TID_CONFIG, NL80211_CMD_UNPROT_BEACON, @@ -2957,19 +2950,6 @@ enum nl80211_attrs { NL80211_ATTR_HE_BSS_COLOR, - NL80211_ATTR_MULTI_BSSID_MODE, - NL80211_ATTR_MULTI_BSSID_PARENT, - NL80211_ATTR_MULTI_BSSID_INDEX, - NL80211_ATTR_MULTI_BSSID_COUNT, - - NL80211_ATTR_OBSS_COLOR_BITMAP, - - NL80211_ATTR_CCA_COUNT, - NL80211_ATTR_CCA_COLOR, - NL80211_ATTR_CCA_IES, - NL80211_ATTR_CCA_C_OFF_BEACON, - NL80211_ATTR_CCA_C_OFF_PRESP, - NL80211_ATTR_IFTYPE_AKM_SUITES, NL80211_ATTR_TID_CONFIG, @@ -2981,7 +2961,6 @@ enum nl80211_attrs { NL80211_ATTR_RECEIVE_MULTICAST, - /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -2989,37 +2968,6 @@ enum nl80211_attrs { NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 }; - -/** - * enum nl80211_multi_bssid_mode - Multiple BSSID beacon type - * - * Used by cfg80211_ap_settings - * - * @MULTIPLE_BSSID_LEGACY: This BSS is not part of a multiple BSSID group - * @MULTIPLE_BSSID_TRANSMITTED: This BSS is broadcasting a multiple BSSID - * beacon - * @MULTIPLE_BSSID_NON_TRANSMITTED: This BSS is not broadcasting a beacon - */ -enum nl80211_multi_bssid_mode { - NL80211_MULTIPLE_BSSID_LEGACY = 0, - NL80211_MULTIPLE_BSSID_TRANSMITTED, - NL80211_MULTIPLE_BSSID_NON_TRANSMITTED, -}; - -/** - * enum nl80211_beacon_tx_mode - Beacon tx mode settings - * - * @BEACON_TX_MODE_DEFAULT: The beacons shall be sent out in its default mode - * @BEACON_TX_MODE_STAGGERED: The beacons shall be sent out in staggered mode - * @BEACON_TX_MODE_BURST: The beacons shall be sent out in burst mode - * beacon - */ -enum nl80211_beacon_tx_mode { - NL80211_BEACON_TX_MODE_STAGGERED = 0, - NL80211_BEACON_TX_MODE_BURST, -}; - - /* source-level API compatibility */ #define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION #define NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG @@ -5803,6 +5751,7 @@ enum nl80211_ext_feature_index { NL80211_EXT_FEATURE_STA_TX_PWR, NL80211_EXT_FEATURE_SAE_OFFLOAD, NL80211_EXT_FEATURE_VLAN_OFFLOAD, + NL80211_EXT_FEATURE_WIDE_BAND_SCAN, NL80211_EXT_FEATURE_AQL, NL80211_EXT_FEATURE_BEACON_PROTECTION, NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH, diff --git a/feeds/ipq807x/mac80211/patches/192-mac80211-add-vlan-offload-support.patch b/feeds/ipq807x/mac80211/patches/192-mac80211-add-vlan-offload-support.patch deleted file mode 100644 index 4f2391b48..000000000 --- a/feeds/ipq807x/mac80211/patches/192-mac80211-add-vlan-offload-support.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 0f581eec294296d42f1ada495c5846b4ec1546a4 Mon Sep 17 00:00:00 2001 -From: Seevalamuthu Mariappan -Date: Mon, 15 Jun 2020 12:47:20 +0530 -Subject: [PATCH 1/2] mac80211: Add GTK offload support for AP_VLAN - -Current implementation does not support GTK encryption for VLAN interfaces -in driver/hardware since the driver is not aware AP-VLAN interfaces. This -patch adds feature flag to allow group key encryption in driver/hardware. -Drivers can identify VLAN interfaces from vlan_id in ieee80211_key_conf. - -Signed-off-by: Seevalamuthu Mariappan ---- - include/net/mac80211.h | 6 ++++++ - net/mac80211/cfg.c | 1 + - net/mac80211/debugfs.c | 1 + - net/mac80211/iface.c | 8 +++++++- - net/mac80211/key.c | 3 ++- - net/mac80211/tx.c | 11 ++++++++++- - 6 files changed, 27 insertions(+), 3 deletions(-) - -diff --git a/include/net/mac80211.h b/include/net/mac80211.h -index f4506ec..f87d7ac 100644 ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -1773,6 +1773,7 @@ enum ieee80211_key_flags { - * - Temporal Authenticator Rx MIC Key (64 bits) - * @icv_len: The ICV length for this key type - * @iv_len: The IV length for this key type -+ * @vlan_id: For VLAN interfaces 1-4096, 0 for non-vlan interfaces - */ - struct ieee80211_key_conf { - atomic64_t tx_pn; -@@ -1783,6 +1784,7 @@ struct ieee80211_key_conf { - s8 keyidx; - u16 flags; - u8 keylen; -+ u16 vlan_id; - u8 key[0]; - }; - -@@ -2308,6 +2310,9 @@ struct ieee80211_txq { - * aggregating MPDUs with the same keyid, allowing mac80211 to keep Tx - * A-MPDU sessions active while rekeying with Extended Key ID. - * -+ * @IEEE80211_HW_VLAN_CRYPTO_CONTROL: The driver (or firmware) supports crypto -+ * algorithms for AP_VLAN interfaces -+ * - * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays - */ - enum ieee80211_hw_flags { -@@ -2360,6 +2365,7 @@ enum ieee80211_hw_flags { - IEEE80211_HW_SUPPORTS_MULTI_BSSID, - IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID, - IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT, -+ IEEE80211_HW_VLAN_CRYPTO_CONTROL, - - /* keep last, obviously */ - NUM_IEEE80211_HW_FLAGS -diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c -index 64e807d..5e8f3a4 100644 ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -460,6 +460,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, - break; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_AP_VLAN: -+ key->conf.vlan_id = params->vlan_id; - /* Keys without a station are used for TX only */ - if (sta && test_sta_flag(sta, WLAN_STA_MFP)) - key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; -diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c -index 2c2e07c..006afd1 100644 ---- a/net/mac80211/debugfs.c -+++ b/net/mac80211/debugfs.c -@@ -408,6 +408,7 @@ static const char *hw_flag_names[] = { - FLAG(SUPPORTS_MULTI_BSSID), - FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID), - FLAG(AMPDU_KEYBORDER_SUPPORT), -+ FLAG(VLAN_CRYPTO_CONTROL), - #undef FLAG - }; - -diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c -index b2a2165..1f0822b 100644 ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -300,8 +300,14 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, - * can only add VLANs to enabled APs - */ - if (iftype == NL80211_IFTYPE_AP_VLAN && -- nsdata->vif.type == NL80211_IFTYPE_AP) -+ nsdata->vif.type == NL80211_IFTYPE_AP) { -+ if (ieee80211_hw_check(&local->hw, VLAN_CRYPTO_CONTROL) && -+ nsdata->hw_80211_encap) { -+ sdata->dev->netdev_ops = nsdata->dev->netdev_ops; -+ sdata->hw_80211_encap = true; -+ } - sdata->bss = &nsdata->u.ap; -+ } - } - } - -diff --git a/net/mac80211/key.c b/net/mac80211/key.c -index 4b1c45b..96bed31 100644 ---- a/net/mac80211/key.c -+++ b/net/mac80211/key.c -@@ -167,7 +167,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) - goto out_unsupported; - - sdata = key->sdata; -- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { -+ if (!ieee80211_hw_check(&key->local->hw, VLAN_CRYPTO_CONTROL) && -+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { - /* - * The driver doesn't know anything about VLAN interfaces. - * Hence, don't send GTKs for VLAN interfaces to the driver. -diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c -index eed6b2c..e833cb8 100644 ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -4184,6 +4184,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, - bool authorized = false; - bool multicast; - unsigned char *ra = ehdr->h_dest; -+ struct ieee80211_key *key; - - if (IS_ERR(sta) || (sta && !sta->uploaded)) - sta = NULL; -@@ -4209,6 +4210,10 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, - !atomic_read(&sdata->u.ap.num_mcast_sta)) - goto out_free; - -+ if (multicast && sdata->vif.type == NL80211_IFTYPE_AP_VLAN && -+ !atomic_read(&sdata->u.vlan.num_mcast_sta)) -+ goto out_free; -+ - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && - test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) - goto out_free; -@@ -4237,9 +4242,13 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, - sta->tx_stats.packets[skb_get_queue_mapping(skb)]++; - } - -- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { -+ if (multicast && ieee80211_hw_check(&local->hw, VLAN_CRYPTO_CONTROL) && -+ (key = rcu_dereference(sdata->default_multicast_key))) -+ info->control.hw_key = &key->conf; - sdata = container_of(sdata->bss, - struct ieee80211_sub_if_data, u.ap); -+ } - - info->control.flags |= IEEE80211_TX_CTRL_HW_80211_ENCAP; - info->control.vif = &sdata->vif; --- -2.7.4 - diff --git a/feeds/ipq807x/mac80211/patches/193-ath11k-add-dynamic-vlan-support.patch b/feeds/ipq807x/mac80211/patches/193-ath11k-add-dynamic-vlan-support.patch deleted file mode 100644 index 1b8485dc5..000000000 --- a/feeds/ipq807x/mac80211/patches/193-ath11k-add-dynamic-vlan-support.patch +++ /dev/null @@ -1,583 +0,0 @@ -From a9098659ead1f0ae630e9dfc231659ba99f024dd Mon Sep 17 00:00:00 2001 -From: Seevalamuthu Mariappan -Date: Mon, 15 Jun 2020 12:50:31 +0530 -Subject: [PATCH 2/2] ath11k: Add Dynamic VLAN support - -Dynamic VLAN offload implementation relies on multiple group key encryption -support in hardware. Driver should advertise IEEE80211_HW_VLAN_CRYPTO_ENABLE -flag to mac80211 about VLAN group crypto support in hardware. Also, driver -should advertise NL80211_EXT_FEATURE_VLAN_OFFLOAD to enable vlan offload in -hostapd. Group Key for multiple vlan interfaces are configured with the help -of group key index as the hardware uses this index to get the corresponding -group key during transmission. Each AP-VLAN interface chose unique group key -index and the same group key will be sent in htt meta data info in dp_tx. Set -exception to fw flag in tx meta data flags. This group key index shall be -configured in meta data info only for VLAN group traffic. - -Currently, the firmware supports upto 128 group keys for an AP interface. -The multiple group key support can be enabled during resource config. - -Signed-off-by: Seevalamuthu Mariappan ---- - drivers/net/wireless/ath/ath11k/core.h | 7 ++ - drivers/net/wireless/ath/ath11k/dp_tx.c | 67 ++++++++++- - drivers/net/wireless/ath/ath11k/dp_tx.h | 198 ++++++++++++++++++++++++++++++++ - drivers/net/wireless/ath/ath11k/mac.c | 76 ++++++++++++ - drivers/net/wireless/ath/ath11k/wmi.c | 3 + - drivers/net/wireless/ath/ath11k/wmi.h | 2 + - 6 files changed, 352 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h -index 49b0a9d..6699491 100644 ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -67,6 +67,11 @@ enum ath11k_crypt_mode { - ATH11K_CRYPT_MODE_SW, - }; - -+#define ATH11K_GROUP_KEYS_NUM_MAX 128 -+#define ATH11K_FREE_GROUP_IDX_MAP_BITS 32 -+#define ATH11K_FREE_GROUP_IDX_MAP_MAX (ATH11K_GROUP_KEYS_NUM_MAX / \ -+ ATH11K_FREE_GROUP_IDX_MAP_BITS) -+ - static inline enum wme_ac ath11k_tid_to_ac(u32 tid) - { - return (((tid == 0) || (tid == 3)) ? WME_AC_BE : -@@ -248,6 +253,8 @@ struct ath11k_vif { - int txpower; - struct dentry *debugfs_twt; - struct ath11k_mgmt_frame_stats mgmt_stats; -+ u16 *vlan_keyid_map; -+ DECLARE_BITMAP(free_groupidx_map, ATH11K_GROUP_KEYS_NUM_MAX); - }; - - struct ath11k_vif_iter { -diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c -index ba6cdd9..1549dc0 100644 ---- a/drivers/net/wireless/ath/ath11k/dp_tx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -76,6 +76,34 @@ enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher) - } - } - -+#define HTT_META_DATA_ALIGNMENT 0x8 -+ -+static int ath11k_dp_prepare_htt_metadata(struct sk_buff *skb, -+ u8 group_key_idx, -+ u8 *htt_metadata_size) -+{ -+ u8 htt_desc_size; -+ /* Size rounded of multiple of 8 bytes */ -+ u8 htt_desc_size_aligned; -+ struct htt_tx_msdu_desc_ext *desc_ext; -+ -+ htt_desc_size = sizeof(struct htt_tx_msdu_desc_ext); -+ htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT); -+ -+ if (skb_headroom(skb) < htt_desc_size_aligned) -+ if (pskb_expand_head(skb, htt_desc_size_aligned, 0, GFP_ATOMIC)) -+ return -ENOMEM; -+ -+ skb_push(skb, htt_desc_size_aligned); -+ memset(skb->data, 0, htt_desc_size_aligned); -+ desc_ext = (struct htt_tx_msdu_desc_ext *)skb->data; -+ desc_ext->valid_key_flags = 1; -+ desc_ext->key_flags = group_key_idx; -+ *htt_metadata_size = htt_desc_size_aligned; -+ -+ return 0; -+} -+ - int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, - struct sk_buff *skb) - { -@@ -86,6 +114,7 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, - struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb); - struct hal_srng *tcl_ring; - struct ieee80211_hdr *hdr = (void *)skb->data; -+ struct ethhdr *ethhdr = (struct ethhdr *)skb->data; - struct dp_tx_ring *tx_ring; - void *hal_tcl_desc; - u8 pool_id; -@@ -93,6 +122,8 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, - int ret; - u8 ring_selector = 0, ring_map = 0; - bool tcl_ring_retry; -+ u8 align_pad, htt_meta_size = 0; -+ bool multicast; - - if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) - return -ESHUTDOWN; -@@ -197,6 +228,38 @@ tcl_ring_sel: - goto fail_remove_idr; - } - -+ if (ti.encap_type == HAL_TCL_ENCAP_TYPE_ETHERNET) -+ multicast = is_multicast_ether_addr(ethhdr->h_dest); -+ else -+ multicast = is_multicast_ether_addr(hdr->addr1); -+ -+ if (multicast && info->control.hw_key && info->control.hw_key->vlan_id) { -+ /* HW requirement is that metadata should always point to a -+ * 8-byte aligned address. So we add alignment pad to start of -+ * buffer. HTT Metadata should be ensured to be multiple of 8-bytes -+ * to get 8-byte aligned start address along with align_pad added -+ */ -+ -+ align_pad = ((unsigned long)skb->data) & (HTT_META_DATA_ALIGNMENT - 1); -+ if (skb_headroom(skb) < align_pad) { -+ if (pskb_expand_head(skb, align_pad, 0, GFP_ATOMIC)) { -+ ret = -ENOMEM; -+ goto fail_remove_idr; -+ } -+ } -+ skb_push(skb, align_pad); -+ ti.pkt_offset += align_pad; -+ memset(skb->data, 0, align_pad); -+ ret = ath11k_dp_prepare_htt_metadata(skb, -+ info->control.hw_key->hw_key_idx, &htt_meta_size); -+ if (ret) -+ goto fail_remove_idr; -+ -+ ti.pkt_offset += htt_meta_size; -+ ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT; -+ ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1); -+ } -+ - ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(ab->dev, ti.paddr)) { - atomic_inc(&ab->soc_stats.tx_err.misc_fail); -@@ -205,7 +268,7 @@ tcl_ring_sel: - goto fail_remove_idr; - } - -- ti.data_len = skb->len; -+ ti.data_len = skb->len - ti.pkt_offset; - skb_cb->paddr = ti.paddr; - skb_cb->vif = arvif->vif; - skb_cb->ar = ar; -@@ -258,6 +321,8 @@ fail_unmap_dma: - dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); - - fail_remove_idr: -+ if (ti.pkt_offset) -+ skb_pull(skb, ti.pkt_offset); - spin_lock_bh(&tx_ring->tx_idr_lock); - idr_remove(&tx_ring->txbuf_idr, - FIELD_GET(DP_TX_DESC_ID_MSDU_ID, ti.desc_id)); -diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.h b/drivers/net/wireless/ath/ath11k/dp_tx.h -index f8a9f9c..a5f0dfd 100644 ---- a/drivers/net/wireless/ath/ath11k/dp_tx.h -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h -@@ -15,6 +15,204 @@ struct ath11k_dp_htt_wbm_tx_status { - int ack_rssi; - }; - -+/* htt_tx_msdu_desc_ext -+ * -+ * valid_pwr -+ * if set, tx pwr spec is valid -+ * -+ * valid_mcs_mask -+ * if set, tx MCS mask is valid -+ * -+ * valid_nss_mask -+ * if set, tx Nss mask is valid -+ * -+ * valid_preamble_type -+ * if set, tx preamble spec is valid -+ * -+ * valid_retries -+ * if set, tx retries spec is valid -+ * -+ * valid_bw_info -+ * if set, tx dyn_bw and bw_mask are valid -+ * -+ * valid_guard_interval -+ * if set, tx guard intv spec is valid -+ * -+ * valid_chainmask -+ * if set, tx chainmask is valid -+ * -+ * valid_encrypt_type -+ * if set, encrypt type is valid -+ * -+ * valid_key_flags -+ * if set, key flags is valid -+ * -+ * valid_expire_tsf -+ * if set, tx expire TSF spec is valid -+ * -+ * valid_chanfreq -+ * if set, chanfreq is valid -+ * -+ * is_dsrc -+ * if set, MSDU is a DSRC frame -+ * -+ * guard_interval -+ * 0.4us, 0.8us, 1.6us, 3.2us -+ * -+ * encrypt_type -+ * 0 = NO_ENCRYPT, -+ * 1 = ENCRYPT, -+ * 2 ~ 3 - Reserved -+ * -+ * retry_limit -+ * Specify the maximum number of transmissions, including the -+ * initial transmission, to attempt before giving up if no ack -+ * is received. -+ * If the tx rate is specified, then all retries shall use the -+ * same rate as the initial transmission. -+ * If no tx rate is specified, the target can choose whether to -+ * retain the original rate during the retransmissions, or to -+ * fall back to a more robust rate. -+ * -+ * use_dcm_11ax -+ * If set, Use Dual subcarrier modulation. -+ * Valid only for 11ax preamble types HE_SU -+ * and HE_EXT_SU -+ * -+ * ltf_subtype_11ax -+ * Takes enum values of htt_11ax_ltf_subtype_t -+ * Valid only for 11ax preamble types HE_SU -+ * and HE_EXT_SU -+ * -+ * dyn_bw -+ * 0 = static bw, 1 = dynamic bw -+ * -+ * bw_mask -+ * Valid only if dyn_bw == 0 (static bw). -+ * -+ * host_tx_desc_pool -+ * If set, Firmware allocates tx_descriptors -+ * in WAL_BUFFERID_TX_HOST_DATA_EXP,instead -+ * of WAL_BUFFERID_TX_TCL_DATA_EXP. -+ * Use cases: -+ * Any time firmware uses TQM-BYPASS for Data -+ * TID, firmware expect host to set this bit. -+ * -+ * power -+ * unit of the power field is 0.5 dbm -+ * signed value ranging from -64dbm to 63.5 dbm -+ * -+ * mcs_mask -+ * mcs bit mask of 0 ~ 11 -+ * Setting more than one MCS isn't currently -+ * supported by the target (but is supported -+ * in the interface in case in the future -+ * the target supports specifications of -+ * a limited set of MCS values. -+ * -+ * nss_mask -+ * Nss bit mask 0 ~ 7 -+ * Setting more than one Nss isn't currently -+ * supported by the target (but is supported -+ * in the interface in case in the future -+ * the target supports specifications of -+ * a limited set of Nss values. -+ * -+ * pream_type -+ * Preamble types -+ * -+ * update_peer_cache -+ * When set these custom values will be -+ * used for all packets, until the next -+ * update via this ext header. -+ * This is to make sure not all packets -+ * need to include this header. -+ * -+ * chain_mask -+ * specify which chains to transmit from -+ * -+ * key_flags -+ * Key Index and related flags - used in mesh mode -+ * -+ * chanfreq -+ * Channel frequency: This identifies the desired channel -+ * frequency (in MHz) for tx frames. This is used by FW to help -+ * determine when it is safe to transmit or drop frames for -+ * off-channel operation. -+ * The default value of zero indicates to FW that the corresponding -+ * VDEV's home channel (if there is one) is the desired channel -+ * frequency. -+ * -+ * expire_tsf_lo -+ * tx expiry time (TSF) LSBs -+ * -+ * expire_tsf_hi -+ * tx expiry time (TSF) MSBs -+ * -+ * learning_frame -+ * When this flag is set, this frame will be dropped by FW -+ * rather than being enqueued to the Transmit Queue Manager (TQM) HW. -+ * -+ * send_as_standalone -+ * This will indicate if the msdu needs to be sent as a singleton PPDU, -+ * i.e. with no A-MSDU or A-MPDU aggregation. -+ * The scope is extended to other use-cases. -+ * -+ * is_host_opaque_valid -+ * set this bit to 1 if the host_opaque_cookie is populated -+ * with valid information. -+ * -+ * host_opaque_cookie -+ * Host opaque cookie for special frames -+ */ -+ -+struct htt_tx_msdu_desc_ext { -+ u32 -+ valid_pwr : 1, -+ valid_mcs_mask : 1, -+ valid_nss_mask : 1, -+ valid_preamble_type : 1, -+ valid_retries : 1, -+ valid_bw_info : 1, -+ valid_guard_interval : 1, -+ valid_chainmask : 1, -+ valid_encrypt_type : 1, -+ valid_key_flags : 1, -+ valid_expire_tsf : 1, -+ valid_chanfreq : 1, -+ is_dsrc : 1, -+ guard_interval : 2, -+ encrypt_type : 2, -+ retry_limit : 4, -+ use_dcm_11ax : 1, -+ ltf_subtype_11ax : 2, -+ dyn_bw : 1, -+ bw_mask : 6, -+ host_tx_desc_pool : 1; -+ u32 -+ power : 8, -+ mcs_mask : 12, -+ nss_mask : 8, -+ pream_type : 3, -+ update_peer_cache : 1; -+ u32 -+ chain_mask : 8, -+ key_flags : 8, -+ chanfreq : 16; -+ -+ u32 expire_tsf_lo; -+ u32 expire_tsf_hi; -+ -+ u32 -+ learning_frame : 1, -+ send_as_standalone : 1, -+ is_host_opaque_valid : 1, -+ rsvd0 : 29; -+ u32 -+ host_opaque_cookie : 16, -+ rsvd1 : 16; -+} __packed; -+ - int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab); - int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, - struct sk_buff *skb); -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index bc007d8..eac1f73 100644 ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -2897,6 +2897,9 @@ static int ath11k_install_key(struct ath11k_vif *arvif, - if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) - return 0; - -+ if (key->vlan_id) -+ arg.group_key_idx = key->hw_key_idx; -+ - if (cmd == DISABLE_KEY) { - /* TODO: Check if FW expects value other than NONE for del */ - /* arg.key_cipher = WMI_CIPHER_NONE; */ -@@ -2988,6 +2991,27 @@ static int ath11k_clear_peer_keys(struct ath11k_vif *arvif, - return first_errno; - } - -+static int ath11k_get_vlan_groupkey_index(struct ath11k_vif *arvif, -+ struct ieee80211_key_conf *key) -+{ -+ int map_idx = 0; -+ int free_bit; -+ -+ for (map_idx = 0; map_idx < ATH11K_FREE_GROUP_IDX_MAP_MAX; map_idx++) -+ if (arvif->free_groupidx_map[map_idx] != 0) -+ break; -+ -+ if (map_idx == ATH11K_FREE_GROUP_IDX_MAP_MAX) -+ return -ENOSPC; -+ -+ /* select the first free key index */ -+ free_bit = __ffs64(arvif->free_groupidx_map[map_idx]); -+ key->hw_key_idx = (map_idx * ATH11K_FREE_GROUP_IDX_MAP_BITS) + free_bit; -+ /* clear the selected bit from free index map */ -+ clear_bit(key->hw_key_idx, arvif->free_groupidx_map); -+ return 0; -+} -+ - static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -@@ -3046,6 +3070,36 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - } - } - -+ if (key->vlan_id && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { -+ key->hw_key_idx = arvif->vlan_keyid_map[key->vlan_id]; -+ switch (cmd) { -+ case SET_KEY: -+ /* If the group key idx is already available, -+ * no need to find the free index again. -+ * This happens during GTK rekey. It uses -+ * the same index after rekey also. -+ */ -+ if (!key->hw_key_idx) -+ ret = ath11k_get_vlan_groupkey_index(arvif, key); -+ break; -+ case DISABLE_KEY: -+ /* If the group key idx is already 0, -+ * no need of freeing the index. -+ */ -+ if (key->hw_key_idx) -+ /* make the group index as available */ -+ set_bit(key->hw_key_idx, arvif->free_groupidx_map); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ if (ret) { -+ ath11k_warn(ab, "failed to set group key index for vlan %u : %d\n", -+ key->vlan_id, ret); -+ goto exit; -+ } -+ } -+ - if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) - flags |= WMI_KEY_PAIRWISE; - else -@@ -3074,12 +3128,15 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - peer->mcast_keyidx = key->keyidx; - peer->sec_type_grp = ath11k_dp_tx_get_encrypt_type(key->cipher); - } -+ /* storing group key idx which will be used during rekey */ -+ arvif->vlan_keyid_map[key->vlan_id] = key->hw_key_idx; - } else if (peer && cmd == DISABLE_KEY) { - peer->keys[key->keyidx] = NULL; - if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) - peer->ucast_keyidx = 0; - else - peer->mcast_keyidx = 0; -+ arvif->vlan_keyid_map[key->vlan_id] = 0; - } else if (!peer) - /* impossible unless FW goes crazy */ - ath11k_warn(ab, "peer %pM disappeared!\n", peer_addr); -@@ -5012,6 +5069,18 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, - arvif->vdev_id = bit; - arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; - -+ /* Configure vlan specific parameters */ -+ for (i = 0; i < ATH11K_FREE_GROUP_IDX_MAP_MAX; i++) -+ arvif->free_groupidx_map[i] = 0xFFFFFFFFL; -+ /* Group idx 0 is not valid for VLAN*/ -+ arvif->free_groupidx_map[0] &= ~(1L); -+ -+ arvif->vlan_keyid_map = kzalloc(VLAN_N_VID, GFP_KERNEL); -+ if (!arvif->vlan_keyid_map) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ - switch (vif->type) { - case NL80211_IFTYPE_UNSPECIFIED: - case NL80211_IFTYPE_STATION: -@@ -5244,6 +5313,7 @@ err_vdev_del: - spin_unlock_bh(&ar->data_lock); - - err: -+ kfree(arvif->vlan_keyid_map); - mutex_unlock(&ar->conf_mutex); - - return ret; -@@ -5314,6 +5384,7 @@ err_vdev_del: - list_del(&arvif->list); - spin_unlock_bh(&ar->data_lock); - -+ kfree(arvif->vlan_keyid_map); - ath11k_peer_cleanup(ar, arvif->vdev_id); - - idr_for_each(&ar->txmgmt_idr, -@@ -7108,6 +7179,7 @@ static int __ath11k_mac_register(struct ath11k *ar) - ieee80211_hw_set(ar->hw, SUPPORTS_AMSDU_IN_AMPDU); - ieee80211_hw_set(ar->hw, USES_RSS); - } -+ ieee80211_hw_set(ar->hw, VLAN_CRYPTO_CONTROL); - - ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; - ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; -@@ -7152,6 +7224,7 @@ static int __ath11k_mac_register(struct ath11k *ar) - - wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); - wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_STA_TX_PWR); -+ wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VLAN_OFFLOAD); - - if (test_bit(WMI_TLV_SERVICE_SCAN_PHYMODE_SUPPORT, - ar->ab->wmi_ab.svc_map)) -@@ -7179,6 +7252,9 @@ static int __ath11k_mac_register(struct ath11k *ar) - goto err_free; - } - -+ ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); -+ ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN); -+ - /* Apply the regd received during initialization */ - ret = ath11k_regd_update(ar, true); - if (ret) { -diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c -index e548fce..d1d4d7f 100644 ---- a/drivers/net/wireless/ath/ath11k/wmi.c -+++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1804,6 +1804,7 @@ int ath11k_wmi_vdev_install_key(struct ath11k *ar, - cmd->key_len = arg->key_len; - cmd->key_txmic_len = arg->key_txmic_len; - cmd->key_rxmic_len = arg->key_rxmic_len; -+ cmd->group_key_id = arg->group_key_idx; - - if (arg->key_rsc_counter) - memcpy(&cmd->key_rsc_counter, &arg->key_rsc_counter, -@@ -3465,6 +3466,7 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg, - wmi_cfg->sched_params = tg_cfg->sched_params; - wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count; - wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count; -+ wmi_cfg->max_num_group_keys = tg_cfg->max_num_group_keys; - } - - static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi, -@@ -3697,6 +3699,7 @@ int ath11k_wmi_cmd_init(struct ath11k_base *ab) - config.peer_map_unmap_v2_support = 1; - config.twt_ap_pdev_count = ab->num_radios; - config.twt_ap_sta_count = 1000; -+ config.max_num_group_keys = ATH11K_GROUP_KEYS_NUM_MAX; - - memcpy(&wmi_sc->wlan_resource_config, &config, sizeof(config)); - -diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h -index 9d29ee2..c28fa30 100644 ---- a/drivers/net/wireless/ath/ath11k/wmi.h -+++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -3517,6 +3517,7 @@ struct wmi_vdev_install_key_arg { - u32 vdev_id; - const u8 *macaddr; - u32 key_idx; -+ u32 group_key_idx; - u32 key_flags; - u32 key_cipher; - u32 key_len; -@@ -5223,6 +5224,7 @@ struct target_resource_config { - u32 bpf_instruction_size; - u32 max_bssid_rx_filters; - u32 use_pdev_id; -+ u32 max_num_group_keys; - u32 peer_map_unmap_v2_support; - u32 sched_params; - u32 twt_ap_pdev_count; --- -2.7.4 -