rtw_mesh_hwmp.c 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2017 Realtek Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. *****************************************************************************/
  15. #define _RTW_HWMP_C_
  16. #ifdef CONFIG_RTW_MESH
  17. #include <drv_types.h>
  18. #include <hal_data.h>
  19. #define RTW_TEST_FRAME_LEN 8192
  20. #define RTW_MAX_METRIC 0xffffffff
  21. #define RTW_ARITH_SHIFT 8
  22. #define RTW_LINK_FAIL_THRESH 95
  23. #define RTW_MAX_PREQ_QUEUE_LEN 64
  24. #define RTW_ATLM_REQ_CYCLE 1000
  25. #define rtw_ilog2(n) \
  26. ( \
  27. (n) < 2 ? 0 : \
  28. (n) & (1ULL << 63) ? 63 : \
  29. (n) & (1ULL << 62) ? 62 : \
  30. (n) & (1ULL << 61) ? 61 : \
  31. (n) & (1ULL << 60) ? 60 : \
  32. (n) & (1ULL << 59) ? 59 : \
  33. (n) & (1ULL << 58) ? 58 : \
  34. (n) & (1ULL << 57) ? 57 : \
  35. (n) & (1ULL << 56) ? 56 : \
  36. (n) & (1ULL << 55) ? 55 : \
  37. (n) & (1ULL << 54) ? 54 : \
  38. (n) & (1ULL << 53) ? 53 : \
  39. (n) & (1ULL << 52) ? 52 : \
  40. (n) & (1ULL << 51) ? 51 : \
  41. (n) & (1ULL << 50) ? 50 : \
  42. (n) & (1ULL << 49) ? 49 : \
  43. (n) & (1ULL << 48) ? 48 : \
  44. (n) & (1ULL << 47) ? 47 : \
  45. (n) & (1ULL << 46) ? 46 : \
  46. (n) & (1ULL << 45) ? 45 : \
  47. (n) & (1ULL << 44) ? 44 : \
  48. (n) & (1ULL << 43) ? 43 : \
  49. (n) & (1ULL << 42) ? 42 : \
  50. (n) & (1ULL << 41) ? 41 : \
  51. (n) & (1ULL << 40) ? 40 : \
  52. (n) & (1ULL << 39) ? 39 : \
  53. (n) & (1ULL << 38) ? 38 : \
  54. (n) & (1ULL << 37) ? 37 : \
  55. (n) & (1ULL << 36) ? 36 : \
  56. (n) & (1ULL << 35) ? 35 : \
  57. (n) & (1ULL << 34) ? 34 : \
  58. (n) & (1ULL << 33) ? 33 : \
  59. (n) & (1ULL << 32) ? 32 : \
  60. (n) & (1ULL << 31) ? 31 : \
  61. (n) & (1ULL << 30) ? 30 : \
  62. (n) & (1ULL << 29) ? 29 : \
  63. (n) & (1ULL << 28) ? 28 : \
  64. (n) & (1ULL << 27) ? 27 : \
  65. (n) & (1ULL << 26) ? 26 : \
  66. (n) & (1ULL << 25) ? 25 : \
  67. (n) & (1ULL << 24) ? 24 : \
  68. (n) & (1ULL << 23) ? 23 : \
  69. (n) & (1ULL << 22) ? 22 : \
  70. (n) & (1ULL << 21) ? 21 : \
  71. (n) & (1ULL << 20) ? 20 : \
  72. (n) & (1ULL << 19) ? 19 : \
  73. (n) & (1ULL << 18) ? 18 : \
  74. (n) & (1ULL << 17) ? 17 : \
  75. (n) & (1ULL << 16) ? 16 : \
  76. (n) & (1ULL << 15) ? 15 : \
  77. (n) & (1ULL << 14) ? 14 : \
  78. (n) & (1ULL << 13) ? 13 : \
  79. (n) & (1ULL << 12) ? 12 : \
  80. (n) & (1ULL << 11) ? 11 : \
  81. (n) & (1ULL << 10) ? 10 : \
  82. (n) & (1ULL << 9) ? 9 : \
  83. (n) & (1ULL << 8) ? 8 : \
  84. (n) & (1ULL << 7) ? 7 : \
  85. (n) & (1ULL << 6) ? 6 : \
  86. (n) & (1ULL << 5) ? 5 : \
  87. (n) & (1ULL << 4) ? 4 : \
  88. (n) & (1ULL << 3) ? 3 : \
  89. (n) & (1ULL << 2) ? 2 : \
  90. 1 \
  91. )
  92. enum rtw_mpath_frame_type {
  93. RTW_MPATH_PREQ = 0,
  94. RTW_MPATH_PREP,
  95. RTW_MPATH_PERR,
  96. RTW_MPATH_RANN
  97. };
  98. static inline u32 rtw_u32_field_get(const u8 *preq_elem, int shift, BOOLEAN ae)
  99. {
  100. if (ae)
  101. shift += 6;
  102. return LE_BITS_TO_4BYTE(preq_elem + shift, 0, 32);
  103. }
  104. static inline u16 rtw_u16_field_get(const u8 *preq_elem, int shift, BOOLEAN ae)
  105. {
  106. if (ae)
  107. shift += 6;
  108. return LE_BITS_TO_2BYTE(preq_elem + shift, 0, 16);
  109. }
  110. /* HWMP IE processing macros */
  111. #define RTW_AE_F (1<<6)
  112. #define RTW_AE_F_SET(x) (*x & RTW_AE_F)
  113. #define RTW_PREQ_IE_FLAGS(x) (*(x))
  114. #define RTW_PREQ_IE_HOPCOUNT(x) (*(x + 1))
  115. #define RTW_PREQ_IE_TTL(x) (*(x + 2))
  116. #define RTW_PREQ_IE_PREQ_ID(x) rtw_u32_field_get(x, 3, 0)
  117. #define RTW_PREQ_IE_ORIG_ADDR(x) (x + 7)
  118. #define RTW_PREQ_IE_ORIG_SN(x) rtw_u32_field_get(x, 13, 0)
  119. #define RTW_PREQ_IE_LIFETIME(x) rtw_u32_field_get(x, 17, RTW_AE_F_SET(x))
  120. #define RTW_PREQ_IE_METRIC(x) rtw_u32_field_get(x, 21, RTW_AE_F_SET(x))
  121. #define RTW_PREQ_IE_TARGET_F(x) (*(RTW_AE_F_SET(x) ? x + 32 : x + 26))
  122. #define RTW_PREQ_IE_TARGET_ADDR(x) (RTW_AE_F_SET(x) ? x + 33 : x + 27)
  123. #define RTW_PREQ_IE_TARGET_SN(x) rtw_u32_field_get(x, 33, RTW_AE_F_SET(x))
  124. #define RTW_PREP_IE_FLAGS(x) RTW_PREQ_IE_FLAGS(x)
  125. #define RTW_PREP_IE_HOPCOUNT(x) RTW_PREQ_IE_HOPCOUNT(x)
  126. #define RTW_PREP_IE_TTL(x) RTW_PREQ_IE_TTL(x)
  127. #define RTW_PREP_IE_ORIG_ADDR(x) (RTW_AE_F_SET(x) ? x + 27 : x + 21)
  128. #define RTW_PREP_IE_ORIG_SN(x) rtw_u32_field_get(x, 27, RTW_AE_F_SET(x))
  129. #define RTW_PREP_IE_LIFETIME(x) rtw_u32_field_get(x, 13, RTW_AE_F_SET(x))
  130. #define RTW_PREP_IE_METRIC(x) rtw_u32_field_get(x, 17, RTW_AE_F_SET(x))
  131. #define RTW_PREP_IE_TARGET_ADDR(x) (x + 3)
  132. #define RTW_PREP_IE_TARGET_SN(x) rtw_u32_field_get(x, 9, 0)
  133. #define RTW_PERR_IE_TTL(x) (*(x))
  134. #define RTW_PERR_IE_TARGET_FLAGS(x) (*(x + 2))
  135. #define RTW_PERR_IE_TARGET_ADDR(x) (x + 3)
  136. #define RTW_PERR_IE_TARGET_SN(x) rtw_u32_field_get(x, 9, 0)
  137. #define RTW_PERR_IE_TARGET_RCODE(x) rtw_u16_field_get(x, 13, 0)
  138. #define RTW_TU_TO_SYSTIME(x) (rtw_us_to_systime((x) * 1024))
  139. #define RTW_TU_TO_EXP_TIME(x) (rtw_get_current_time() + RTW_TU_TO_SYSTIME(x))
  140. #define RTW_MSEC_TO_TU(x) (x*1000/1024)
  141. #define RTW_SN_GT(x, y) ((s32)(y - x) < 0)
  142. #define RTW_SN_LT(x, y) ((s32)(x - y) < 0)
  143. #define RTW_MAX_SANE_SN_DELTA 32
  144. static inline u32 RTW_SN_DELTA(u32 x, u32 y)
  145. {
  146. return x >= y ? x - y : y - x;
  147. }
  148. #define rtw_net_traversal_jiffies(adapter) \
  149. rtw_ms_to_systime(adapter->mesh_cfg.dot11MeshHWMPnetDiameterTraversalTime)
  150. #define rtw_default_lifetime(adapter) \
  151. RTW_MSEC_TO_TU(adapter->mesh_cfg.dot11MeshHWMPactivePathTimeout)
  152. #define rtw_min_preq_int_jiff(adapter) \
  153. (rtw_ms_to_systime(adapter->mesh_cfg.dot11MeshHWMPpreqMinInterval))
  154. #define rtw_max_preq_retries(adapter) (adapter->mesh_cfg.dot11MeshHWMPmaxPREQretries)
  155. #define rtw_disc_timeout_jiff(adapter) \
  156. rtw_ms_to_systime(adapter->mesh_cfg.min_discovery_timeout)
  157. #define rtw_root_path_confirmation_jiffies(adapter) \
  158. rtw_ms_to_systime(adapter->mesh_cfg.dot11MeshHWMPconfirmationInterval)
  159. static inline BOOLEAN rtw_ether_addr_equal(const u8 *addr1, const u8 *addr2)
  160. {
  161. return _rtw_memcmp(addr1, addr2, ETH_ALEN);
  162. }
  163. #ifdef PLATFORM_LINUX
  164. #define rtw_print_ratelimit() printk_ratelimit()
  165. #define rtw_mod_timer(ptimer, expires) mod_timer(&(ptimer)->timer, expires)
  166. #else
  167. #endif
  168. #define RTW_MESH_EWMA_PRECISION 20
  169. #define RTW_MESH_EWMA_WEIGHT_RCP 8
  170. #define RTW_TOTAL_PKT_MIN_THRESHOLD 1
  171. inline void rtw_ewma_err_rate_init(struct rtw_ewma_err_rate *e)
  172. {
  173. e->internal = 0;
  174. }
  175. inline unsigned long rtw_ewma_err_rate_read(struct rtw_ewma_err_rate *e)
  176. {
  177. return e->internal >> (RTW_MESH_EWMA_PRECISION);
  178. }
  179. inline void rtw_ewma_err_rate_add(struct rtw_ewma_err_rate *e,
  180. unsigned long val)
  181. {
  182. unsigned long internal = e->internal;
  183. unsigned long weight_rcp = rtw_ilog2(RTW_MESH_EWMA_WEIGHT_RCP);
  184. unsigned long precision = RTW_MESH_EWMA_PRECISION;
  185. (e->internal) = internal ? (((internal << weight_rcp) - internal) +
  186. (val << precision)) >> weight_rcp :
  187. (val << precision);
  188. }
  189. static const u8 bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  190. static int rtw_mesh_path_sel_frame_tx(enum rtw_mpath_frame_type mpath_action, u8 flags,
  191. const u8 *originator_addr, u32 originator_sn,
  192. u8 target_flags, const u8 *target,
  193. u32 target_sn, const u8 *da, u8 hopcount, u8 ttl,
  194. u32 lifetime, u32 metric, u32 preq_id,
  195. _adapter *adapter)
  196. {
  197. struct xmit_priv *pxmitpriv = &(adapter->xmitpriv);
  198. struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
  199. struct xmit_frame *pmgntframe = NULL;
  200. struct rtw_ieee80211_hdr *pwlanhdr = NULL;
  201. struct pkt_attrib *pattrib = NULL;
  202. u8 category = RTW_WLAN_CATEGORY_MESH;
  203. u8 action = RTW_ACT_MESH_HWMP_PATH_SELECTION;
  204. u16 *fctrl = NULL;
  205. u8 *pos, ie_len;
  206. pmgntframe = alloc_mgtxmitframe(pxmitpriv);
  207. if (pmgntframe == NULL)
  208. return -1;
  209. pattrib = &pmgntframe->attrib;
  210. update_mgntframe_attrib(adapter, pattrib);
  211. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  212. pos = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  213. pwlanhdr = (struct rtw_ieee80211_hdr *)pos;
  214. fctrl = &(pwlanhdr->frame_ctl);
  215. *(fctrl) = 0;
  216. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  217. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(adapter), ETH_ALEN);
  218. _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(adapter), ETH_ALEN);
  219. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  220. pmlmeext->mgnt_seq++;
  221. set_frame_sub_type(pos, WIFI_ACTION);
  222. pos += sizeof(struct rtw_ieee80211_hdr_3addr);
  223. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  224. pos = rtw_set_fixed_ie(pos, 1, &(category), &(pattrib->pktlen));
  225. pos = rtw_set_fixed_ie(pos, 1, &(action), &(pattrib->pktlen));
  226. switch (mpath_action) {
  227. case RTW_MPATH_PREQ:
  228. RTW_HWMP_DBG("sending PREQ to "MAC_FMT"\n", MAC_ARG(target));
  229. ie_len = 37;
  230. pattrib->pktlen += (ie_len + 2);
  231. *pos++ = WLAN_EID_PREQ;
  232. break;
  233. case RTW_MPATH_PREP:
  234. RTW_HWMP_DBG("sending PREP to "MAC_FMT"\n", MAC_ARG(originator_addr));
  235. ie_len = 31;
  236. pattrib->pktlen += (ie_len + 2);
  237. *pos++ = WLAN_EID_PREP;
  238. break;
  239. case RTW_MPATH_RANN:
  240. RTW_HWMP_DBG("sending RANN from "MAC_FMT"\n", MAC_ARG(originator_addr));
  241. ie_len = sizeof(struct rtw_ieee80211_rann_ie);
  242. pattrib->pktlen += (ie_len + 2);
  243. *pos++ = WLAN_EID_RANN;
  244. break;
  245. default:
  246. rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
  247. rtw_free_xmitframe(pxmitpriv, pmgntframe);
  248. return _FAIL;
  249. }
  250. *pos++ = ie_len;
  251. *pos++ = flags;
  252. *pos++ = hopcount;
  253. *pos++ = ttl;
  254. if (mpath_action == RTW_MPATH_PREP) {
  255. _rtw_memcpy(pos, target, ETH_ALEN);
  256. pos += ETH_ALEN;
  257. *(u32 *)pos = cpu_to_le32(target_sn);
  258. pos += 4;
  259. } else {
  260. if (mpath_action == RTW_MPATH_PREQ) {
  261. *(u32 *)pos = cpu_to_le32(preq_id);
  262. pos += 4;
  263. }
  264. _rtw_memcpy(pos, originator_addr, ETH_ALEN);
  265. pos += ETH_ALEN;
  266. *(u32 *)pos = cpu_to_le32(originator_sn);
  267. pos += 4;
  268. }
  269. *(u32 *)pos = cpu_to_le32(lifetime);
  270. pos += 4;
  271. *(u32 *)pos = cpu_to_le32(metric);
  272. pos += 4;
  273. if (mpath_action == RTW_MPATH_PREQ) {
  274. *pos++ = 1; /* support only 1 destination now */
  275. *pos++ = target_flags;
  276. _rtw_memcpy(pos, target, ETH_ALEN);
  277. pos += ETH_ALEN;
  278. *(u32 *)pos = cpu_to_le32(target_sn);
  279. pos += 4;
  280. } else if (mpath_action == RTW_MPATH_PREP) {
  281. _rtw_memcpy(pos, originator_addr, ETH_ALEN);
  282. pos += ETH_ALEN;
  283. *(u32 *)pos = cpu_to_le32(originator_sn);
  284. pos += 4;
  285. }
  286. pattrib->last_txcmdsz = pattrib->pktlen;
  287. dump_mgntframe(adapter, pmgntframe);
  288. return 0;
  289. }
  290. int rtw_mesh_path_error_tx(_adapter *adapter,
  291. u8 ttl, const u8 *target, u32 target_sn,
  292. u16 perr_reason_code, const u8 *ra)
  293. {
  294. struct xmit_priv *pxmitpriv = &(adapter->xmitpriv);
  295. struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
  296. struct xmit_frame *pmgntframe = NULL;
  297. struct rtw_ieee80211_hdr *pwlanhdr = NULL;
  298. struct pkt_attrib *pattrib = NULL;
  299. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  300. u8 category = RTW_WLAN_CATEGORY_MESH;
  301. u8 action = RTW_ACT_MESH_HWMP_PATH_SELECTION;
  302. u8 *pos, ie_len;
  303. u16 *fctrl = NULL;
  304. if (rtw_time_before(rtw_get_current_time(), minfo->next_perr))
  305. return -1;
  306. pmgntframe = alloc_mgtxmitframe(pxmitpriv);
  307. if (pmgntframe == NULL)
  308. return -1;
  309. pattrib = &pmgntframe->attrib;
  310. update_mgntframe_attrib(adapter, pattrib);
  311. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  312. pos = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  313. pwlanhdr = (struct rtw_ieee80211_hdr *)pos;
  314. fctrl = &(pwlanhdr->frame_ctl);
  315. *(fctrl) = 0;
  316. _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN);
  317. _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(adapter), ETH_ALEN);
  318. _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(adapter), ETH_ALEN);
  319. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  320. pmlmeext->mgnt_seq++;
  321. set_frame_sub_type(pos, WIFI_ACTION);
  322. pos += sizeof(struct rtw_ieee80211_hdr_3addr);
  323. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  324. pos = rtw_set_fixed_ie(pos, 1, &(category), &(pattrib->pktlen));
  325. pos = rtw_set_fixed_ie(pos, 1, &(action), &(pattrib->pktlen));
  326. ie_len = 15;
  327. pattrib->pktlen += (2 + ie_len);
  328. *pos++ = WLAN_EID_PERR;
  329. *pos++ = ie_len;
  330. /* ttl */
  331. *pos++ = ttl;
  332. /* The Number of Destinations N */
  333. *pos++ = 1;
  334. /* Flags format | B7 | B6 | B5:B0 | = | rsvd | AE | rsvd | */
  335. *pos = 0;
  336. pos++;
  337. _rtw_memcpy(pos, target, ETH_ALEN);
  338. pos += ETH_ALEN;
  339. *(u32 *)pos = cpu_to_le32(target_sn);
  340. pos += 4;
  341. *(u16 *)pos = cpu_to_le16(perr_reason_code);
  342. adapter->mesh_info.next_perr = RTW_TU_TO_EXP_TIME(
  343. adapter->mesh_cfg.dot11MeshHWMPperrMinInterval);
  344. pattrib->last_txcmdsz = pattrib->pktlen;
  345. /* Send directly. Rewrite it if deferred tx is needed */
  346. dump_mgntframe(adapter, pmgntframe);
  347. RTW_HWMP_DBG("TX PERR toward "MAC_FMT", ra = "MAC_FMT"\n", MAC_ARG(target), MAC_ARG(ra));
  348. return 0;
  349. }
  350. static u32 rtw_get_vht_bitrate(u8 mcs, u8 bw, u8 nss, u8 sgi)
  351. {
  352. static const u32 base[4][10] = {
  353. { 6500000,
  354. 13000000,
  355. 19500000,
  356. 26000000,
  357. 39000000,
  358. 52000000,
  359. 58500000,
  360. 65000000,
  361. 78000000,
  362. /* not in the spec, but some devices use this: */
  363. 86500000,
  364. },
  365. { 13500000,
  366. 27000000,
  367. 40500000,
  368. 54000000,
  369. 81000000,
  370. 108000000,
  371. 121500000,
  372. 135000000,
  373. 162000000,
  374. 180000000,
  375. },
  376. { 29300000,
  377. 58500000,
  378. 87800000,
  379. 117000000,
  380. 175500000,
  381. 234000000,
  382. 263300000,
  383. 292500000,
  384. 351000000,
  385. 390000000,
  386. },
  387. { 58500000,
  388. 117000000,
  389. 175500000,
  390. 234000000,
  391. 351000000,
  392. 468000000,
  393. 526500000,
  394. 585000000,
  395. 702000000,
  396. 780000000,
  397. },
  398. };
  399. u32 bitrate;
  400. int bw_idx;
  401. if (mcs > 9) {
  402. RTW_HWMP_INFO("Invalid mcs = %d\n", mcs);
  403. return 0;
  404. }
  405. if (nss > 4 || nss < 1) {
  406. RTW_HWMP_INFO("Now only support nss = 1, 2, 3, 4\n");
  407. }
  408. switch (bw) {
  409. case CHANNEL_WIDTH_160:
  410. bw_idx = 3;
  411. break;
  412. case CHANNEL_WIDTH_80:
  413. bw_idx = 2;
  414. break;
  415. case CHANNEL_WIDTH_40:
  416. bw_idx = 1;
  417. break;
  418. case CHANNEL_WIDTH_20:
  419. bw_idx = 0;
  420. break;
  421. default:
  422. RTW_HWMP_INFO("bw = %d currently not supported\n", bw);
  423. return 0;
  424. }
  425. bitrate = base[bw_idx][mcs];
  426. bitrate *= nss;
  427. if (sgi)
  428. bitrate = (bitrate / 9) * 10;
  429. /* do NOT round down here */
  430. return (bitrate + 50000) / 100000;
  431. }
  432. static u32 rtw_get_ht_bitrate(u8 mcs, u8 bw, u8 sgi)
  433. {
  434. int modulation, streams, bitrate;
  435. /* the formula below does only work for MCS values smaller than 32 */
  436. if (mcs >= 32) {
  437. RTW_HWMP_INFO("Invalid mcs = %d\n", mcs);
  438. return 0;
  439. }
  440. if (bw > 1) {
  441. RTW_HWMP_INFO("Now HT only support bw = 0(20Mhz), 1(40Mhz)\n");
  442. return 0;
  443. }
  444. modulation = mcs & 7;
  445. streams = (mcs >> 3) + 1;
  446. bitrate = (bw == 1) ? 13500000 : 6500000;
  447. if (modulation < 4)
  448. bitrate *= (modulation + 1);
  449. else if (modulation == 4)
  450. bitrate *= (modulation + 2);
  451. else
  452. bitrate *= (modulation + 3);
  453. bitrate *= streams;
  454. if (sgi)
  455. bitrate = (bitrate / 9) * 10;
  456. /* do NOT round down here */
  457. return (bitrate + 50000) / 100000;
  458. }
  459. /**
  460. * @bw: 0(20Mhz), 1(40Mhz), 2(80Mhz), 3(160Mhz)
  461. * @rate_idx: DESC_RATEXXXX & 0x7f
  462. * @sgi: DESC_RATEXXXX >> 7
  463. * Returns: bitrate in 100kbps
  464. */
  465. static u32 rtw_desc_rate_to_bitrate(u8 bw, u8 rate_idx, u8 sgi)
  466. {
  467. u32 bitrate;
  468. if (rate_idx <= DESC_RATE54M){
  469. u16 ofdm_rate[12] = {10, 20, 55, 110,
  470. 60, 90, 120, 180, 240, 360, 480, 540};
  471. bitrate = ofdm_rate[rate_idx];
  472. } else if ((DESC_RATEMCS0 <= rate_idx) &&
  473. (rate_idx <= DESC_RATEMCS31)) {
  474. u8 mcs = rate_idx - DESC_RATEMCS0;
  475. bitrate = rtw_get_ht_bitrate(mcs, bw, sgi);
  476. } else if ((DESC_RATEVHTSS1MCS0 <= rate_idx) &&
  477. (rate_idx <= DESC_RATEVHTSS4MCS9)) {
  478. u8 mcs = (rate_idx - DESC_RATEVHTSS1MCS0) % 10;
  479. u8 nss = ((rate_idx - DESC_RATEVHTSS1MCS0) / 10) + 1;
  480. bitrate = rtw_get_vht_bitrate(mcs, bw, nss, sgi);
  481. } else {
  482. /* 60Ghz ??? */
  483. bitrate = 1;
  484. }
  485. return bitrate;
  486. }
  487. static u32 rtw_airtime_link_metric_get(_adapter *adapter, struct sta_info *sta)
  488. {
  489. struct dm_struct *dm = adapter_to_phydm(adapter);
  490. int device_constant = phydm_get_plcp(dm, sta->cmn.mac_id) << RTW_ARITH_SHIFT;
  491. u32 test_frame_len = RTW_TEST_FRAME_LEN << RTW_ARITH_SHIFT;
  492. u32 s_unit = 1 << RTW_ARITH_SHIFT;
  493. u32 err;
  494. u16 rate;
  495. u32 tx_time, estimated_retx;
  496. u64 result;
  497. /* The fail_avg should <= 100 here */
  498. u32 fail_avg = (u32)rtw_ewma_err_rate_read(&sta->metrics.err_rate);
  499. if (fail_avg > RTW_LINK_FAIL_THRESH)
  500. return RTW_MAX_METRIC;
  501. rate = sta->metrics.data_rate;
  502. /* rate unit is 100Kbps, min rate = 10 */
  503. if (rate < 10) {
  504. RTW_HWMP_INFO("rate = %d\n", rate);
  505. return RTW_MAX_METRIC;
  506. }
  507. err = (fail_avg << RTW_ARITH_SHIFT) / 100;
  508. /* test_frame_len*10 to adjust the unit of rate(100kbps/unit) */
  509. tx_time = (device_constant + 10 * test_frame_len / rate);
  510. estimated_retx = ((1 << (2 * RTW_ARITH_SHIFT)) / (s_unit - err));
  511. result = (tx_time * estimated_retx) >> (2 * RTW_ARITH_SHIFT);
  512. /* Convert us to 0.01 TU(10.24us). x/10.24 = x*100/1024 */
  513. result = (result * 100) >> 10;
  514. return (u32)result;
  515. }
  516. void rtw_ieee80211s_update_metric(_adapter *adapter, u8 mac_id,
  517. u8 per, u8 rate,
  518. u8 bw, u8 total_pkt)
  519. {
  520. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  521. struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
  522. struct sta_info *sta;
  523. u8 rate_idx;
  524. u8 sgi;
  525. sta = macid_ctl->sta[mac_id];
  526. if (!sta)
  527. return;
  528. /* if RA, use reported rate */
  529. if (adapter->fix_rate == 0xff) {
  530. rate_idx = rate & 0x7f;
  531. sgi = rate >> 7;
  532. } else {
  533. rate_idx = adapter->fix_rate & 0x7f;
  534. sgi = adapter->fix_rate >> 7;
  535. }
  536. sta->metrics.data_rate = rtw_desc_rate_to_bitrate(bw, rate_idx, sgi);
  537. if (total_pkt < RTW_TOTAL_PKT_MIN_THRESHOLD)
  538. return;
  539. /* TBD: sta->metrics.overhead = phydm_get_plcp(void *dm_void, u16 macid); */
  540. sta->metrics.total_pkt = total_pkt;
  541. rtw_ewma_err_rate_add(&sta->metrics.err_rate, per);
  542. if (rtw_ewma_err_rate_read(&sta->metrics.err_rate) >
  543. RTW_LINK_FAIL_THRESH)
  544. rtw_mesh_plink_broken(sta);
  545. }
  546. static void rtw_hwmp_preq_frame_process(_adapter *adapter,
  547. struct rtw_ieee80211_hdr_3addr *mgmt,
  548. const u8 *preq_elem, u32 originator_metric)
  549. {
  550. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  551. struct rtw_mesh_cfg *mshcfg = &adapter->mesh_cfg;
  552. struct rtw_mesh_path *path = NULL;
  553. const u8 *target_addr, *originator_addr;
  554. const u8 *da;
  555. u8 target_flags, ttl, flags, to_gate_ask = 0;
  556. u32 originator_sn, target_sn, lifetime, target_metric = 0;
  557. BOOLEAN reply = _FALSE;
  558. BOOLEAN forward = _TRUE;
  559. BOOLEAN preq_is_gate;
  560. /* Update target SN, if present */
  561. target_addr = RTW_PREQ_IE_TARGET_ADDR(preq_elem);
  562. originator_addr = RTW_PREQ_IE_ORIG_ADDR(preq_elem);
  563. target_sn = RTW_PREQ_IE_TARGET_SN(preq_elem);
  564. originator_sn = RTW_PREQ_IE_ORIG_SN(preq_elem);
  565. target_flags = RTW_PREQ_IE_TARGET_F(preq_elem);
  566. /* PREQ gate announcements */
  567. flags = RTW_PREQ_IE_FLAGS(preq_elem);
  568. preq_is_gate = !!(flags & RTW_IEEE80211_PREQ_IS_GATE_FLAG);
  569. RTW_HWMP_DBG("received PREQ from "MAC_FMT"\n", MAC_ARG(originator_addr));
  570. if (rtw_ether_addr_equal(target_addr, adapter_mac_addr(adapter))) {
  571. RTW_HWMP_DBG("PREQ is for us\n");
  572. #ifdef CONFIG_RTW_MESH_ON_DMD_GANN
  573. rtw_rcu_read_lock();
  574. path = rtw_mesh_path_lookup(adapter, originator_addr);
  575. if (path) {
  576. if (preq_is_gate)
  577. rtw_mesh_path_add_gate(path);
  578. else if (path->is_gate) {
  579. enter_critical_bh(&path->state_lock);
  580. rtw_mesh_gate_del(adapter->mesh_info.mesh_paths, path);
  581. exit_critical_bh(&path->state_lock);
  582. }
  583. }
  584. path = NULL;
  585. rtw_rcu_read_unlock();
  586. #endif
  587. forward = _FALSE;
  588. reply = _TRUE;
  589. to_gate_ask = 1;
  590. target_metric = 0;
  591. if (rtw_time_after(rtw_get_current_time(), minfo->last_sn_update +
  592. rtw_net_traversal_jiffies(adapter)) ||
  593. rtw_time_before(rtw_get_current_time(), minfo->last_sn_update)) {
  594. ++minfo->sn;
  595. minfo->last_sn_update = rtw_get_current_time();
  596. }
  597. target_sn = minfo->sn;
  598. } else if (is_broadcast_mac_addr(target_addr) &&
  599. (target_flags & RTW_IEEE80211_PREQ_TO_FLAG)) {
  600. rtw_rcu_read_lock();
  601. path = rtw_mesh_path_lookup(adapter, originator_addr);
  602. if (path) {
  603. if (flags & RTW_IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
  604. reply = _TRUE;
  605. target_addr = adapter_mac_addr(adapter);
  606. target_sn = ++minfo->sn;
  607. target_metric = 0;
  608. minfo->last_sn_update = rtw_get_current_time();
  609. }
  610. if (preq_is_gate) {
  611. lifetime = RTW_PREQ_IE_LIFETIME(preq_elem);
  612. path->gate_ann_int = lifetime;
  613. path->gate_asked = false;
  614. rtw_mesh_path_add_gate(path);
  615. } else if (path->is_gate) {
  616. enter_critical_bh(&path->state_lock);
  617. rtw_mesh_gate_del(adapter->mesh_info.mesh_paths, path);
  618. exit_critical_bh(&path->state_lock);
  619. }
  620. }
  621. rtw_rcu_read_unlock();
  622. } else {
  623. rtw_rcu_read_lock();
  624. #ifdef CONFIG_RTW_MESH_ON_DMD_GANN
  625. path = rtw_mesh_path_lookup(adapter, originator_addr);
  626. if (path) {
  627. if (preq_is_gate)
  628. rtw_mesh_path_add_gate(path);
  629. else if (path->is_gate) {
  630. enter_critical_bh(&path->state_lock);
  631. rtw_mesh_gate_del(adapter->mesh_info.mesh_paths, path);
  632. exit_critical_bh(&path->state_lock);
  633. }
  634. }
  635. path = NULL;
  636. #endif
  637. path = rtw_mesh_path_lookup(adapter, target_addr);
  638. if (path) {
  639. if ((!(path->flags & RTW_MESH_PATH_SN_VALID)) ||
  640. RTW_SN_LT(path->sn, target_sn)) {
  641. path->sn = target_sn;
  642. path->flags |= RTW_MESH_PATH_SN_VALID;
  643. } else if ((!(target_flags & RTW_IEEE80211_PREQ_TO_FLAG)) &&
  644. (path->flags & RTW_MESH_PATH_ACTIVE)) {
  645. reply = _TRUE;
  646. target_metric = path->metric;
  647. target_sn = path->sn;
  648. /* Case E2 of sec 13.10.9.3 IEEE 802.11-2012*/
  649. target_flags |= RTW_IEEE80211_PREQ_TO_FLAG;
  650. }
  651. }
  652. rtw_rcu_read_unlock();
  653. }
  654. if (reply) {
  655. lifetime = RTW_PREQ_IE_LIFETIME(preq_elem);
  656. ttl = mshcfg->element_ttl;
  657. if (ttl != 0 && !to_gate_ask) {
  658. RTW_HWMP_DBG("replying to the PREQ\n");
  659. rtw_mesh_path_sel_frame_tx(RTW_MPATH_PREP, 0, originator_addr,
  660. originator_sn, 0, target_addr,
  661. target_sn, mgmt->addr2, 0, ttl,
  662. lifetime, target_metric, 0,
  663. adapter);
  664. } else if (ttl != 0 && to_gate_ask) {
  665. RTW_HWMP_DBG("replying to the PREQ (PREQ for us)\n");
  666. if (mshcfg->dot11MeshGateAnnouncementProtocol) {
  667. /* BIT 7 is used to identify the prep is from mesh gate */
  668. to_gate_ask = RTW_IEEE80211_PREQ_IS_GATE_FLAG | BIT(7);
  669. } else {
  670. to_gate_ask = 0;
  671. }
  672. rtw_mesh_path_sel_frame_tx(RTW_MPATH_PREP, to_gate_ask, originator_addr,
  673. originator_sn, 0, target_addr,
  674. target_sn, mgmt->addr2, 0, ttl,
  675. lifetime, target_metric, 0,
  676. adapter);
  677. } else {
  678. minfo->mshstats.dropped_frames_ttl++;
  679. }
  680. }
  681. if (forward && mshcfg->dot11MeshForwarding) {
  682. u32 preq_id;
  683. u8 hopcount;
  684. ttl = RTW_PREQ_IE_TTL(preq_elem);
  685. lifetime = RTW_PREQ_IE_LIFETIME(preq_elem);
  686. if (ttl <= 1) {
  687. minfo->mshstats.dropped_frames_ttl++;
  688. return;
  689. }
  690. RTW_HWMP_DBG("forwarding the PREQ from "MAC_FMT"\n", MAC_ARG(originator_addr));
  691. --ttl;
  692. preq_id = RTW_PREQ_IE_PREQ_ID(preq_elem);
  693. hopcount = RTW_PREQ_IE_HOPCOUNT(preq_elem) + 1;
  694. da = (path && path->is_root) ?
  695. path->rann_snd_addr : bcast_addr;
  696. if (flags & RTW_IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
  697. target_addr = RTW_PREQ_IE_TARGET_ADDR(preq_elem);
  698. target_sn = RTW_PREQ_IE_TARGET_SN(preq_elem);
  699. }
  700. rtw_mesh_path_sel_frame_tx(RTW_MPATH_PREQ, flags, originator_addr,
  701. originator_sn, target_flags, target_addr,
  702. target_sn, da, hopcount, ttl, lifetime,
  703. originator_metric, preq_id, adapter);
  704. if (!is_multicast_mac_addr(da))
  705. minfo->mshstats.fwded_unicast++;
  706. else
  707. minfo->mshstats.fwded_mcast++;
  708. minfo->mshstats.fwded_frames++;
  709. }
  710. }
  711. static inline struct sta_info *
  712. rtw_next_hop_deref_protected(struct rtw_mesh_path *path)
  713. {
  714. return rtw_rcu_dereference_protected(path->next_hop,
  715. rtw_lockdep_is_held(&path->state_lock));
  716. }
  717. static void rtw_hwmp_prep_frame_process(_adapter *adapter,
  718. struct rtw_ieee80211_hdr_3addr *mgmt,
  719. const u8 *prep_elem, u32 metric)
  720. {
  721. struct rtw_mesh_cfg *mshcfg = &adapter->mesh_cfg;
  722. struct rtw_mesh_stats *mshstats = &adapter->mesh_info.mshstats;
  723. struct rtw_mesh_path *path;
  724. const u8 *target_addr, *originator_addr;
  725. u8 ttl, hopcount, flags;
  726. u8 next_hop[ETH_ALEN];
  727. u32 target_sn, originator_sn, lifetime;
  728. RTW_HWMP_DBG("received PREP from "MAC_FMT"\n",
  729. MAC_ARG(RTW_PREP_IE_TARGET_ADDR(prep_elem)));
  730. originator_addr = RTW_PREP_IE_ORIG_ADDR(prep_elem);
  731. if (rtw_ether_addr_equal(originator_addr, adapter_mac_addr(adapter))) {
  732. /* destination, no forwarding required */
  733. rtw_rcu_read_lock();
  734. target_addr = RTW_PREP_IE_TARGET_ADDR(prep_elem);
  735. path = rtw_mesh_path_lookup(adapter, target_addr);
  736. if (path && path->gate_asked) {
  737. flags = RTW_PREP_IE_FLAGS(prep_elem);
  738. if (flags & BIT(7)) {
  739. enter_critical_bh(&path->state_lock);
  740. path->gate_asked = false;
  741. exit_critical_bh(&path->state_lock);
  742. if (!(flags & RTW_IEEE80211_PREQ_IS_GATE_FLAG)) {
  743. enter_critical_bh(&path->state_lock);
  744. rtw_mesh_gate_del(adapter->mesh_info.mesh_paths, path);
  745. exit_critical_bh(&path->state_lock);
  746. }
  747. }
  748. }
  749. rtw_rcu_read_unlock();
  750. return;
  751. }
  752. if (!mshcfg->dot11MeshForwarding)
  753. return;
  754. ttl = RTW_PREP_IE_TTL(prep_elem);
  755. if (ttl <= 1) {
  756. mshstats->dropped_frames_ttl++;
  757. return;
  758. }
  759. rtw_rcu_read_lock();
  760. path = rtw_mesh_path_lookup(adapter, originator_addr);
  761. if (path)
  762. enter_critical_bh(&path->state_lock);
  763. else
  764. goto fail;
  765. if (!(path->flags & RTW_MESH_PATH_ACTIVE)) {
  766. exit_critical_bh(&path->state_lock);
  767. goto fail;
  768. }
  769. _rtw_memcpy(next_hop, rtw_next_hop_deref_protected(path)->cmn.mac_addr, ETH_ALEN);
  770. exit_critical_bh(&path->state_lock);
  771. --ttl;
  772. flags = RTW_PREP_IE_FLAGS(prep_elem);
  773. lifetime = RTW_PREP_IE_LIFETIME(prep_elem);
  774. hopcount = RTW_PREP_IE_HOPCOUNT(prep_elem) + 1;
  775. target_addr = RTW_PREP_IE_TARGET_ADDR(prep_elem);
  776. target_sn = RTW_PREP_IE_TARGET_SN(prep_elem);
  777. originator_sn = RTW_PREP_IE_ORIG_SN(prep_elem);
  778. rtw_mesh_path_sel_frame_tx(RTW_MPATH_PREP, flags, originator_addr, originator_sn, 0,
  779. target_addr, target_sn, next_hop, hopcount,
  780. ttl, lifetime, metric, 0, adapter);
  781. rtw_rcu_read_unlock();
  782. mshstats->fwded_unicast++;
  783. mshstats->fwded_frames++;
  784. return;
  785. fail:
  786. rtw_rcu_read_unlock();
  787. mshstats->dropped_frames_no_route++;
  788. }
  789. static void rtw_hwmp_perr_frame_process(_adapter *adapter,
  790. struct rtw_ieee80211_hdr_3addr *mgmt,
  791. const u8 *perr_elem)
  792. {
  793. struct rtw_mesh_cfg *mshcfg = &adapter->mesh_cfg;
  794. struct rtw_mesh_stats *mshstats = &adapter->mesh_info.mshstats;
  795. struct rtw_mesh_path *path;
  796. u8 ttl;
  797. const u8 *ta, *target_addr;
  798. u32 target_sn;
  799. u16 perr_reason_code;
  800. ta = mgmt->addr2;
  801. ttl = RTW_PERR_IE_TTL(perr_elem);
  802. if (ttl <= 1) {
  803. mshstats->dropped_frames_ttl++;
  804. return;
  805. }
  806. ttl--;
  807. target_addr = RTW_PERR_IE_TARGET_ADDR(perr_elem);
  808. target_sn = RTW_PERR_IE_TARGET_SN(perr_elem);
  809. perr_reason_code = RTW_PERR_IE_TARGET_RCODE(perr_elem);
  810. RTW_HWMP_DBG("received PERR toward target "MAC_FMT"\n", MAC_ARG(target_addr));
  811. rtw_rcu_read_lock();
  812. path = rtw_mesh_path_lookup(adapter, target_addr);
  813. if (path) {
  814. struct sta_info *sta;
  815. enter_critical_bh(&path->state_lock);
  816. sta = rtw_next_hop_deref_protected(path);
  817. if (path->flags & RTW_MESH_PATH_ACTIVE &&
  818. rtw_ether_addr_equal(ta, sta->cmn.mac_addr) &&
  819. !(path->flags & RTW_MESH_PATH_FIXED) &&
  820. (!(path->flags & RTW_MESH_PATH_SN_VALID) ||
  821. RTW_SN_GT(target_sn, path->sn) || target_sn == 0)) {
  822. path->flags &= ~RTW_MESH_PATH_ACTIVE;
  823. if (target_sn != 0)
  824. path->sn = target_sn;
  825. else
  826. path->sn += 1;
  827. exit_critical_bh(&path->state_lock);
  828. if (!mshcfg->dot11MeshForwarding)
  829. goto endperr;
  830. rtw_mesh_path_error_tx(adapter, ttl, target_addr,
  831. target_sn, perr_reason_code,
  832. bcast_addr);
  833. } else
  834. exit_critical_bh(&path->state_lock);
  835. }
  836. endperr:
  837. rtw_rcu_read_unlock();
  838. }
  839. static void rtw_hwmp_rann_frame_process(_adapter *adapter,
  840. struct rtw_ieee80211_hdr_3addr *mgmt,
  841. const struct rtw_ieee80211_rann_ie *rann)
  842. {
  843. struct sta_info *sta;
  844. struct sta_priv *pstapriv = &adapter->stapriv;
  845. struct rtw_mesh_cfg *mshcfg = &adapter->mesh_cfg;
  846. struct rtw_mesh_stats *mshstats = &adapter->mesh_info.mshstats;
  847. struct rtw_mesh_path *path;
  848. u8 ttl, flags, hopcount;
  849. const u8 *originator_addr;
  850. u32 originator_sn, metric, metric_txsta, interval;
  851. BOOLEAN root_is_gate;
  852. ttl = rann->rann_ttl;
  853. flags = rann->rann_flags;
  854. root_is_gate = !!(flags & RTW_RANN_FLAG_IS_GATE);
  855. originator_addr = rann->rann_addr;
  856. originator_sn = le32_to_cpu(rann->rann_seq);
  857. interval = le32_to_cpu(rann->rann_interval);
  858. hopcount = rann->rann_hopcount;
  859. hopcount++;
  860. metric = le32_to_cpu(rann->rann_metric);
  861. /* Ignore our own RANNs */
  862. if (rtw_ether_addr_equal(originator_addr, adapter_mac_addr(adapter)))
  863. return;
  864. RTW_HWMP_DBG("received RANN from "MAC_FMT" via neighbour "MAC_FMT" (is_gate=%d)\n",
  865. MAC_ARG(originator_addr), MAC_ARG(mgmt->addr2), root_is_gate);
  866. rtw_rcu_read_lock();
  867. sta = rtw_get_stainfo(pstapriv, mgmt->addr2);
  868. if (!sta) {
  869. rtw_rcu_read_unlock();
  870. return;
  871. }
  872. metric_txsta = rtw_airtime_link_metric_get(adapter, sta);
  873. path = rtw_mesh_path_lookup(adapter, originator_addr);
  874. if (!path) {
  875. path = rtw_mesh_path_add(adapter, originator_addr);
  876. if (IS_ERR(path)) {
  877. rtw_rcu_read_unlock();
  878. mshstats->dropped_frames_no_route++;
  879. return;
  880. }
  881. }
  882. if (!(RTW_SN_LT(path->sn, originator_sn)) &&
  883. !(path->sn == originator_sn && metric < path->rann_metric)) {
  884. rtw_rcu_read_unlock();
  885. return;
  886. }
  887. if ((!(path->flags & (RTW_MESH_PATH_ACTIVE | RTW_MESH_PATH_RESOLVING)) ||
  888. (rtw_time_after(rtw_get_current_time(), path->last_preq_to_root +
  889. rtw_root_path_confirmation_jiffies(adapter)) ||
  890. rtw_time_before(rtw_get_current_time(), path->last_preq_to_root))) &&
  891. !(path->flags & RTW_MESH_PATH_FIXED) && (ttl != 0)) {
  892. u8 preq_node_flag = RTW_PREQ_Q_F_START | RTW_PREQ_Q_F_REFRESH;
  893. RTW_HWMP_DBG("time to refresh root path "MAC_FMT"\n",
  894. MAC_ARG(originator_addr));
  895. #ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
  896. if (RTW_SN_LT(path->sn, originator_sn) &&
  897. (path->rann_metric + mshcfg->sane_metric_delta < metric) &&
  898. _rtw_memcmp(bcast_addr, path->rann_snd_addr, ETH_ALEN) == _FALSE) {
  899. RTW_HWMP_DBG("Trigger additional check for root "
  900. "confirm PREQ. rann_snd_addr = "MAC_FMT
  901. "add_chk_rann_snd_addr= "MAC_FMT"\n",
  902. MAC_ARG(mgmt->addr2),
  903. MAC_ARG(path->rann_snd_addr));
  904. _rtw_memcpy(path->add_chk_rann_snd_addr,
  905. path->rann_snd_addr, ETH_ALEN);
  906. preq_node_flag |= RTW_PREQ_Q_F_CHK;
  907. }
  908. #endif
  909. rtw_mesh_queue_preq(path, preq_node_flag);
  910. path->last_preq_to_root = rtw_get_current_time();
  911. }
  912. path->sn = originator_sn;
  913. path->rann_metric = metric + metric_txsta;
  914. path->is_root = _TRUE;
  915. /* Recording RANNs sender address to send individually
  916. * addressed PREQs destined for root mesh STA */
  917. _rtw_memcpy(path->rann_snd_addr, mgmt->addr2, ETH_ALEN);
  918. if (root_is_gate) {
  919. path->gate_ann_int = interval;
  920. path->gate_asked = false;
  921. rtw_mesh_path_add_gate(path);
  922. } else if (path->is_gate) {
  923. enter_critical_bh(&path->state_lock);
  924. rtw_mesh_gate_del(adapter->mesh_info.mesh_paths, path);
  925. exit_critical_bh(&path->state_lock);
  926. }
  927. if (ttl <= 1) {
  928. mshstats->dropped_frames_ttl++;
  929. rtw_rcu_read_unlock();
  930. return;
  931. }
  932. ttl--;
  933. if (mshcfg->dot11MeshForwarding) {
  934. rtw_mesh_path_sel_frame_tx(RTW_MPATH_RANN, flags, originator_addr,
  935. originator_sn, 0, NULL, 0, bcast_addr,
  936. hopcount, ttl, interval,
  937. metric + metric_txsta, 0, adapter);
  938. }
  939. rtw_rcu_read_unlock();
  940. }
  941. static u32 rtw_hwmp_route_info_get(_adapter *adapter,
  942. struct rtw_ieee80211_hdr_3addr *mgmt,
  943. const u8 *hwmp_ie, enum rtw_mpath_frame_type action)
  944. {
  945. struct rtw_mesh_path *path;
  946. struct sta_priv *pstapriv = &adapter->stapriv;
  947. struct sta_info *sta;
  948. BOOLEAN fresh_info;
  949. const u8 *originator_addr, *ta;
  950. u32 originator_sn, originator_metric;
  951. unsigned long originator_lifetime, exp_time;
  952. u32 last_hop_metric, new_metric;
  953. BOOLEAN process = _TRUE;
  954. rtw_rcu_read_lock();
  955. sta = rtw_get_stainfo(pstapriv, mgmt->addr2);
  956. if (!sta) {
  957. rtw_rcu_read_unlock();
  958. return 0;
  959. }
  960. last_hop_metric = rtw_airtime_link_metric_get(adapter, sta);
  961. /* Update and check originator routing info */
  962. fresh_info = _TRUE;
  963. switch (action) {
  964. case RTW_MPATH_PREQ:
  965. originator_addr = RTW_PREQ_IE_ORIG_ADDR(hwmp_ie);
  966. originator_sn = RTW_PREQ_IE_ORIG_SN(hwmp_ie);
  967. originator_lifetime = RTW_PREQ_IE_LIFETIME(hwmp_ie);
  968. originator_metric = RTW_PREQ_IE_METRIC(hwmp_ie);
  969. break;
  970. case RTW_MPATH_PREP:
  971. /* Note: For coding, the naming is not consist with spec */
  972. originator_addr = RTW_PREP_IE_TARGET_ADDR(hwmp_ie);
  973. originator_sn = RTW_PREP_IE_TARGET_SN(hwmp_ie);
  974. originator_lifetime = RTW_PREP_IE_LIFETIME(hwmp_ie);
  975. originator_metric = RTW_PREP_IE_METRIC(hwmp_ie);
  976. break;
  977. default:
  978. rtw_rcu_read_unlock();
  979. return 0;
  980. }
  981. new_metric = originator_metric + last_hop_metric;
  982. if (new_metric < originator_metric)
  983. new_metric = RTW_MAX_METRIC;
  984. exp_time = RTW_TU_TO_EXP_TIME(originator_lifetime);
  985. if (rtw_ether_addr_equal(originator_addr, adapter_mac_addr(adapter))) {
  986. process = _FALSE;
  987. fresh_info = _FALSE;
  988. } else {
  989. path = rtw_mesh_path_lookup(adapter, originator_addr);
  990. if (path) {
  991. enter_critical_bh(&path->state_lock);
  992. if (path->flags & RTW_MESH_PATH_FIXED)
  993. fresh_info = _FALSE;
  994. else if ((path->flags & RTW_MESH_PATH_ACTIVE) &&
  995. (path->flags & RTW_MESH_PATH_SN_VALID)) {
  996. if (RTW_SN_GT(path->sn, originator_sn) ||
  997. (path->sn == originator_sn &&
  998. new_metric >= path->metric)) {
  999. process = _FALSE;
  1000. fresh_info = _FALSE;
  1001. }
  1002. } else if (!(path->flags & RTW_MESH_PATH_ACTIVE)) {
  1003. BOOLEAN have_sn, newer_sn, bounced;
  1004. have_sn = path->flags & RTW_MESH_PATH_SN_VALID;
  1005. newer_sn = have_sn && RTW_SN_GT(originator_sn, path->sn);
  1006. bounced = have_sn &&
  1007. (RTW_SN_DELTA(originator_sn, path->sn) >
  1008. RTW_MAX_SANE_SN_DELTA);
  1009. if (!have_sn || newer_sn) {
  1010. } else if (bounced) {
  1011. } else {
  1012. process = _FALSE;
  1013. fresh_info = _FALSE;
  1014. }
  1015. }
  1016. } else {
  1017. path = rtw_mesh_path_add(adapter, originator_addr);
  1018. if (IS_ERR(path)) {
  1019. rtw_rcu_read_unlock();
  1020. return 0;
  1021. }
  1022. enter_critical_bh(&path->state_lock);
  1023. }
  1024. if (fresh_info) {
  1025. rtw_mesh_path_assign_nexthop(path, sta);
  1026. path->flags |= RTW_MESH_PATH_SN_VALID;
  1027. path->metric = new_metric;
  1028. path->sn = originator_sn;
  1029. path->exp_time = rtw_time_after(path->exp_time, exp_time)
  1030. ? path->exp_time : exp_time;
  1031. rtw_mesh_path_activate(path);
  1032. #ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
  1033. if (path->is_root && (action == RTW_MPATH_PREP)) {
  1034. _rtw_memcpy(path->rann_snd_addr,
  1035. mgmt->addr2, ETH_ALEN);
  1036. path->rann_metric = new_metric;
  1037. }
  1038. #endif
  1039. exit_critical_bh(&path->state_lock);
  1040. rtw_mesh_path_tx_pending(path);
  1041. } else
  1042. exit_critical_bh(&path->state_lock);
  1043. }
  1044. /* Update and check transmitter routing info */
  1045. ta = mgmt->addr2;
  1046. if (rtw_ether_addr_equal(originator_addr, ta))
  1047. fresh_info = _FALSE;
  1048. else {
  1049. fresh_info = _TRUE;
  1050. path = rtw_mesh_path_lookup(adapter, ta);
  1051. if (path) {
  1052. enter_critical_bh(&path->state_lock);
  1053. if ((path->flags & RTW_MESH_PATH_FIXED) ||
  1054. ((path->flags & RTW_MESH_PATH_ACTIVE) &&
  1055. (last_hop_metric > path->metric)))
  1056. fresh_info = _FALSE;
  1057. } else {
  1058. path = rtw_mesh_path_add(adapter, ta);
  1059. if (IS_ERR(path)) {
  1060. rtw_rcu_read_unlock();
  1061. return 0;
  1062. }
  1063. enter_critical_bh(&path->state_lock);
  1064. }
  1065. if (fresh_info) {
  1066. rtw_mesh_path_assign_nexthop(path, sta);
  1067. path->metric = last_hop_metric;
  1068. path->exp_time = rtw_time_after(path->exp_time, exp_time)
  1069. ? path->exp_time : exp_time;
  1070. rtw_mesh_path_activate(path);
  1071. exit_critical_bh(&path->state_lock);
  1072. rtw_mesh_path_tx_pending(path);
  1073. } else
  1074. exit_critical_bh(&path->state_lock);
  1075. }
  1076. rtw_rcu_read_unlock();
  1077. return process ? new_metric : 0;
  1078. }
  1079. static void rtw_mesh_rx_hwmp_frame_cnts(_adapter *adapter, u8 *addr)
  1080. {
  1081. struct sta_info *sta;
  1082. sta = rtw_get_stainfo(&adapter->stapriv, addr);
  1083. if (sta)
  1084. sta->sta_stats.rx_hwmp_pkts++;
  1085. }
  1086. void rtw_mesh_rx_path_sel_frame(_adapter *adapter, union recv_frame *rframe)
  1087. {
  1088. struct mesh_plink_ent *plink = NULL;
  1089. struct rtw_ieee802_11_elems elems;
  1090. u32 path_metric;
  1091. struct rx_pkt_attrib *attrib = &rframe->u.hdr.attrib;
  1092. u8 *pframe = rframe->u.hdr.rx_data, *start;
  1093. uint frame_len = rframe->u.hdr.len, left;
  1094. struct rtw_ieee80211_hdr_3addr *frame_hdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
  1095. u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  1096. ParseRes parse_res;
  1097. plink = rtw_mesh_plink_get(adapter, get_addr2_ptr(pframe));
  1098. if (!plink || plink->plink_state != RTW_MESH_PLINK_ESTAB)
  1099. return;
  1100. rtw_mesh_rx_hwmp_frame_cnts(adapter, get_addr2_ptr(pframe));
  1101. /* Mesh action frame IE offset = 2 */
  1102. attrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  1103. left = frame_len - attrib->hdrlen - attrib->iv_len - attrib->icv_len - 2;
  1104. start = pframe + attrib->hdrlen + 2;
  1105. parse_res = rtw_ieee802_11_parse_elems(start, left, &elems, 1);
  1106. if (parse_res == ParseFailed)
  1107. RTW_HWMP_INFO(FUNC_ADPT_FMT" Path Select Frame ParseFailed\n"
  1108. , FUNC_ADPT_ARG(adapter));
  1109. else if (parse_res == ParseUnknown)
  1110. RTW_HWMP_INFO(FUNC_ADPT_FMT" Path Select Frame ParseUnknown\n"
  1111. , FUNC_ADPT_ARG(adapter));
  1112. if (elems.preq) {
  1113. if (elems.preq_len != 37)
  1114. /* Right now we support just 1 destination and no AE */
  1115. return;
  1116. path_metric = rtw_hwmp_route_info_get(adapter, frame_hdr, elems.preq,
  1117. MPATH_PREQ);
  1118. if (path_metric)
  1119. rtw_hwmp_preq_frame_process(adapter, frame_hdr, elems.preq,
  1120. path_metric);
  1121. }
  1122. if (elems.prep) {
  1123. if (elems.prep_len != 31)
  1124. /* Right now we support no AE */
  1125. return;
  1126. path_metric = rtw_hwmp_route_info_get(adapter, frame_hdr, elems.prep,
  1127. MPATH_PREP);
  1128. if (path_metric)
  1129. rtw_hwmp_prep_frame_process(adapter, frame_hdr, elems.prep,
  1130. path_metric);
  1131. }
  1132. if (elems.perr) {
  1133. if (elems.perr_len != 15)
  1134. /* Right now we support only one destination per PERR */
  1135. return;
  1136. rtw_hwmp_perr_frame_process(adapter, frame_hdr, elems.perr);
  1137. }
  1138. if (elems.rann)
  1139. rtw_hwmp_rann_frame_process(adapter, frame_hdr, (struct rtw_ieee80211_rann_ie *)elems.rann);
  1140. }
  1141. void rtw_mesh_queue_preq(struct rtw_mesh_path *path, u8 flags)
  1142. {
  1143. _adapter *adapter = path->adapter;
  1144. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1145. struct rtw_mesh_preq_queue *preq_node;
  1146. preq_node = rtw_malloc(sizeof(struct rtw_mesh_preq_queue));
  1147. if (!preq_node) {
  1148. RTW_HWMP_INFO("could not allocate PREQ node\n");
  1149. return;
  1150. }
  1151. enter_critical_bh(&minfo->mesh_preq_queue_lock);
  1152. if (minfo->preq_queue_len == RTW_MAX_PREQ_QUEUE_LEN) {
  1153. exit_critical_bh(&minfo->mesh_preq_queue_lock);
  1154. rtw_mfree(preq_node, sizeof(struct rtw_mesh_preq_queue));
  1155. if (rtw_print_ratelimit())
  1156. RTW_HWMP_INFO("PREQ node queue full\n");
  1157. return;
  1158. }
  1159. _rtw_spinlock(&path->state_lock);
  1160. if (path->flags & RTW_MESH_PATH_REQ_QUEUED) {
  1161. _rtw_spinunlock(&path->state_lock);
  1162. exit_critical_bh(&minfo->mesh_preq_queue_lock);
  1163. rtw_mfree(preq_node, sizeof(struct rtw_mesh_preq_queue));
  1164. return;
  1165. }
  1166. _rtw_memcpy(preq_node->dst, path->dst, ETH_ALEN);
  1167. preq_node->flags = flags;
  1168. path->flags |= RTW_MESH_PATH_REQ_QUEUED;
  1169. #ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
  1170. if (flags & RTW_PREQ_Q_F_CHK)
  1171. path->flags |= RTW_MESH_PATH_ROOT_ADD_CHK;
  1172. #endif
  1173. if (flags & RTW_PREQ_Q_F_PEER_AKA)
  1174. path->flags |= RTW_MESH_PATH_PEER_AKA;
  1175. _rtw_spinunlock(&path->state_lock);
  1176. rtw_list_insert_tail(&preq_node->list, &minfo->preq_queue.list);
  1177. ++minfo->preq_queue_len;
  1178. exit_critical_bh(&minfo->mesh_preq_queue_lock);
  1179. if (rtw_time_after(rtw_get_current_time(), minfo->last_preq + rtw_min_preq_int_jiff(adapter)))
  1180. rtw_mesh_work(&adapter->mesh_work);
  1181. else if (rtw_time_before(rtw_get_current_time(), minfo->last_preq)) {
  1182. /* systime wrapped around issue */
  1183. minfo->last_preq = rtw_get_current_time() - rtw_min_preq_int_jiff(adapter) - 1;
  1184. rtw_mesh_work(&adapter->mesh_work);
  1185. } else
  1186. rtw_mod_timer(&adapter->mesh_path_timer, minfo->last_preq +
  1187. rtw_min_preq_int_jiff(adapter) + 1);
  1188. }
  1189. static const u8 *rtw_hwmp_preq_da(struct rtw_mesh_path *path,
  1190. BOOLEAN is_root_add_chk, BOOLEAN da_is_peer)
  1191. {
  1192. const u8 *da;
  1193. if (da_is_peer)
  1194. da = path->dst;
  1195. else if (path->is_root)
  1196. #ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
  1197. da = is_root_add_chk ? path->add_chk_rann_snd_addr:
  1198. path->rann_snd_addr;
  1199. #else
  1200. da = path->rann_snd_addr;
  1201. #endif
  1202. else
  1203. da = bcast_addr;
  1204. return da;
  1205. }
  1206. void rtw_mesh_path_start_discovery(_adapter *adapter)
  1207. {
  1208. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1209. struct rtw_mesh_cfg *mshcfg = &adapter->mesh_cfg;
  1210. struct rtw_mesh_preq_queue *preq_node;
  1211. struct rtw_mesh_path *path;
  1212. u8 ttl, target_flags = 0;
  1213. const u8 *da;
  1214. u32 lifetime;
  1215. u8 flags = 0;
  1216. BOOLEAN is_root_add_chk = _FALSE;
  1217. BOOLEAN da_is_peer;
  1218. enter_critical_bh(&minfo->mesh_preq_queue_lock);
  1219. if (!minfo->preq_queue_len ||
  1220. rtw_time_before(rtw_get_current_time(), minfo->last_preq +
  1221. rtw_min_preq_int_jiff(adapter))) {
  1222. exit_critical_bh(&minfo->mesh_preq_queue_lock);
  1223. return;
  1224. }
  1225. preq_node = rtw_list_first_entry(&minfo->preq_queue.list,
  1226. struct rtw_mesh_preq_queue, list);
  1227. rtw_list_delete(&preq_node->list); /* list_del_init(&preq_node->list); */
  1228. --minfo->preq_queue_len;
  1229. exit_critical_bh(&minfo->mesh_preq_queue_lock);
  1230. rtw_rcu_read_lock();
  1231. path = rtw_mesh_path_lookup(adapter, preq_node->dst);
  1232. if (!path)
  1233. goto enddiscovery;
  1234. enter_critical_bh(&path->state_lock);
  1235. if (path->flags & (RTW_MESH_PATH_DELETED | RTW_MESH_PATH_FIXED)) {
  1236. exit_critical_bh(&path->state_lock);
  1237. goto enddiscovery;
  1238. }
  1239. path->flags &= ~RTW_MESH_PATH_REQ_QUEUED;
  1240. if (preq_node->flags & RTW_PREQ_Q_F_START) {
  1241. if (path->flags & RTW_MESH_PATH_RESOLVING) {
  1242. exit_critical_bh(&path->state_lock);
  1243. goto enddiscovery;
  1244. } else {
  1245. path->flags &= ~RTW_MESH_PATH_RESOLVED;
  1246. path->flags |= RTW_MESH_PATH_RESOLVING;
  1247. path->discovery_retries = 0;
  1248. path->discovery_timeout = rtw_disc_timeout_jiff(adapter);
  1249. }
  1250. } else if (!(path->flags & RTW_MESH_PATH_RESOLVING) ||
  1251. path->flags & RTW_MESH_PATH_RESOLVED) {
  1252. path->flags &= ~RTW_MESH_PATH_RESOLVING;
  1253. exit_critical_bh(&path->state_lock);
  1254. goto enddiscovery;
  1255. }
  1256. minfo->last_preq = rtw_get_current_time();
  1257. if (rtw_time_after(rtw_get_current_time(), minfo->last_sn_update +
  1258. rtw_net_traversal_jiffies(adapter)) ||
  1259. rtw_time_before(rtw_get_current_time(), minfo->last_sn_update)) {
  1260. ++minfo->sn;
  1261. minfo->last_sn_update = rtw_get_current_time();
  1262. }
  1263. lifetime = rtw_default_lifetime(adapter);
  1264. ttl = mshcfg->element_ttl;
  1265. if (ttl == 0) {
  1266. minfo->mshstats.dropped_frames_ttl++;
  1267. exit_critical_bh(&path->state_lock);
  1268. goto enddiscovery;
  1269. }
  1270. if (preq_node->flags & RTW_PREQ_Q_F_REFRESH)
  1271. target_flags |= RTW_IEEE80211_PREQ_TO_FLAG;
  1272. else
  1273. target_flags &= ~RTW_IEEE80211_PREQ_TO_FLAG;
  1274. #ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
  1275. is_root_add_chk = !!(path->flags & RTW_MESH_PATH_ROOT_ADD_CHK);
  1276. #endif
  1277. da_is_peer = !!(path->flags & RTW_MESH_PATH_PEER_AKA);
  1278. exit_critical_bh(&path->state_lock);
  1279. da = rtw_hwmp_preq_da(path, is_root_add_chk, da_is_peer);
  1280. #ifdef CONFIG_RTW_MESH_ON_DMD_GANN
  1281. flags = (mshcfg->dot11MeshGateAnnouncementProtocol)
  1282. ? RTW_IEEE80211_PREQ_IS_GATE_FLAG : 0;
  1283. #endif
  1284. rtw_mesh_path_sel_frame_tx(RTW_MPATH_PREQ, flags, adapter_mac_addr(adapter), minfo->sn,
  1285. target_flags, path->dst, path->sn, da, 0,
  1286. ttl, lifetime, 0, minfo->preq_id++, adapter);
  1287. rtw_mod_timer(&path->timer, rtw_get_current_time() + path->discovery_timeout);
  1288. enddiscovery:
  1289. rtw_rcu_read_unlock();
  1290. rtw_mfree(preq_node, sizeof(struct rtw_mesh_preq_queue));
  1291. }
  1292. void rtw_mesh_path_timer(void *ctx)
  1293. {
  1294. struct rtw_mesh_path *path = (void *) ctx;
  1295. _adapter *adapter = path->adapter;
  1296. int ret;
  1297. u8 retry = 0;
  1298. #ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
  1299. struct rtw_mesh_cfg *mshcfg = &adapter->mesh_cfg;
  1300. #endif
  1301. /* TBD: Proctect for suspend */
  1302. #if 0
  1303. if (suspending)
  1304. return;
  1305. #endif
  1306. enter_critical_bh(&path->state_lock);
  1307. if (path->flags & RTW_MESH_PATH_RESOLVED ||
  1308. (!(path->flags & RTW_MESH_PATH_RESOLVING))) {
  1309. path->flags &= ~(RTW_MESH_PATH_RESOLVING |
  1310. RTW_MESH_PATH_RESOLVED |
  1311. RTW_MESH_PATH_ROOT_ADD_CHK |
  1312. RTW_MESH_PATH_PEER_AKA);
  1313. exit_critical_bh(&path->state_lock);
  1314. } else if (path->discovery_retries < rtw_max_preq_retries(adapter)) {
  1315. ++path->discovery_retries;
  1316. path->discovery_timeout *= 2;
  1317. path->flags &= ~RTW_MESH_PATH_REQ_QUEUED;
  1318. #ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
  1319. if (path->discovery_retries > mshcfg->max_root_add_chk_cnt)
  1320. path->flags &= ~RTW_MESH_PATH_ROOT_ADD_CHK;
  1321. #endif
  1322. if (path->gate_asked)
  1323. retry |= RTW_PREQ_Q_F_REFRESH;
  1324. exit_critical_bh(&path->state_lock);
  1325. rtw_mesh_queue_preq(path, retry);
  1326. } else {
  1327. path->flags &= ~(RTW_MESH_PATH_RESOLVING |
  1328. RTW_MESH_PATH_RESOLVED |
  1329. RTW_MESH_PATH_REQ_QUEUED |
  1330. RTW_MESH_PATH_ROOT_ADD_CHK |
  1331. RTW_MESH_PATH_PEER_AKA);
  1332. path->exp_time = rtw_get_current_time();
  1333. exit_critical_bh(&path->state_lock);
  1334. if (!path->is_gate && rtw_mesh_gate_num(adapter) > 0) {
  1335. ret = rtw_mesh_path_send_to_gates(path);
  1336. if (ret)
  1337. RTW_HWMP_DBG("no gate was reachable\n");
  1338. } else
  1339. rtw_mesh_path_flush_pending(path);
  1340. }
  1341. }
  1342. void rtw_mesh_path_tx_root_frame(_adapter *adapter)
  1343. {
  1344. struct rtw_mesh_cfg *mshcfg = &adapter->mesh_cfg;
  1345. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1346. u32 interval = mshcfg->dot11MeshHWMPRannInterval;
  1347. u8 flags, target_flags = 0;
  1348. flags = (mshcfg->dot11MeshGateAnnouncementProtocol)
  1349. ? RTW_RANN_FLAG_IS_GATE : 0;
  1350. switch (mshcfg->dot11MeshHWMPRootMode) {
  1351. case RTW_IEEE80211_PROACTIVE_RANN:
  1352. rtw_mesh_path_sel_frame_tx(RTW_MPATH_RANN, flags, adapter_mac_addr(adapter),
  1353. ++minfo->sn, 0, NULL, 0, bcast_addr,
  1354. 0, mshcfg->element_ttl,
  1355. interval, 0, 0, adapter);
  1356. break;
  1357. case RTW_IEEE80211_PROACTIVE_PREQ_WITH_PREP:
  1358. flags |= RTW_IEEE80211_PREQ_PROACTIVE_PREP_FLAG;
  1359. case RTW_IEEE80211_PROACTIVE_PREQ_NO_PREP:
  1360. interval = mshcfg->dot11MeshHWMPactivePathToRootTimeout;
  1361. target_flags |= RTW_IEEE80211_PREQ_TO_FLAG |
  1362. RTW_IEEE80211_PREQ_USN_FLAG;
  1363. rtw_mesh_path_sel_frame_tx(RTW_MPATH_PREQ, flags, adapter_mac_addr(adapter),
  1364. ++minfo->sn, target_flags,
  1365. (u8 *) bcast_addr, 0, bcast_addr,
  1366. 0, mshcfg->element_ttl, interval,
  1367. 0, minfo->preq_id++, adapter);
  1368. break;
  1369. default:
  1370. RTW_HWMP_INFO("Proactive mechanism not supported\n");
  1371. return;
  1372. }
  1373. }
  1374. void rtw_mesh_work(_workitem *work)
  1375. {
  1376. /* use kernel global workqueue */
  1377. _set_workitem(work);
  1378. }
  1379. void rtw_ieee80211_mesh_path_timer(void *ctx)
  1380. {
  1381. _adapter *adapter = (_adapter *)ctx;
  1382. rtw_mesh_work(&adapter->mesh_work);
  1383. }
  1384. void rtw_ieee80211_mesh_path_root_timer(void *ctx)
  1385. {
  1386. _adapter *adapter = (_adapter *)ctx;
  1387. rtw_set_bit(RTW_MESH_WORK_ROOT, &adapter->wrkq_flags);
  1388. rtw_mesh_work(&adapter->mesh_work);
  1389. }
  1390. static void rtw_ieee80211_mesh_rootpath(_adapter *adapter)
  1391. {
  1392. u32 interval;
  1393. rtw_mesh_path_tx_root_frame(adapter);
  1394. if (adapter->mesh_cfg.dot11MeshHWMPRootMode == RTW_IEEE80211_PROACTIVE_RANN)
  1395. interval = adapter->mesh_cfg.dot11MeshHWMPRannInterval;
  1396. else
  1397. interval = adapter->mesh_cfg.dot11MeshHWMProotInterval;
  1398. rtw_mod_timer(&adapter->mesh_path_root_timer,
  1399. RTW_TU_TO_EXP_TIME(interval));
  1400. }
  1401. BOOLEAN rtw_ieee80211_mesh_root_setup(_adapter *adapter)
  1402. {
  1403. BOOLEAN root_enabled = _FALSE;
  1404. if (adapter->mesh_cfg.dot11MeshHWMPRootMode > RTW_IEEE80211_ROOTMODE_ROOT) {
  1405. rtw_set_bit(RTW_MESH_WORK_ROOT, &adapter->wrkq_flags);
  1406. root_enabled = _TRUE;
  1407. }
  1408. else {
  1409. rtw_clear_bit(RTW_MESH_WORK_ROOT, &adapter->wrkq_flags);
  1410. /* stop running timer */
  1411. _cancel_timer_ex(&adapter->mesh_path_root_timer);
  1412. root_enabled = _FALSE;
  1413. }
  1414. return root_enabled;
  1415. }
  1416. void rtw_mesh_work_hdl(_workitem *work)
  1417. {
  1418. _adapter *adapter = container_of(work, _adapter, mesh_work);
  1419. while(adapter->mesh_info.preq_queue_len) {
  1420. if (rtw_time_after(rtw_get_current_time(),
  1421. adapter->mesh_info.last_preq + rtw_min_preq_int_jiff(adapter)))
  1422. /* It will consume preq_queue_len */
  1423. rtw_mesh_path_start_discovery(adapter);
  1424. else {
  1425. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1426. rtw_mod_timer(&adapter->mesh_path_timer,
  1427. minfo->last_preq + rtw_min_preq_int_jiff(adapter) + 1);
  1428. break;
  1429. }
  1430. }
  1431. if (rtw_test_and_clear_bit(RTW_MESH_WORK_ROOT, &adapter->wrkq_flags))
  1432. rtw_ieee80211_mesh_rootpath(adapter);
  1433. }
  1434. #ifndef RTW_PER_CMD_SUPPORT_FW
  1435. static void rtw_update_metric_directly(_adapter *adapter)
  1436. {
  1437. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1438. struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
  1439. u8 i;
  1440. for (i = 0; i < macid_ctl->num; i++) {
  1441. u8 role;
  1442. role = GET_H2CCMD_MSRRPT_PARM_ROLE(&macid_ctl->h2c_msr[i]);
  1443. if (role == H2C_MSR_ROLE_MESH) {
  1444. struct sta_info *sta = macid_ctl->sta[i];
  1445. u8 rate_idx, sgi, bw;
  1446. u32 rate;
  1447. if (!sta)
  1448. continue;
  1449. rate_idx = rtw_get_current_tx_rate(adapter, sta);
  1450. sgi = rtw_get_current_tx_sgi(adapter, sta);
  1451. bw = sta->cmn.bw_mode;
  1452. rate = rtw_desc_rate_to_bitrate(bw, rate_idx, sgi);
  1453. sta->metrics.data_rate = rate;
  1454. }
  1455. }
  1456. }
  1457. #endif
  1458. void rtw_mesh_atlm_param_req_timer(void *ctx)
  1459. {
  1460. _adapter *adapter = (_adapter *)ctx;
  1461. u8 ret = _FAIL;
  1462. #ifdef RTW_PER_CMD_SUPPORT_FW
  1463. ret = rtw_req_per_cmd(adapter);
  1464. if (ret == _FAIL)
  1465. RTW_HWMP_INFO("rtw_req_per_cmd fail\n");
  1466. #else
  1467. rtw_update_metric_directly(adapter);
  1468. #endif
  1469. _set_timer(&adapter->mesh_atlm_param_req_timer, RTW_ATLM_REQ_CYCLE);
  1470. }
  1471. #endif /* CONFIG_RTW_MESH */