Skip to content

Commit 8b325d2

Browse files
committed
Merge tag 'mac80211-next-for-net-next-2021-08-26' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says: ==================== A few more things: * Use correct DFS domain for self-managed devices * some preparations for transmit power element handling and other 6 GHz regulatory handling * TWT support in AP mode in mac80211 ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 723783d + 90bd5be commit 8b325d2

File tree

11 files changed

+558
-4
lines changed

11 files changed

+558
-4
lines changed

include/linux/ieee80211.h

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,48 @@ struct ieee80211_ext {
10881088
} u;
10891089
} __packed __aligned(2);
10901090

1091+
#define IEEE80211_TWT_CONTROL_NDP BIT(0)
1092+
#define IEEE80211_TWT_CONTROL_RESP_MODE BIT(1)
1093+
#define IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST BIT(3)
1094+
#define IEEE80211_TWT_CONTROL_RX_DISABLED BIT(4)
1095+
#define IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT BIT(5)
1096+
1097+
#define IEEE80211_TWT_REQTYPE_REQUEST BIT(0)
1098+
#define IEEE80211_TWT_REQTYPE_SETUP_CMD GENMASK(3, 1)
1099+
#define IEEE80211_TWT_REQTYPE_TRIGGER BIT(4)
1100+
#define IEEE80211_TWT_REQTYPE_IMPLICIT BIT(5)
1101+
#define IEEE80211_TWT_REQTYPE_FLOWTYPE BIT(6)
1102+
#define IEEE80211_TWT_REQTYPE_FLOWID GENMASK(9, 7)
1103+
#define IEEE80211_TWT_REQTYPE_WAKE_INT_EXP GENMASK(14, 10)
1104+
#define IEEE80211_TWT_REQTYPE_PROTECTION BIT(15)
1105+
1106+
enum ieee80211_twt_setup_cmd {
1107+
TWT_SETUP_CMD_REQUEST,
1108+
TWT_SETUP_CMD_SUGGEST,
1109+
TWT_SETUP_CMD_DEMAND,
1110+
TWT_SETUP_CMD_GROUPING,
1111+
TWT_SETUP_CMD_ACCEPT,
1112+
TWT_SETUP_CMD_ALTERNATE,
1113+
TWT_SETUP_CMD_DICTATE,
1114+
TWT_SETUP_CMD_REJECT,
1115+
};
1116+
1117+
struct ieee80211_twt_params {
1118+
__le16 req_type;
1119+
__le64 twt;
1120+
u8 min_twt_dur;
1121+
__le16 mantissa;
1122+
u8 channel;
1123+
} __packed;
1124+
1125+
struct ieee80211_twt_setup {
1126+
u8 dialog_token;
1127+
u8 element_id;
1128+
u8 length;
1129+
u8 control;
1130+
u8 params[];
1131+
} __packed;
1132+
10911133
struct ieee80211_mgmt {
10921134
__le16 frame_control;
10931135
__le16 duration;
@@ -1252,6 +1294,10 @@ struct ieee80211_mgmt {
12521294
__le16 toa_error;
12531295
u8 variable[0];
12541296
} __packed ftm;
1297+
struct {
1298+
u8 action_code;
1299+
u8 variable[];
1300+
} __packed s1g;
12551301
} u;
12561302
} __packed action;
12571303
} u;
@@ -2266,6 +2312,9 @@ ieee80211_he_ppe_size(u8 ppe_thres_hdr, const u8 *phy_cap_info)
22662312
#define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR 0x40000000
22672313
#define IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED 0x80000000
22682314

