Skip to content

Commit 6aea26c

Browse files
nbd168jmberg-intel
authored andcommitted
mac80211: rework tx encapsulation offload API
The current API (which lets the driver turn on/off per vif directly) has a number of limitations: - it does not deal with AP_VLAN - conditions for enabling (no tkip, no monitor) are only checked at add_interface time - no way to indicate 4-addr support In order to address this, store offload flags in struct ieee80211_vif (easy to extend for decap offload later). mac80211 initially sets the enable flag, but gives the driver a chance to modify it before its settings are applied. In addition to the .add_interface op, a .update_vif_offload op is introduced, which can be used for runtime changes. If a driver can't disable encap offload at runtime, or if it has some extra limitations, it can simply override the flags within those ops. Support for encap offload with 4-address mode interfaces can be enabled by setting a flag from .add_interface or .update_vif_offload. Signed-off-by: Felix Fietkau <[email protected]> Link: https://lore.kernel.org/r/[email protected] [resolved conflict with commit aa2092a ("ath11k: add raw mode and software crypto support")] Signed-off-by: Johannes Berg <[email protected]>
1 parent ae04515 commit 6aea26c

File tree

9 files changed

+219
-114
lines changed

9 files changed

+219
-114
lines changed

drivers/net/wireless/ath/ath11k/mac.c

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4349,6 +4349,37 @@ static int ath11k_set_he_mu_sounding_mode(struct ath11k *ar,
43494349
return ret;
43504350
}
43514351

4352+
static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw,
4353+
struct ieee80211_vif *vif)
4354+
{
4355+
struct ath11k *ar = hw->priv;
4356+
struct ath11k_base *ab = ar->ab;
4357+
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
4358+
u32 param_id, param_value;
4359+
int ret;
4360+
4361+
param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
4362+
if (ath11k_frame_mode != ATH11K_HW_TXRX_ETHERNET ||
4363+
(vif->type != NL80211_IFTYPE_STATION &&
4364+
vif->type != NL80211_IFTYPE_AP))
4365+
vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
4366+
4367+
if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
4368+
param_value = ATH11K_HW_TXRX_ETHERNET;
4369+
else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
4370+
param_value = ATH11K_HW_TXRX_RAW;
4371+
else
4372+
param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
4373+
4374+
ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
4375+
param_id, param_value);
4376+
if (ret) {
4377+
ath11k_warn(ab, "failed to set vdev %d tx encap mode: %d\n",
4378+
arvif->vdev_id, ret);
4379+
vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
4380+
}
4381+
}
4382+
43524383
static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
43534384
struct ieee80211_vif *vif)
43544385
{
@@ -4358,7 +4389,6 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
43584389
struct vdev_create_params vdev_param = {0};
43594390
struct peer_create_params peer_param;
43604391
u32 param_id, param_value;
4361-
int hw_encap = 0;
43624392
u16 nss;
43634393
int i;
43644394
int ret;
@@ -4452,32 +4482,7 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
44524482
list_add(&arvif->list, &ar->arvifs);
44534483
spin_unlock_bh(&ar->data_lock);
44544484

4455-
param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
4456-
if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET)
4457-
switch (vif->type) {
4458-
case NL80211_IFTYPE_STATION:
4459-
case NL80211_IFTYPE_AP_VLAN:
4460-
case NL80211_IFTYPE_AP:
4461-
hw_encap = 1;
4462-
break;
4463-
default:
4464-
break;
4465-
}
4466-
4467-
if (ieee80211_set_hw_80211_encap(vif, hw_encap))
4468-
param_value = ATH11K_HW_TXRX_ETHERNET;
4469-
else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
4470-
param_value = ATH11K_HW_TXRX_RAW;
4471-
else
4472-
param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
4473-
4474-
ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
4475-
param_id, param_value);
4476-
if (ret) {
4477-
ath11k_warn(ab, "failed to set vdev %d tx encap mode: %d\n",
4478-
arvif->vdev_id, ret);
4479-
goto err_vdev_del;
4480-
}
4485+
ath11k_mac_op_update_vif_offload(hw, vif);
44814486

