wme.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright 2004, Instant802 Networks, Inc.
  4. * Copyright 2013-2014 Intel Mobile Communications GmbH
  5. * Copyright (C) 2022 Intel Corporation
  6. */
  7. #include <linux/netdevice.h>
  8. #include <linux/skbuff.h>
  9. #include <linux/module.h>
  10. #include <linux/if_arp.h>
  11. #include <linux/types.h>
  12. #include <net/ip.h>
  13. #include <net/pkt_sched.h>
  14. #include <net/mac80211.h>
  15. #include "ieee80211_i.h"
  16. #include "wme.h"
  17. /* Default mapping in classifier to work with default
  18. * queue setup.
  19. */
  20. const int ieee802_1d_to_ac[8] = {
  21. IEEE80211_AC_BE,
  22. IEEE80211_AC_BK,
  23. IEEE80211_AC_BK,
  24. IEEE80211_AC_BE,
  25. IEEE80211_AC_VI,
  26. IEEE80211_AC_VI,
  27. IEEE80211_AC_VO,
  28. IEEE80211_AC_VO
  29. };
  30. static int wme_downgrade_ac(struct sk_buff *skb)
  31. {
  32. switch (skb->priority) {
  33. case 6:
  34. case 7:
  35. skb->priority = 5; /* VO -> VI */
  36. return 0;
  37. case 4:
  38. case 5:
  39. skb->priority = 3; /* VI -> BE */
  40. return 0;
  41. case 0:
  42. case 3:
  43. skb->priority = 2; /* BE -> BK */
  44. return 0;
  45. default:
  46. return -1;
  47. }
  48. }
  49. /**
  50. * ieee80211_fix_reserved_tid - return the TID to use if this one is reserved
  51. * @tid: the assumed-reserved TID
  52. *
  53. * Returns: the alternative TID to use, or 0 on error
  54. */
  55. static inline u8 ieee80211_fix_reserved_tid(u8 tid)
  56. {
  57. switch (tid) {
  58. case 0:
  59. return 3;
  60. case 1:
  61. return 2;
  62. case 2:
  63. return 1;
  64. case 3:
  65. return 0;
  66. case 4:
  67. return 5;
  68. case 5:
  69. return 4;
  70. case 6:
  71. return 7;
  72. case 7:
  73. return 6;
  74. }
  75. return 0;
  76. }
  77. static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata,
  78. struct sta_info *sta, struct sk_buff *skb)
  79. {
  80. struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  81. /* in case we are a client verify acm is not set for this ac */
  82. while (sdata->wmm_acm & BIT(skb->priority)) {
  83. int ac = ieee802_1d_to_ac[skb->priority];
  84. if (ifmgd->tx_tspec[ac].admitted_time &&
  85. skb->priority == ifmgd->tx_tspec[ac].up)
  86. return ac;
  87. if (wme_downgrade_ac(skb)) {
  88. /*
  89. * This should not really happen. The AP has marked all
  90. * lower ACs to require admission control which is not
  91. * a reasonable configuration. Allow the frame to be
  92. * transmitted using AC_BK as a workaround.
  93. */
  94. break;
  95. }
  96. }
  97. /* Check to see if this is a reserved TID */
  98. if (sta && sta->reserved_tid == skb->priority)
  99. skb->priority = ieee80211_fix_reserved_tid(skb->priority);
  100. /* look up which queue to use for frames with this 1d tag */
  101. return ieee802_1d_to_ac[skb->priority];
  102. }
  103. /* Indicate which queue to use for this fully formed 802.11 frame */
  104. u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
  105. struct sk_buff *skb,
  106. struct ieee80211_hdr *hdr)
  107. {
  108. struct ieee80211_local *local = sdata->local;
  109. struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  110. u8 *p;
  111. if ((info->control.flags & IEEE80211_TX_CTRL_DONT_REORDER) ||
  112. local->hw.queues < IEEE80211_NUM_ACS)
  113. return 0;
  114. if (!ieee80211_is_data(hdr->frame_control)) {
  115. skb->priority = 7;
  116. return ieee802_1d_to_ac[skb->priority];
  117. }
  118. if (!ieee80211_is_data_qos(hdr->frame_control)) {
  119. skb->priority = 0;
  120. return ieee802_1d_to_ac[skb->priority];
  121. }
  122. p = ieee80211_get_qos_ctl(hdr);
  123. skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
  124. return ieee80211_downgrade_queue(sdata, NULL, skb);
  125. }
  126. u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
  127. struct sta_info *sta, struct sk_buff *skb)
  128. {
  129. const struct ethhdr *eth = (void *)skb->data;
  130. struct mac80211_qos_map *qos_map;
  131. bool qos;
  132. /* all mesh/ocb stations are required to support WME */
  133. if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT &&
  134. !is_multicast_ether_addr(eth->h_dest)) ||
  135. (sdata->vif.type == NL80211_IFTYPE_OCB && sta))
  136. qos = true;
  137. else if (sta)
  138. qos = sta->sta.wme;
  139. else
  140. qos = false;
  141. if (!qos) {
  142. skb->priority = 0; /* required for correct WPA/11i MIC */
  143. return IEEE80211_AC_BE;
  144. }
  145. if (skb->protocol == sdata->control_port_protocol) {
  146. skb->priority = 7;
  147. goto downgrade;
  148. }
  149. /* use the data classifier to determine what 802.1d tag the
  150. * data frame has */
  151. qos_map = rcu_dereference(sdata->qos_map);
  152. skb->priority = cfg80211_classify8021d(skb, qos_map ?
  153. &qos_map->qos_map : NULL);
  154. downgrade:
  155. return ieee80211_downgrade_queue(sdata, sta, skb);
  156. }
  157. /* Indicate which queue to use. */
  158. u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
  159. struct sk_buff *skb)
  160. {
  161. struct ieee80211_local *local = sdata->local;
  162. struct sta_info *sta = NULL;
  163. const u8 *ra = NULL;
  164. u16 ret;
  165. /* when using iTXQ, we can do this later */
  166. if (local->ops->wake_tx_queue)
  167. return 0;
  168. if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
  169. skb->priority = 0; /* required for correct WPA/11i MIC */
  170. return 0;
  171. }
  172. rcu_read_lock();
  173. switch (sdata->vif.type) {
  174. case NL80211_IFTYPE_AP_VLAN:
  175. sta = rcu_dereference(sdata->u.vlan.sta);
  176. if (sta)
  177. break;
  178. fallthrough;
  179. case NL80211_IFTYPE_AP:
  180. ra = skb->data;
  181. break;
  182. case NL80211_IFTYPE_STATION:
  183. /* might be a TDLS station */
  184. sta = sta_info_get(sdata, skb->data);
  185. if (sta)
  186. break;
  187. ra = sdata->deflink.u.mgd.bssid;
  188. break;
  189. case NL80211_IFTYPE_ADHOC:
  190. ra = skb->data;
  191. break;
  192. default:
  193. break;
  194. }
  195. if (!sta && ra && !is_multicast_ether_addr(ra))
  196. sta = sta_info_get(sdata, ra);
  197. ret = __ieee80211_select_queue(sdata, sta, skb);
  198. rcu_read_unlock();
  199. return ret;
  200. }
  201. /**
  202. * ieee80211_set_qos_hdr - Fill in the QoS header if there is one.
  203. *
  204. * @sdata: local subif
  205. * @skb: packet to be updated
  206. */
  207. void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
  208. struct sk_buff *skb)
  209. {
  210. struct ieee80211_hdr *hdr = (void *)skb->data;
  211. struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  212. u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
  213. u8 flags;
  214. u8 *p;
  215. if (!ieee80211_is_data_qos(hdr->frame_control))
  216. return;
  217. p = ieee80211_get_qos_ctl(hdr);
  218. /* don't overwrite the QoS field of injected frames */
  219. if (info->flags & IEEE80211_TX_CTL_INJECTED) {
  220. /* do take into account Ack policy of injected frames */
  221. if (*p & IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
  222. info->flags |= IEEE80211_TX_CTL_NO_ACK;
  223. return;
  224. }
  225. /* set up the first byte */
  226. /*
  227. * preserve everything but the TID and ACK policy
  228. * (which we both write here)
  229. */
  230. flags = *p & ~(IEEE80211_QOS_CTL_TID_MASK |
  231. IEEE80211_QOS_CTL_ACK_POLICY_MASK);
  232. if (is_multicast_ether_addr(hdr->addr1) ||
  233. sdata->noack_map & BIT(tid)) {
  234. flags |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
  235. info->flags |= IEEE80211_TX_CTL_NO_ACK;
  236. }
  237. *p = flags | tid;
  238. /* set up the second byte */
  239. p++;
  240. if (ieee80211_vif_is_mesh(&sdata->vif)) {
  241. /* preserve RSPI and Mesh PS Level bit */
  242. *p &= ((IEEE80211_QOS_CTL_RSPI |
  243. IEEE80211_QOS_CTL_MESH_PS_LEVEL) >> 8);
  244. /* Nulls don't have a mesh header (frame body) */
  245. if (!ieee80211_is_qos_nullfunc(hdr->frame_control))
  246. *p |= (IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8);
  247. } else {
  248. *p = 0;
  249. }
  250. }