2315+
#define IEEE80211_6GHZ_CTRL_REG_LPI_AP 0
2316+
#define IEEE80211_6GHZ_CTRL_REG_SP_AP 1
2317+
22692318
/**
22702319
* ieee80211_he_6ghz_oper - HE 6 GHz operation Information field
22712320
* @primary: primary channel
@@ -2282,12 +2331,51 @@ struct ieee80211_he_6ghz_oper {
22822331
#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ 2
22832332
#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ 3
22842333
#define IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON 0x4
2334+
#define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO 0x38
22852335
u8 control;
22862336
u8 ccfs0;
22872337
u8 ccfs1;
22882338
u8 minrate;
22892339
} __packed;
22902340

2341+
/*
2342+
* In "9.4.2.161 Transmit Power Envelope element" of "IEEE Std 802.11ax-2021",
2343+
* it show four types in "Table 9-275a-Maximum Transmit Power Interpretation
2344+
* subfield encoding", and two category for each type in "Table E-12-Regulatory
2345+
* Info subfield encoding in the United States".
2346+
* So it it totally max 8 Transmit Power Envelope element.
2347+
*/
2348+
#define IEEE80211_TPE_MAX_IE_COUNT 8
2349+
/*
2350+
* In "Table 9-277—Meaning of Maximum Transmit Power Count subfield"
2351+
* of "IEEE Std 802.11ax™‐2021", the max power level is 8.
2352+
*/
2353+
#define IEEE80211_MAX_NUM_PWR_LEVEL 8
2354+
2355+
#define IEEE80211_TPE_MAX_POWER_COUNT 8
2356+
2357+
/* transmit power interpretation type of transmit power envelope element */
2358+
enum ieee80211_tx_power_intrpt_type {
2359+
IEEE80211_TPE_LOCAL_EIRP,
2360+
IEEE80211_TPE_LOCAL_EIRP_PSD,
2361+
IEEE80211_TPE_REG_CLIENT_EIRP,
2362+
IEEE80211_TPE_REG_CLIENT_EIRP_PSD,
2363+
};
2364+
2365+
/**
2366+
* struct ieee80211_tx_pwr_env
2367+
*
2368+
* This structure represents the "Transmit Power Envelope element"
2369+
*/
2370+
struct ieee80211_tx_pwr_env {
2371+
u8 tx_power_info;
2372+
s8 tx_power[IEEE80211_TPE_MAX_POWER_COUNT];
2373+
} __packed;
2374+
2375+
#define IEEE80211_TX_PWR_ENV_INFO_COUNT 0x7
2376+
#define IEEE80211_TX_PWR_ENV_INFO_INTERPRET 0x38
2377+
#define IEEE80211_TX_PWR_ENV_INFO_CATEGORY 0xC0
2378+
22912379
/*
22922380
* ieee80211_he_oper_size - calculate 802.11ax HE Operations IE size
22932381
* @he_oper_ie: byte data of the He Operations IE, stating from the byte
@@ -2869,7 +2957,7 @@ enum ieee80211_eid {
28692957
WLAN_EID_VHT_OPERATION = 192,
28702958
WLAN_EID_EXTENDED_BSS_LOAD = 193,
28712959
WLAN_EID_WIDE_BW_CHANNEL_SWITCH = 194,
2872-
WLAN_EID_VHT_TX_POWER_ENVELOPE = 195,
2960+
WLAN_EID_TX_POWER_ENVELOPE = 195,
28732961
WLAN_EID_CHANNEL_SWITCH_WRAPPER = 196,
28742962
WLAN_EID_AID = 197,
28752963
WLAN_EID_QUIET_CHANNEL = 198,
@@ -2881,6 +2969,7 @@ enum ieee80211_eid {
28812969
WLAN_EID_AID_RESPONSE = 211,
28822970
WLAN_EID_S1G_BCN_COMPAT = 213,
28832971
WLAN_EID_S1G_SHORT_BCN_INTERVAL = 214,
2972+
WLAN_EID_S1G_TWT = 216,
28842973
WLAN_EID_S1G_CAPABILITIES = 217,
28852974
WLAN_EID_VENDOR_SPECIFIC = 221,
28862975
WLAN_EID_QOS_PARAMETER = 222,
@@ -2950,6 +3039,7 @@ enum ieee80211_category {
29503039
WLAN_CATEGORY_FST = 18,
29513040
WLAN_CATEGORY_UNPROT_DMG = 20,
29523041
WLAN_CATEGORY_VHT = 21,
3042+
WLAN_CATEGORY_S1G = 22,
29533043
WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
29543044
WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
29553045
};
@@ -3023,6 +3113,20 @@ enum ieee80211_key_len {
30233113
WLAN_KEY_LEN_BIP_GMAC_256 = 32,
30243114
};
30253115

3116+
enum ieee80211_s1g_actioncode {
3117+
WLAN_S1G_AID_SWITCH_REQUEST,
3118+
WLAN_S1G_AID_SWITCH_RESPONSE,
3119+
WLAN_S1G_SYNC_CONTROL,
3120+
WLAN_S1G_STA_INFO_ANNOUNCE,
3121+
WLAN_S1G_EDCA_PARAM_SET,
3122+
WLAN_S1G_EL_OPERATION,
3123+
WLAN_S1G_TWT_SETUP,
3124+
WLAN_S1G_TWT_TEARDOWN,
3125+
WLAN_S1G_SECT_GROUP_ID_LIST,
3126+
WLAN_S1G_SECT_ID_FEEDBACK,
3127+
WLAN_S1G_TWT_INFORMATION = 11,
3128+
};
3129+
30263130
#define IEEE80211_WEP_IV_LEN 4
30273131
#define IEEE80211_WEP_ICV_LEN 4
30283132
#define IEEE80211_CCMP_HDR_LEN 8

include/net/mac80211.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3926,6 +3926,13 @@ struct ieee80211_prep_tx_info {
39263926
* @set_sar_specs: Update the SAR (TX power) settings.
39273927
* @sta_set_decap_offload: Called to notify the driver when a station is allowed
39283928
* to use rx decapsulation offload
3929+
* @add_twt_setup: Update hw with TWT agreement parameters received from the peer.
3930+
* This callback allows the hw to check if requested parameters
3931+
* are supported and if there is enough room for a new agreement.
3932+
* The hw is expected to set agreement result in the req_type field of
3933+
* twt structure.
3934+
* @twt_teardown_request: Update the hw with TWT teardown request received
3935+
* from the peer.
39293936
*/
39303937
struct ieee80211_ops {
39313938
void (*tx)(struct ieee80211_hw *hw,
@@ -4249,6 +4256,11 @@ struct ieee80211_ops {
42494256
void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
42504257
struct ieee80211_vif *vif,
42514258
struct ieee80211_sta *sta, bool enabled);
4259+
void (*add_twt_setup)(struct ieee80211_hw *hw,
4260+
struct ieee80211_sta *sta,
4261+
struct ieee80211_twt_setup *twt);
4262+
void (*twt_teardown_request)(struct ieee80211_hw *hw,
4263+
struct ieee80211_sta *sta, u8 flowid);
42524264
};
42534265

42544266
/**

net/mac80211/driver-ops.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,4 +1447,40 @@ static inline void drv_sta_set_decap_offload(struct ieee80211_local *local,
14471447
trace_drv_return_void(local);
14481448
}
14491449

1450+
static inline void drv_add_twt_setup(struct ieee80211_local *local,
1451+
struct ieee80211_sub_if_data *sdata,
1452+
struct ieee80211_sta *sta,
1453+
struct ieee80211_twt_setup *twt)
1454+
{
1455+
struct ieee80211_twt_params *twt_agrt;
1456+
1457+
might_sleep();
1458+
1459+
if (!check_sdata_in_driver(sdata))
1460+
return;
1461+
1462+
twt_agrt = (void *)twt->params;
1463+
1464+
trace_drv_add_twt_setup(local, sta, twt, twt_agrt);
1465+
local->ops->add_twt_setup(&local->hw, sta, twt);
1466+
trace_drv_return_void(local);
1467+
}
1468+
1469+
static inline void drv_twt_teardown_request(struct ieee80211_local *local,
1470+
struct ieee80211_sub_if_data *sdata,
1471+
struct ieee80211_sta *sta,
1472+
u8 flowid)
1473+
{
1474+
might_sleep();
1475+
if (!check_sdata_in_driver(sdata))
1476+
return;
1477+
1478+
if (!local->ops->twt_teardown_request)
1479+
return;
1480+
1481+
trace_drv_twt_teardown_request(local, sta, flowid);
1482+
local->ops->twt_teardown_request(&local->hw, sta, flowid);
1483+
trace_drv_return_void(local);
1484+
}
1485+
14501486
#endif /* __MAC80211_DRIVER_OPS */

net/mac80211/ieee80211_i.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,7 @@ struct ieee80211_sub_if_data {
946946

947947
struct work_struct work;
948948
struct sk_buff_head skb_queue;
949+
struct sk_buff_head status_queue;
949950

950951
u8 needed_rx_chains;
951952
enum ieee80211_smps_mode smps_mode;
@@ -1533,6 +1534,7 @@ struct ieee802_11_elems {
15331534
const struct ieee80211_he_spr *he_spr;
15341535
const struct ieee80211_mu_edca_param_set *mu_edca_param_set;
15351536
const struct ieee80211_he_6ghz_capa *he_6ghz_capa;
1537+
const struct ieee80211_tx_pwr_env *tx_pwr_env[IEEE80211_TPE_MAX_IE_COUNT];
15361538
const u8 *uora_element;
15371539
const u8 *mesh_id;
15381540
const u8 *peering;
@@ -1583,6 +1585,8 @@ struct ieee802_11_elems {
15831585
u8 perr_len;
15841586
u8 country_elem_len;
15851587
u8 bssid_index_len;
1588+
u8 tx_pwr_env_len[IEEE80211_TPE_MAX_IE_COUNT];
1589+
u8 tx_pwr_env_num;
15861590

15871591
/* whether a parse error occurred while retrieving these elements */
15881592
bool parse_error;
@@ -2080,6 +2084,11 @@ ieee80211_he_op_ie_to_bss_conf(struct ieee80211_vif *vif,
20802084

20812085
/* S1G */
20822086
void ieee80211_s1g_sta_rate_init(struct sta_info *sta);
2087+
bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb);
2088+
void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
2089+
struct sk_buff *skb);
2090+
void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
2091+
struct sk_buff *skb);
20832092

20842093
/* Spectrum management */
20852094
void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,

net/mac80211/iface.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
552552
*/
553553
ieee80211_free_keys(sdata, true);
554554
skb_queue_purge(&sdata->skb_queue);
555+
skb_queue_purge(&sdata->status_queue);
555556
}
556557

557558
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
@@ -984,6 +985,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
984985
}
985986

