@@ -1092,6 +1092,7 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
struct cfg80211_mbssid_elems *mbssid = NULL;
struct beacon_data *new, *old;
int new_head_len, new_tail_len;
+ int new_short_head_len, new_short_tail_len;
int size, err;
u32 changed = BSS_CHANGED_BEACON;
struct ieee80211_bss_conf *link_conf = link->conf;
@@ -1108,6 +1109,14 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
else
new_head_len = old->head_len;
+ /* Short head is not a mandatory field */
+ new_short_head_len = 0;
+ if (params->short_head)
+ new_short_head_len = params->short_head_len;
+ else
+ if (old && old->short_head)
+ new_short_head_len = old->short_head_len;
+
/* new or old tail? */
if (params->tail || !old)
/* params->tail_len will be zero for !params->tail */
@@ -1115,7 +1124,14 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
else
new_tail_len = old->tail_len;
- size = sizeof(*new) + new_head_len + new_tail_len;
+ if (params->short_tail || !old)
+ /* params->tail_len will be zero for !params->tail */
+ new_short_tail_len = params->short_tail_len;
+ else
+ new_short_tail_len = old->short_tail_len;
+
+ size = sizeof(*new) + new_head_len + new_tail_len +
+ new_short_head_len + new_short_tail_len;
/* new or old multiple BSSID elements? */
if (params->mbssid_ies) {
@@ -1140,11 +1156,16 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
*/
new->head = ((u8 *) new) + sizeof(*new);
new->tail = new->head + new_head_len;
+ new->short_head = new->tail + new_tail_len;
+ new->short_tail = new->short_head + new_short_head_len;
new->head_len = new_head_len;
new->tail_len = new_tail_len;
+ new->short_head_len = new_short_head_len;
+ new->short_tail_len = new_short_tail_len;
+
/* copy in optional mbssid_ies */
if (mbssid) {
- u8 *pos = new->tail + new->tail_len;
+ u8 *pos = new->short_tail + new->short_tail_len;
new->mbssid_ies = (void *)pos;
pos += struct_size(new->mbssid_ies, elem, mbssid->cnt);
@@ -1170,6 +1191,12 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
else
memcpy(new->head, old->head, new_head_len);
+ if (params->short_head)
+ memcpy(new->short_head, params->short_head, new_short_head_len);
+ else
+ if (old && old->short_head)
+ memcpy(new->short_head, old->short_head, new_short_head_len);
+
/* copy in optional tail */
if (params->tail)
memcpy(new->tail, params->tail, new_tail_len);
@@ -1177,6 +1204,13 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
if (old)
memcpy(new->tail, old->tail, new_tail_len);
+ /* copy in optional short tail */
+ if (params->short_tail)
+ memcpy(new->short_tail, params->short_tail, new_short_tail_len);
+ else
+ if (old)
+ memcpy(new->short_tail, old->short_tail, new_short_tail_len);
+
err = ieee80211_set_probe_resp(sdata, params->probe_resp,
params->probe_resp_len, csa, cca, link);
if (err < 0) {
@@ -264,7 +264,9 @@ struct ieee80211_color_change_settings {
struct beacon_data {
u8 *head, *tail;
+ u8 *short_head, *short_tail;
int head_len, tail_len;
+ int short_head_len, short_tail_len;
struct ieee80211_meshconf_ie *meshconf;
u16 cntdwn_counter_offsets[IEEE80211_MAX_CNTDWN_COUNTERS_NUM];
u8 cntdwn_current_counter;
@@ -5147,7 +5147,11 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
return NULL;
skb_reserve(skb, local->tx_headroom);
- skb_put_data(skb, beacon->head, beacon->head_len);
+
+ if (is_short)
+ skb_put_data(skb, beacon->short_head, beacon->short_head_len);
+ else
+ skb_put_data(skb, beacon->head, beacon->head_len);
ieee80211_beacon_add_tim(sdata, link, &ap->ps, skb, is_template);
@@ -5165,7 +5169,9 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
csa_off_base = skb->len;
}
- if (beacon->tail && !is_short)
+ if (beacon->short_tail && is_short)
+ skb_put_data(skb, beacon->short_tail, beacon->short_tail_len);
+ else if (beacon->tail && !is_short)
skb_put_data(skb, beacon->tail, beacon->tail_len);
if (ieee80211_beacon_protect(skb, local, sdata, link) < 0)