312-mac80211-split-beacon-retrieval-functions.patch 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. From: Aloka Dixit <[email protected]>
  2. Date: Tue, 5 Oct 2021 21:09:36 -0700
  3. Subject: [PATCH] mac80211: split beacon retrieval functions
  4. Split __ieee80211_beacon_get() into a separate function for AP mode
  5. ieee80211_beacon_get_ap().
  6. Also, move the code common to all modes (AP, adhoc and mesh) to
  7. a separate function ieee80211_beacon_get_finish().
  8. Signed-off-by: Aloka Dixit <[email protected]>
  9. Link: https://lore.kernel.org/r/[email protected]
  10. Signed-off-by: Johannes Berg <[email protected]>
  11. ---
  12. --- a/net/mac80211/tx.c
  13. +++ b/net/mac80211/tx.c
  14. @@ -4988,6 +4988,115 @@ static int ieee80211_beacon_protect(stru
  15. return 0;
  16. }
  17. +static void
  18. +ieee80211_beacon_get_finish(struct ieee80211_hw *hw,
  19. + struct ieee80211_vif *vif,
  20. + struct ieee80211_mutable_offsets *offs,
  21. + struct beacon_data *beacon,
  22. + struct sk_buff *skb,
  23. + struct ieee80211_chanctx_conf *chanctx_conf,
  24. + u16 csa_off_base)
  25. +{
  26. + struct ieee80211_local *local = hw_to_local(hw);
  27. + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
  28. + struct ieee80211_tx_info *info;
  29. + enum nl80211_band band;
  30. + struct ieee80211_tx_rate_control txrc;
  31. +
  32. + /* CSA offsets */
  33. + if (offs && beacon) {
  34. + u16 i;
  35. +
  36. + for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; i++) {
  37. + u16 csa_off = beacon->cntdwn_counter_offsets[i];
  38. +
  39. + if (!csa_off)
  40. + continue;
  41. +
  42. + offs->cntdwn_counter_offs[i] = csa_off_base + csa_off;
  43. + }
  44. + }
  45. +
  46. + band = chanctx_conf->def.chan->band;
  47. + info = IEEE80211_SKB_CB(skb);
  48. + info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
  49. + info->flags |= IEEE80211_TX_CTL_NO_ACK;
  50. + info->band = band;
  51. +
  52. + memset(&txrc, 0, sizeof(txrc));
  53. + txrc.hw = hw;
  54. + txrc.sband = local->hw.wiphy->bands[band];
  55. + txrc.bss_conf = &sdata->vif.bss_conf;
  56. + txrc.skb = skb;
  57. + txrc.reported_rate.idx = -1;
  58. + if (sdata->beacon_rate_set && sdata->beacon_rateidx_mask[band])
  59. + txrc.rate_idx_mask = sdata->beacon_rateidx_mask[band];
  60. + else
  61. + txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];
  62. + txrc.bss = true;
  63. + rate_control_get_rate(sdata, NULL, &txrc);
  64. +
  65. + info->control.vif = vif;
  66. + info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT |
  67. + IEEE80211_TX_CTL_ASSIGN_SEQ |
  68. + IEEE80211_TX_CTL_FIRST_FRAGMENT;
  69. +}
  70. +
  71. +static struct sk_buff *
  72. +ieee80211_beacon_get_ap(struct ieee80211_hw *hw,
  73. + struct ieee80211_vif *vif,
  74. + struct ieee80211_mutable_offsets *offs,
  75. + bool is_template,
  76. + struct beacon_data *beacon,
  77. + struct ieee80211_chanctx_conf *chanctx_conf)
  78. +{
  79. + struct ieee80211_local *local = hw_to_local(hw);
  80. + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
  81. + struct ieee80211_if_ap *ap = &sdata->u.ap;
  82. + struct sk_buff *skb = NULL;
  83. + u16 csa_off_base = 0;
  84. +
  85. + if (beacon->cntdwn_counter_offsets[0]) {
  86. + if (!is_template)
  87. + ieee80211_beacon_update_cntdwn(vif);
  88. +
  89. + ieee80211_set_beacon_cntdwn(sdata, beacon);
  90. + }
  91. +
  92. + /* headroom, head length,
  93. + * tail length and maximum TIM length
  94. + */
  95. + skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
  96. + beacon->tail_len + 256 +
  97. + local->hw.extra_beacon_tailroom);
  98. + if (!skb)
  99. + return NULL;
  100. +
  101. + skb_reserve(skb, local->tx_headroom);
  102. + skb_put_data(skb, beacon->head, beacon->head_len);
  103. +
  104. + ieee80211_beacon_add_tim(sdata, &ap->ps, skb, is_template);
  105. +
  106. + if (offs) {
  107. + offs->tim_offset = beacon->head_len;
  108. + offs->tim_length = skb->len - beacon->head_len;
  109. + offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
  110. +
  111. + /* for AP the csa offsets are from tail */
  112. + csa_off_base = skb->len;
  113. + }
  114. +
  115. + if (beacon->tail)
  116. + skb_put_data(skb, beacon->tail, beacon->tail_len);
  117. +
  118. + if (ieee80211_beacon_protect(skb, local, sdata) < 0)
  119. + return NULL;
  120. +
  121. + ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb, chanctx_conf,
  122. + csa_off_base);
  123. + return skb;
  124. +}
  125. +
  126. static struct sk_buff *
  127. __ieee80211_beacon_get(struct ieee80211_hw *hw,
  128. struct ieee80211_vif *vif,
  129. @@ -4997,12 +5106,8 @@ __ieee80211_beacon_get(struct ieee80211_
  130. struct ieee80211_local *local = hw_to_local(hw);
  131. struct beacon_data *beacon = NULL;
  132. struct sk_buff *skb = NULL;
  133. - struct ieee80211_tx_info *info;
  134. struct ieee80211_sub_if_data *sdata = NULL;
  135. - enum nl80211_band band;
  136. - struct ieee80211_tx_rate_control txrc;
  137. struct ieee80211_chanctx_conf *chanctx_conf;
  138. - int csa_off_base = 0;
  139. rcu_read_lock();
  140. @@ -5019,48 +5124,11 @@ __ieee80211_beacon_get(struct ieee80211_
  141. struct ieee80211_if_ap *ap = &sdata->u.ap;
  142. beacon = rcu_dereference(ap->beacon);
  143. - if (beacon) {
  144. - if (beacon->cntdwn_counter_offsets[0]) {
  145. - if (!is_template)
  146. - ieee80211_beacon_update_cntdwn(vif);
  147. -
  148. - ieee80211_set_beacon_cntdwn(sdata, beacon);
  149. - }
  150. -
  151. - /*
  152. - * headroom, head length,
  153. - * tail length and maximum TIM length
  154. - */
  155. - skb = dev_alloc_skb(local->tx_headroom +
  156. - beacon->head_len +
  157. - beacon->tail_len + 256 +
  158. - local->hw.extra_beacon_tailroom);
  159. - if (!skb)
  160. - goto out;
  161. -
  162. - skb_reserve(skb, local->tx_headroom);
  163. - skb_put_data(skb, beacon->head, beacon->head_len);
  164. -
  165. - ieee80211_beacon_add_tim(sdata, &ap->ps, skb,
  166. - is_template);
  167. -
  168. - if (offs) {
  169. - offs->tim_offset = beacon->head_len;
  170. - offs->tim_length = skb->len - beacon->head_len;
  171. - offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
  172. -
  173. - /* for AP the csa offsets are from tail */
  174. - csa_off_base = skb->len;
  175. - }
  176. -
  177. - if (beacon->tail)
  178. - skb_put_data(skb, beacon->tail,
  179. - beacon->tail_len);
  180. -
  181. - if (ieee80211_beacon_protect(skb, local, sdata) < 0)
  182. - goto out;
  183. - } else
  184. + if (!beacon)
  185. goto out;
  186. +
  187. + skb = ieee80211_beacon_get_ap(hw, vif, offs, is_template,
  188. + beacon, chanctx_conf);
  189. } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
  190. struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
  191. struct ieee80211_hdr *hdr;
  192. @@ -5086,6 +5154,9 @@ __ieee80211_beacon_get(struct ieee80211_
  193. hdr = (struct ieee80211_hdr *) skb->data;
  194. hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
  195. IEEE80211_STYPE_BEACON);
  196. +
  197. + ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb,
  198. + chanctx_conf, 0);
  199. } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
  200. struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
  201. @@ -5125,51 +5196,13 @@ __ieee80211_beacon_get(struct ieee80211_
  202. }
  203. skb_put_data(skb, beacon->tail, beacon->tail_len);
  204. + ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb,
  205. + chanctx_conf, 0);
  206. } else {
  207. WARN_ON(1);
  208. goto out;
  209. }
  210. - /* CSA offsets */
  211. - if (offs && beacon) {
  212. - int i;
  213. -
  214. - for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; i++) {
  215. - u16 csa_off = beacon->cntdwn_counter_offsets[i];
  216. -
  217. - if (!csa_off)
  218. - continue;
  219. -
  220. - offs->cntdwn_counter_offs[i] = csa_off_base + csa_off;
  221. - }
  222. - }
  223. -
  224. - band = chanctx_conf->def.chan->band;
  225. -
  226. - info = IEEE80211_SKB_CB(skb);
  227. -
  228. - info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
  229. - info->flags |= IEEE80211_TX_CTL_NO_ACK;
  230. - info->band = band;
  231. -
  232. - memset(&txrc, 0, sizeof(txrc));
  233. - txrc.hw = hw;
  234. - txrc.sband = local->hw.wiphy->bands[band];
  235. - txrc.bss_conf = &sdata->vif.bss_conf;
  236. - txrc.skb = skb;
  237. - txrc.reported_rate.idx = -1;
  238. - if (sdata->beacon_rate_set && sdata->beacon_rateidx_mask[band])
  239. - txrc.rate_idx_mask = sdata->beacon_rateidx_mask[band];
  240. - else
  241. - txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];
  242. - txrc.bss = true;
  243. - rate_control_get_rate(sdata, NULL, &txrc);
  244. -
  245. - info->control.vif = vif;
  246. -
  247. - info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT |
  248. - IEEE80211_TX_CTL_ASSIGN_SEQ |
  249. - IEEE80211_TX_CTL_FIRST_FRAGMENT;
  250. out:
  251. rcu_read_unlock();
  252. return skb;