+ if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
+ ap = &sdata->u.ap;
+ beacon = rcu_dereference(ap->beacon);
+ if (ap && beacon) {
+ /*
+ * headroom, head length,
+ * tail length and maximum TIM length
+ */
+ skb = dev_alloc_skb(local->tx_headroom +
+ beacon->head_len +
+ beacon->tail_len + 256);
+ if (!skb)
+ goto out;
+
+ skb_reserve(skb, local->tx_headroom);
+ memcpy(skb_put(skb, beacon->head_len), beacon->head,
+ beacon->head_len);
+
+ ieee80211_include_sequence(sdata,
+ (struct ieee80211_hdr *)skb->data);
+
+ /*
+ * Not very nice, but we want to allow the driver to call
+ * ieee80211_beacon_get() as a response to the set_tim()
+ * callback. That, however, is already invoked under the
+ * sta_lock to guarantee consistent and race-free update
+ * of the tim bitmap in mac80211 and the driver.
+ */
+ if (local->tim_in_locked_section) {
+ ieee80211_beacon_add_tim(local, ap, skb, beacon);
+ } else {
+ unsigned long flags;
+
+ spin_lock_irqsave(&local->sta_lock, flags);
+ ieee80211_beacon_add_tim(local, ap, skb, beacon);
+ spin_unlock_irqrestore(&local->sta_lock, flags);
+ }
+
+ if (beacon->tail)
+ memcpy(skb_put(skb, beacon->tail_len),
+ beacon->tail, beacon->tail_len);
+
+ num_beacons = &ap->num_beacons;
+
+ err = false;
+ }
+ } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
+ /* headroom, head length, tail length and maximum TIM length */
+ skb = dev_alloc_skb(local->tx_headroom + 400);
+ if (!skb)
+ goto out;
+
+ skb_reserve(skb, local->hw.extra_tx_headroom);
+ mgmt = (struct ieee80211_mgmt *)
+ skb_put(skb, 24 + sizeof(mgmt->u.beacon));
+ memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
+ mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
+ IEEE80211_STYPE_BEACON);
+ memset(mgmt->da, 0xff, ETH_ALEN);
+ memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
+ /* BSSID is left zeroed, wildcard value */
+ mgmt->u.beacon.beacon_int =
+ cpu_to_le16(local->hw.conf.beacon_int);
+ mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */
+
+ pos = skb_put(skb, 2);
+ *pos++ = WLAN_EID_SSID;
+ *pos++ = 0x0;
+
+ mesh_mgmt_ies_add(skb, sdata->dev);
+
+ num_beacons = &sdata->u.sta.num_beacons;