#define EHT_QOS_CONTROL_INFO_PRESENCE_MASK_OFFSET 9
#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 */
enum mscs_description_subelem {
MCSC_SUBELEM_STATUS = 1,
* [tclas_processing=<0|1>]
* [qos_characteristics] <up/down/direct> [min_si=<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>] ...
*/
pos1 = os_strstr(cmd, "scs_id=");
while (pos1) {
struct scs_desc_elem *n1;
struct active_scs_elem *active_scs_desc;
- char *next_scs_desc;
+ char *next_scs_desc, *pos2;
unsigned int num_tclas_elem = 0;
bool scsid_active = false, tclas_present = false;
struct qos_characteristics *qos_elem = &desc_elem.qos_char_elem;
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:
n1 = os_realloc(scs_data->scs_desc_elems, (num_scs_desc + 1) *
sizeof(struct scs_desc_elem));
len1 = wpabuf_put(buf, 1);
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,
* Figure 9-1001av (Control Info field format)
*/
/* 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;
}
3 + /* Minimum Data Rate */
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;
}
u32 min_data_rate;
/* 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;
};