986987
skb_queue_head_init(&sdata->skb_queue);
988+
skb_queue_head_init(&sdata->status_queue);
987989
INIT_WORK(&sdata->work, ieee80211_iface_work);
988990

989991
return 0;
@@ -1382,6 +1384,16 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
13821384
WARN_ON(1);
13831385
break;
13841386
}
1387+
} else if (ieee80211_is_action(mgmt->frame_control) &&
1388+
mgmt->u.action.category == WLAN_CATEGORY_S1G) {
1389+
switch (mgmt->u.action.u.s1g.action_code) {
1390+
case WLAN_S1G_TWT_TEARDOWN:
1391+
case WLAN_S1G_TWT_SETUP:
1392+
ieee80211_s1g_rx_twt_action(sdata, skb);
1393+
break;
1394+
default:
1395+
break;
1396+
}
13851397
} else if (ieee80211_is_ext(mgmt->frame_control)) {
13861398
if (sdata->vif.type == NL80211_IFTYPE_STATION)
13871399
ieee80211_sta_rx_queued_ext(sdata, skb);
@@ -1437,6 +1449,24 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
14371449
}
14381450
}
14391451

1452+
static void ieee80211_iface_process_status(struct ieee80211_sub_if_data *sdata,
1453+
struct sk_buff *skb)
1454+
{
1455+
struct ieee80211_mgmt *mgmt = (void *)skb->data;
1456+
1457+
if (ieee80211_is_action(mgmt->frame_control) &&
1458+
mgmt->u.action.category == WLAN_CATEGORY_S1G) {
1459+
switch (mgmt->u.action.u.s1g.action_code) {
1460+
case WLAN_S1G_TWT_TEARDOWN:
1461+
case WLAN_S1G_TWT_SETUP:
1462+
ieee80211_s1g_status_twt_action(sdata, skb);
1463+
break;
1464+
default:
1465+
break;
1466+
}
1467+
}
1468+
}
1469+
14401470
static void ieee80211_iface_work(struct work_struct *work)
14411471
{
14421472
struct ieee80211_sub_if_data *sdata =
@@ -1466,6 +1496,16 @@ static void ieee80211_iface_work(struct work_struct *work)
14661496
kcov_remote_stop();
14671497
}
14681498

1499+
/* process status queue */
1500+
while ((skb = skb_dequeue(&sdata->status_queue))) {
1501+
kcov_remote_start_common(skb_get_kcov_handle(skb));
1502+
1503+
ieee80211_iface_process_status(sdata, skb);
1504+
kfree_skb(skb);
1505+
1506+
kcov_remote_stop();
1507+
}
1508+
14691509
/* then other type-dependent work */
14701510
switch (sdata->vif.type) {
14711511
case NL80211_IFTYPE_STATION:
@@ -1529,6 +1569,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
15291569
}
15301570

15311571
skb_queue_head_init(&sdata->skb_queue);
1572+
skb_queue_head_init(&sdata->status_queue);
15321573
INIT_WORK(&sdata->work, ieee80211_iface_work);
15331574
INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
15341575
INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);

0 commit comments

Comments
 (0)