SCS: Add support for optional QoS Charateristics parameters

Per IEEE P802.11be/D4.0, 9.4.2.316 (QoS Characteristics element), enable
support for the following optional QoS Characteristics parameters:
 - Maximum MSDU Size
 - Service Start Time
 - Service Start Time LinkID
 - Mean Data Rate
 - Delayed Bounded Burst Size
 - MSDU Lifetime
 - MSDU Delivery Info
 - Medium Time

Signed-off-by: Purushottam Kushwaha <quic_pkushwah@quicinc.com>
This commit is contained in:
Purushottam Kushwaha 2023-04-18 19:34:19 +05:30 committed by Jouni Malinen
parent 33da386553
commit edfca280cb
4 changed files with 151 additions and 2 deletions

View file

@ -2789,6 +2789,19 @@ enum scs_direction {
#define EHT_QOS_CONTROL_INFO_PRESENCE_MASK_OFFSET 9 #define EHT_QOS_CONTROL_INFO_PRESENCE_MASK_OFFSET 9
#define EHT_QOS_CONTROL_INFO_LINK_ID_OFFSET 25 #define EHT_QOS_CONTROL_INFO_LINK_ID_OFFSET 25
/*
* IEEE P802.11be/D4.0, 9.4.2.316 QoS Characteristics element,
* Presence Bitmap Of Additional Parameters
*/
#define SCS_QOS_BIT_MAX_MSDU_SIZE ((u16) BIT(0))
#define SCS_QOS_BIT_SERVICE_START_TIME ((u16) BIT(1))
#define SCS_QOS_BIT_SERVICE_START_TIME_LINKID ((u16) BIT(2))
#define SCS_QOS_BIT_MEAN_DATA_RATE ((u16) BIT(3))
#define SCS_QOS_BIT_DELAYED_BOUNDED_BURST_SIZE ((u16) BIT(4))
#define SCS_QOS_BIT_MSDU_LIFETIME ((u16) BIT(5))
#define SCS_QOS_BIT_MSDU_DELIVERY_INFO ((u16) BIT(6))
#define SCS_QOS_BIT_MEDIUM_TIME ((u16) BIT(7))
/* Optional subelement IDs for MSCS Descriptor element */ /* Optional subelement IDs for MSCS Descriptor element */
enum mscs_description_subelem { enum mscs_description_subelem {
MCSC_SUBELEM_STATUS = 1, MCSC_SUBELEM_STATUS = 1,

View file

@ -11531,7 +11531,12 @@ static int wpas_ctrl_iface_configure_scs(struct wpa_supplicant *wpa_s,
* [tclas_processing=<0|1>] * [tclas_processing=<0|1>]
* [qos_characteristics] <up/down/direct> [min_si=<decimal number>] * [qos_characteristics] <up/down/direct> [min_si=<decimal number>]
* [max_si=<decimal number>] [min_data_rate=<decimal number>] * [max_si=<decimal number>] [min_data_rate=<decimal number>]
* [delay_bound=<decimal number>] * [delay_bound=<decimal number>] [max_msdu=<decimal number>]
* [service_start_time=<decimal number>]
* [service_start_time_link_id=<decimal number>]
* [mean_data_rate=<decimal number>] [burst_size=<decimal number>]
* [msdu_lifetime=<decimal number>]
* [msdu_delivery_info=<decimal number>] [medium_time=<decimal number>]
* [scs_id=<decimal number>] ... * [scs_id=<decimal number>] ...
*/ */
pos1 = os_strstr(cmd, "scs_id="); pos1 = os_strstr(cmd, "scs_id=");
@ -11545,7 +11550,7 @@ static int wpas_ctrl_iface_configure_scs(struct wpa_supplicant *wpa_s,
while (pos1) { while (pos1) {
struct scs_desc_elem *n1; struct scs_desc_elem *n1;
struct active_scs_elem *active_scs_desc; struct active_scs_elem *active_scs_desc;
char *next_scs_desc; char *next_scs_desc, *pos2;
unsigned int num_tclas_elem = 0; unsigned int num_tclas_elem = 0;
bool scsid_active = false, tclas_present = false; bool scsid_active = false, tclas_present = false;
struct qos_characteristics *qos_elem = &desc_elem.qos_char_elem; struct qos_characteristics *qos_elem = &desc_elem.qos_char_elem;
@ -11752,6 +11757,55 @@ static int wpas_ctrl_iface_configure_scs(struct wpa_supplicant *wpa_s,
goto free_scs_desc; goto free_scs_desc;
} }
pos2 = os_strstr(pos1, "max_msdu=");
if (pos2) {
qos_elem->max_msdu_size = atoi(pos2 + 9);
qos_elem->mask |= SCS_QOS_BIT_MAX_MSDU_SIZE;
}
pos2 = os_strstr(pos1, "service_start_time=");
if (pos2) {
qos_elem->service_start_time = atoi(pos2 + 19);
qos_elem->mask |= SCS_QOS_BIT_SERVICE_START_TIME;
}
pos2 = os_strstr(pos1, "service_start_time_link_id=");
if (pos2) {
qos_elem->service_start_time_link_id = atoi(pos2 + 27);
qos_elem->mask |= SCS_QOS_BIT_SERVICE_START_TIME_LINKID;
}
pos2 = os_strstr(pos1, "mean_data_rate=");
if (pos2) {
qos_elem->mean_data_rate = atoi(pos2 + 15);
qos_elem->mask |= SCS_QOS_BIT_MEAN_DATA_RATE;
}
pos2 = os_strstr(pos1, "burst_size=");
if (pos2) {
qos_elem->burst_size = atoi(pos2 + 11);
qos_elem->mask |=
SCS_QOS_BIT_DELAYED_BOUNDED_BURST_SIZE;
}
pos2 = os_strstr(pos1, "msdu_lifetime=");
if (pos2) {
qos_elem->msdu_lifetime = atoi(pos2 + 14);
qos_elem->mask |= SCS_QOS_BIT_MSDU_LIFETIME;
}
pos2 = os_strstr(pos1, "msdu_delivery_info=");
if (pos2) {
qos_elem->msdu_delivery_info = atoi(pos2 + 19);
qos_elem->mask |= SCS_QOS_BIT_MSDU_DELIVERY_INFO;
}
pos2 = os_strstr(pos1, "medium_time=");
if (pos2) {
qos_elem->medium_time = atoi(pos2 + 12);
qos_elem->mask |= SCS_QOS_BIT_MEDIUM_TIME;
}
scs_desc_end: scs_desc_end:
n1 = os_realloc(scs_data->scs_desc_elems, (num_scs_desc + 1) * n1 = os_realloc(scs_data->scs_desc_elems, (num_scs_desc + 1) *
sizeof(struct scs_desc_elem)); sizeof(struct scs_desc_elem));

View file

@ -190,6 +190,21 @@ skip_tclas_elem:
len1 = wpabuf_put(buf, 1); len1 = wpabuf_put(buf, 1);
wpabuf_put_u8(buf, WLAN_EID_EXT_QOS_CHARACTERISTICS); wpabuf_put_u8(buf, WLAN_EID_EXT_QOS_CHARACTERISTICS);
/* Remove invalid mask bits */
/* Medium Time is applicable only for direct link */
if ((qos_elem->mask & SCS_QOS_BIT_MEDIUM_TIME) &&
qos_elem->direction != SCS_DIRECTION_DIRECT)
qos_elem->mask &= ~SCS_QOS_BIT_MEDIUM_TIME;
/* Service Start Time LinkID is valid only when Service Start
* Time is present.
*/
if ((qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME_LINKID) &&
!(qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME))
qos_elem->mask &=
~SCS_QOS_BIT_SERVICE_START_TIME_LINKID;
/* IEEE P802.11be/D4.0, 9.4.2.316 QoS Characteristics element, /* IEEE P802.11be/D4.0, 9.4.2.316 QoS Characteristics element,
* Figure 9-1001av (Control Info field format) * Figure 9-1001av (Control Info field format)
*/ */
@ -213,6 +228,32 @@ skip_tclas_elem:
/* Delay Bound */ /* Delay Bound */
wpabuf_put_le24(buf, qos_elem->delay_bound); wpabuf_put_le24(buf, qos_elem->delay_bound);
/* Maximum MSDU Size */
if (qos_elem->mask & SCS_QOS_BIT_MAX_MSDU_SIZE)
wpabuf_put_le16(buf, qos_elem->max_msdu_size);
/* Start Service Time */
if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME)
wpabuf_put_le32(buf, qos_elem->service_start_time);
/* Service Start Time LinkID */
if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME_LINKID)
wpabuf_put_u8(buf,
qos_elem->service_start_time_link_id);
/* Mean Data Rate */
if (qos_elem->mask & SCS_QOS_BIT_MEAN_DATA_RATE)
wpabuf_put_le24(buf, qos_elem->mean_data_rate);
/* Delayed Bounded Burst Size */
if (qos_elem->mask & SCS_QOS_BIT_DELAYED_BOUNDED_BURST_SIZE)
wpabuf_put_le32(buf, qos_elem->burst_size);
/* MSDU Lifetime */
if (qos_elem->mask & SCS_QOS_BIT_MSDU_LIFETIME)
wpabuf_put_le16(buf, qos_elem->msdu_lifetime);
/* MSDU Delivery Info */
if (qos_elem->mask & SCS_QOS_BIT_MSDU_DELIVERY_INFO)
wpabuf_put_u8(buf, qos_elem->msdu_delivery_info);
/* Medium Time */
if (qos_elem->mask & SCS_QOS_BIT_MEDIUM_TIME)
wpabuf_put_le16(buf, qos_elem->medium_time);
*len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1; *len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1;
} }
@ -338,6 +379,31 @@ static size_t qos_char_len(const struct qos_characteristics *qos_elem)
3 + /* Minimum Data Rate */ 3 + /* Minimum Data Rate */
3; /* Delay Bound */ 3; /* Delay Bound */
if (qos_elem->mask & SCS_QOS_BIT_MAX_MSDU_SIZE)
buf_len += 2; /* Maximum MSDU Size */
if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME) {
buf_len += 4; /* Service Start Time */
if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME_LINKID)
buf_len++; /* Service Start Time LinkID */
}
if (qos_elem->mask & SCS_QOS_BIT_MEAN_DATA_RATE)
buf_len += 3; /* Mean Data Rate */
if (qos_elem->mask & SCS_QOS_BIT_DELAYED_BOUNDED_BURST_SIZE)
buf_len += 4; /* Delayed Bounded Burst Size */
if (qos_elem->mask & SCS_QOS_BIT_MSDU_LIFETIME)
buf_len += 2; /* MSDU Lifetime */
if (qos_elem->mask & SCS_QOS_BIT_MSDU_DELIVERY_INFO)
buf_len++; /* MSDU Delivery Info */
if (qos_elem->mask & SCS_QOS_BIT_MEDIUM_TIME &&
qos_elem->direction == SCS_DIRECTION_DIRECT)
buf_len += 2; /* Medium Time */
return buf_len; return buf_len;
} }

View file

@ -611,6 +611,22 @@ struct qos_characteristics {
u32 min_data_rate; u32 min_data_rate;
/* Delay Bound */ /* Delay Bound */
u32 delay_bound; u32 delay_bound;
/* Maximum MSDU Size */
u16 max_msdu_size;
/* Service Start Time */
u32 service_start_time;
/* Service Start Time LinkID */
u8 service_start_time_link_id;
/* Mean Data Rate */
u32 mean_data_rate;
/* Delayed Bounded Burst Size */
u32 burst_size;
/* MSDU Lifetime */
u16 msdu_lifetime;
/* MSDU Delivery Info */
u8 msdu_delivery_info;
/* Medium Time */
u16 medium_time;
}; };