44824487
nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1;
44834488
ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
@@ -5840,6 +5845,7 @@ static const struct ieee80211_ops ath11k_ops = {
58405845
.reconfig_complete = ath11k_mac_op_reconfig_complete,
58415846
.add_interface = ath11k_mac_op_add_interface,
58425847
.remove_interface = ath11k_mac_op_remove_interface,
5848+
.update_vif_offload = ath11k_mac_op_update_vif_offload,
58435849
.config = ath11k_mac_op_config,
58445850
.bss_info_changed = ath11k_mac_op_bss_info_changed,
58455851
.configure_filter = ath11k_mac_op_configure_filter,
@@ -6148,6 +6154,7 @@ static int __ath11k_mac_register(struct ath11k *ar)
61486154
ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
61496155
ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
61506156
ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
6157+
ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
61516158
if (ht_cap & WMI_HT_CAP_ENABLED) {
61526159
ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
61536160
ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);

include/net/mac80211.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,6 +1606,21 @@ enum ieee80211_vif_flags {
16061606
IEEE80211_VIF_GET_NOA_UPDATE = BIT(3),
16071607
};
16081608

1609+
1610+
/**
1611+
* enum ieee80211_offload_flags - virtual interface offload flags
1612+
*
1613+
* @IEEE80211_OFFLOAD_ENCAP_ENABLED: tx encapsulation offload is enabled
1614+
* The driver supports sending frames passed as 802.3 frames by mac80211.
1615+
* It must also support sending 802.11 packets for the same interface.
1616+
* @IEEE80211_OFFLOAD_ENCAP_4ADDR: support 4-address mode encapsulation offload
1617+
*/
1618+
1619+
enum ieee80211_offload_flags {
1620+
IEEE80211_OFFLOAD_ENCAP_ENABLED = BIT(0),
1621+
IEEE80211_OFFLOAD_ENCAP_4ADDR = BIT(1),
1622+
};
1623+
16091624
/**
16101625
* struct ieee80211_vif - per-interface data
16111626
*
@@ -1626,6 +1641,11 @@ enum ieee80211_vif_flags {
16261641
* these need to be set (or cleared) when the interface is added
16271642
* or, if supported by the driver, the interface type is changed
16281643
* at runtime, mac80211 will never touch this field
1644+
* @offloaad_flags: hardware offload capabilities/flags for this interface.
1645+
* These are initialized by mac80211 before calling .add_interface,
1646+
* .change_interface or .update_vif_offload and updated by the driver
1647+
* within these ops, based on supported features or runtime change
1648+
* restrictions.
16291649
* @hw_queue: hardware queue for each AC
16301650
* @cab_queue: content-after-beacon (DTIM beacon really) queue, AP mode only
16311651
* @chanctx_conf: The channel context this interface is assigned to, or %NULL
@@ -1662,6 +1682,7 @@ struct ieee80211_vif {
16621682
struct ieee80211_chanctx_conf __rcu *chanctx_conf;
16631683

16641684
u32 driver_flags;
1685+
u32 offload_flags;
16651686

16661687
#ifdef CONFIG_MAC80211_DEBUGFS
16671688
struct dentry *debugfs_dir;
@@ -2328,6 +2349,9 @@ struct ieee80211_txq {
23282349
* aggregating MPDUs with the same keyid, allowing mac80211 to keep Tx
23292350
* A-MPDU sessions active while rekeying with Extended Key ID.
23302351
*
2352+
* @IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD: Hardware supports tx encapsulation
2353+
* offload
2354+
*
23312355
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
23322356
*/
23332357
enum ieee80211_hw_flags {
@@ -2380,6 +2404,7 @@ enum ieee80211_hw_flags {
23802404
IEEE80211_HW_SUPPORTS_MULTI_BSSID,
23812405
IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
23822406
IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT,
2407+
IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
23832408

23842409
/* keep last, obviously */
23852410
NUM_IEEE80211_HW_FLAGS
@@ -3814,6 +3839,8 @@ enum ieee80211_reconfig_type {
38143839
* @set_tid_config: Apply TID specific configurations. This callback may sleep.
38153840
* @reset_tid_config: Reset TID specific configuration for the peer.
38163841
* This callback may sleep.
3842+
* @update_vif_config: Update virtual interface offload flags
3843+
* This callback may sleep.
38173844
*/
38183845
struct ieee80211_ops {
38193846
void (*tx)(struct ieee80211_hw *hw,
@@ -4125,6 +4152,8 @@ struct ieee80211_ops {
41254152
int (*reset_tid_config)(struct ieee80211_hw *hw,
41264153
struct ieee80211_vif *vif,
41274154
struct ieee80211_sta *sta, u8 tids);
4155+
void (*update_vif_offload)(struct ieee80211_hw *hw,
4156+
struct ieee80211_vif *vif);
41284157
};
41294158

41304159
/**

net/mac80211/debugfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ static const char *hw_flag_names[] = {
408408
FLAG(SUPPORTS_MULTI_BSSID),
409409
FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
410410
FLAG(AMPDU_KEYBORDER_SUPPORT),
411+
FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
411412
#undef FLAG
412413
};
413414

net/mac80211/driver-ops.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,4 +1384,19 @@ static inline int drv_reset_tid_config(struct ieee80211_local *local,
13841384

13851385
return ret;
13861386
}
1387+
1388+
static inline void drv_update_vif_offload(struct ieee80211_local *local,
1389+
struct ieee80211_sub_if_data *sdata)
1390+
{
1391+
might_sleep();
1392+
check_sdata_in_driver(sdata);
1393+
1394+
if (!local->ops->update_vif_offload)
1395+
return;
1396+
1397+
trace_drv_update_vif_offload(local, sdata);
1398+
local->ops->update_vif_offload(&local->hw, &sdata->vif);
1399+
trace_drv_return_void(local);
1400+
}
1401+
13871402
#endif /* __MAC80211_DRIVER_OPS */

net/mac80211/ieee80211_i.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -989,8 +989,6 @@ struct ieee80211_sub_if_data {
989989
} debugfs;
990990
#endif
991991

992-
bool hw_80211_encap;
993-
994992
/* must be last, dynamically sized area in this! */
995993
struct ieee80211_vif vif;
996994
};
@@ -1767,6 +1765,7 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
17671765
bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
17681766
void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
17691767
bool update_bss);
1768+
void ieee80211_recalc_offload(struct ieee80211_local *local);
17701769

17711770
static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
17721771
{

0 commit comments

Comments
 (0)