rtw_mesh.c 111 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097
  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_MESH_C_
  16. #ifdef CONFIG_RTW_MESH
  17. #include <drv_types.h>
  18. const char *_rtw_mesh_plink_str[] = {
  19. "UNKNOWN",
  20. "LISTEN",
  21. "OPN_SNT",
  22. "OPN_RCVD",
  23. "CNF_RCVD",
  24. "ESTAB",
  25. "HOLDING",
  26. "BLOCKED",
  27. };
  28. const char *_rtw_mesh_ps_str[] = {
  29. "UNKNOWN",
  30. "ACTIVE",
  31. "LSLEEP",
  32. "DSLEEP",
  33. };
  34. const char *_action_self_protected_str[] = {
  35. "ACT_SELF_PROTECTED_RSVD",
  36. "MESH_OPEN",
  37. "MESH_CONF",
  38. "MESH_CLOSE",
  39. "MESH_GK_INFORM",
  40. "MESH_GK_ACK",
  41. };
  42. inline u8 *rtw_set_ie_mesh_id(u8 *buf, u32 *buf_len, const char *mesh_id, u8 id_len)
  43. {
  44. return rtw_set_ie(buf, WLAN_EID_MESH_ID, id_len, mesh_id, buf_len);
  45. }
  46. inline u8 *rtw_set_ie_mesh_config(u8 *buf, u32 *buf_len
  47. , u8 path_sel_proto, u8 path_sel_metric, u8 congest_ctl_mode, u8 sync_method, u8 auth_proto
  48. , u8 num_of_peerings, bool cto_mgate, bool cto_as
  49. , bool accept_peerings, bool mcca_sup, bool mcca_en, bool forwarding
  50. , bool mbca_en, bool tbtt_adj, bool ps_level)
  51. {
  52. u8 conf[7] = {0};
  53. SET_MESH_CONF_ELE_PATH_SEL_PROTO_ID(conf, path_sel_proto);
  54. SET_MESH_CONF_ELE_PATH_SEL_METRIC_ID(conf, path_sel_metric);
  55. SET_MESH_CONF_ELE_CONGEST_CTRL_MODE_ID(conf, congest_ctl_mode);
  56. SET_MESH_CONF_ELE_SYNC_METHOD_ID(conf, sync_method);
  57. SET_MESH_CONF_ELE_AUTH_PROTO_ID(conf, auth_proto);
  58. SET_MESH_CONF_ELE_CTO_MGATE(conf, cto_mgate);
  59. SET_MESH_CONF_ELE_NUM_OF_PEERINGS(conf, num_of_peerings);
  60. SET_MESH_CONF_ELE_CTO_AS(conf, cto_as);
  61. SET_MESH_CONF_ELE_ACCEPT_PEERINGS(conf, accept_peerings);
  62. SET_MESH_CONF_ELE_MCCA_SUP(conf, mcca_sup);
  63. SET_MESH_CONF_ELE_MCCA_EN(conf, mcca_en);
  64. SET_MESH_CONF_ELE_FORWARDING(conf, forwarding);
  65. SET_MESH_CONF_ELE_MBCA_EN(conf, mbca_en);
  66. SET_MESH_CONF_ELE_TBTT_ADJ(conf, tbtt_adj);
  67. SET_MESH_CONF_ELE_PS_LEVEL(conf, ps_level);
  68. return rtw_set_ie(buf, WLAN_EID_MESH_CONFIG, 7, conf, buf_len);
  69. }
  70. inline u8 *rtw_set_ie_mpm(u8 *buf, u32 *buf_len
  71. , u8 proto_id, u16 llid, u16 *plid, u16 *reason, u8 *chosen_pmk)
  72. {
  73. u8 data[24] = {0};
  74. u8 *pos = data;
  75. RTW_PUT_LE16(pos, proto_id);
  76. pos += 2;
  77. RTW_PUT_LE16(pos, llid);
  78. pos += 2;
  79. if (plid) {
  80. RTW_PUT_LE16(pos, *plid);
  81. pos += 2;
  82. }
  83. if (reason) {
  84. RTW_PUT_LE16(pos, *reason);
  85. pos += 2;
  86. }
  87. if (chosen_pmk) {
  88. _rtw_memcpy(pos, chosen_pmk, 16);
  89. pos += 16;
  90. }
  91. return rtw_set_ie(buf, WLAN_EID_MPM, pos - data, data, buf_len);
  92. }
  93. bool rtw_bss_is_forwarding(WLAN_BSSID_EX *bss)
  94. {
  95. u8 *ie;
  96. int ie_len;
  97. bool ret = 0;
  98. ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len,
  99. BSS_EX_TLV_IES_LEN(bss));
  100. if (!ie || ie_len != 7)
  101. goto exit;
  102. ret = GET_MESH_CONF_ELE_FORWARDING(ie + 2);
  103. exit:
  104. return ret;
  105. }
  106. bool rtw_bss_is_cto_mgate(WLAN_BSSID_EX *bss)
  107. {
  108. u8 *ie;
  109. int ie_len;
  110. bool ret = 0;
  111. ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len,
  112. BSS_EX_TLV_IES_LEN(bss));
  113. if (!ie || ie_len != 7)
  114. goto exit;
  115. ret = GET_MESH_CONF_ELE_CTO_MGATE(ie + 2);
  116. exit:
  117. return ret;
  118. }
  119. int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
  120. {
  121. int ret = 0;
  122. u8 *a_mconf_ie, *b_mconf_ie;
  123. sint a_mconf_ie_len, b_mconf_ie_len;
  124. if (a->InfrastructureMode != Ndis802_11_mesh)
  125. goto exit;
  126. a_mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(a), WLAN_EID_MESH_CONFIG, &a_mconf_ie_len, BSS_EX_TLV_IES_LEN(a));
  127. if (!a_mconf_ie || a_mconf_ie_len != 7)
  128. goto exit;
  129. if (b->InfrastructureMode != Ndis802_11_mesh)
  130. goto exit;
  131. b_mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(b), WLAN_EID_MESH_CONFIG, &b_mconf_ie_len, BSS_EX_TLV_IES_LEN(b));
  132. if (!b_mconf_ie || b_mconf_ie_len != 7)
  133. goto exit;
  134. if (a->mesh_id.SsidLength != b->mesh_id.SsidLength
  135. || _rtw_memcmp(a->mesh_id.Ssid, b->mesh_id.Ssid, a->mesh_id.SsidLength) == _FALSE)
  136. goto exit;
  137. if (_rtw_memcmp(a_mconf_ie + 2, b_mconf_ie + 2, 5) == _FALSE)
  138. goto exit;
  139. ret = 1;
  140. exit:
  141. return ret;
  142. }
  143. int rtw_bss_is_candidate_mesh_peer(WLAN_BSSID_EX *self, WLAN_BSSID_EX *target, u8 ch, u8 add_peer)
  144. {
  145. int ret = 0;
  146. u8 *mconf_ie;
  147. sint mconf_ie_len;
  148. int i, j;
  149. if (!rtw_bss_is_same_mbss(self, target))
  150. goto exit;
  151. if (ch && self->Configuration.DSConfig != target->Configuration.DSConfig)
  152. goto exit;
  153. if (add_peer) {
  154. /* Accept additional mesh peerings */
  155. mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(target), WLAN_EID_MESH_CONFIG, &mconf_ie_len, BSS_EX_TLV_IES_LEN(target));
  156. if (!mconf_ie || mconf_ie_len != 7)
  157. goto exit;
  158. if (GET_MESH_CONF_ELE_ACCEPT_PEERINGS(mconf_ie + 2) == 0)
  159. goto exit;
  160. }
  161. /* BSSBasicRateSet */
  162. for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
  163. if (target->SupportedRates[i] == 0)
  164. break;
  165. if (target->SupportedRates[i] & 0x80) {
  166. u8 match = 0;
  167. if (!ch) {
  168. /* off-channel, check target with our hardcode capability */
  169. if (target->Configuration.DSConfig > 14)
  170. match = rtw_is_basic_rate_ofdm(target->SupportedRates[i]);
  171. else
  172. match = rtw_is_basic_rate_mix(target->SupportedRates[i]);
  173. } else {
  174. for (j = 0; j < NDIS_802_11_LENGTH_RATES_EX; j++) {
  175. if (self->SupportedRates[j] == 0)
  176. break;
  177. if (self->SupportedRates[j] == target->SupportedRates[i]) {
  178. match = 1;
  179. break;
  180. }
  181. }
  182. }
  183. if (!match)
  184. goto exit;
  185. }
  186. }
  187. /* BSSBasicMCSSet */
  188. /* 802.1X connected to AS ? */
  189. ret = 1;
  190. exit:
  191. return ret;
  192. }
  193. void rtw_mesh_bss_peering_status(WLAN_BSSID_EX *bss, u8 *nop, u8 *accept)
  194. {
  195. u8 *ie;
  196. int ie_len;
  197. if (nop)
  198. *nop = 0;
  199. if (accept)
  200. *accept = 0;
  201. ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len,
  202. BSS_EX_TLV_IES_LEN(bss));
  203. if (!ie || ie_len != 7)
  204. goto exit;
  205. if (nop)
  206. *nop = GET_MESH_CONF_ELE_NUM_OF_PEERINGS(ie + 2);
  207. if (accept)
  208. *accept = GET_MESH_CONF_ELE_ACCEPT_PEERINGS(ie + 2);
  209. exit:
  210. return;
  211. }
  212. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  213. void rtw_mesh_update_scanned_acnode_status(_adapter *adapter, struct wlan_network *scanned)
  214. {
  215. bool acnode;
  216. u8 nop, accept;
  217. rtw_mesh_bss_peering_status(&scanned->network, &nop, &accept);
  218. acnode = !nop && accept;
  219. if (acnode && scanned->acnode_stime == 0) {
  220. scanned->acnode_stime = rtw_get_current_time();
  221. if (scanned->acnode_stime == 0)
  222. scanned->acnode_stime++;
  223. } else if (!acnode) {
  224. scanned->acnode_stime = 0;
  225. scanned->acnode_notify_etime = 0;
  226. }
  227. }
  228. bool rtw_mesh_scanned_is_acnode_confirmed(_adapter *adapter, struct wlan_network *scanned)
  229. {
  230. return scanned->acnode_stime
  231. && rtw_get_passing_time_ms(scanned->acnode_stime)
  232. > adapter->mesh_cfg.peer_sel_policy.acnode_conf_timeout_ms;
  233. }
  234. static bool rtw_mesh_scanned_is_acnode_allow_notify(_adapter *adapter, struct wlan_network *scanned)
  235. {
  236. return scanned->acnode_notify_etime
  237. && rtw_time_after(scanned->acnode_notify_etime, rtw_get_current_time());
  238. }
  239. bool rtw_mesh_acnode_prevent_allow_sacrifice(_adapter *adapter)
  240. {
  241. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  242. struct sta_priv *stapriv = &adapter->stapriv;
  243. bool allow = 0;
  244. if (!mcfg->peer_sel_policy.acnode_prevent
  245. || mcfg->max_peer_links <= 1
  246. || stapriv->asoc_list_cnt < mcfg->max_peer_links)
  247. goto exit;
  248. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  249. if (rtw_mesh_cto_mgate_required(adapter))
  250. goto exit;
  251. #endif
  252. allow = 1;
  253. exit:
  254. return allow;
  255. }
  256. static bool rtw_mesh_acnode_candidate_exist(_adapter *adapter)
  257. {
  258. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  259. struct sta_priv *stapriv = &adapter->stapriv;
  260. struct mlme_priv *mlme = &adapter->mlmepriv;
  261. _queue *queue = &(mlme->scanned_queue);
  262. _list *head, *list;
  263. _irqL irqL;
  264. struct wlan_network *scanned = NULL;
  265. struct sta_info *sta = NULL;
  266. bool need = 0;
  267. _enter_critical_bh(&(mlme->scanned_queue.lock), &irqL);
  268. head = get_list_head(queue);
  269. list = get_next(head);
  270. while (!rtw_end_of_queue_search(head, list)) {
  271. scanned = LIST_CONTAINOR(list, struct wlan_network, list);
  272. list = get_next(list);
  273. if (rtw_get_passing_time_ms(scanned->last_scanned) < mcfg->peer_sel_policy.scanr_exp_ms
  274. && rtw_mesh_scanned_is_acnode_confirmed(adapter, scanned)
  275. && (!mcfg->rssi_threshold || mcfg->rssi_threshold <= scanned->network.Rssi)
  276. #if CONFIG_RTW_MACADDR_ACL
  277. && rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE
  278. #endif
  279. && rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1)
  280. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  281. && !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
  282. #endif
  283. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  284. && rtw_mesh_cto_mgate_network_filter(adapter, scanned)
  285. #endif
  286. ) {
  287. need = 1;
  288. break;
  289. }
  290. }
  291. _exit_critical_bh(&(mlme->scanned_queue.lock), &irqL);
  292. exit:
  293. return need;
  294. }
  295. static int rtw_mesh_acnode_prevent_sacrifice_chk(_adapter *adapter, struct sta_info **sac, struct sta_info *com)
  296. {
  297. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  298. int updated = 0;
  299. /*
  300. * TODO: compare next_hop reference cnt of forwarding info
  301. * don't sacrifice working next_hop or choose sta with least cnt
  302. */
  303. if (*sac == NULL) {
  304. updated = 1;
  305. goto exit;
  306. }
  307. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  308. if (mcfg->peer_sel_policy.cto_mgate_require
  309. && !mcfg->dot11MeshGateAnnouncementProtocol
  310. ) {
  311. if (IS_CTO_MGATE_CONF_TIMEOUT(com->plink)) {
  312. if (!IS_CTO_MGATE_CONF_TIMEOUT((*sac)->plink)) {
  313. /* blacklist > not blacklist */
  314. updated = 1;
  315. goto exit;
  316. }
  317. } else if (!IS_CTO_MGATE_CONF_DISABLED(com->plink)) {
  318. if (IS_CTO_MGATE_CONF_DISABLED((*sac)->plink)) {
  319. /* confirming > disabled */
  320. updated = 1;
  321. goto exit;
  322. }
  323. }
  324. }
  325. #endif
  326. exit:
  327. if (updated)
  328. *sac = com;
  329. return updated;
  330. }
  331. struct sta_info *_rtw_mesh_acnode_prevent_pick_sacrifice(_adapter *adapter)
  332. {
  333. struct sta_priv *stapriv = &adapter->stapriv;
  334. _list *head, *list;
  335. struct sta_info *sta, *sacrifice = NULL;
  336. u8 nop;
  337. head = &stapriv->asoc_list;
  338. list = get_next(head);
  339. while (rtw_end_of_queue_search(head, list) == _FALSE) {
  340. sta = LIST_CONTAINOR(list, struct sta_info, asoc_list);
  341. list = get_next(list);
  342. if (!sta->plink || !sta->plink->scanned) {
  343. rtw_warn_on(1);
  344. continue;
  345. }
  346. rtw_mesh_bss_peering_status(&sta->plink->scanned->network, &nop, NULL);
  347. if (nop < 2)
  348. continue;
  349. rtw_mesh_acnode_prevent_sacrifice_chk(adapter, &sacrifice, sta);
  350. }
  351. return sacrifice;
  352. }
  353. struct sta_info *rtw_mesh_acnode_prevent_pick_sacrifice(_adapter *adapter)
  354. {
  355. struct sta_priv *stapriv = &adapter->stapriv;
  356. struct sta_info *sacrifice = NULL;
  357. enter_critical_bh(&stapriv->asoc_list_lock);
  358. sacrifice = _rtw_mesh_acnode_prevent_pick_sacrifice(adapter);
  359. exit_critical_bh(&stapriv->asoc_list_lock);
  360. return sacrifice;
  361. }
  362. static void rtw_mesh_acnode_rsvd_chk(_adapter *adapter)
  363. {
  364. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  365. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  366. u8 acnode_rsvd = 0;
  367. if (rtw_mesh_acnode_prevent_allow_sacrifice(adapter)
  368. && rtw_mesh_acnode_prevent_pick_sacrifice(adapter)
  369. && rtw_mesh_acnode_candidate_exist(adapter))
  370. acnode_rsvd = 1;
  371. if (plink_ctl->acnode_rsvd != acnode_rsvd) {
  372. plink_ctl->acnode_rsvd = acnode_rsvd;
  373. RTW_INFO(FUNC_ADPT_FMT" acnode_rsvd = %d\n", FUNC_ADPT_ARG(adapter), plink_ctl->acnode_rsvd);
  374. update_beacon(adapter, WLAN_EID_MESH_CONFIG, NULL, 1);
  375. }
  376. }
  377. static void rtw_mesh_acnode_set_notify_etime(_adapter *adapter, u8 *rframe_whdr)
  378. {
  379. if (adapter->mesh_info.plink_ctl.acnode_rsvd) {
  380. struct wlan_network *scanned = rtw_find_network(&adapter->mlmepriv.scanned_queue, get_addr2_ptr(rframe_whdr));
  381. if (rtw_mesh_scanned_is_acnode_confirmed(adapter, scanned)) {
  382. scanned->acnode_notify_etime = rtw_get_current_time()
  383. + rtw_ms_to_systime(adapter->mesh_cfg.peer_sel_policy.acnode_notify_timeout_ms);
  384. if (scanned->acnode_notify_etime == 0)
  385. scanned->acnode_notify_etime++;
  386. }
  387. }
  388. }
  389. void dump_mesh_acnode_prevent_settings(void *sel, _adapter *adapter)
  390. {
  391. struct mesh_peer_sel_policy *peer_sel_policy = &adapter->mesh_cfg.peer_sel_policy;
  392. RTW_PRINT_SEL(sel, "%-6s %-12s %-14s\n"
  393. , "enable", "conf_timeout", "nofity_timeout");
  394. RTW_PRINT_SEL(sel, "%6u %12u %14u\n"
  395. , peer_sel_policy->acnode_prevent
  396. , peer_sel_policy->acnode_conf_timeout_ms
  397. , peer_sel_policy->acnode_notify_timeout_ms);
  398. }
  399. #endif /* CONFIG_RTW_MESH_ACNODE_PREVENT */
  400. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  401. int rtw_mesh_peer_blacklist_add(_adapter *adapter, const u8 *addr)
  402. {
  403. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  404. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  405. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  406. return rtw_blacklist_add(&plink_ctl->peer_blacklist, addr
  407. , mcfg->peer_sel_policy.peer_blacklist_timeout_ms);
  408. }
  409. int rtw_mesh_peer_blacklist_del(_adapter *adapter, const u8 *addr)
  410. {
  411. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  412. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  413. return rtw_blacklist_del(&plink_ctl->peer_blacklist, addr);
  414. }
  415. int rtw_mesh_peer_blacklist_search(_adapter *adapter, const u8 *addr)
  416. {
  417. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  418. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  419. return rtw_blacklist_search(&plink_ctl->peer_blacklist, addr);
  420. }
  421. void rtw_mesh_peer_blacklist_flush(_adapter *adapter)
  422. {
  423. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  424. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  425. rtw_blacklist_flush(&plink_ctl->peer_blacklist);
  426. }
  427. void dump_mesh_peer_blacklist(void *sel, _adapter *adapter)
  428. {
  429. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  430. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  431. dump_blacklist(sel, &plink_ctl->peer_blacklist, "blacklist");
  432. }
  433. void dump_mesh_peer_blacklist_settings(void *sel, _adapter *adapter)
  434. {
  435. struct mesh_peer_sel_policy *peer_sel_policy = &adapter->mesh_cfg.peer_sel_policy;
  436. RTW_PRINT_SEL(sel, "%-12s %-17s\n"
  437. , "conf_timeout", "blacklist_timeout");
  438. RTW_PRINT_SEL(sel, "%12u %17u\n"
  439. , peer_sel_policy->peer_conf_timeout_ms
  440. , peer_sel_policy->peer_blacklist_timeout_ms);
  441. }
  442. #endif /* CONFIG_RTW_MESH_PEER_BLACKLIST */
  443. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  444. u8 rtw_mesh_cto_mgate_required(_adapter *adapter)
  445. {
  446. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  447. struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
  448. return mcfg->peer_sel_policy.cto_mgate_require
  449. && !rtw_bss_is_cto_mgate(&(mlmeext->mlmext_info.network));
  450. }
  451. u8 rtw_mesh_cto_mgate_network_filter(_adapter *adapter, struct wlan_network *scanned)
  452. {
  453. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  454. struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
  455. return !rtw_mesh_cto_mgate_required(adapter)
  456. || (rtw_bss_is_cto_mgate(&scanned->network)
  457. && !rtw_mesh_cto_mgate_blacklist_search(adapter, scanned->network.MacAddress));
  458. }
  459. int rtw_mesh_cto_mgate_blacklist_add(_adapter *adapter, const u8 *addr)
  460. {
  461. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  462. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  463. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  464. return rtw_blacklist_add(&plink_ctl->cto_mgate_blacklist, addr
  465. , mcfg->peer_sel_policy.cto_mgate_blacklist_timeout_ms);
  466. }
  467. int rtw_mesh_cto_mgate_blacklist_del(_adapter *adapter, const u8 *addr)
  468. {
  469. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  470. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  471. return rtw_blacklist_del(&plink_ctl->cto_mgate_blacklist, addr);
  472. }
  473. int rtw_mesh_cto_mgate_blacklist_search(_adapter *adapter, const u8 *addr)
  474. {
  475. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  476. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  477. return rtw_blacklist_search(&plink_ctl->cto_mgate_blacklist, addr);
  478. }
  479. void rtw_mesh_cto_mgate_blacklist_flush(_adapter *adapter)
  480. {
  481. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  482. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  483. rtw_blacklist_flush(&plink_ctl->cto_mgate_blacklist);
  484. }
  485. void dump_mesh_cto_mgate_blacklist(void *sel, _adapter *adapter)
  486. {
  487. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  488. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  489. dump_blacklist(sel, &plink_ctl->cto_mgate_blacklist, "blacklist");
  490. }
  491. void dump_mesh_cto_mgate_blacklist_settings(void *sel, _adapter *adapter)
  492. {
  493. struct mesh_peer_sel_policy *peer_sel_policy = &adapter->mesh_cfg.peer_sel_policy;
  494. RTW_PRINT_SEL(sel, "%-12s %-17s\n"
  495. , "conf_timeout", "blacklist_timeout");
  496. RTW_PRINT_SEL(sel, "%12u %17u\n"
  497. , peer_sel_policy->cto_mgate_conf_timeout_ms
  498. , peer_sel_policy->cto_mgate_blacklist_timeout_ms);
  499. }
  500. static void rtw_mesh_cto_mgate_blacklist_chk(_adapter *adapter)
  501. {
  502. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  503. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  504. _queue *blist = &plink_ctl->cto_mgate_blacklist;
  505. _list *list, *head;
  506. struct blacklist_ent *ent = NULL;
  507. struct wlan_network *scanned = NULL;
  508. enter_critical_bh(&blist->lock);
  509. head = &blist->queue;
  510. list = get_next(head);
  511. while (rtw_end_of_queue_search(head, list) == _FALSE) {
  512. ent = LIST_CONTAINOR(list, struct blacklist_ent, list);
  513. list = get_next(list);
  514. if (rtw_time_after(rtw_get_current_time(), ent->exp_time)) {
  515. rtw_list_delete(&ent->list);
  516. rtw_mfree(ent, sizeof(struct blacklist_ent));
  517. continue;
  518. }
  519. scanned = rtw_find_network(&adapter->mlmepriv.scanned_queue, ent->addr);
  520. if (!scanned)
  521. continue;
  522. if (rtw_bss_is_forwarding(&scanned->network)) {
  523. rtw_list_delete(&ent->list);
  524. rtw_mfree(ent, sizeof(struct blacklist_ent));
  525. }
  526. }
  527. exit_critical_bh(&blist->lock);
  528. }
  529. #endif /* CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST */
  530. void rtw_chk_candidate_peer_notify(_adapter *adapter, struct wlan_network *scanned)
  531. {
  532. struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
  533. struct mlme_priv *mlme = &adapter->mlmepriv;
  534. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  535. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  536. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  537. bool acnode = 0;
  538. if (IS_CH_WAITING(rfctl) && !IS_UNDER_CAC(rfctl))
  539. goto exit;
  540. if (plink_ctl->num >= RTW_MESH_MAX_PEER_CANDIDATES)
  541. goto exit;
  542. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  543. if (plink_ctl->acnode_rsvd) {
  544. acnode = rtw_mesh_scanned_is_acnode_confirmed(adapter, scanned);
  545. if (acnode && !rtw_mesh_scanned_is_acnode_allow_notify(adapter, scanned))
  546. goto exit;
  547. }
  548. #endif
  549. /* wpa_supplicant's auto peer will initiate peering when candidate peer is reported without max_peer_links consideration */
  550. if (plink_ctl->num >= mcfg->max_peer_links + acnode ? 1 : 0)
  551. goto exit;
  552. if (rtw_get_passing_time_ms(scanned->last_scanned) >= mcfg->peer_sel_policy.scanr_exp_ms
  553. || (mcfg->rssi_threshold && mcfg->rssi_threshold > scanned->network.Rssi)
  554. || !rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1)
  555. #if CONFIG_RTW_MACADDR_ACL
  556. || rtw_access_ctrl(adapter, scanned->network.MacAddress) == _FALSE
  557. #endif
  558. || rtw_mesh_plink_get(adapter, scanned->network.MacAddress)
  559. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  560. || rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
  561. #endif
  562. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  563. || !rtw_mesh_cto_mgate_network_filter(adapter, scanned)
  564. #endif
  565. )
  566. goto exit;
  567. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  568. if (acnode) {
  569. scanned->acnode_notify_etime = 0;
  570. RTW_INFO(FUNC_ADPT_FMT" acnode "MAC_FMT"\n"
  571. , FUNC_ADPT_ARG(adapter), MAC_ARG(scanned->network.MacAddress));
  572. }
  573. #endif
  574. #ifdef CONFIG_IOCTL_CFG80211
  575. rtw_cfg80211_notify_new_peer_candidate(adapter->rtw_wdev
  576. , scanned->network.MacAddress
  577. , BSS_EX_TLV_IES(&scanned->network)
  578. , BSS_EX_TLV_IES_LEN(&scanned->network)
  579. , GFP_ATOMIC
  580. );
  581. #endif
  582. exit:
  583. return;
  584. }
  585. void rtw_mesh_peer_status_chk(_adapter *adapter)
  586. {
  587. struct mlme_priv *mlme = &adapter->mlmepriv;
  588. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  589. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  590. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  591. struct mesh_plink_ent *plink;
  592. _list *head, *list;
  593. struct sta_info *sta = NULL;
  594. struct sta_priv *stapriv = &adapter->stapriv;
  595. int stainfo_offset;
  596. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  597. u8 cto_mgate, forwarding, mgate;
  598. #endif
  599. u8 flush;
  600. s8 flush_list[NUM_STA];
  601. u8 flush_num = 0;
  602. int i;
  603. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  604. if (rtw_mesh_cto_mgate_required(adapter)) {
  605. /* active scan on operating channel */
  606. issue_probereq_ex(adapter, &adapter->mlmepriv.cur_network.network.mesh_id, NULL, 0, 0, 0, 0);
  607. }
  608. #endif
  609. enter_critical_bh(&(plink_ctl->lock));
  610. /* check established peers */
  611. enter_critical_bh(&stapriv->asoc_list_lock);
  612. head = &stapriv->asoc_list;
  613. list = get_next(head);
  614. while (rtw_end_of_queue_search(head, list) == _FALSE) {
  615. sta = LIST_CONTAINOR(list, struct sta_info, asoc_list);
  616. list = get_next(list);
  617. if (!sta->plink || !sta->plink->scanned) {
  618. rtw_warn_on(1);
  619. continue;
  620. }
  621. plink = sta->plink;
  622. flush = 0;
  623. /* remove unsuitable peer */
  624. if (!rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &plink->scanned->network, 1, 0)
  625. #if CONFIG_RTW_MACADDR_ACL
  626. || rtw_access_ctrl(adapter, plink->addr) == _FALSE
  627. #endif
  628. ) {
  629. flush = 1;
  630. goto flush_add;
  631. }
  632. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  633. cto_mgate = rtw_bss_is_cto_mgate(&(plink->scanned->network));
  634. forwarding = rtw_bss_is_forwarding(&(plink->scanned->network));
  635. mgate = rtw_mesh_gate_search(minfo->mesh_paths, sta->cmn.mac_addr);
  636. /* CTO_MGATE required, remove peer without CTO_MGATE */
  637. if (rtw_mesh_cto_mgate_required(adapter) && !cto_mgate) {
  638. flush = 1;
  639. goto flush_add;
  640. }
  641. /* cto_mgate_conf status update */
  642. if (IS_CTO_MGATE_CONF_DISABLED(plink)) {
  643. if (cto_mgate && !forwarding && !mgate)
  644. SET_CTO_MGATE_CONF_END_TIME(plink, mcfg->peer_sel_policy.cto_mgate_conf_timeout_ms);
  645. else
  646. rtw_mesh_cto_mgate_blacklist_del(adapter, sta->cmn.mac_addr);
  647. } else {
  648. /* cto_mgate_conf ongoing */
  649. if (cto_mgate && !forwarding && !mgate) {
  650. if (IS_CTO_MGATE_CONF_TIMEOUT(plink)) {
  651. rtw_mesh_cto_mgate_blacklist_add(adapter, sta->cmn.mac_addr);
  652. /* CTO_MGATE required, remove peering can't achieve CTO_MGATE */
  653. if (rtw_mesh_cto_mgate_required(adapter)) {
  654. flush = 1;
  655. goto flush_add;
  656. }
  657. }
  658. } else {
  659. SET_CTO_MGATE_CONF_DISABLED(plink);
  660. rtw_mesh_cto_mgate_blacklist_del(adapter, sta->cmn.mac_addr);
  661. }
  662. }
  663. #endif /* CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST */
  664. flush_add:
  665. if (flush) {
  666. rtw_list_delete(&sta->asoc_list);
  667. stapriv->asoc_list_cnt--;
  668. STA_SET_MESH_PLINK(sta, NULL);
  669. stainfo_offset = rtw_stainfo_offset(stapriv, sta);
  670. if (stainfo_offset_valid(stainfo_offset))
  671. flush_list[flush_num++] = stainfo_offset;
  672. else
  673. rtw_warn_on(1);
  674. }
  675. }
  676. exit_critical_bh(&stapriv->asoc_list_lock);
  677. /* check non-established peers */
  678. for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
  679. plink = &plink_ctl->ent[i];
  680. if (plink->valid != _TRUE || plink->plink_state == RTW_MESH_PLINK_ESTAB)
  681. continue;
  682. /* remove unsuitable peer */
  683. if (!rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &plink->scanned->network, 1, 1)
  684. #if CONFIG_RTW_MACADDR_ACL
  685. || rtw_access_ctrl(adapter, plink->addr) == _FALSE
  686. #endif
  687. ) {
  688. _rtw_mesh_expire_peer_ent(adapter, plink);
  689. continue;
  690. }
  691. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  692. /* peer confirm check timeout, add to black list */
  693. if (IS_PEER_CONF_TIMEOUT(plink)) {
  694. rtw_mesh_peer_blacklist_add(adapter, plink->addr);
  695. _rtw_mesh_expire_peer_ent(adapter, plink);
  696. }
  697. #endif
  698. }
  699. exit_critical_bh(&(plink_ctl->lock));
  700. if (flush_num) {
  701. u8 sta_addr[ETH_ALEN];
  702. u8 updated = _FALSE;
  703. for (i = 0; i < flush_num; i++) {
  704. sta = rtw_get_stainfo_by_offset(stapriv, flush_list[i]);
  705. _rtw_memcpy(sta_addr, sta->cmn.mac_addr, ETH_ALEN);
  706. updated |= ap_free_sta(adapter, sta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _FALSE);
  707. rtw_mesh_expire_peer(adapter, sta_addr);
  708. }
  709. associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL);
  710. }
  711. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  712. /* loop cto_mgate_blacklist to remove ent according to scan_r */
  713. rtw_mesh_cto_mgate_blacklist_chk(adapter);
  714. #endif
  715. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  716. rtw_mesh_acnode_rsvd_chk(adapter);
  717. #endif
  718. return;
  719. }
  720. #if CONFIG_RTW_MESH_OFFCH_CAND
  721. static u8 rtw_mesh_offch_cto_mgate_required(_adapter *adapter)
  722. {
  723. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  724. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  725. struct mlme_priv *mlme = &adapter->mlmepriv;
  726. _queue *queue = &(mlme->scanned_queue);
  727. _list *head, *pos;
  728. struct wlan_network *scanned = NULL;
  729. u8 ret = 0;
  730. if (!rtw_mesh_cto_mgate_required(adapter))
  731. goto exit;
  732. enter_critical_bh(&(mlme->scanned_queue.lock));
  733. head = get_list_head(queue);
  734. pos = get_next(head);
  735. while (!rtw_end_of_queue_search(head, pos)) {
  736. scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
  737. if (rtw_get_passing_time_ms(scanned->last_scanned) < mcfg->peer_sel_policy.scanr_exp_ms
  738. && (!mcfg->rssi_threshold || mcfg->rssi_threshold <= scanned->network.Rssi)
  739. #if CONFIG_RTW_MACADDR_ACL
  740. && rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE
  741. #endif
  742. && rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1)
  743. && rtw_bss_is_cto_mgate(&scanned->network)
  744. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  745. && !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
  746. #endif
  747. && !rtw_mesh_cto_mgate_blacklist_search(adapter, scanned->network.MacAddress)
  748. )
  749. break;
  750. pos = get_next(pos);
  751. }
  752. if (rtw_end_of_queue_search(head, pos))
  753. ret = 1;
  754. exit_critical_bh(&(mlme->scanned_queue.lock));
  755. exit:
  756. return ret;
  757. #else
  758. return 0;
  759. #endif /* CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST */
  760. }
  761. u8 rtw_mesh_offch_candidate_accepted(_adapter *adapter)
  762. {
  763. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  764. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  765. u8 ret = 0;
  766. if (!adapter->mesh_cfg.peer_sel_policy.offch_cand)
  767. goto exit;
  768. ret = MLME_IS_MESH(adapter) && MLME_IS_ASOC(adapter)
  769. && (!plink_ctl->num || rtw_mesh_offch_cto_mgate_required(adapter))
  770. ;
  771. #ifdef CONFIG_CONCURRENT_MODE
  772. if (ret) {
  773. struct mi_state mstate_no_self;
  774. rtw_mi_status_no_self(adapter, &mstate_no_self);
  775. if (MSTATE_STA_LD_NUM(&mstate_no_self))
  776. ret = 0;
  777. }
  778. #endif
  779. exit:
  780. return ret;
  781. }
  782. /*
  783. * this function is called under off channel candidate is required
  784. * the channel with maximum candidate count is selected
  785. */
  786. u8 rtw_mesh_select_operating_ch(_adapter *adapter)
  787. {
  788. struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
  789. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  790. struct mlme_priv *mlme = &adapter->mlmepriv;
  791. _queue *queue = &(mlme->scanned_queue);
  792. _list *head, *pos;
  793. _irqL irqL;
  794. struct wlan_network *scanned = NULL;
  795. int i;
  796. /* statistics for candidate accept peering */
  797. u8 cand_ap_cnt[MAX_CHANNEL_NUM] = {0};
  798. u8 max_cand_ap_ch = 0;
  799. u8 max_cand_ap_cnt = 0;
  800. /* statistics for candidate including not accept peering */
  801. u8 cand_cnt[MAX_CHANNEL_NUM] = {0};
  802. u8 max_cand_ch = 0;
  803. u8 max_cand_cnt = 0;
  804. _enter_critical_bh(&(mlme->scanned_queue.lock), &irqL);
  805. head = get_list_head(queue);
  806. pos = get_next(head);
  807. while (!rtw_end_of_queue_search(head, pos)) {
  808. scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
  809. pos = get_next(pos);
  810. if (rtw_get_passing_time_ms(scanned->last_scanned) < mcfg->peer_sel_policy.scanr_exp_ms
  811. && (!mcfg->rssi_threshold || mcfg->rssi_threshold <= scanned->network.Rssi)
  812. #if CONFIG_RTW_MACADDR_ACL
  813. && rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE
  814. #endif
  815. && rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 0, 0)
  816. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  817. && !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
  818. #endif
  819. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  820. && rtw_mesh_cto_mgate_network_filter(adapter, scanned)
  821. #endif
  822. ) {
  823. int ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scanned->network.Configuration.DSConfig);
  824. if (ch_set_idx >= 0
  825. && !CH_IS_NON_OCP(&rfctl->channel_set[ch_set_idx])
  826. ) {
  827. u8 nop, accept;
  828. rtw_mesh_bss_peering_status(&scanned->network, &nop, &accept);
  829. cand_cnt[ch_set_idx]++;
  830. if (max_cand_cnt < cand_cnt[ch_set_idx]) {
  831. max_cand_cnt = cand_cnt[ch_set_idx];
  832. max_cand_ch = rfctl->channel_set[ch_set_idx].ChannelNum;
  833. }
  834. if (accept) {
  835. cand_ap_cnt[ch_set_idx]++;
  836. if (max_cand_ap_cnt < cand_ap_cnt[ch_set_idx]) {
  837. max_cand_ap_cnt = cand_ap_cnt[ch_set_idx];
  838. max_cand_ap_ch = rfctl->channel_set[ch_set_idx].ChannelNum;
  839. }
  840. }
  841. }
  842. }
  843. }
  844. _exit_critical_bh(&(mlme->scanned_queue.lock), &irqL);
  845. return max_cand_ap_ch ? max_cand_ap_ch : max_cand_ch;
  846. }
  847. void dump_mesh_offch_cand_settings(void *sel, _adapter *adapter)
  848. {
  849. struct mesh_peer_sel_policy *peer_sel_policy = &adapter->mesh_cfg.peer_sel_policy;
  850. RTW_PRINT_SEL(sel, "%-6s %-11s\n"
  851. , "enable", "find_int_ms");
  852. RTW_PRINT_SEL(sel, "%6u %11u\n"
  853. , peer_sel_policy->offch_cand, peer_sel_policy->offch_find_int_ms);
  854. }
  855. #endif /* CONFIG_RTW_MESH_OFFCH_CAND */
  856. void dump_mesh_peer_sel_policy(void *sel, _adapter *adapter)
  857. {
  858. struct mesh_peer_sel_policy *peer_sel_policy = &adapter->mesh_cfg.peer_sel_policy;
  859. RTW_PRINT_SEL(sel, "%-12s\n", "scanr_exp_ms");
  860. RTW_PRINT_SEL(sel, "%12u\n", peer_sel_policy->scanr_exp_ms);
  861. }
  862. void dump_mesh_networks(void *sel, _adapter *adapter)
  863. {
  864. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  865. #define NSTATE_TITLE_FMT_ACN " %-5s"
  866. #define NSTATE_VALUE_FMT_ACN " %5d"
  867. #define NSTATE_TITLE_ARG_ACN , "acn"
  868. #define NSTATE_VALUE_ARG_ACN , (acn_ms < 99999 ? acn_ms : 99999)
  869. #else
  870. #define NSTATE_TITLE_FMT_ACN ""
  871. #define NSTATE_VALUE_FMT_ACN ""
  872. #define NSTATE_TITLE_ARG_ACN
  873. #define NSTATE_VALUE_ARG_ACN
  874. #endif
  875. struct mlme_priv *mlme = &(adapter->mlmepriv);
  876. _queue *queue = &(mlme->scanned_queue);
  877. struct wlan_network *network;
  878. _list *list, *head;
  879. u8 same_mbss;
  880. u8 candidate;
  881. struct mesh_plink_ent *plink;
  882. u8 blocked;
  883. u8 established;
  884. s32 age_ms;
  885. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  886. s32 acn_ms;
  887. #endif
  888. u8 *mesh_conf_ie;
  889. sint mesh_conf_ie_len;
  890. struct wlan_network **mesh_networks;
  891. u8 mesh_network_cnt = 0;
  892. int i;
  893. mesh_networks = rtw_zvmalloc(mlme->max_bss_cnt * sizeof(struct wlan_network *));
  894. if (!mesh_networks)
  895. return;
  896. enter_critical_bh(&queue->lock);
  897. head = get_list_head(queue);
  898. list = get_next(head);
  899. while (rtw_end_of_queue_search(head, list) == _FALSE) {
  900. network = LIST_CONTAINOR(list, struct wlan_network, list);
  901. list = get_next(list);
  902. if (network->network.InfrastructureMode != Ndis802_11_mesh)
  903. continue;
  904. mesh_conf_ie = rtw_get_ie(BSS_EX_TLV_IES(&network->network), WLAN_EID_MESH_CONFIG
  905. , &mesh_conf_ie_len, BSS_EX_TLV_IES_LEN(&network->network));
  906. if (!mesh_conf_ie || mesh_conf_ie_len != 7)
  907. continue;
  908. mesh_networks[mesh_network_cnt++] = network;
  909. }
  910. exit_critical_bh(&queue->lock);
  911. RTW_PRINT_SEL(sel, " %-17s %-3s %-4s %-5s %-32s %-3s %-3s %-3s"
  912. NSTATE_TITLE_FMT_ACN
  913. "\n"
  914. , "bssid", "ch", "rssi", "age", "mesh_id", "nop", "fwd", "cto"
  915. NSTATE_TITLE_ARG_ACN
  916. );
  917. for (i = 0; i < mesh_network_cnt; i++) {
  918. network = mesh_networks[i];
  919. if (network->network.InfrastructureMode != Ndis802_11_mesh)
  920. continue;
  921. mesh_conf_ie = rtw_get_ie(BSS_EX_TLV_IES(&network->network), WLAN_EID_MESH_CONFIG
  922. , &mesh_conf_ie_len, BSS_EX_TLV_IES_LEN(&network->network));
  923. if (!mesh_conf_ie || mesh_conf_ie_len != 7)
  924. continue;
  925. age_ms = rtw_get_passing_time_ms(network->last_scanned);
  926. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  927. if (network->acnode_stime == 0)
  928. acn_ms = 0;
  929. else
  930. acn_ms = rtw_get_passing_time_ms(network->acnode_stime);
  931. #endif
  932. same_mbss = 0;
  933. candidate = 0;
  934. plink = NULL;
  935. blocked = 0;
  936. established = 0;
  937. if (MLME_IS_MESH(adapter) && MLME_IS_ASOC(adapter)) {
  938. plink = rtw_mesh_plink_get(adapter, network->network.MacAddress);
  939. if (plink && plink->plink_state == RTW_MESH_PLINK_ESTAB)
  940. established = 1;
  941. else if (plink && plink->plink_state == RTW_MESH_PLINK_BLOCKED)
  942. blocked = 1;
  943. else if (plink)
  944. ;
  945. else if (rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &network->network, 0, 1))
  946. candidate = 1;
  947. else if (rtw_bss_is_same_mbss(&mlme->cur_network.network, &network->network))
  948. same_mbss = 1;
  949. }
  950. RTW_PRINT_SEL(sel, "%c "MAC_FMT" %3d %4ld %5d %-32s %c%2u %3u %c%c "
  951. NSTATE_VALUE_FMT_ACN
  952. "\n"
  953. , established ? 'E' : (blocked ? 'B' : (plink ? 'N' : (candidate ? 'C' : (same_mbss ? 'S' : ' '))))
  954. , MAC_ARG(network->network.MacAddress)
  955. , network->network.Configuration.DSConfig
  956. , network->network.Rssi
  957. , age_ms < 99999 ? age_ms : 99999
  958. , network->network.mesh_id.Ssid
  959. , GET_MESH_CONF_ELE_ACCEPT_PEERINGS(mesh_conf_ie + 2) ? '+' : ' '
  960. , GET_MESH_CONF_ELE_NUM_OF_PEERINGS(mesh_conf_ie + 2)
  961. , GET_MESH_CONF_ELE_FORWARDING(mesh_conf_ie + 2)
  962. , GET_MESH_CONF_ELE_CTO_MGATE(mesh_conf_ie + 2) ? 'G' : ' '
  963. , GET_MESH_CONF_ELE_CTO_AS(mesh_conf_ie + 2) ? 'A' : ' '
  964. NSTATE_VALUE_ARG_ACN
  965. );
  966. }
  967. rtw_vmfree(mesh_networks, mlme->max_bss_cnt * sizeof(struct wlan_network *));
  968. }
  969. void rtw_mesh_adjust_chbw(u8 req_ch, u8 *req_bw, u8 *req_offset)
  970. {
  971. if (req_ch >= 5 && req_ch <= 9) {
  972. /* prevent secondary channel offset mismatch */
  973. if (*req_bw > CHANNEL_WIDTH_20) {
  974. *req_bw = CHANNEL_WIDTH_20;
  975. *req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  976. }
  977. }
  978. }
  979. int rtw_sae_check_frames(_adapter *adapter, const u8 *buf, u32 len, u8 tx)
  980. {
  981. const u8 *frame_body = buf + sizeof(struct rtw_ieee80211_hdr_3addr);
  982. u16 alg;
  983. u16 seq;
  984. u16 status;
  985. int ret = 0;
  986. alg = RTW_GET_LE16(frame_body);
  987. if (alg != 3)
  988. goto exit;
  989. seq = RTW_GET_LE16(frame_body + 2);
  990. status = RTW_GET_LE16(frame_body + 4);
  991. RTW_INFO("RTW_%s:AUTH alg:0x%04x, seq:0x%04x, status:0x%04x\n"
  992. , (tx == _TRUE) ? "Tx" : "Rx", alg, seq, status);
  993. ret = 1;
  994. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  995. if (tx && seq == 1)
  996. rtw_mesh_plink_set_peer_conf_timeout(adapter, GetAddr1Ptr(buf));
  997. #endif
  998. exit:
  999. return ret;
  1000. }
  1001. #if CONFIG_RTW_MPM_TX_IES_SYNC_BSS
  1002. #ifdef CONFIG_RTW_MESH_AEK
  1003. static int rtw_mpm_ampe_dec(_adapter *adapter, struct mesh_plink_ent *plink
  1004. , u8 *fhead, size_t flen, u8* fbody, u8 *mic_ie, u8 *ampe_buf)
  1005. {
  1006. int ret = _FAIL, verify_ret;
  1007. const u8 *aad[] = {adapter_mac_addr(adapter), plink->addr, fbody};
  1008. const size_t aad_len[] = {ETH_ALEN, ETH_ALEN, mic_ie - fbody};
  1009. u8 *iv_crypt;
  1010. size_t iv_crypt_len = flen - (mic_ie + 2 - fhead);
  1011. iv_crypt = rtw_malloc(iv_crypt_len);
  1012. if (!iv_crypt)
  1013. goto exit;
  1014. _rtw_memcpy(iv_crypt, mic_ie + 2, iv_crypt_len);
  1015. verify_ret = aes_siv_decrypt(plink->aek, iv_crypt, iv_crypt_len
  1016. , 3, aad, aad_len, ampe_buf);
  1017. rtw_mfree(iv_crypt, iv_crypt_len);
  1018. if (verify_ret) {
  1019. RTW_WARN("verify error, aek_valid=%u\n", plink->aek_valid);
  1020. goto exit;
  1021. } else if (*ampe_buf != WLAN_EID_AMPE) {
  1022. RTW_WARN("plaintext is not AMPE IE\n");
  1023. goto exit;
  1024. } else if (AES_BLOCK_SIZE + 2 + *(ampe_buf + 1) > iv_crypt_len) {
  1025. RTW_WARN("plaintext AMPE IE length is not valid\n");
  1026. goto exit;
  1027. }
  1028. ret = _SUCCESS;
  1029. exit:
  1030. return ret;
  1031. }
  1032. static int rtw_mpm_ampe_enc(_adapter *adapter, struct mesh_plink_ent *plink
  1033. , u8* fbody, u8 *mic_ie, u8 *ampe_buf, bool inverse)
  1034. {
  1035. int ret = _FAIL, protect_ret;
  1036. const u8 *aad[3];
  1037. const size_t aad_len[3] = {ETH_ALEN, ETH_ALEN, mic_ie - fbody};
  1038. u8 *ampe_ie;
  1039. size_t ampe_ie_len = *(ampe_buf + 1) + 2; /* including id & len */
  1040. if (inverse) {
  1041. aad[0] = plink->addr;
  1042. aad[1] = adapter_mac_addr(adapter);
  1043. } else {
  1044. aad[0] = adapter_mac_addr(adapter);
  1045. aad[1] = plink->addr;
  1046. }
  1047. aad[2] = fbody;
  1048. ampe_ie = rtw_malloc(ampe_ie_len);
  1049. if (!ampe_ie)
  1050. goto exit;
  1051. _rtw_memcpy(ampe_ie, ampe_buf, ampe_ie_len);
  1052. protect_ret = aes_siv_encrypt(plink->aek, ampe_ie, ampe_ie_len
  1053. , 3, aad, aad_len, mic_ie + 2);
  1054. rtw_mfree(ampe_ie, ampe_ie_len);
  1055. if (protect_ret) {
  1056. RTW_WARN("protect error, aek_valid=%u\n", plink->aek_valid);
  1057. goto exit;
  1058. }
  1059. ret = _SUCCESS;
  1060. exit:
  1061. return ret;
  1062. }
  1063. #endif /* CONFIG_RTW_MESH_AEK */
  1064. static int rtw_mpm_tx_ies_sync_bss(_adapter *adapter, struct mesh_plink_ent *plink
  1065. , u8 *fhead, size_t flen, u8* fbody, u8 tlv_ies_offset, u8 *mpm_ie, u8 *mic_ie
  1066. , u8 **nbuf, size_t *nlen)
  1067. {
  1068. int ret = _FAIL;
  1069. struct mlme_priv *mlme = &(adapter->mlmepriv);
  1070. struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
  1071. struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
  1072. WLAN_BSSID_EX *network = &(mlmeinfo->network);
  1073. uint left;
  1074. u8 *pos;
  1075. uint mpm_ielen = *(mpm_ie + 1);
  1076. u8 *fpos;
  1077. u8 *new_buf = NULL;
  1078. size_t new_len = 0;
  1079. u8 *new_fhead;
  1080. size_t new_flen;
  1081. u8 *new_fbody;
  1082. u8 *new_mic_ie;
  1083. #ifdef CONFIG_RTW_MESH_AEK
  1084. u8 *ampe_buf = NULL;
  1085. size_t ampe_buf_len = 0;
  1086. /* decode */
  1087. if (mic_ie) {
  1088. ampe_buf_len = flen - (mic_ie + 2 + AES_BLOCK_SIZE - fhead);
  1089. ampe_buf = rtw_malloc(ampe_buf_len);
  1090. if (!ampe_buf)
  1091. goto exit;
  1092. if (rtw_mpm_ampe_dec(adapter, plink, fhead, flen, fbody, mic_ie, ampe_buf) != _SUCCESS)
  1093. goto exit;
  1094. if (*(ampe_buf + 1) >= 68) {
  1095. _rtw_memcpy(plink->sel_pcs, ampe_buf + 2, 4);
  1096. _rtw_memcpy(plink->l_nonce, ampe_buf + 6, 32);
  1097. _rtw_memcpy(plink->p_nonce, ampe_buf + 38, 32);
  1098. }
  1099. }
  1100. #endif
  1101. /* count for new frame length */
  1102. new_len = sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset;
  1103. left = BSS_EX_TLV_IES_LEN(network);
  1104. pos = BSS_EX_TLV_IES(network);
  1105. while (left >= 2) {
  1106. u8 id, elen;
  1107. id = *pos++;
  1108. elen = *pos++;
  1109. left -= 2;
  1110. if (elen > left)
  1111. break;
  1112. switch (id) {
  1113. case WLAN_EID_SSID:
  1114. case WLAN_EID_DS_PARAMS:
  1115. case WLAN_EID_TIM:
  1116. break;
  1117. default:
  1118. new_len += 2 + elen;
  1119. }
  1120. left -= elen;
  1121. pos += elen;
  1122. }
  1123. new_len += mpm_ielen + 2;
  1124. if (mic_ie)
  1125. new_len += AES_BLOCK_SIZE + 2 + ampe_buf_len;
  1126. /* alloc new frame */
  1127. new_buf = rtw_malloc(new_len);
  1128. if (!new_buf) {
  1129. rtw_warn_on(1);
  1130. goto exit;
  1131. }
  1132. /* build new frame */
  1133. _rtw_memcpy(new_buf, fhead, sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset);
  1134. new_fhead = new_buf;
  1135. new_flen = new_len;
  1136. new_fbody = new_fhead + sizeof(struct rtw_ieee80211_hdr_3addr);
  1137. fpos = new_fbody + tlv_ies_offset;
  1138. left = BSS_EX_TLV_IES_LEN(network);
  1139. pos = BSS_EX_TLV_IES(network);
  1140. while (left >= 2) {
  1141. u8 id, elen;
  1142. id = *pos++;
  1143. elen = *pos++;
  1144. left -= 2;
  1145. if (elen > left)
  1146. break;
  1147. switch (id) {
  1148. case WLAN_EID_SSID:
  1149. case WLAN_EID_DS_PARAMS:
  1150. case WLAN_EID_TIM:
  1151. break;
  1152. default:
  1153. fpos = rtw_set_ie(fpos, id, elen, pos, NULL);
  1154. if (id == WLAN_EID_MESH_CONFIG)
  1155. fpos = rtw_set_ie(fpos, WLAN_EID_MPM, mpm_ielen, mpm_ie + 2, NULL);
  1156. }
  1157. left -= elen;
  1158. pos += elen;
  1159. }
  1160. if (mic_ie) {
  1161. new_mic_ie = fpos;
  1162. *fpos++ = WLAN_EID_MIC;
  1163. *fpos++ = AES_BLOCK_SIZE;
  1164. }
  1165. #ifdef CONFIG_RTW_MESH_AEK
  1166. /* encode */
  1167. if (mic_ie) {
  1168. int enc_ret = rtw_mpm_ampe_enc(adapter, plink, new_fbody, new_mic_ie, ampe_buf, 0);
  1169. if (enc_ret != _SUCCESS)
  1170. goto exit;
  1171. }
  1172. #endif
  1173. *nlen = new_len;
  1174. *nbuf = new_buf;
  1175. ret = _SUCCESS;
  1176. exit:
  1177. if (ret != _SUCCESS && new_buf)
  1178. rtw_mfree(new_buf, new_len);
  1179. #ifdef CONFIG_RTW_MESH_AEK
  1180. if (ampe_buf)
  1181. rtw_mfree(ampe_buf, ampe_buf_len);
  1182. #endif
  1183. return ret;
  1184. }
  1185. #endif /* CONFIG_RTW_MPM_TX_IES_SYNC_BSS */
  1186. struct mpm_frame_info {
  1187. u8 *aid;
  1188. u16 aid_v;
  1189. u8 *pid;
  1190. u16 pid_v;
  1191. u8 *llid;
  1192. u16 llid_v;
  1193. u8 *plid;
  1194. u16 plid_v;
  1195. u8 *reason;
  1196. u16 reason_v;
  1197. u8 *chosen_pmk;
  1198. };
  1199. /*
  1200. * pid:00000 llid:00000 chosen_pmk:0x00000000000000000000000000000000
  1201. * aid:00000 pid:00000 llid:00000 plid:00000 chosen_pmk:0x00000000000000000000000000000000
  1202. * pid:00000 llid:00000 plid:00000 reason:00000 chosen_pmk:0x00000000000000000000000000000000
  1203. */
  1204. #define MPM_LOG_BUF_LEN 92 /* this length is limited for legal combination */
  1205. static void rtw_mpm_info_msg(struct mpm_frame_info *mpm_info, u8 *mpm_log_buf)
  1206. {
  1207. int cnt = 0;
  1208. if (mpm_info->aid) {
  1209. cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "aid:%u ", mpm_info->aid_v);
  1210. if (cnt >= MPM_LOG_BUF_LEN - 1)
  1211. goto exit;
  1212. }
  1213. if (mpm_info->pid) {
  1214. cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "pid:%u ", mpm_info->pid_v);
  1215. if (cnt >= MPM_LOG_BUF_LEN - 1)
  1216. goto exit;
  1217. }
  1218. if (mpm_info->llid) {
  1219. cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "llid:%u ", mpm_info->llid_v);
  1220. if (cnt >= MPM_LOG_BUF_LEN - 1)
  1221. goto exit;
  1222. }
  1223. if (mpm_info->plid) {
  1224. cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "plid:%u ", mpm_info->plid_v);
  1225. if (cnt >= MPM_LOG_BUF_LEN - 1)
  1226. goto exit;
  1227. }
  1228. if (mpm_info->reason) {
  1229. cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "reason:%u ", mpm_info->reason_v);
  1230. if (cnt >= MPM_LOG_BUF_LEN - 1)
  1231. goto exit;
  1232. }
  1233. if (mpm_info->chosen_pmk) {
  1234. cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "chosen_pmk:0x"KEY_FMT, KEY_ARG(mpm_info->chosen_pmk));
  1235. if (cnt >= MPM_LOG_BUF_LEN - 1)
  1236. goto exit;
  1237. }
  1238. exit:
  1239. return;
  1240. }
  1241. static int rtw_mpm_check_frames(_adapter *adapter, u8 action, const u8 **buf, size_t *len, u8 tx)
  1242. {
  1243. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1244. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1245. struct mesh_plink_ent *plink = NULL;
  1246. u8 *nbuf = NULL;
  1247. size_t nlen = 0;
  1248. u8 *fhead = (u8 *)*buf;
  1249. size_t flen = *len;
  1250. u8 *peer_addr = tx ? GetAddr1Ptr(fhead) : get_addr2_ptr(fhead);
  1251. u8 *frame_body = fhead + sizeof(struct rtw_ieee80211_hdr_3addr);
  1252. struct mpm_frame_info mpm_info;
  1253. u8 tlv_ies_offset;
  1254. u8 *mpm_ie = NULL;
  1255. uint mpm_ielen = 0;
  1256. u8 *mic_ie = NULL;
  1257. uint mic_ielen = 0;
  1258. int ret = 0;
  1259. u8 mpm_log_buf[MPM_LOG_BUF_LEN] = {0};
  1260. if (action == RTW_ACT_SELF_PROTECTED_MESH_OPEN)
  1261. tlv_ies_offset = 4;
  1262. else if (action == RTW_ACT_SELF_PROTECTED_MESH_CONF)
  1263. tlv_ies_offset = 6;
  1264. else if (action == RTW_ACT_SELF_PROTECTED_MESH_CLOSE)
  1265. tlv_ies_offset = 2;
  1266. else {
  1267. rtw_warn_on(1);
  1268. goto exit;
  1269. }
  1270. plink = rtw_mesh_plink_get(adapter, peer_addr);
  1271. if (!plink && (tx == _TRUE || action == RTW_ACT_SELF_PROTECTED_MESH_CONF)) {
  1272. /* warning message if no plink when: 1.TX all MPM or 2.RX CONF */
  1273. RTW_WARN("RTW_%s:%s without plink of "MAC_FMT"\n"
  1274. , (tx == _TRUE) ? "Tx" : "Rx", action_self_protected_str(action), MAC_ARG(peer_addr));
  1275. goto exit;
  1276. }
  1277. _rtw_memset(&mpm_info, 0, sizeof(struct mpm_frame_info));
  1278. if (action == RTW_ACT_SELF_PROTECTED_MESH_CONF) {
  1279. mpm_info.aid = (u8 *)frame_body + 4;
  1280. mpm_info.aid_v = RTW_GET_LE16(mpm_info.aid);
  1281. }
  1282. mpm_ie = rtw_get_ie(fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
  1283. , WLAN_EID_MPM, &mpm_ielen
  1284. , flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
  1285. if (!mpm_ie || mpm_ielen < 2 + 2)
  1286. goto exit;
  1287. mpm_info.pid = mpm_ie + 2;
  1288. mpm_info.pid_v = RTW_GET_LE16(mpm_info.pid);
  1289. mpm_info.llid = mpm_info.pid + 2;
  1290. mpm_info.llid_v = RTW_GET_LE16(mpm_info.llid);
  1291. switch (action) {
  1292. case RTW_ACT_SELF_PROTECTED_MESH_OPEN:
  1293. /* pid:2, llid:2, (chosen_pmk:16) */
  1294. if (mpm_info.pid_v == 0 && mpm_ielen == 4)
  1295. ;
  1296. else if (mpm_info.pid_v == 1 && mpm_ielen == 20)
  1297. mpm_info.chosen_pmk = mpm_info.llid + 2;
  1298. else
  1299. goto exit;
  1300. break;
  1301. case RTW_ACT_SELF_PROTECTED_MESH_CONF:
  1302. /* pid:2, llid:2, plid:2, (chosen_pmk:16) */
  1303. mpm_info.plid = mpm_info.llid + 2;
  1304. mpm_info.plid_v = RTW_GET_LE16(mpm_info.plid);
  1305. if (mpm_info.pid_v == 0 && mpm_ielen == 6)
  1306. ;
  1307. else if (mpm_info.pid_v == 1 && mpm_ielen == 22)
  1308. mpm_info.chosen_pmk = mpm_info.plid + 2;
  1309. else
  1310. goto exit;
  1311. break;
  1312. case RTW_ACT_SELF_PROTECTED_MESH_CLOSE:
  1313. /* pid:2, llid:2, (plid:2), reason:2, (chosen_pmk:16) */
  1314. if (mpm_info.pid_v == 0 && mpm_ielen == 6) {
  1315. /* MPM, without plid */
  1316. mpm_info.reason = mpm_info.llid + 2;
  1317. mpm_info.reason_v = RTW_GET_LE16(mpm_info.reason);
  1318. } else if (mpm_info.pid_v == 0 && mpm_ielen == 8) {
  1319. /* MPM, with plid */
  1320. mpm_info.plid = mpm_info.llid + 2;
  1321. mpm_info.plid_v = RTW_GET_LE16(mpm_info.plid);
  1322. mpm_info.reason = mpm_info.plid + 2;
  1323. mpm_info.reason_v = RTW_GET_LE16(mpm_info.reason);
  1324. } else if (mpm_info.pid_v == 1 && mpm_ielen == 22) {
  1325. /* AMPE, without plid */
  1326. mpm_info.reason = mpm_info.llid + 2;
  1327. mpm_info.reason_v = RTW_GET_LE16(mpm_info.reason);
  1328. mpm_info.chosen_pmk = mpm_info.reason + 2;
  1329. } else if (mpm_info.pid_v == 1 && mpm_ielen == 24) {
  1330. /* AMPE, with plid */
  1331. mpm_info.plid = mpm_info.llid + 2;
  1332. mpm_info.plid_v = RTW_GET_LE16(mpm_info.plid);
  1333. mpm_info.reason = mpm_info.plid + 2;
  1334. mpm_info.reason_v = RTW_GET_LE16(mpm_info.reason);
  1335. mpm_info.chosen_pmk = mpm_info.reason + 2;
  1336. } else
  1337. goto exit;
  1338. break;
  1339. };
  1340. if (mpm_info.pid_v == 1) {
  1341. mic_ie = rtw_get_ie(fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
  1342. , WLAN_EID_MIC, &mic_ielen
  1343. , flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
  1344. if (!mic_ie || mic_ielen != AES_BLOCK_SIZE)
  1345. goto exit;
  1346. }
  1347. #if CONFIG_RTW_MPM_TX_IES_SYNC_BSS
  1348. if ((action == RTW_ACT_SELF_PROTECTED_MESH_OPEN || action == RTW_ACT_SELF_PROTECTED_MESH_CONF)
  1349. && tx == _TRUE
  1350. ) {
  1351. #define DBG_RTW_MPM_TX_IES_SYNC_BSS 0
  1352. if (mpm_info.pid_v == 1 && (!plink || !MESH_PLINK_AEK_VALID(plink))) {
  1353. RTW_WARN("AEK not ready, IEs can't sync with BSS\n");
  1354. goto bypass_sync_bss;
  1355. }
  1356. if (DBG_RTW_MPM_TX_IES_SYNC_BSS) {
  1357. RTW_INFO(FUNC_ADPT_FMT" before:\n", FUNC_ADPT_ARG(adapter));
  1358. dump_ies(RTW_DBGDUMP
  1359. , fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
  1360. , flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
  1361. }
  1362. rtw_mpm_tx_ies_sync_bss(adapter, plink
  1363. , fhead, flen, frame_body, tlv_ies_offset, mpm_ie, mic_ie
  1364. , &nbuf, &nlen);
  1365. if (!nbuf)
  1366. goto exit;
  1367. /* update pointer & len for new frame */
  1368. fhead = nbuf;
  1369. flen = nlen;
  1370. frame_body = fhead + sizeof(struct rtw_ieee80211_hdr_3addr);
  1371. if (mpm_info.pid_v == 1) {
  1372. mic_ie = rtw_get_ie(fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
  1373. , WLAN_EID_MIC, &mic_ielen
  1374. , flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
  1375. }
  1376. if (DBG_RTW_MPM_TX_IES_SYNC_BSS) {
  1377. RTW_INFO(FUNC_ADPT_FMT" after:\n", FUNC_ADPT_ARG(adapter));
  1378. dump_ies(RTW_DBGDUMP
  1379. , fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
  1380. , flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
  1381. }
  1382. }
  1383. bypass_sync_bss:
  1384. #endif /* CONFIG_RTW_MPM_TX_IES_SYNC_BSS */
  1385. if (!plink)
  1386. goto mpm_log;
  1387. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  1388. if (action == RTW_ACT_SELF_PROTECTED_MESH_OPEN) {
  1389. if (tx)
  1390. rtw_mesh_plink_set_peer_conf_timeout(adapter, peer_addr);
  1391. } else
  1392. #endif
  1393. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  1394. if (action == RTW_ACT_SELF_PROTECTED_MESH_CLOSE) {
  1395. if (tx && mpm_info.reason && mpm_info.reason_v == WLAN_REASON_MESH_MAX_PEERS) {
  1396. if (rtw_mesh_scanned_is_acnode_confirmed(adapter, plink->scanned)
  1397. && rtw_mesh_acnode_prevent_allow_sacrifice(adapter)
  1398. ) {
  1399. struct sta_info *sac = rtw_mesh_acnode_prevent_pick_sacrifice(adapter);
  1400. if (sac) {
  1401. struct sta_priv *stapriv = &adapter->stapriv;
  1402. _irqL irqL;
  1403. u8 sta_addr[ETH_ALEN];
  1404. u8 updated = _FALSE;
  1405. _enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
  1406. if (!rtw_is_list_empty(&sac->asoc_list)) {
  1407. rtw_list_delete(&sac->asoc_list);
  1408. stapriv->asoc_list_cnt--;
  1409. STA_SET_MESH_PLINK(sac, NULL);
  1410. }
  1411. _exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
  1412. RTW_INFO(FUNC_ADPT_FMT" sacrifice "MAC_FMT" for acnode\n"
  1413. , FUNC_ADPT_ARG(adapter), MAC_ARG(sac->cmn.mac_addr));
  1414. _rtw_memcpy(sta_addr, sac->cmn.mac_addr, ETH_ALEN);
  1415. updated = ap_free_sta(adapter, sac, 0, 0, 1);
  1416. rtw_mesh_expire_peer(stapriv->padapter, sta_addr);
  1417. associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL);
  1418. }
  1419. }
  1420. }
  1421. } else
  1422. #endif
  1423. if (action == RTW_ACT_SELF_PROTECTED_MESH_CONF) {
  1424. _irqL irqL;
  1425. u8 *ies = NULL;
  1426. u16 ies_len = 0;
  1427. _enter_critical_bh(&(plink_ctl->lock), &irqL);
  1428. plink = _rtw_mesh_plink_get(adapter, peer_addr);
  1429. if (!plink)
  1430. goto release_plink_ctl;
  1431. if (tx == _FALSE) {
  1432. ies = plink->rx_conf_ies;
  1433. ies_len = plink->rx_conf_ies_len;
  1434. plink->rx_conf_ies = NULL;
  1435. plink->rx_conf_ies_len = 0;
  1436. plink->llid = mpm_info.plid_v;
  1437. plink->plid = mpm_info.llid_v;
  1438. plink->peer_aid = mpm_info.aid_v;
  1439. if (mpm_info.pid_v == 1)
  1440. _rtw_memcpy(plink->chosen_pmk, mpm_info.chosen_pmk, 16);
  1441. }
  1442. #ifdef CONFIG_RTW_MESH_DRIVER_AID
  1443. else {
  1444. ies = plink->tx_conf_ies;
  1445. ies_len = plink->tx_conf_ies_len;
  1446. plink->tx_conf_ies = NULL;
  1447. plink->tx_conf_ies_len = 0;
  1448. }
  1449. #endif
  1450. if (ies && ies_len)
  1451. rtw_mfree(ies, ies_len);
  1452. #ifndef CONFIG_RTW_MESH_DRIVER_AID
  1453. if (tx == _TRUE)
  1454. goto release_plink_ctl; /* no need to copy tx conf ies */
  1455. #endif
  1456. /* copy mesh confirm IEs */
  1457. if (mpm_info.pid_v == 1) /* not include MIC & encrypted AMPE */
  1458. ies_len = (mic_ie - fhead) - sizeof(struct rtw_ieee80211_hdr_3addr) - 2;
  1459. else
  1460. ies_len = flen - sizeof(struct rtw_ieee80211_hdr_3addr) - 2;
  1461. ies = rtw_zmalloc(ies_len);
  1462. if (ies) {
  1463. _rtw_memcpy(ies, fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + 2, ies_len);
  1464. if (tx == _FALSE) {
  1465. plink->rx_conf_ies = ies;
  1466. plink->rx_conf_ies_len = ies_len;
  1467. }
  1468. #ifdef CONFIG_RTW_MESH_DRIVER_AID
  1469. else {
  1470. plink->tx_conf_ies = ies;
  1471. plink->tx_conf_ies_len = ies_len;
  1472. }
  1473. #endif
  1474. }
  1475. release_plink_ctl:
  1476. _exit_critical_bh(&(plink_ctl->lock), &irqL);
  1477. }
  1478. mpm_log:
  1479. rtw_mpm_info_msg(&mpm_info, mpm_log_buf);
  1480. RTW_INFO("RTW_%s:%s %s\n"
  1481. , (tx == _TRUE) ? "Tx" : "Rx"
  1482. , action_self_protected_str(action)
  1483. , mpm_log_buf
  1484. );
  1485. ret = 1;
  1486. exit:
  1487. if (nbuf) {
  1488. if (ret == 1) {
  1489. *buf = nbuf;
  1490. *len = nlen;
  1491. } else
  1492. rtw_mfree(nbuf, nlen);
  1493. }
  1494. return ret;
  1495. }
  1496. static int rtw_mesh_check_frames(_adapter *adapter, const u8 **buf, size_t *len, u8 tx)
  1497. {
  1498. int is_mesh_frame = -1;
  1499. const u8 *frame_body;
  1500. u8 category, action;
  1501. frame_body = *buf + sizeof(struct rtw_ieee80211_hdr_3addr);
  1502. category = frame_body[0];
  1503. if (category == RTW_WLAN_CATEGORY_SELF_PROTECTED) {
  1504. action = frame_body[1];
  1505. switch (action) {
  1506. case RTW_ACT_SELF_PROTECTED_MESH_OPEN:
  1507. case RTW_ACT_SELF_PROTECTED_MESH_CONF:
  1508. case RTW_ACT_SELF_PROTECTED_MESH_CLOSE:
  1509. rtw_mpm_check_frames(adapter, action, buf, len, tx);
  1510. is_mesh_frame = action;
  1511. break;
  1512. case RTW_ACT_SELF_PROTECTED_MESH_GK_INFORM:
  1513. case RTW_ACT_SELF_PROTECTED_MESH_GK_ACK:
  1514. RTW_INFO("RTW_%s:%s\n", (tx == _TRUE) ? "Tx" : "Rx", action_self_protected_str(action));
  1515. is_mesh_frame = action;
  1516. break;
  1517. default:
  1518. break;
  1519. };
  1520. }
  1521. exit:
  1522. return is_mesh_frame;
  1523. }
  1524. int rtw_mesh_check_frames_tx(_adapter *adapter, const u8 **buf, size_t *len)
  1525. {
  1526. return rtw_mesh_check_frames(adapter, buf, len, _TRUE);
  1527. }
  1528. int rtw_mesh_check_frames_rx(_adapter *adapter, const u8 *buf, size_t len)
  1529. {
  1530. return rtw_mesh_check_frames(adapter, &buf, &len, _FALSE);
  1531. }
  1532. int rtw_mesh_on_auth(_adapter *adapter, union recv_frame *rframe)
  1533. {
  1534. u8 *whdr = rframe->u.hdr.rx_data;
  1535. #if CONFIG_RTW_MACADDR_ACL
  1536. if (rtw_access_ctrl(adapter, get_addr2_ptr(whdr)) == _FALSE)
  1537. return _SUCCESS;
  1538. #endif
  1539. if (!rtw_mesh_plink_get(adapter, get_addr2_ptr(whdr))) {
  1540. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  1541. rtw_mesh_acnode_set_notify_etime(adapter, whdr);
  1542. #endif
  1543. if (adapter_to_rfctl(adapter)->offch_state == OFFCHS_NONE)
  1544. issue_probereq(adapter, &adapter->mlmepriv.cur_network.network.mesh_id, get_addr2_ptr(whdr));
  1545. /* only peer being added (checked by notify conditions) is allowed */
  1546. return _SUCCESS;
  1547. }
  1548. rtw_cfg80211_rx_mframe(adapter, rframe, NULL);
  1549. return _SUCCESS;
  1550. }
  1551. unsigned int on_action_self_protected(_adapter *adapter, union recv_frame *rframe)
  1552. {
  1553. unsigned int ret = _FAIL;
  1554. struct sta_info *sta = NULL;
  1555. u8 *pframe = rframe->u.hdr.rx_data;
  1556. uint frame_len = rframe->u.hdr.len;
  1557. u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  1558. u8 category;
  1559. u8 action;
  1560. /* check RA matches or not */
  1561. if (!_rtw_memcmp(adapter_mac_addr(adapter), GetAddr1Ptr(pframe), ETH_ALEN))
  1562. goto exit;
  1563. category = frame_body[0];
  1564. if (category != RTW_WLAN_CATEGORY_SELF_PROTECTED)
  1565. goto exit;
  1566. action = frame_body[1];
  1567. switch (action) {
  1568. case RTW_ACT_SELF_PROTECTED_MESH_OPEN:
  1569. case RTW_ACT_SELF_PROTECTED_MESH_CONF:
  1570. case RTW_ACT_SELF_PROTECTED_MESH_CLOSE:
  1571. case RTW_ACT_SELF_PROTECTED_MESH_GK_INFORM:
  1572. case RTW_ACT_SELF_PROTECTED_MESH_GK_ACK:
  1573. if (!(MLME_IS_MESH(adapter) && MLME_IS_ASOC(adapter)))
  1574. goto exit;
  1575. #ifdef CONFIG_IOCTL_CFG80211
  1576. #if CONFIG_RTW_MACADDR_ACL
  1577. if (rtw_access_ctrl(adapter, get_addr2_ptr(pframe)) == _FALSE)
  1578. goto exit;
  1579. #endif
  1580. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  1581. if (rtw_mesh_cto_mgate_required(adapter)
  1582. /* only peer being added (checked by notify conditions) is allowed */
  1583. && !rtw_mesh_plink_get(adapter, get_addr2_ptr(pframe)))
  1584. goto exit;
  1585. #endif
  1586. rtw_cfg80211_rx_action(adapter, rframe, NULL);
  1587. ret = _SUCCESS;
  1588. #endif /* CONFIG_IOCTL_CFG80211 */
  1589. break;
  1590. default:
  1591. break;
  1592. }
  1593. exit:
  1594. return ret;
  1595. }
  1596. const u8 ae_to_mesh_ctrl_len[] = {
  1597. 6,
  1598. 12, /* MESH_FLAGS_AE_A4 */
  1599. 18, /* MESH_FLAGS_AE_A5_A6 */
  1600. 0,
  1601. };
  1602. unsigned int on_action_mesh(_adapter *adapter, union recv_frame *rframe)
  1603. {
  1604. unsigned int ret = _FAIL;
  1605. struct sta_info *sta = NULL;
  1606. struct sta_priv *stapriv = &adapter->stapriv;
  1607. u8 *pframe = rframe->u.hdr.rx_data;
  1608. uint frame_len = rframe->u.hdr.len;
  1609. u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  1610. u8 category;
  1611. u8 action;
  1612. if (!MLME_IS_MESH(adapter))
  1613. goto exit;
  1614. /* check stainfo exist? */
  1615. category = frame_body[0];
  1616. if (category != RTW_WLAN_CATEGORY_MESH)
  1617. goto exit;
  1618. action = frame_body[1];
  1619. switch (action) {
  1620. case RTW_ACT_MESH_HWMP_PATH_SELECTION:
  1621. rtw_mesh_rx_path_sel_frame(adapter, rframe);
  1622. ret = _SUCCESS;
  1623. break;
  1624. default:
  1625. break;
  1626. }
  1627. exit:
  1628. return ret;
  1629. }
  1630. bool rtw_mesh_update_bss_peering_status(_adapter *adapter, WLAN_BSSID_EX *bss)
  1631. {
  1632. struct sta_priv *stapriv = &adapter->stapriv;
  1633. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  1634. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1635. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1636. u8 num_of_peerings = stapriv->asoc_list_cnt;
  1637. bool accept_peerings = stapriv->asoc_list_cnt < mcfg->max_peer_links;
  1638. u8 *ie;
  1639. int ie_len;
  1640. bool updated = 0;
  1641. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  1642. accept_peerings |= plink_ctl->acnode_rsvd;
  1643. #endif
  1644. ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len, BSS_EX_TLV_IES_LEN(bss));
  1645. if (!ie || ie_len != 7) {
  1646. rtw_warn_on(1);
  1647. goto exit;
  1648. }
  1649. if (GET_MESH_CONF_ELE_NUM_OF_PEERINGS(ie + 2) != num_of_peerings) {
  1650. SET_MESH_CONF_ELE_NUM_OF_PEERINGS(ie + 2, num_of_peerings);
  1651. updated = 1;
  1652. }
  1653. if (GET_MESH_CONF_ELE_ACCEPT_PEERINGS(ie + 2) != accept_peerings) {
  1654. SET_MESH_CONF_ELE_ACCEPT_PEERINGS(ie + 2, accept_peerings);
  1655. updated = 1;
  1656. }
  1657. exit:
  1658. return updated;
  1659. }
  1660. bool rtw_mesh_update_bss_formation_info(_adapter *adapter, WLAN_BSSID_EX *bss)
  1661. {
  1662. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  1663. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1664. u8 cto_mgate = (minfo->num_gates || mcfg->dot11MeshGateAnnouncementProtocol);
  1665. u8 cto_as = 0;
  1666. u8 *ie;
  1667. int ie_len;
  1668. bool updated = 0;
  1669. ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len,
  1670. BSS_EX_TLV_IES_LEN(bss));
  1671. if (!ie || ie_len != 7) {
  1672. rtw_warn_on(1);
  1673. goto exit;
  1674. }
  1675. if (GET_MESH_CONF_ELE_CTO_MGATE(ie + 2) != cto_mgate) {
  1676. SET_MESH_CONF_ELE_CTO_MGATE(ie + 2, cto_mgate);
  1677. updated = 1;
  1678. }
  1679. if (GET_MESH_CONF_ELE_CTO_AS(ie + 2) != cto_as) {
  1680. SET_MESH_CONF_ELE_CTO_AS(ie + 2, cto_as);
  1681. updated = 1;
  1682. }
  1683. exit:
  1684. return updated;
  1685. }
  1686. bool rtw_mesh_update_bss_forwarding_state(_adapter *adapter, WLAN_BSSID_EX *bss)
  1687. {
  1688. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  1689. u8 forward = mcfg->dot11MeshForwarding;
  1690. u8 *ie;
  1691. int ie_len;
  1692. bool updated = 0;
  1693. ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len,
  1694. BSS_EX_TLV_IES_LEN(bss));
  1695. if (!ie || ie_len != 7) {
  1696. rtw_warn_on(1);
  1697. goto exit;
  1698. }
  1699. if (GET_MESH_CONF_ELE_FORWARDING(ie + 2) != forward) {
  1700. SET_MESH_CONF_ELE_FORWARDING(ie + 2, forward);
  1701. updated = 1;
  1702. }
  1703. exit:
  1704. return updated;
  1705. }
  1706. struct mesh_plink_ent *_rtw_mesh_plink_get(_adapter *adapter, const u8 *hwaddr)
  1707. {
  1708. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1709. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1710. struct mesh_plink_ent *ent = NULL;
  1711. int i;
  1712. for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
  1713. if (plink_ctl->ent[i].valid == _TRUE
  1714. && _rtw_memcmp(plink_ctl->ent[i].addr, hwaddr, ETH_ALEN) == _TRUE
  1715. ) {
  1716. ent = &plink_ctl->ent[i];
  1717. break;
  1718. }
  1719. }
  1720. exit:
  1721. return ent;
  1722. }
  1723. struct mesh_plink_ent *rtw_mesh_plink_get(_adapter *adapter, const u8 *hwaddr)
  1724. {
  1725. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1726. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1727. struct mesh_plink_ent *ent = NULL;
  1728. _irqL irqL;
  1729. _enter_critical_bh(&(plink_ctl->lock), &irqL);
  1730. ent = _rtw_mesh_plink_get(adapter, hwaddr);
  1731. _exit_critical_bh(&(plink_ctl->lock), &irqL);
  1732. exit:
  1733. return ent;
  1734. }
  1735. struct mesh_plink_ent *rtw_mesh_plink_get_no_estab_by_idx(_adapter *adapter, u8 idx)
  1736. {
  1737. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1738. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1739. struct mesh_plink_ent *ent = NULL;
  1740. int i, j = 0;
  1741. _irqL irqL;
  1742. _enter_critical_bh(&(plink_ctl->lock), &irqL);
  1743. for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
  1744. if (plink_ctl->ent[i].valid == _TRUE
  1745. && plink_ctl->ent[i].plink_state != RTW_MESH_PLINK_ESTAB
  1746. ) {
  1747. if (j == idx) {
  1748. ent = &plink_ctl->ent[i];
  1749. break;
  1750. }
  1751. j++;
  1752. }
  1753. }
  1754. _exit_critical_bh(&(plink_ctl->lock), &irqL);
  1755. return ent;
  1756. }
  1757. int _rtw_mesh_plink_add(_adapter *adapter, const u8 *hwaddr)
  1758. {
  1759. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1760. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1761. struct mesh_plink_ent *ent = NULL;
  1762. u8 exist = _FALSE;
  1763. int i;
  1764. for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
  1765. if (plink_ctl->ent[i].valid == _TRUE
  1766. && _rtw_memcmp(plink_ctl->ent[i].addr, hwaddr, ETH_ALEN) == _TRUE
  1767. ) {
  1768. ent = &plink_ctl->ent[i];
  1769. exist = _TRUE;
  1770. break;
  1771. }
  1772. if (ent == NULL && plink_ctl->ent[i].valid == _FALSE)
  1773. ent = &plink_ctl->ent[i];
  1774. }
  1775. if (exist == _FALSE && ent) {
  1776. _rtw_memcpy(ent->addr, hwaddr, ETH_ALEN);
  1777. ent->valid = _TRUE;
  1778. #ifdef CONFIG_RTW_MESH_AEK
  1779. ent->aek_valid = 0;
  1780. #endif
  1781. ent->llid = 0;
  1782. ent->plid = 0;
  1783. _rtw_memset(ent->chosen_pmk, 0, 16);
  1784. #ifdef CONFIG_RTW_MESH_AEK
  1785. _rtw_memset(ent->sel_pcs, 0, 4);
  1786. _rtw_memset(ent->l_nonce, 0, 32);
  1787. _rtw_memset(ent->p_nonce, 0, 32);
  1788. #endif
  1789. ent->plink_state = RTW_MESH_PLINK_LISTEN;
  1790. #ifndef CONFIG_RTW_MESH_DRIVER_AID
  1791. ent->aid = 0;
  1792. #endif
  1793. ent->peer_aid = 0;
  1794. SET_PEER_CONF_DISABLED(ent);
  1795. SET_CTO_MGATE_CONF_DISABLED(ent);
  1796. plink_ctl->num++;
  1797. }
  1798. exit:
  1799. return exist == _TRUE ? RTW_ALREADY : (ent ? _SUCCESS : _FAIL);
  1800. }
  1801. int rtw_mesh_plink_add(_adapter *adapter, const u8 *hwaddr)
  1802. {
  1803. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1804. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1805. _irqL irqL;
  1806. int ret;
  1807. _enter_critical_bh(&(plink_ctl->lock), &irqL);
  1808. ret = _rtw_mesh_plink_add(adapter, hwaddr);
  1809. _exit_critical_bh(&(plink_ctl->lock), &irqL);
  1810. return ret;
  1811. }
  1812. int rtw_mesh_plink_set_state(_adapter *adapter, const u8 *hwaddr, u8 state)
  1813. {
  1814. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1815. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1816. struct mesh_plink_ent *ent = NULL;
  1817. _irqL irqL;
  1818. _enter_critical_bh(&(plink_ctl->lock), &irqL);
  1819. ent = _rtw_mesh_plink_get(adapter, hwaddr);
  1820. if (ent)
  1821. ent->plink_state = state;
  1822. _exit_critical_bh(&(plink_ctl->lock), &irqL);
  1823. exit:
  1824. return ent ? _SUCCESS : _FAIL;
  1825. }
  1826. #ifdef CONFIG_RTW_MESH_AEK
  1827. int rtw_mesh_plink_set_aek(_adapter *adapter, const u8 *hwaddr, const u8 *aek)
  1828. {
  1829. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1830. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1831. struct mesh_plink_ent *ent = NULL;
  1832. _irqL irqL;
  1833. _enter_critical_bh(&(plink_ctl->lock), &irqL);
  1834. ent = _rtw_mesh_plink_get(adapter, hwaddr);
  1835. if (ent) {
  1836. _rtw_memcpy(ent->aek, aek, 32);
  1837. ent->aek_valid = 1;
  1838. }
  1839. _exit_critical_bh(&(plink_ctl->lock), &irqL);
  1840. exit:
  1841. return ent ? _SUCCESS : _FAIL;
  1842. }
  1843. #endif
  1844. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  1845. int rtw_mesh_plink_set_peer_conf_timeout(_adapter *adapter, const u8 *hwaddr)
  1846. {
  1847. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  1848. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1849. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1850. struct mesh_plink_ent *ent = NULL;
  1851. _irqL irqL;
  1852. _enter_critical_bh(&(plink_ctl->lock), &irqL);
  1853. ent = _rtw_mesh_plink_get(adapter, hwaddr);
  1854. if (ent) {
  1855. if (IS_PEER_CONF_DISABLED(ent))
  1856. SET_PEER_CONF_END_TIME(ent, mcfg->peer_sel_policy.peer_conf_timeout_ms);
  1857. }
  1858. _exit_critical_bh(&(plink_ctl->lock), &irqL);
  1859. exit:
  1860. return ent ? _SUCCESS : _FAIL;
  1861. }
  1862. #endif
  1863. void _rtw_mesh_plink_del_ent(_adapter *adapter, struct mesh_plink_ent *ent)
  1864. {
  1865. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1866. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1867. ent->valid = _FALSE;
  1868. #ifdef CONFIG_RTW_MESH_DRIVER_AID
  1869. if (ent->tx_conf_ies && ent->tx_conf_ies_len)
  1870. rtw_mfree(ent->tx_conf_ies, ent->tx_conf_ies_len);
  1871. ent->tx_conf_ies = NULL;
  1872. ent->tx_conf_ies_len = 0;
  1873. #endif
  1874. if (ent->rx_conf_ies && ent->rx_conf_ies_len)
  1875. rtw_mfree(ent->rx_conf_ies, ent->rx_conf_ies_len);
  1876. ent->rx_conf_ies = NULL;
  1877. ent->rx_conf_ies_len = 0;
  1878. if (ent->scanned)
  1879. ent->scanned = NULL;
  1880. plink_ctl->num--;
  1881. }
  1882. int rtw_mesh_plink_del(_adapter *adapter, const u8 *hwaddr)
  1883. {
  1884. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1885. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1886. struct mesh_plink_ent *ent = NULL;
  1887. u8 exist = _FALSE;
  1888. int i;
  1889. _irqL irqL;
  1890. _enter_critical_bh(&(plink_ctl->lock), &irqL);
  1891. for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
  1892. if (plink_ctl->ent[i].valid == _TRUE
  1893. && _rtw_memcmp(plink_ctl->ent[i].addr, hwaddr, ETH_ALEN) == _TRUE
  1894. ) {
  1895. ent = &plink_ctl->ent[i];
  1896. exist = _TRUE;
  1897. break;
  1898. }
  1899. }
  1900. if (exist == _TRUE)
  1901. _rtw_mesh_plink_del_ent(adapter, ent);
  1902. _exit_critical_bh(&(plink_ctl->lock), &irqL);
  1903. exit:
  1904. return exist == _TRUE ? _SUCCESS : RTW_ALREADY;
  1905. }
  1906. void rtw_mesh_plink_ctl_init(_adapter *adapter)
  1907. {
  1908. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1909. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1910. int i;
  1911. _rtw_spinlock_init(&plink_ctl->lock);
  1912. plink_ctl->num = 0;
  1913. for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++)
  1914. plink_ctl->ent[i].valid = _FALSE;
  1915. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  1916. _rtw_init_queue(&plink_ctl->peer_blacklist);
  1917. #endif
  1918. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  1919. _rtw_init_queue(&plink_ctl->cto_mgate_blacklist);
  1920. #endif
  1921. }
  1922. void rtw_mesh_plink_ctl_deinit(_adapter *adapter)
  1923. {
  1924. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1925. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1926. struct mesh_plink_ent *ent;
  1927. int i;
  1928. _irqL irqL;
  1929. _enter_critical_bh(&(plink_ctl->lock), &irqL);
  1930. for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
  1931. ent = &plink_ctl->ent[i];
  1932. #ifdef CONFIG_RTW_MESH_DRIVER_AID
  1933. if (ent->tx_conf_ies && ent->tx_conf_ies_len)
  1934. rtw_mfree(ent->tx_conf_ies, ent->tx_conf_ies_len);
  1935. #endif
  1936. if (ent->rx_conf_ies && ent->rx_conf_ies_len)
  1937. rtw_mfree(ent->rx_conf_ies, ent->rx_conf_ies_len);
  1938. }
  1939. _exit_critical_bh(&(plink_ctl->lock), &irqL);
  1940. _rtw_spinlock_free(&plink_ctl->lock);
  1941. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  1942. rtw_mesh_peer_blacklist_flush(adapter);
  1943. _rtw_deinit_queue(&plink_ctl->peer_blacklist);
  1944. #endif
  1945. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  1946. rtw_mesh_cto_mgate_blacklist_flush(adapter);
  1947. _rtw_deinit_queue(&plink_ctl->cto_mgate_blacklist);
  1948. #endif
  1949. }
  1950. void dump_mesh_plink_ctl(void *sel, _adapter *adapter)
  1951. {
  1952. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  1953. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  1954. struct mesh_plink_ent *ent;
  1955. int i;
  1956. RTW_PRINT_SEL(sel, "num:%u\n", plink_ctl->num);
  1957. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  1958. RTW_PRINT_SEL(sel, "acnode_rsvd:%u\n", plink_ctl->acnode_rsvd);
  1959. #endif
  1960. for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
  1961. ent = &plink_ctl->ent[i];
  1962. if (!ent->valid)
  1963. continue;
  1964. RTW_PRINT_SEL(sel, "\n");
  1965. RTW_PRINT_SEL(sel, "peer:"MAC_FMT"\n", MAC_ARG(ent->addr));
  1966. RTW_PRINT_SEL(sel, "plink_state:%s\n", rtw_mesh_plink_str(ent->plink_state));
  1967. #ifdef CONFIG_RTW_MESH_AEK
  1968. if (ent->aek_valid)
  1969. RTW_PRINT_SEL(sel, "aek:"KEY_FMT KEY_FMT"\n", KEY_ARG(ent->aek), KEY_ARG(ent->aek + 16));
  1970. #endif
  1971. RTW_PRINT_SEL(sel, "llid:%u, plid:%u\n", ent->llid, ent->plid);
  1972. #ifndef CONFIG_RTW_MESH_DRIVER_AID
  1973. RTW_PRINT_SEL(sel, "aid:%u\n", ent->aid);
  1974. #endif
  1975. RTW_PRINT_SEL(sel, "peer_aid:%u\n", ent->peer_aid);
  1976. RTW_PRINT_SEL(sel, "chosen_pmk:"KEY_FMT"\n", KEY_ARG(ent->chosen_pmk));
  1977. #ifdef CONFIG_RTW_MESH_AEK
  1978. RTW_PRINT_SEL(sel, "sel_pcs:%02x%02x%02x%02x\n"
  1979. , ent->sel_pcs[0], ent->sel_pcs[1], ent->sel_pcs[2], ent->sel_pcs[3]);
  1980. RTW_PRINT_SEL(sel, "l_nonce:"KEY_FMT KEY_FMT"\n", KEY_ARG(ent->l_nonce), KEY_ARG(ent->l_nonce + 16));
  1981. RTW_PRINT_SEL(sel, "p_nonce:"KEY_FMT KEY_FMT"\n", KEY_ARG(ent->p_nonce), KEY_ARG(ent->p_nonce + 16));
  1982. #endif
  1983. #ifdef CONFIG_RTW_MESH_DRIVER_AID
  1984. RTW_PRINT_SEL(sel, "tx_conf_ies:%p, len:%u\n", ent->tx_conf_ies, ent->tx_conf_ies_len);
  1985. #endif
  1986. RTW_PRINT_SEL(sel, "rx_conf_ies:%p, len:%u\n", ent->rx_conf_ies, ent->rx_conf_ies_len);
  1987. RTW_PRINT_SEL(sel, "scanned:%p\n", ent->scanned);
  1988. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  1989. if (!IS_PEER_CONF_DISABLED(ent)) {
  1990. if (!IS_PEER_CONF_TIMEOUT(ent))
  1991. RTW_PRINT_SEL(sel, "peer_conf:%d\n", rtw_systime_to_ms(ent->peer_conf_end_time - rtw_get_current_time()));
  1992. else
  1993. RTW_PRINT_SEL(sel, "peer_conf:TIMEOUT\n");
  1994. }
  1995. #endif
  1996. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  1997. if (!IS_CTO_MGATE_CONF_DISABLED(ent)) {
  1998. if (!IS_CTO_MGATE_CONF_TIMEOUT(ent))
  1999. RTW_PRINT_SEL(sel, "cto_mgate_conf:%d\n", rtw_systime_to_ms(ent->cto_mgate_conf_end_time - rtw_get_current_time()));
  2000. else
  2001. RTW_PRINT_SEL(sel, "cto_mgate_conf:TIMEOUT\n");
  2002. }
  2003. #endif
  2004. }
  2005. }
  2006. /* this function is called with plink_ctl being locked */
  2007. int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, struct sta_info *sta)
  2008. {
  2009. #ifndef DBG_RTW_MESH_PEER_ESTABLISH
  2010. #define DBG_RTW_MESH_PEER_ESTABLISH 0
  2011. #endif
  2012. struct sta_priv *stapriv = &adapter->stapriv;
  2013. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  2014. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  2015. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  2016. u8 *tlv_ies;
  2017. u16 tlv_ieslen;
  2018. struct rtw_ieee802_11_elems elems;
  2019. _irqL irqL;
  2020. int i;
  2021. int ret = _FAIL;
  2022. if (!plink->rx_conf_ies || !plink->rx_conf_ies_len) {
  2023. RTW_INFO(FUNC_ADPT_FMT" no rx confirm from sta "MAC_FMT"\n"
  2024. , FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
  2025. goto exit;
  2026. }
  2027. if (plink->rx_conf_ies_len < 4) {
  2028. RTW_INFO(FUNC_ADPT_FMT" confirm from sta "MAC_FMT" too short\n"
  2029. , FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
  2030. goto exit;
  2031. }
  2032. #ifdef CONFIG_RTW_MESH_DRIVER_AID
  2033. if (!plink->tx_conf_ies || !plink->tx_conf_ies_len) {
  2034. RTW_INFO(FUNC_ADPT_FMT" no tx confirm to sta "MAC_FMT"\n"
  2035. , FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
  2036. goto exit;
  2037. }
  2038. if (plink->tx_conf_ies_len < 4) {
  2039. RTW_INFO(FUNC_ADPT_FMT" confirm to sta "MAC_FMT" too short\n"
  2040. , FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
  2041. goto exit;
  2042. }
  2043. #endif
  2044. tlv_ies = plink->rx_conf_ies + 4;
  2045. tlv_ieslen = plink->rx_conf_ies_len - 4;
  2046. if (DBG_RTW_MESH_PEER_ESTABLISH)
  2047. dump_ies(RTW_DBGDUMP, tlv_ies, tlv_ieslen);
  2048. if (rtw_ieee802_11_parse_elems(tlv_ies, tlv_ieslen, &elems, 1) == ParseFailed) {
  2049. RTW_INFO(FUNC_ADPT_FMT" sta "MAC_FMT" sent invalid confirm\n"
  2050. , FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
  2051. goto exit;
  2052. }
  2053. SET_PEER_CONF_DISABLED(plink);
  2054. if (rtw_bss_is_cto_mgate(&plink->scanned->network)
  2055. && !rtw_bss_is_forwarding(&plink->scanned->network))
  2056. SET_CTO_MGATE_CONF_END_TIME(plink, mcfg->peer_sel_policy.cto_mgate_conf_timeout_ms);
  2057. else
  2058. SET_CTO_MGATE_CONF_DISABLED(plink);
  2059. sta->state &= (~WIFI_FW_AUTH_SUCCESS);
  2060. sta->state |= WIFI_FW_ASSOC_STATE;
  2061. rtw_ap_parse_sta_capability(adapter, sta, plink->rx_conf_ies);
  2062. if (rtw_ap_parse_sta_supported_rates(adapter, sta, tlv_ies, tlv_ieslen) != _STATS_SUCCESSFUL_)
  2063. goto exit;
  2064. if (rtw_ap_parse_sta_security_ie(adapter, sta, &elems) != _STATS_SUCCESSFUL_)
  2065. goto exit;
  2066. rtw_ap_parse_sta_wmm_ie(adapter, sta, tlv_ies, tlv_ieslen);
  2067. rtw_ap_parse_sta_ht_ie(adapter, sta, &elems);
  2068. rtw_ap_parse_sta_vht_ie(adapter, sta, &elems);
  2069. /* AID */
  2070. #ifdef CONFIG_RTW_MESH_DRIVER_AID
  2071. sta->cmn.aid = RTW_GET_LE16(plink->tx_conf_ies + 2);
  2072. #else
  2073. sta->cmn.aid = plink->aid;
  2074. #endif
  2075. stapriv->sta_aid[sta->cmn.aid - 1] = sta;
  2076. RTW_INFO(FUNC_ADPT_FMT" sta "MAC_FMT" aid:%u\n"
  2077. , FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr), sta->cmn.aid);
  2078. sta->state &= (~WIFI_FW_ASSOC_STATE);
  2079. sta->state |= WIFI_FW_ASSOC_SUCCESS;
  2080. sta->local_mps = RTW_MESH_PS_ACTIVE;
  2081. rtw_ewma_err_rate_init(&sta->metrics.err_rate);
  2082. rtw_ewma_err_rate_add(&sta->metrics.err_rate, 1);
  2083. /* init data_rate to 1M */
  2084. sta->metrics.data_rate = 10;
  2085. _enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
  2086. if (rtw_is_list_empty(&sta->asoc_list)) {
  2087. STA_SET_MESH_PLINK(sta, plink);
  2088. /* TBD: up layer timeout mechanism */
  2089. /* sta->expire_to = mcfg->plink_timeout / 2; */
  2090. rtw_list_insert_tail(&sta->asoc_list, &stapriv->asoc_list);
  2091. stapriv->asoc_list_cnt++;
  2092. }
  2093. _exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
  2094. bss_cap_update_on_sta_join(adapter, sta);
  2095. sta_info_update(adapter, sta);
  2096. report_add_sta_event(adapter, sta->cmn.mac_addr);
  2097. ret = _SUCCESS;
  2098. exit:
  2099. return ret;
  2100. }
  2101. void rtw_mesh_expire_peer_notify(_adapter *adapter, const u8 *peer_addr)
  2102. {
  2103. u8 null_ssid[2] = {0, 0};
  2104. #ifdef CONFIG_IOCTL_CFG80211
  2105. rtw_cfg80211_notify_new_peer_candidate(adapter->rtw_wdev
  2106. , peer_addr
  2107. , null_ssid
  2108. , 2
  2109. , GFP_ATOMIC
  2110. );
  2111. #endif
  2112. exit:
  2113. return;
  2114. }
  2115. static u8 *rtw_mesh_construct_peer_mesh_close(_adapter *adapter, struct mesh_plink_ent *plink, u16 reason, u32 *len)
  2116. {
  2117. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  2118. u8 *frame = NULL, *pos;
  2119. u32 flen;
  2120. struct rtw_ieee80211_hdr *whdr;
  2121. if (minfo->mesh_auth_id && !MESH_PLINK_AEK_VALID(plink))
  2122. goto exit;
  2123. flen = sizeof(struct rtw_ieee80211_hdr_3addr)
  2124. + 2 /* category, action */
  2125. + 2 + minfo->mesh_id_len /* mesh id */
  2126. + 2 + 8 + (minfo->mesh_auth_id ? 16 : 0) /* mpm */
  2127. + (minfo->mesh_auth_id ? 2 + AES_BLOCK_SIZE : 0) /* mic */
  2128. + (minfo->mesh_auth_id ? 70 : 0) /* ampe */
  2129. ;
  2130. pos = frame = rtw_zmalloc(flen);
  2131. if (!frame)
  2132. goto exit;
  2133. whdr = (struct rtw_ieee80211_hdr *)frame;
  2134. _rtw_memcpy(whdr->addr1, adapter_mac_addr(adapter), ETH_ALEN);
  2135. _rtw_memcpy(whdr->addr2, plink->addr, ETH_ALEN);
  2136. _rtw_memcpy(whdr->addr3, adapter_mac_addr(adapter), ETH_ALEN);
  2137. set_frame_sub_type(frame, WIFI_ACTION);
  2138. pos += sizeof(struct rtw_ieee80211_hdr_3addr);
  2139. *(pos++) = RTW_WLAN_CATEGORY_SELF_PROTECTED;
  2140. *(pos++) = RTW_ACT_SELF_PROTECTED_MESH_CLOSE;
  2141. pos = rtw_set_ie_mesh_id(pos, NULL, minfo->mesh_id, minfo->mesh_id_len);
  2142. pos = rtw_set_ie_mpm(pos, NULL
  2143. , minfo->mesh_auth_id ? 1 : 0
  2144. , plink->plid
  2145. , &plink->llid
  2146. , &reason
  2147. , minfo->mesh_auth_id ? plink->chosen_pmk : NULL);
  2148. #ifdef CONFIG_RTW_MESH_AEK
  2149. if (minfo->mesh_auth_id) {
  2150. u8 ampe_buf[70];
  2151. int enc_ret;
  2152. *pos = WLAN_EID_MIC;
  2153. *(pos + 1) = AES_BLOCK_SIZE;
  2154. ampe_buf[0] = WLAN_EID_AMPE;
  2155. ampe_buf[1] = 68;
  2156. _rtw_memcpy(ampe_buf + 2, plink->sel_pcs, 4);
  2157. _rtw_memcpy(ampe_buf + 6, plink->p_nonce, 32);
  2158. _rtw_memcpy(ampe_buf + 38, plink->l_nonce, 32);
  2159. enc_ret = rtw_mpm_ampe_enc(adapter, plink
  2160. , frame + sizeof(struct rtw_ieee80211_hdr_3addr)
  2161. , pos, ampe_buf, 1);
  2162. if (enc_ret != _SUCCESS) {
  2163. rtw_mfree(frame, flen);
  2164. frame = NULL;
  2165. goto exit;
  2166. }
  2167. }
  2168. #endif
  2169. *len = flen;
  2170. exit:
  2171. return frame;
  2172. }
  2173. void _rtw_mesh_expire_peer_ent(_adapter *adapter, struct mesh_plink_ent *plink)
  2174. {
  2175. #if defined(CONFIG_RTW_MESH_STA_DEL_DISASOC)
  2176. _rtw_mesh_plink_del_ent(adapter, plink);
  2177. rtw_cfg80211_indicate_sta_disassoc(adapter, plink->addr, 0);
  2178. #else
  2179. u8 *frame = NULL;
  2180. u32 flen;
  2181. if (plink->plink_state == RTW_MESH_PLINK_ESTAB)
  2182. frame = rtw_mesh_construct_peer_mesh_close(adapter, plink, WLAN_REASON_MESH_CLOSE, &flen);
  2183. if (frame) {
  2184. struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
  2185. struct wireless_dev *wdev = adapter->rtw_wdev;
  2186. s32 freq = rtw_ch2freq(mlmeext->cur_channel);
  2187. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
  2188. rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, flen, GFP_ATOMIC);
  2189. #else
  2190. cfg80211_rx_action(adapter->pnetdev, freq, frame, flen, GFP_ATOMIC);
  2191. #endif
  2192. rtw_mfree(frame, flen);
  2193. } else {
  2194. rtw_mesh_expire_peer_notify(adapter, plink->addr);
  2195. RTW_INFO(FUNC_ADPT_FMT" set "MAC_FMT" plink unknown\n"
  2196. , FUNC_ADPT_ARG(adapter), MAC_ARG(plink->addr));
  2197. plink->plink_state = RTW_MESH_PLINK_UNKNOWN;
  2198. }
  2199. #endif
  2200. }
  2201. void rtw_mesh_expire_peer(_adapter *adapter, const u8 *peer_addr)
  2202. {
  2203. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  2204. struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
  2205. struct mesh_plink_ent *plink;
  2206. _irqL irqL;
  2207. _enter_critical_bh(&(plink_ctl->lock), &irqL);
  2208. plink = _rtw_mesh_plink_get(adapter, peer_addr);
  2209. if (!plink)
  2210. goto exit;
  2211. _rtw_mesh_expire_peer_ent(adapter, plink);
  2212. exit:
  2213. _exit_critical_bh(&(plink_ctl->lock), &irqL);
  2214. }
  2215. u8 rtw_mesh_ps_annc(_adapter *adapter, u8 ps)
  2216. {
  2217. _irqL irqL;
  2218. _list *head, *list;
  2219. struct sta_info *sta;
  2220. struct sta_priv *stapriv = &adapter->stapriv;
  2221. u8 sta_alive_num = 0, i;
  2222. char sta_alive_list[NUM_STA];
  2223. u8 annc_cnt = 0;
  2224. if (rtw_linked_check(adapter) == _FALSE)
  2225. goto exit;
  2226. _enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
  2227. head = &stapriv->asoc_list;
  2228. list = get_next(head);
  2229. while ((rtw_end_of_queue_search(head, list)) == _FALSE) {
  2230. int stainfo_offset;
  2231. sta = LIST_CONTAINOR(list, struct sta_info, asoc_list);
  2232. list = get_next(list);
  2233. stainfo_offset = rtw_stainfo_offset(stapriv, sta);
  2234. if (stainfo_offset_valid(stainfo_offset))
  2235. sta_alive_list[sta_alive_num++] = stainfo_offset;
  2236. }
  2237. _exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
  2238. for (i = 0; i < sta_alive_num; i++) {
  2239. sta = rtw_get_stainfo_by_offset(stapriv, sta_alive_list[i]);
  2240. if (!sta)
  2241. continue;
  2242. issue_qos_nulldata(adapter, sta->cmn.mac_addr, 7, ps, 3, 500);
  2243. annc_cnt++;
  2244. }
  2245. exit:
  2246. return annc_cnt;
  2247. }
  2248. static void mpath_tx_tasklet_hdl(void *priv)
  2249. {
  2250. _adapter *adapter = (_adapter *)priv;
  2251. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  2252. struct xmit_frame *xframe;
  2253. _list *list, *head;
  2254. _list tmp;
  2255. u32 tmp_len;
  2256. s32 res;
  2257. _rtw_init_listhead(&tmp);
  2258. while (1) {
  2259. tmp_len = 0;
  2260. enter_critical_bh(&minfo->mpath_tx_queue.lock);
  2261. if (minfo->mpath_tx_queue_len) {
  2262. rtw_list_splice_init(&minfo->mpath_tx_queue.queue, &tmp);
  2263. tmp_len = minfo->mpath_tx_queue_len;
  2264. minfo->mpath_tx_queue_len = 0;
  2265. }
  2266. exit_critical_bh(&minfo->mpath_tx_queue.lock);
  2267. if (!tmp_len)
  2268. break;
  2269. head = &tmp;
  2270. list = get_next(head);
  2271. while (rtw_end_of_queue_search(head, list) == _FALSE) {
  2272. xframe = LIST_CONTAINOR(list, struct xmit_frame, list);
  2273. list = get_next(list);
  2274. rtw_list_delete(&xframe->list);
  2275. res = rtw_xmit_posthandle(adapter, xframe, xframe->pkt);
  2276. if (res < 0) {
  2277. #ifdef DBG_TX_DROP_FRAME
  2278. RTW_INFO("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__);
  2279. #endif
  2280. adapter->xmitpriv.tx_drop++;
  2281. }
  2282. }
  2283. }
  2284. }
  2285. static void rtw_mpath_tx_queue_flush(_adapter *adapter)
  2286. {
  2287. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  2288. struct xmit_frame *xframe;
  2289. _list *list, *head;
  2290. _list tmp;
  2291. _rtw_init_listhead(&tmp);
  2292. enter_critical_bh(&minfo->mpath_tx_queue.lock);
  2293. rtw_list_splice_init(&minfo->mpath_tx_queue.queue, &tmp);
  2294. minfo->mpath_tx_queue_len = 0;
  2295. exit_critical_bh(&minfo->mpath_tx_queue.lock);
  2296. head = &tmp;
  2297. list = get_next(head);
  2298. while (rtw_end_of_queue_search(head, list) == _FALSE) {
  2299. xframe = LIST_CONTAINOR(list, struct xmit_frame, list);
  2300. list = get_next(list);
  2301. rtw_list_delete(&xframe->list);
  2302. rtw_free_xmitframe(&adapter->xmitpriv, xframe);
  2303. }
  2304. }
  2305. #ifdef PLATFORM_LINUX /* 3.10 ~ 4.13 checked */
  2306. #if defined(CONFIG_SLUB)
  2307. #include <linux/slub_def.h>
  2308. #elif defined(CONFIG_SLAB)
  2309. #include <linux/slab_def.h>
  2310. #endif
  2311. typedef struct kmem_cache rtw_mcache;
  2312. #endif
  2313. rtw_mcache *rtw_mcache_create(const char *name, size_t size)
  2314. {
  2315. #ifdef PLATFORM_LINUX /* 3.10 ~ 4.13 checked */
  2316. return kmem_cache_create(name, size, 0, 0, NULL);
  2317. #else
  2318. #error "TBD\n";
  2319. #endif
  2320. }
  2321. void rtw_mcache_destroy(rtw_mcache *s)
  2322. {
  2323. #ifdef PLATFORM_LINUX /* 3.10 ~ 4.13 checked */
  2324. kmem_cache_destroy(s);
  2325. #else
  2326. #error "TBD\n";
  2327. #endif
  2328. }
  2329. void *_rtw_mcache_alloc(rtw_mcache *cachep)
  2330. {
  2331. #ifdef PLATFORM_LINUX /* 3.10 ~ 4.13 checked */
  2332. return kmem_cache_alloc(cachep, GFP_ATOMIC);
  2333. #else
  2334. #error "TBD\n";
  2335. #endif
  2336. }
  2337. void _rtw_mcache_free(rtw_mcache *cachep, void *objp)
  2338. {
  2339. #ifdef PLATFORM_LINUX /* 3.10 ~ 4.13 checked */
  2340. kmem_cache_free(cachep, objp);
  2341. #else
  2342. #error "TBD\n";
  2343. #endif
  2344. }
  2345. #ifdef DBG_MEM_ALLOC
  2346. inline void *dbg_rtw_mcache_alloc(rtw_mcache *cachep, const enum mstat_f flags, const char *func, const int line)
  2347. {
  2348. void *p;
  2349. u32 sz = cachep->size;
  2350. if (match_mstat_sniff_rules(flags, sz))
  2351. RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%u)\n", func, line, __func__, sz);
  2352. p = _rtw_mcache_alloc(cachep);
  2353. rtw_mstat_update(
  2354. flags
  2355. , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
  2356. , sz
  2357. );
  2358. return p;
  2359. }
  2360. inline void dbg_rtw_mcache_free(rtw_mcache *cachep, void *pbuf, const enum mstat_f flags, const char *func, const int line)
  2361. {
  2362. u32 sz = cachep->size;
  2363. if (match_mstat_sniff_rules(flags, sz))
  2364. RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%u)\n", func, line, __func__, sz);
  2365. _rtw_mcache_free(cachep, pbuf);
  2366. rtw_mstat_update(
  2367. flags
  2368. , MSTAT_FREE
  2369. , sz
  2370. );
  2371. }
  2372. #define rtw_mcache_alloc(cachep) dbg_rtw_mcache_alloc(cachep, MSTAT_TYPE_PHY, __FUNCTION__, __LINE__)
  2373. #define rtw_mcache_free(cachep, objp) dbg_rtw_mcache_free(cachep, objp, MSTAT_TYPE_PHY, __FUNCTION__, __LINE__)
  2374. #else
  2375. #define rtw_mcache_alloc(cachep) _rtw_mcache_alloc(cachep)
  2376. #define rtw_mcache_free(cachep, objp) _rtw_mcache_free(cachep, objp)
  2377. #endif /* DBG_MEM_ALLOC */
  2378. /* Mesh Received Cache */
  2379. #define RTW_MRC_BUCKETS 256 /* must be a power of 2 */
  2380. #define RTW_MRC_QUEUE_MAX_LEN 4
  2381. #define RTW_MRC_TIMEOUT_MS (3 * 1000)
  2382. /**
  2383. * struct rtw_mrc_entry - entry in the Mesh Received Cache
  2384. *
  2385. * @seqnum: mesh sequence number of the frame
  2386. * @exp_time: expiration time of the entry
  2387. * @msa: mesh source address of the frame
  2388. * @list: hashtable list pointer
  2389. *
  2390. * The Mesh Received Cache keeps track of the latest received frames that
  2391. * have been received by a mesh interface and discards received frames
  2392. * that are found in the cache.
  2393. */
  2394. struct rtw_mrc_entry {
  2395. rtw_hlist_node list;
  2396. systime exp_time;
  2397. u32 seqnum;
  2398. u8 msa[ETH_ALEN];
  2399. };
  2400. struct rtw_mrc {
  2401. rtw_hlist_head bucket[RTW_MRC_BUCKETS];
  2402. u32 idx_mask;
  2403. rtw_mcache *cache;
  2404. };
  2405. static int rtw_mrc_init(_adapter *adapter)
  2406. {
  2407. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  2408. char cache_name[IFNAMSIZ + 8 + 1];
  2409. int i;
  2410. minfo->mrc = rtw_malloc(sizeof(struct rtw_mrc));
  2411. if (!minfo->mrc)
  2412. return -ENOMEM;
  2413. minfo->mrc->idx_mask = RTW_MRC_BUCKETS - 1;
  2414. for (i = 0; i < RTW_MRC_BUCKETS; i++)
  2415. rtw_hlist_head_init(&minfo->mrc->bucket[i]);
  2416. sprintf(cache_name, "rtw_mrc_%s", ADPT_ARG(adapter));
  2417. minfo->mrc->cache = rtw_mcache_create(cache_name, sizeof(struct rtw_mrc_entry));
  2418. return 0;
  2419. }
  2420. static void rtw_mrc_free(_adapter *adapter)
  2421. {
  2422. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  2423. struct rtw_mrc *mrc = minfo->mrc;
  2424. struct rtw_mrc_entry *p;
  2425. rtw_hlist_node *np, *n;
  2426. int i;
  2427. if (!mrc)
  2428. return;
  2429. for (i = 0; i < RTW_MRC_BUCKETS; i++) {
  2430. rtw_hlist_for_each_entry_safe(p, np, n, &mrc->bucket[i], list) {
  2431. rtw_hlist_del(&p->list);
  2432. rtw_mcache_free(mrc->cache, p);
  2433. }
  2434. }
  2435. rtw_mcache_destroy(mrc->cache);
  2436. rtw_mfree(mrc, sizeof(struct rtw_mrc));
  2437. minfo->mrc = NULL;
  2438. }
  2439. /**
  2440. * rtw_mrc_check - Check frame in mesh received cache and add if absent.
  2441. *
  2442. * @adapter: interface
  2443. * @msa: mesh source address
  2444. * @seq: mesh seq number
  2445. *
  2446. * Returns: 0 if the frame is not in the cache, nonzero otherwise.
  2447. *
  2448. * Checks using the mesh source address and the mesh sequence number if we have
  2449. * received this frame lately. If the frame is not in the cache, it is added to
  2450. * it.
  2451. */
  2452. static int rtw_mrc_check(_adapter *adapter, const u8 *msa, u32 seq)
  2453. {
  2454. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  2455. struct rtw_mrc *mrc = minfo->mrc;
  2456. int entries = 0;
  2457. u8 idx;
  2458. struct rtw_mrc_entry *p;
  2459. rtw_hlist_node *np, *n;
  2460. u8 timeout;
  2461. if (!mrc)
  2462. return -1;
  2463. idx = seq & mrc->idx_mask;
  2464. rtw_hlist_for_each_entry_safe(p, np, n, &mrc->bucket[idx], list) {
  2465. ++entries;
  2466. timeout = rtw_time_after(rtw_get_current_time(), p->exp_time);
  2467. if (timeout || entries == RTW_MRC_QUEUE_MAX_LEN) {
  2468. if (!timeout)
  2469. minfo->mshstats.mrc_del_qlen++;
  2470. rtw_hlist_del(&p->list);
  2471. rtw_mcache_free(mrc->cache, p);
  2472. --entries;
  2473. } else if ((seq == p->seqnum) && _rtw_memcmp(msa, p->msa, ETH_ALEN) == _TRUE)
  2474. return -1;
  2475. }
  2476. p = rtw_mcache_alloc(mrc->cache);
  2477. if (!p)
  2478. return 0;
  2479. p->seqnum = seq;
  2480. p->exp_time = rtw_get_current_time() + rtw_ms_to_systime(RTW_MRC_TIMEOUT_MS);
  2481. _rtw_memcpy(p->msa, msa, ETH_ALEN);
  2482. rtw_hlist_add_head(&p->list, &mrc->bucket[idx]);
  2483. return 0;
  2484. }
  2485. static int rtw_mesh_decache(_adapter *adapter, const u8 *msa, u32 seq)
  2486. {
  2487. return rtw_mrc_check(adapter, msa, seq);
  2488. }
  2489. #ifndef RTW_MESH_SCAN_RESULT_EXP_MS
  2490. #define RTW_MESH_SCAN_RESULT_EXP_MS (10 * 1000)
  2491. #endif
  2492. #ifndef RTW_MESH_ACNODE_PREVENT
  2493. #define RTW_MESH_ACNODE_PREVENT 0
  2494. #endif
  2495. #ifndef RTW_MESH_ACNODE_CONF_TIMEOUT_MS
  2496. #define RTW_MESH_ACNODE_CONF_TIMEOUT_MS (20 * 1000)
  2497. #endif
  2498. #ifndef RTW_MESH_ACNODE_NOTIFY_TIMEOUT_MS
  2499. #define RTW_MESH_ACNODE_NOTIFY_TIMEOUT_MS (2 * 1000)
  2500. #endif
  2501. #ifndef RTW_MESH_OFFCH_CAND
  2502. #define RTW_MESH_OFFCH_CAND 1
  2503. #endif
  2504. #ifndef RTW_MESH_OFFCH_CAND_FIND_INT_MS
  2505. #define RTW_MESH_OFFCH_CAND_FIND_INT_MS (10 * 1000)
  2506. #endif
  2507. #ifndef RTW_MESH_PEER_CONF_TIMEOUT_MS
  2508. #define RTW_MESH_PEER_CONF_TIMEOUT_MS (20 * 1000)
  2509. #endif
  2510. #ifndef RTW_MESH_PEER_BLACKLIST_TIMEOUT_MS
  2511. #define RTW_MESH_PEER_BLACKLIST_TIMEOUT_MS (20 * 1000)
  2512. #endif
  2513. #ifndef RTW_MESH_CTO_MGATE_REQUIRE
  2514. #define RTW_MESH_CTO_MGATE_REQUIRE 0
  2515. #endif
  2516. #ifndef RTW_MESH_CTO_MGATE_CONF_TIMEOUT_MS
  2517. #define RTW_MESH_CTO_MGATE_CONF_TIMEOUT_MS (20 * 1000)
  2518. #endif
  2519. #ifndef RTW_MESH_CTO_MGATE_BLACKLIST_TIMEOUT_MS
  2520. #define RTW_MESH_CTO_MGATE_BLACKLIST_TIMEOUT_MS (20 * 1000)
  2521. #endif
  2522. void rtw_mesh_cfg_init_peer_sel_policy(struct rtw_mesh_cfg *mcfg)
  2523. {
  2524. struct mesh_peer_sel_policy *sel_policy = &mcfg->peer_sel_policy;
  2525. sel_policy->scanr_exp_ms = RTW_MESH_SCAN_RESULT_EXP_MS;
  2526. #if CONFIG_RTW_MESH_ACNODE_PREVENT
  2527. sel_policy->acnode_prevent = RTW_MESH_ACNODE_PREVENT;
  2528. sel_policy->acnode_conf_timeout_ms = RTW_MESH_ACNODE_CONF_TIMEOUT_MS;
  2529. sel_policy->acnode_notify_timeout_ms = RTW_MESH_ACNODE_NOTIFY_TIMEOUT_MS;
  2530. #endif
  2531. #if CONFIG_RTW_MESH_OFFCH_CAND
  2532. sel_policy->offch_cand = RTW_MESH_OFFCH_CAND;
  2533. sel_policy->offch_find_int_ms = RTW_MESH_OFFCH_CAND_FIND_INT_MS;
  2534. #endif
  2535. #if CONFIG_RTW_MESH_PEER_BLACKLIST
  2536. sel_policy->peer_conf_timeout_ms = RTW_MESH_PEER_CONF_TIMEOUT_MS;
  2537. sel_policy->peer_blacklist_timeout_ms = RTW_MESH_PEER_BLACKLIST_TIMEOUT_MS;
  2538. #endif
  2539. #if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
  2540. sel_policy->cto_mgate_require = RTW_MESH_CTO_MGATE_REQUIRE;
  2541. sel_policy->cto_mgate_conf_timeout_ms = RTW_MESH_CTO_MGATE_CONF_TIMEOUT_MS;
  2542. sel_policy->cto_mgate_blacklist_timeout_ms = RTW_MESH_CTO_MGATE_BLACKLIST_TIMEOUT_MS;
  2543. #endif
  2544. }
  2545. void rtw_mesh_cfg_init(_adapter *adapter)
  2546. {
  2547. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  2548. mcfg->max_peer_links = RTW_MESH_MAX_PEER_LINKS;
  2549. mcfg->plink_timeout = RTW_MESH_PEER_LINK_TIMEOUT;
  2550. mcfg->dot11MeshTTL = RTW_MESH_TTL;
  2551. mcfg->element_ttl = RTW_MESH_DEFAULT_ELEMENT_TTL;
  2552. mcfg->dot11MeshHWMPmaxPREQretries = RTW_MESH_MAX_PREQ_RETRIES;
  2553. mcfg->path_refresh_time = RTW_MESH_PATH_REFRESH_TIME;
  2554. mcfg->min_discovery_timeout = RTW_MESH_MIN_DISCOVERY_TIMEOUT;
  2555. mcfg->dot11MeshHWMPactivePathTimeout = RTW_MESH_PATH_TIMEOUT;
  2556. mcfg->dot11MeshHWMPpreqMinInterval = RTW_MESH_PREQ_MIN_INT;
  2557. mcfg->dot11MeshHWMPperrMinInterval = RTW_MESH_PERR_MIN_INT;
  2558. mcfg->dot11MeshHWMPnetDiameterTraversalTime = RTW_MESH_DIAM_TRAVERSAL_TIME;
  2559. mcfg->dot11MeshHWMPRootMode = RTW_IEEE80211_ROOTMODE_NO_ROOT;
  2560. mcfg->dot11MeshHWMPRannInterval = RTW_MESH_RANN_INTERVAL;
  2561. mcfg->dot11MeshGateAnnouncementProtocol = _FALSE;
  2562. mcfg->dot11MeshForwarding = _TRUE;
  2563. mcfg->rssi_threshold = 0;
  2564. mcfg->dot11MeshHWMPactivePathToRootTimeout = RTW_MESH_PATH_TO_ROOT_TIMEOUT;
  2565. mcfg->dot11MeshHWMProotInterval = RTW_MESH_ROOT_INTERVAL;
  2566. mcfg->dot11MeshHWMPconfirmationInterval = RTW_MESH_ROOT_CONFIRMATION_INTERVAL;
  2567. mcfg->path_gate_timeout_factor = 3;
  2568. rtw_mesh_cfg_init_peer_sel_policy(mcfg);
  2569. #ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
  2570. mcfg->sane_metric_delta = RTW_MESH_SANE_METRIC_DELTA;
  2571. mcfg->max_root_add_chk_cnt = RTW_MESH_MAX_ROOT_ADD_CHK_CNT;
  2572. #endif
  2573. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  2574. mcfg->b2u_flags_msrc = 0;
  2575. mcfg->b2u_flags_mfwd = RTW_MESH_B2U_GA_UCAST;
  2576. #endif
  2577. }
  2578. void rtw_mesh_cfg_init_max_peer_links(_adapter *adapter, u8 stack_conf)
  2579. {
  2580. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  2581. mcfg->max_peer_links = RTW_MESH_MAX_PEER_LINKS;
  2582. if (mcfg->max_peer_links > stack_conf)
  2583. mcfg->max_peer_links = stack_conf;
  2584. }
  2585. void rtw_mesh_cfg_init_plink_timeout(_adapter *adapter, u32 stack_conf)
  2586. {
  2587. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  2588. mcfg->plink_timeout = stack_conf;
  2589. }
  2590. void rtw_mesh_init_mesh_info(_adapter *adapter)
  2591. {
  2592. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  2593. _rtw_memset(minfo, 0, sizeof(struct rtw_mesh_info));
  2594. rtw_mesh_plink_ctl_init(adapter);
  2595. minfo->last_preq = rtw_get_current_time();
  2596. /* minfo->last_sn_update = rtw_get_current_time(); */
  2597. minfo->next_perr = rtw_get_current_time();
  2598. ATOMIC_SET(&minfo->mpaths, 0);
  2599. rtw_mesh_pathtbl_init(adapter);
  2600. _rtw_init_queue(&minfo->mpath_tx_queue);
  2601. tasklet_init(&minfo->mpath_tx_tasklet
  2602. , (void(*)(unsigned long))mpath_tx_tasklet_hdl
  2603. , (unsigned long)adapter);
  2604. rtw_mrc_init(adapter);
  2605. _rtw_init_listhead(&minfo->preq_queue.list);
  2606. _rtw_spinlock_init(&minfo->mesh_preq_queue_lock);
  2607. rtw_init_timer(&adapter->mesh_path_timer, adapter, rtw_ieee80211_mesh_path_timer, adapter);
  2608. rtw_init_timer(&adapter->mesh_path_root_timer, adapter, rtw_ieee80211_mesh_path_root_timer, adapter);
  2609. rtw_init_timer(&adapter->mesh_atlm_param_req_timer, adapter, rtw_mesh_atlm_param_req_timer, adapter);
  2610. _init_workitem(&adapter->mesh_work, rtw_mesh_work_hdl, NULL);
  2611. }
  2612. void rtw_mesh_deinit_mesh_info(_adapter *adapter)
  2613. {
  2614. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  2615. tasklet_kill(&minfo->mpath_tx_tasklet);
  2616. rtw_mpath_tx_queue_flush(adapter);
  2617. _rtw_deinit_queue(&adapter->mesh_info.mpath_tx_queue);
  2618. rtw_mrc_free(adapter);
  2619. rtw_mesh_pathtbl_unregister(adapter);
  2620. rtw_mesh_plink_ctl_deinit(adapter);
  2621. _cancel_workitem_sync(&adapter->mesh_work);
  2622. _cancel_timer_ex(&adapter->mesh_path_timer);
  2623. _cancel_timer_ex(&adapter->mesh_path_root_timer);
  2624. _cancel_timer_ex(&adapter->mesh_atlm_param_req_timer);
  2625. }
  2626. /**
  2627. * rtw_mesh_nexthop_resolve - lookup next hop; conditionally start path discovery
  2628. *
  2629. * @skb: 802.11 frame to be sent
  2630. * @sdata: network subif the frame will be sent through
  2631. *
  2632. * Lookup next hop for given skb and start path discovery if no
  2633. * forwarding information is found.
  2634. *
  2635. * Returns: 0 if the next hop was found and -ENOENT if the frame was queued.
  2636. * skb is freeed here if no mpath could be allocated.
  2637. */
  2638. int rtw_mesh_nexthop_resolve(_adapter *adapter,
  2639. struct xmit_frame *xframe)
  2640. {
  2641. struct pkt_attrib *attrib = &xframe->attrib;
  2642. struct rtw_mesh_path *mpath;
  2643. struct xmit_frame *xframe_to_free = NULL;
  2644. u8 *target_addr = attrib->mda;
  2645. int err = 0;
  2646. int ret = _SUCCESS;
  2647. rtw_rcu_read_lock();
  2648. err = rtw_mesh_nexthop_lookup(adapter, target_addr, attrib->msa, attrib->ra);
  2649. if (!err)
  2650. goto endlookup;
  2651. /* no nexthop found, start resolving */
  2652. mpath = rtw_mesh_path_lookup(adapter, target_addr);
  2653. if (!mpath) {
  2654. mpath = rtw_mesh_path_add(adapter, target_addr);
  2655. if (IS_ERR(mpath)) {
  2656. xframe->pkt = NULL; /* free pkt outside */
  2657. rtw_mesh_path_discard_frame(adapter, xframe);
  2658. err = PTR_ERR(mpath);
  2659. ret = _FAIL;
  2660. goto endlookup;
  2661. }
  2662. }
  2663. if (!(mpath->flags & RTW_MESH_PATH_RESOLVING))
  2664. rtw_mesh_queue_preq(mpath, RTW_PREQ_Q_F_START);
  2665. enter_critical_bh(&mpath->frame_queue.lock);
  2666. if (mpath->frame_queue_len >= RTW_MESH_FRAME_QUEUE_LEN) {
  2667. xframe_to_free = LIST_CONTAINOR(get_next(get_list_head(&mpath->frame_queue)), struct xmit_frame, list);
  2668. rtw_list_delete(&(xframe_to_free->list));
  2669. mpath->frame_queue_len--;
  2670. }
  2671. rtw_list_insert_tail(&xframe->list, get_list_head(&mpath->frame_queue));
  2672. mpath->frame_queue_len++;
  2673. exit_critical_bh(&mpath->frame_queue.lock);
  2674. ret = RTW_RA_RESOLVING;
  2675. if (xframe_to_free)
  2676. rtw_mesh_path_discard_frame(adapter, xframe_to_free);
  2677. endlookup:
  2678. rtw_rcu_read_unlock();
  2679. return ret;
  2680. }
  2681. /**
  2682. * rtw_mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling
  2683. * this function is considered "using" the associated mpath, so preempt a path
  2684. * refresh if this mpath expires soon.
  2685. *
  2686. * @skb: 802.11 frame to be sent
  2687. * @sdata: network subif the frame will be sent through
  2688. *
  2689. * Returns: 0 if the next hop was found. Nonzero otherwise.
  2690. */
  2691. int rtw_mesh_nexthop_lookup(_adapter *adapter,
  2692. const u8 *mda, const u8 *msa, u8 *ra)
  2693. {
  2694. struct rtw_mesh_path *mpath;
  2695. struct sta_info *next_hop;
  2696. const u8 *target_addr = mda;
  2697. int err = -ENOENT;
  2698. rtw_rcu_read_lock();
  2699. mpath = rtw_mesh_path_lookup(adapter, target_addr);
  2700. if (!mpath || !(mpath->flags & RTW_MESH_PATH_ACTIVE))
  2701. goto endlookup;
  2702. if (rtw_time_after(rtw_get_current_time(),
  2703. mpath->exp_time -
  2704. rtw_ms_to_systime(adapter->mesh_cfg.path_refresh_time)) &&
  2705. _rtw_memcmp(adapter_mac_addr(adapter), msa, ETH_ALEN) == _TRUE &&
  2706. !(mpath->flags & RTW_MESH_PATH_RESOLVING) &&
  2707. !(mpath->flags & RTW_MESH_PATH_FIXED)) {
  2708. rtw_mesh_queue_preq(mpath, RTW_PREQ_Q_F_START | RTW_PREQ_Q_F_REFRESH);
  2709. }
  2710. next_hop = rtw_rcu_dereference(mpath->next_hop);
  2711. if (next_hop) {
  2712. _rtw_memcpy(ra, next_hop->cmn.mac_addr, ETH_ALEN);
  2713. err = 0;
  2714. }
  2715. endlookup:
  2716. rtw_rcu_read_unlock();
  2717. return err;
  2718. }
  2719. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  2720. static bool rtw_mesh_data_bmc_to_uc(_adapter *adapter
  2721. , const u8 *da, const u8 *sa, const u8 *mda, const u8 *msa
  2722. , u8 ae_need, const u8 *ori_ta, u8 mfwd_ttl
  2723. , _list *b2u_list, u8 *b2u_num, u32 *b2u_mseq)
  2724. {
  2725. struct sta_priv *stapriv = &adapter->stapriv;
  2726. struct xmit_priv *xmitpriv = &adapter->xmitpriv;
  2727. _irqL irqL;
  2728. _list *head, *list;
  2729. struct sta_info *sta;
  2730. char b2u_sta_id[NUM_STA];
  2731. u8 b2u_sta_num = 0;
  2732. bool bmc_need = _FALSE;
  2733. int i;
  2734. _enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
  2735. head = &stapriv->asoc_list;
  2736. list = get_next(head);
  2737. while ((rtw_end_of_queue_search(head, list)) == _FALSE) {
  2738. int stainfo_offset;
  2739. sta = LIST_CONTAINOR(list, struct sta_info, asoc_list);
  2740. list = get_next(list);
  2741. stainfo_offset = rtw_stainfo_offset(stapriv, sta);
  2742. if (stainfo_offset_valid(stainfo_offset))
  2743. b2u_sta_id[b2u_sta_num++] = stainfo_offset;
  2744. }
  2745. _exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
  2746. if (!b2u_sta_num)
  2747. goto exit;
  2748. for (i = 0; i < b2u_sta_num; i++) {
  2749. struct xmit_frame *b2uframe;
  2750. struct pkt_attrib *attrib;
  2751. sta = rtw_get_stainfo_by_offset(stapriv, b2u_sta_id[i]);
  2752. if (!(sta->state & _FW_LINKED)
  2753. || _rtw_memcmp(sta->cmn.mac_addr, msa, ETH_ALEN) == _TRUE
  2754. || (ori_ta && _rtw_memcmp(sta->cmn.mac_addr, ori_ta, ETH_ALEN) == _TRUE)
  2755. || is_broadcast_mac_addr(sta->cmn.mac_addr)
  2756. || is_zero_mac_addr(sta->cmn.mac_addr))
  2757. continue;
  2758. b2uframe = rtw_alloc_xmitframe(xmitpriv);
  2759. if (!b2uframe) {
  2760. bmc_need = _TRUE;
  2761. break;
  2762. }
  2763. if ((*b2u_num)++ == 0 && !ori_ta) {
  2764. *b2u_mseq = (cpu_to_le32(adapter->mesh_info.mesh_seqnum));
  2765. adapter->mesh_info.mesh_seqnum++;
  2766. }
  2767. attrib = &b2uframe->attrib;
  2768. attrib->mb2u = 1;
  2769. attrib->mseq = *b2u_mseq;
  2770. attrib->mfwd_ttl = ori_ta ? mfwd_ttl : 0;
  2771. _rtw_memcpy(attrib->ra, sta->cmn.mac_addr, ETH_ALEN);
  2772. _rtw_memcpy(attrib->ta, adapter_mac_addr(adapter), ETH_ALEN);
  2773. _rtw_memcpy(attrib->mda, mda, ETH_ALEN);
  2774. _rtw_memcpy(attrib->msa, msa, ETH_ALEN);
  2775. _rtw_memcpy(attrib->dst, da, ETH_ALEN);
  2776. _rtw_memcpy(attrib->src, sa, ETH_ALEN);
  2777. attrib->mesh_frame_mode = ae_need ? MESH_UCAST_PX_DATA : MESH_UCAST_DATA;
  2778. rtw_list_insert_tail(&b2uframe->list, b2u_list);
  2779. }
  2780. exit:
  2781. return bmc_need;
  2782. }
  2783. void dump_mesh_b2u_flags(void *sel, _adapter *adapter)
  2784. {
  2785. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  2786. RTW_PRINT_SEL(sel, "%4s %4s\n", "msrc", "mfwd");
  2787. RTW_PRINT_SEL(sel, "0x%02x 0x%02x\n", mcfg->b2u_flags_msrc, mcfg->b2u_flags_mfwd);
  2788. }
  2789. #endif /* CONFIG_RTW_MESH_DATA_BMC_TO_UC */
  2790. int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list)
  2791. {
  2792. struct pkt_file pktfile;
  2793. struct ethhdr etherhdr;
  2794. struct pkt_attrib *attrib;
  2795. struct rtw_mesh_path *mpath = NULL, *mppath = NULL;
  2796. u8 is_da_mcast;
  2797. u8 ae_need;
  2798. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  2799. bool bmc_need = _TRUE;
  2800. u8 b2u_num = 0;
  2801. u32 b2u_mseq = 0;
  2802. #endif
  2803. int res = _SUCCESS;
  2804. _rtw_open_pktfile(pkt, &pktfile);
  2805. if (_rtw_pktfile_read(&pktfile, (u8 *)&etherhdr, ETH_HLEN) != ETH_HLEN) {
  2806. res = _FAIL;
  2807. goto exit;
  2808. }
  2809. xframe->pkt = pkt;
  2810. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  2811. _rtw_init_listhead(b2u_list);
  2812. #endif
  2813. is_da_mcast = IS_MCAST(etherhdr.h_dest);
  2814. if (!is_da_mcast) {
  2815. struct sta_info *next_hop;
  2816. bool mpp_lookup = 1;
  2817. mpath = rtw_mesh_path_lookup(adapter, etherhdr.h_dest);
  2818. if (mpath) {
  2819. mpp_lookup = 0;
  2820. next_hop = rtw_rcu_dereference(mpath->next_hop);
  2821. if (!next_hop
  2822. || !(mpath->flags & (RTW_MESH_PATH_ACTIVE | RTW_MESH_PATH_RESOLVING))
  2823. ) {
  2824. /* mpath is not valid, search mppath */
  2825. mpp_lookup = 1;
  2826. }
  2827. }
  2828. if (mpp_lookup) {
  2829. mppath = rtw_mpp_path_lookup(adapter, etherhdr.h_dest);
  2830. if (mppath)
  2831. mppath->exp_time = rtw_get_current_time();
  2832. }
  2833. if (mppath && mpath)
  2834. rtw_mesh_path_del(adapter, mpath->dst);
  2835. ae_need = _rtw_memcmp(adapter_mac_addr(adapter), etherhdr.h_source, ETH_ALEN) == _FALSE
  2836. || (mppath && _rtw_memcmp(mppath->mpp, etherhdr.h_dest, ETH_ALEN) == _FALSE);
  2837. } else {
  2838. ae_need = _rtw_memcmp(adapter_mac_addr(adapter), etherhdr.h_source, ETH_ALEN) == _FALSE;
  2839. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  2840. if (rtw_msrc_b2u_policy_chk(adapter->mesh_cfg.b2u_flags_msrc, etherhdr.h_dest)) {
  2841. bmc_need = rtw_mesh_data_bmc_to_uc(adapter
  2842. , etherhdr.h_dest, etherhdr.h_source
  2843. , etherhdr.h_dest, adapter_mac_addr(adapter), ae_need, NULL, 0
  2844. , b2u_list, &b2u_num, &b2u_mseq);
  2845. if (bmc_need == _FALSE) {
  2846. res = RTW_BMC_NO_NEED;
  2847. goto exit;
  2848. }
  2849. }
  2850. #endif
  2851. }
  2852. attrib = &xframe->attrib;
  2853. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  2854. if (b2u_num) {
  2855. attrib->mb2u = 1;
  2856. attrib->mseq = b2u_mseq;
  2857. } else
  2858. attrib->mb2u = 0;
  2859. #endif
  2860. attrib->mfwd_ttl = 0;
  2861. _rtw_memcpy(attrib->dst, etherhdr.h_dest, ETH_ALEN);
  2862. _rtw_memcpy(attrib->src, etherhdr.h_source, ETH_ALEN);
  2863. _rtw_memcpy(attrib->ta, adapter_mac_addr(adapter), ETH_ALEN);
  2864. if (is_da_mcast) {
  2865. attrib->mesh_frame_mode = ae_need ? MESH_BMCAST_PX_DATA : MESH_BMCAST_DATA;
  2866. _rtw_memcpy(attrib->ra, attrib->dst, ETH_ALEN);
  2867. _rtw_memcpy(attrib->msa, adapter_mac_addr(adapter), ETH_ALEN);
  2868. } else {
  2869. attrib->mesh_frame_mode = ae_need ? MESH_UCAST_PX_DATA : MESH_UCAST_DATA;
  2870. _rtw_memcpy(attrib->mda, (mppath && ae_need) ? mppath->mpp : attrib->dst, ETH_ALEN);
  2871. _rtw_memcpy(attrib->msa, adapter_mac_addr(adapter), ETH_ALEN);
  2872. /* RA needs to be resolved */
  2873. res = rtw_mesh_nexthop_resolve(adapter, xframe);
  2874. }
  2875. exit:
  2876. return res;
  2877. }
  2878. s8 rtw_mesh_tx_set_whdr_mctrl_len(u8 mesh_frame_mode, struct pkt_attrib *attrib)
  2879. {
  2880. u8 ret = 0;
  2881. switch (mesh_frame_mode) {
  2882. case MESH_UCAST_DATA:
  2883. attrib->hdrlen = WLAN_HDR_A4_QOS_LEN;
  2884. /* mesh flag + mesh TTL + Mesh SN. no ext addr. */
  2885. attrib->meshctrl_len = 6;
  2886. break;
  2887. case MESH_BMCAST_DATA:
  2888. attrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
  2889. /* mesh flag + mesh TTL + Mesh SN. no ext addr. */
  2890. attrib->meshctrl_len = 6;
  2891. break;
  2892. case MESH_UCAST_PX_DATA:
  2893. attrib->hdrlen = WLAN_HDR_A4_QOS_LEN;
  2894. /* mesh flag + mesh TTL + Mesh SN + extaddr1 + extaddr2. */
  2895. attrib->meshctrl_len = 18;
  2896. break;
  2897. case MESH_BMCAST_PX_DATA:
  2898. attrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
  2899. /* mesh flag + mesh TTL + Mesh SN + extaddr1 */
  2900. attrib->meshctrl_len = 12;
  2901. break;
  2902. default:
  2903. RTW_WARN("Invalid mesh frame mode:%u\n", mesh_frame_mode);
  2904. ret = -1;
  2905. break;
  2906. }
  2907. return ret;
  2908. }
  2909. void rtw_mesh_tx_build_mctrl(_adapter *adapter, struct pkt_attrib *attrib, u8 *buf)
  2910. {
  2911. struct rtw_ieee80211s_hdr *mctrl = (struct rtw_ieee80211s_hdr *)buf;
  2912. _rtw_memset(mctrl, 0, XATTRIB_GET_MCTRL_LEN(attrib));
  2913. if (attrib->mfwd_ttl
  2914. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  2915. || attrib->mb2u
  2916. #endif
  2917. ) {
  2918. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  2919. if (!attrib->mfwd_ttl)
  2920. mctrl->ttl = adapter->mesh_cfg.dot11MeshTTL;
  2921. else
  2922. #endif
  2923. mctrl->ttl = attrib->mfwd_ttl;
  2924. mctrl->seqnum = (cpu_to_le32(attrib->mseq));
  2925. } else {
  2926. mctrl->ttl = adapter->mesh_cfg.dot11MeshTTL;
  2927. mctrl->seqnum = (cpu_to_le32(adapter->mesh_info.mesh_seqnum));
  2928. adapter->mesh_info.mesh_seqnum++;
  2929. }
  2930. switch (attrib->mesh_frame_mode){
  2931. case MESH_UCAST_DATA:
  2932. case MESH_BMCAST_DATA:
  2933. break;
  2934. case MESH_UCAST_PX_DATA:
  2935. mctrl->flags |= MESH_FLAGS_AE_A5_A6;
  2936. _rtw_memcpy(mctrl->eaddr1, attrib->dst, ETH_ALEN);
  2937. _rtw_memcpy(mctrl->eaddr2, attrib->src, ETH_ALEN);
  2938. break;
  2939. case MESH_BMCAST_PX_DATA:
  2940. mctrl->flags |= MESH_FLAGS_AE_A4;
  2941. _rtw_memcpy(mctrl->eaddr1, attrib->src, ETH_ALEN);
  2942. break;
  2943. case MESH_MHOP_UCAST_ACT:
  2944. /* TBD */
  2945. break;
  2946. case MESH_MHOP_BMCAST_ACT:
  2947. /* TBD */
  2948. break;
  2949. default:
  2950. break;
  2951. }
  2952. }
  2953. u8 rtw_mesh_tx_build_whdr(_adapter *adapter, struct pkt_attrib *attrib
  2954. , u16 *fctrl, struct rtw_ieee80211_hdr *whdr)
  2955. {
  2956. switch (attrib->mesh_frame_mode) {
  2957. case MESH_UCAST_DATA: /* 1, 1, RA, TA, mDA(=DA), mSA(=SA) */
  2958. case MESH_UCAST_PX_DATA: /* 1, 1, RA, TA, mDA, mSA, [DA, SA] */
  2959. SetToDs(fctrl);
  2960. SetFrDs(fctrl);
  2961. _rtw_memcpy(whdr->addr1, attrib->ra, ETH_ALEN);
  2962. _rtw_memcpy(whdr->addr2, attrib->ta, ETH_ALEN);
  2963. _rtw_memcpy(whdr->addr3, attrib->mda, ETH_ALEN);
  2964. _rtw_memcpy(whdr->addr4, attrib->msa, ETH_ALEN);
  2965. break;
  2966. case MESH_BMCAST_DATA: /* 0, 1, RA(DA), TA, mSA(SA) */
  2967. case MESH_BMCAST_PX_DATA: /* 0, 1, RA(DA), TA, mSA, [SA] */
  2968. SetFrDs(fctrl);
  2969. _rtw_memcpy(whdr->addr1, attrib->ra, ETH_ALEN);
  2970. _rtw_memcpy(whdr->addr2, attrib->ta, ETH_ALEN);
  2971. _rtw_memcpy(whdr->addr3, attrib->msa, ETH_ALEN);
  2972. break;
  2973. case MESH_MHOP_UCAST_ACT:
  2974. /* TBD */
  2975. RTW_INFO("MESH_MHOP_UCAST_ACT\n");
  2976. break;
  2977. case MESH_MHOP_BMCAST_ACT:
  2978. /* TBD */
  2979. RTW_INFO("MESH_MHOP_BMCAST_ACT\n");
  2980. break;
  2981. default:
  2982. RTW_WARN("Invalid mesh frame mode\n");
  2983. break;
  2984. }
  2985. return 0;
  2986. }
  2987. int rtw_mesh_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, struct sta_info **sta)
  2988. {
  2989. struct sta_priv *stapriv = &adapter->stapriv;
  2990. struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib;
  2991. u8 *whdr = get_recvframe_data(rframe);
  2992. u8 is_ra_bmc = 0;
  2993. u8 a4_shift = 0;
  2994. u8 ps;
  2995. u8 *qc;
  2996. u8 mps_mode = RTW_MESH_PS_UNKNOWN;
  2997. sint ret = _FAIL;
  2998. if (!(MLME_STATE(adapter) & WIFI_ASOC_STATE))
  2999. goto exit;
  3000. if (!rattrib->qos)
  3001. goto exit;
  3002. switch (rattrib->to_fr_ds) {
  3003. case 1:
  3004. if (!IS_MCAST(GetAddr1Ptr(whdr)))
  3005. goto exit;
  3006. *sta = rtw_get_stainfo(stapriv, get_addr2_ptr(whdr));
  3007. if (*sta == NULL) {
  3008. ret = _SUCCESS; /* return _SUCCESS to drop at sta checking */
  3009. goto exit;
  3010. }
  3011. _rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN);
  3012. _rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN);
  3013. _rtw_memcpy(rattrib->mda, GetAddr1Ptr(whdr), ETH_ALEN);
  3014. _rtw_memcpy(rattrib->msa, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */
  3015. _rtw_memcpy(rattrib->dst, GetAddr1Ptr(whdr), ETH_ALEN);
  3016. _rtw_memcpy(rattrib->src, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking mesh ctrl field */
  3017. _rtw_memcpy(rattrib->bssid, get_addr2_ptr(whdr), ETH_ALEN);
  3018. is_ra_bmc = 1;
  3019. break;
  3020. case 3:
  3021. if (IS_MCAST(GetAddr1Ptr(whdr)))
  3022. goto exit;
  3023. *sta = rtw_get_stainfo(stapriv, get_addr2_ptr(whdr));
  3024. if (*sta == NULL) {
  3025. ret = _SUCCESS; /* return _SUCCESS to drop at sta checking */
  3026. goto exit;
  3027. }
  3028. _rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN);
  3029. _rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN);
  3030. _rtw_memcpy(rattrib->mda, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */
  3031. _rtw_memcpy(rattrib->msa, GetAddr4Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */
  3032. _rtw_memcpy(rattrib->dst, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking mesh ctrl field */
  3033. _rtw_memcpy(rattrib->src, GetAddr4Ptr(whdr), ETH_ALEN); /* may change after checking mesh ctrl field */
  3034. _rtw_memcpy(rattrib->bssid, get_addr2_ptr(whdr), ETH_ALEN);
  3035. a4_shift = ETH_ALEN;
  3036. break;
  3037. default:
  3038. goto exit;
  3039. }
  3040. qc = whdr + WLAN_HDR_A3_LEN + a4_shift;
  3041. ps = GetPwrMgt(whdr);
  3042. mps_mode = ps ? (is_ra_bmc || (get_mps_lv(qc)) ? RTW_MESH_PS_DSLEEP : RTW_MESH_PS_LSLEEP) : RTW_MESH_PS_ACTIVE;
  3043. if (ps) {
  3044. if (!((*sta)->state & WIFI_SLEEP_STATE))
  3045. stop_sta_xmit(adapter, *sta);
  3046. } else {
  3047. if ((*sta)->state & WIFI_SLEEP_STATE)
  3048. wakeup_sta_to_xmit(adapter, *sta);
  3049. }
  3050. if (is_ra_bmc)
  3051. (*sta)->nonpeer_mps = mps_mode;
  3052. else {
  3053. (*sta)->peer_mps = mps_mode;
  3054. if (mps_mode != RTW_MESH_PS_ACTIVE && (*sta)->nonpeer_mps == RTW_MESH_PS_ACTIVE)
  3055. (*sta)->nonpeer_mps = RTW_MESH_PS_DSLEEP;
  3056. }
  3057. if (get_frame_sub_type(whdr) & BIT(6)) {
  3058. /* No data, will not indicate to upper layer, temporily count it here */
  3059. count_rx_stats(adapter, rframe, *sta);
  3060. ret = RTW_RX_HANDLED;
  3061. goto exit;
  3062. }
  3063. rattrib->mesh_ctrl_present = get_mctrl_present(qc) ? 1 : 0;
  3064. if (!rattrib->mesh_ctrl_present)
  3065. goto exit;
  3066. ret = _SUCCESS;
  3067. exit:
  3068. return ret;
  3069. }
  3070. int rtw_mesh_rx_data_validate_mctrl(_adapter *adapter, union recv_frame *rframe
  3071. , const struct rtw_ieee80211s_hdr *mctrl, const u8 *mda, const u8 *msa
  3072. , u8 *mctrl_len
  3073. , const u8 **da, const u8 **sa)
  3074. {
  3075. struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib;
  3076. u8 mlen;
  3077. u8 ae;
  3078. int ret = _SUCCESS;
  3079. ae = mctrl->flags & MESH_FLAGS_AE;
  3080. mlen = ae_to_mesh_ctrl_len[ae];
  3081. switch (rattrib->to_fr_ds) {
  3082. case 1:
  3083. *da = mda;
  3084. if (ae == MESH_FLAGS_AE_A4)
  3085. *sa = mctrl->eaddr1;
  3086. else if (ae == 0)
  3087. *sa = msa;
  3088. else
  3089. ret = _FAIL;
  3090. break;
  3091. case 3:
  3092. if (ae == MESH_FLAGS_AE_A5_A6) {
  3093. *da = mctrl->eaddr1;
  3094. *sa = mctrl->eaddr2;
  3095. } else if (ae == 0) {
  3096. *da = mda;
  3097. *sa = msa;
  3098. } else
  3099. ret = _FAIL;
  3100. break;
  3101. default:
  3102. ret = _FAIL;
  3103. }
  3104. if (ret == _FAIL) {
  3105. #ifdef DBG_RX_DROP_FRAME
  3106. RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" invalid tfDS:%u AE:%u combination ra="MAC_FMT" ta="MAC_FMT"\n"
  3107. , FUNC_ADPT_ARG(adapter), rattrib->to_fr_ds, ae, MAC_ARG(rattrib->ra), MAC_ARG(rattrib->ta));
  3108. #endif
  3109. *mctrl_len = 0;
  3110. } else
  3111. *mctrl_len = mlen;
  3112. return ret;
  3113. }
  3114. inline int rtw_mesh_rx_validate_mctrl_non_amsdu(_adapter *adapter, union recv_frame *rframe)
  3115. {
  3116. struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib;
  3117. const u8 *da, *sa;
  3118. int ret;
  3119. ret = rtw_mesh_rx_data_validate_mctrl(adapter, rframe
  3120. , (struct rtw_ieee80211s_hdr *)(get_recvframe_data(rframe) + rattrib->hdrlen + rattrib->iv_len)
  3121. , rattrib->mda, rattrib->msa
  3122. , &rattrib->mesh_ctrl_len
  3123. , &da, &sa);
  3124. if (ret == _SUCCESS) {
  3125. _rtw_memcpy(rattrib->dst, da, ETH_ALEN);
  3126. _rtw_memcpy(rattrib->src, sa, ETH_ALEN);
  3127. }
  3128. return ret;
  3129. }
  3130. /**
  3131. * rtw_mesh_rx_nexthop_resolve - lookup next hop; conditionally start path discovery
  3132. *
  3133. * @skb: 802.11 frame to be sent
  3134. * @sdata: network subif the frame will be sent through
  3135. *
  3136. * Lookup next hop for given skb and start path discovery if no
  3137. * forwarding information is found.
  3138. *
  3139. * Returns: 0 if the next hop was found and -ENOENT if the frame was queued.
  3140. * skb is freeed here if no mpath could be allocated.
  3141. */
  3142. static int rtw_mesh_rx_nexthop_resolve(_adapter *adapter,
  3143. const u8 *mda, const u8 *msa, u8 *ra)
  3144. {
  3145. struct rtw_mesh_path *mpath;
  3146. struct xmit_frame *xframe_to_free = NULL;
  3147. int err = 0;
  3148. int ret = _SUCCESS;
  3149. rtw_rcu_read_lock();
  3150. err = rtw_mesh_nexthop_lookup(adapter, mda, msa, ra);
  3151. if (!err)
  3152. goto endlookup;
  3153. /* no nexthop found, start resolving */
  3154. mpath = rtw_mesh_path_lookup(adapter, mda);
  3155. if (!mpath) {
  3156. mpath = rtw_mesh_path_add(adapter, mda);
  3157. if (IS_ERR(mpath)) {
  3158. err = PTR_ERR(mpath);
  3159. ret = _FAIL;
  3160. goto endlookup;
  3161. }
  3162. }
  3163. if (!(mpath->flags & RTW_MESH_PATH_RESOLVING))
  3164. rtw_mesh_queue_preq(mpath, RTW_PREQ_Q_F_START);
  3165. ret = _FAIL;
  3166. endlookup:
  3167. rtw_rcu_read_unlock();
  3168. return ret;
  3169. }
  3170. #define RTW_MESH_DECACHE_BMC 1
  3171. #define RTW_MESH_DECACHE_UC 0
  3172. #define RTW_MESH_FORWARD_MDA_SELF_COND 0
  3173. #define DBG_RTW_MESH_FORWARD_MDA_SELF_COND 0
  3174. int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe
  3175. , const u8 *mda, const u8 *msa
  3176. , const u8 *da, const u8 *sa
  3177. , struct rtw_ieee80211s_hdr *mctrl
  3178. , struct xmit_frame **fwd_frame, _list *b2u_list)
  3179. {
  3180. _adapter *adapter = rframe->u.hdr.adapter;
  3181. struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
  3182. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  3183. struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib;
  3184. struct rtw_mesh_path *mppath;
  3185. u8 is_mda_bmc = IS_MCAST(mda);
  3186. u8 is_mda_self = !is_mda_bmc && _rtw_memcmp(mda, adapter_mac_addr(adapter), ETH_ALEN);
  3187. struct xmit_frame *xframe;
  3188. struct pkt_attrib *xattrib;
  3189. u8 fwd_ra[ETH_ALEN] = {0};
  3190. u8 fwd_mpp[ETH_ALEN] = {0}; /* forward to other gate */
  3191. u32 fwd_mseq;
  3192. int act = 0;
  3193. u8 ae_need;
  3194. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  3195. bool bmc_need = _TRUE;
  3196. u8 b2u_num = 0;
  3197. #endif
  3198. /* fwd info lifetime update */
  3199. #if 0
  3200. if (!is_mda_self)
  3201. mDA(A3) fwinfo.lifetime
  3202. mSA(A4) fwinfo.lifetime
  3203. Precursor-to-mDA(A2) fwinfo.lifetime
  3204. #endif
  3205. /* update/create pxoxy info for SA, mSA */
  3206. if ((mctrl->flags & MESH_FLAGS_AE)
  3207. && sa != msa && _rtw_memcmp(sa, msa, ETH_ALEN) == _FALSE
  3208. ) {
  3209. const u8 *proxied_addr = sa;
  3210. const u8 *mpp_addr = msa;
  3211. rtw_rcu_read_lock();
  3212. mppath = rtw_mpp_path_lookup(adapter, proxied_addr);
  3213. if (!mppath)
  3214. rtw_mpp_path_add(adapter, proxied_addr, mpp_addr);
  3215. else {
  3216. enter_critical_bh(&mppath->state_lock);
  3217. if (_rtw_memcmp(mppath->mpp, mpp_addr, ETH_ALEN) == _FALSE)
  3218. _rtw_memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
  3219. mppath->exp_time = rtw_get_current_time();
  3220. exit_critical_bh(&mppath->state_lock);
  3221. }
  3222. rtw_rcu_read_unlock();
  3223. }
  3224. /* mSA is self, need no further process */
  3225. if (_rtw_memcmp(msa, adapter_mac_addr(adapter), ETH_ALEN) == _TRUE)
  3226. goto exit;
  3227. fwd_mseq = le32_to_cpu(mctrl->seqnum);
  3228. /* check duplicate MSDU from mSA */
  3229. if (((RTW_MESH_DECACHE_BMC && is_mda_bmc)
  3230. || (RTW_MESH_DECACHE_UC && !is_mda_bmc))
  3231. && rtw_mesh_decache(adapter, msa, fwd_mseq)
  3232. ) {
  3233. minfo->mshstats.dropped_frames_duplicate++;
  3234. goto exit;
  3235. }
  3236. if (is_mda_bmc) {
  3237. /* mDA is bmc addr */
  3238. act |= RTW_RX_MSDU_ACT_INDICATE;
  3239. if (!mcfg->dot11MeshForwarding)
  3240. goto exit;
  3241. goto fwd_chk;
  3242. } else if (!is_mda_self) {
  3243. /* mDA is unicast but not self */
  3244. if (!mcfg->dot11MeshForwarding) {
  3245. rtw_mesh_path_error_tx(adapter
  3246. , adapter->mesh_cfg.element_ttl
  3247. , mda, 0
  3248. , WLAN_REASON_MESH_PATH_NOFORWARD
  3249. , rattrib->ta
  3250. );
  3251. #ifdef DBG_RX_DROP_FRAME
  3252. RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" mDA("MAC_FMT") not self, !dot11MeshForwarding\n"
  3253. , FUNC_ADPT_ARG(adapter), MAC_ARG(mda));
  3254. #endif
  3255. goto exit;
  3256. }
  3257. if (rtw_mesh_rx_nexthop_resolve(adapter, mda, msa, fwd_ra) != _SUCCESS) {
  3258. /* mDA is unknown */
  3259. rtw_mesh_path_error_tx(adapter
  3260. , adapter->mesh_cfg.element_ttl
  3261. , mda, 0
  3262. , WLAN_REASON_MESH_PATH_NOFORWARD
  3263. , rattrib->ta
  3264. );
  3265. #ifdef DBG_RX_DROP_FRAME
  3266. RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" mDA("MAC_FMT") unknown\n"
  3267. , FUNC_ADPT_ARG(adapter), MAC_ARG(mda));
  3268. #endif
  3269. minfo->mshstats.dropped_frames_no_route++;
  3270. goto exit;
  3271. } else {
  3272. /* mDA is known in fwd info */
  3273. #if 0
  3274. if (TA is not in precursors)
  3275. goto exit;
  3276. #endif
  3277. goto fwd_chk;
  3278. }
  3279. } else {
  3280. /* mDA is self */
  3281. #if RTW_MESH_FORWARD_MDA_SELF_COND
  3282. if (da == mda
  3283. || _rtw_memcmp(da, adapter_mac_addr(adapter), ETH_ALEN)
  3284. ) {
  3285. /* DA is self, indicate */
  3286. act |= RTW_RX_MSDU_ACT_INDICATE;
  3287. goto exit;
  3288. }
  3289. if (rtw_get_iface_by_macddr(adapter, da)) {
  3290. /* DA is buddy, indicate */
  3291. act |= RTW_RX_MSDU_ACT_INDICATE;
  3292. #if DBG_RTW_MESH_FORWARD_MDA_SELF_COND
  3293. RTW_INFO(FUNC_ADPT_FMT" DA("MAC_FMT") is buddy("ADPT_FMT")\n"
  3294. , FUNC_ADPT_ARG(adapter), MAC_ARG(da), ADPT_ARG(rtw_get_iface_by_macddr(adapter, da)));
  3295. #endif
  3296. goto exit;
  3297. }
  3298. /* DA is not self or buddy */
  3299. if (rtw_mesh_nexthop_lookup(adapter, da, msa, fwd_ra) == 0) {
  3300. /* DA is known in fwd info */
  3301. if (!mcfg->dot11MeshForwarding) {
  3302. /* path error to? */
  3303. #if defined(DBG_RX_DROP_FRAME) || DBG_RTW_MESH_FORWARD_MDA_SELF_COND
  3304. RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA("MAC_FMT") not self, !dot11MeshForwarding\n"
  3305. , FUNC_ADPT_ARG(adapter), MAC_ARG(da));
  3306. #endif
  3307. goto exit;
  3308. }
  3309. mda = da;
  3310. #if DBG_RTW_MESH_FORWARD_MDA_SELF_COND
  3311. RTW_INFO(FUNC_ADPT_FMT" fwd to DA("MAC_FMT"), fwd_RA("MAC_FMT")\n"
  3312. , FUNC_ADPT_ARG(adapter), MAC_ARG(da), MAC_ARG(fwd_ra));
  3313. #endif
  3314. goto fwd_chk;
  3315. }
  3316. rtw_rcu_read_lock();
  3317. mppath = rtw_mpp_path_lookup(adapter, da);
  3318. if (mppath) {
  3319. if (_rtw_memcmp(mppath->mpp, adapter_mac_addr(adapter), ETH_ALEN) == _FALSE) {
  3320. /* DA is proxied by others */
  3321. if (!mcfg->dot11MeshForwarding) {
  3322. /* path error to? */
  3323. #if defined(DBG_RX_DROP_FRAME) || DBG_RTW_MESH_FORWARD_MDA_SELF_COND
  3324. RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA("MAC_FMT") is proxied by ("MAC_FMT"), !dot11MeshForwarding\n"
  3325. , FUNC_ADPT_ARG(adapter), MAC_ARG(da), MAC_ARG(mppath->mpp));
  3326. #endif
  3327. rtw_rcu_read_unlock();
  3328. goto exit;
  3329. }
  3330. _rtw_memcpy(fwd_mpp, mppath->mpp, ETH_ALEN);
  3331. mda = fwd_mpp;
  3332. msa = adapter_mac_addr(adapter);
  3333. rtw_rcu_read_unlock();
  3334. /* resolve RA */
  3335. if (rtw_mesh_nexthop_lookup(adapter, mda, msa, fwd_ra) != 0) {
  3336. minfo->mshstats.dropped_frames_no_route++;
  3337. #if defined(DBG_RX_DROP_FRAME) || DBG_RTW_MESH_FORWARD_MDA_SELF_COND
  3338. RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA("MAC_FMT") is proxied by ("MAC_FMT"), RA resolve fail\n"
  3339. , FUNC_ADPT_ARG(adapter), MAC_ARG(da), MAC_ARG(mppath->mpp));
  3340. #endif
  3341. goto exit;
  3342. }
  3343. #if DBG_RTW_MESH_FORWARD_MDA_SELF_COND
  3344. RTW_INFO(FUNC_ADPT_FMT" DA("MAC_FMT") is proxied by ("MAC_FMT"), fwd_RA("MAC_FMT")\n"
  3345. , FUNC_ADPT_ARG(adapter), MAC_ARG(da), MAC_ARG(mppath->mpp), MAC_ARG(fwd_ra));
  3346. #endif
  3347. goto fwd_chk; /* forward to other gate */
  3348. } else {
  3349. #if DBG_RTW_MESH_FORWARD_MDA_SELF_COND
  3350. RTW_INFO(FUNC_ADPT_FMT" DA("MAC_FMT") is proxied by self\n"
  3351. , FUNC_ADPT_ARG(adapter), MAC_ARG(da));
  3352. #endif
  3353. }
  3354. }
  3355. rtw_rcu_read_unlock();
  3356. if (!mppath) {
  3357. #if DBG_RTW_MESH_FORWARD_MDA_SELF_COND
  3358. RTW_INFO(FUNC_ADPT_FMT" DA("MAC_FMT") unknown\n"
  3359. , FUNC_ADPT_ARG(adapter), MAC_ARG(da));
  3360. #endif
  3361. /* DA is unknown */
  3362. #if 0 /* TODO: flags with AE bit */
  3363. rtw_mesh_path_error_tx(adapter
  3364. , adapter->mesh_cfg.element_ttl
  3365. , mda, adapter->mesh_info.last_sn_update
  3366. , WLAN_REASON_MESH_PATH_NOPROXY
  3367. , msa
  3368. );
  3369. #endif
  3370. }
  3371. /*
  3372. * indicate to DS for both cases:
  3373. * 1.) DA is proxied by self
  3374. * 2.) DA is unknown
  3375. */
  3376. #endif /* RTW_MESH_FORWARD_MDA_SELF_COND */
  3377. act |= RTW_RX_MSDU_ACT_INDICATE;
  3378. goto exit;
  3379. }
  3380. fwd_chk:
  3381. if (adapter->stapriv.asoc_list_cnt <= 1)
  3382. goto exit;
  3383. if (mctrl->ttl == 1) {
  3384. minfo->mshstats.dropped_frames_ttl++;
  3385. if (!act) {
  3386. #ifdef DBG_RX_DROP_FRAME
  3387. RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" ttl reaches 0, not forwarding\n"
  3388. , FUNC_ADPT_ARG(adapter));
  3389. #endif
  3390. }
  3391. goto exit;
  3392. }
  3393. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  3394. _rtw_init_listhead(b2u_list);
  3395. #endif
  3396. ae_need = _rtw_memcmp(da , mda, ETH_ALEN) == _FALSE
  3397. || _rtw_memcmp(sa , msa, ETH_ALEN) == _FALSE;
  3398. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  3399. if (is_mda_bmc
  3400. && rtw_mfwd_b2u_policy_chk(mcfg->b2u_flags_mfwd, mda, rattrib->to_fr_ds == 3)
  3401. ) {
  3402. bmc_need = rtw_mesh_data_bmc_to_uc(adapter
  3403. , da, sa, mda, msa, ae_need, rframe->u.hdr.psta->cmn.mac_addr, mctrl->ttl - 1
  3404. , b2u_list, &b2u_num, &fwd_mseq);
  3405. }
  3406. if (bmc_need == _TRUE)
  3407. #endif
  3408. {
  3409. xframe = rtw_alloc_xmitframe(&adapter->xmitpriv);
  3410. if (!xframe) {
  3411. #ifdef DBG_TX_DROP_FRAME
  3412. RTW_INFO("DBG_TX_DROP_FRAME "FUNC_ADPT_FMT" rtw_alloc_xmitframe fail\n"
  3413. , FUNC_ADPT_ARG(adapter));
  3414. #endif
  3415. goto exit;
  3416. }
  3417. xattrib = &xframe->attrib;
  3418. #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
  3419. if (b2u_num)
  3420. xattrib->mb2u = 1;
  3421. else
  3422. xattrib->mb2u = 0;
  3423. #endif
  3424. xattrib->mfwd_ttl = mctrl->ttl - 1;
  3425. xattrib->mseq = fwd_mseq;
  3426. _rtw_memcpy(xattrib->dst, da, ETH_ALEN);
  3427. _rtw_memcpy(xattrib->src, sa, ETH_ALEN);
  3428. _rtw_memcpy(xattrib->mda, mda, ETH_ALEN);
  3429. _rtw_memcpy(xattrib->msa, msa, ETH_ALEN);
  3430. _rtw_memcpy(xattrib->ta, adapter_mac_addr(adapter), ETH_ALEN);
  3431. if (is_mda_bmc) {
  3432. xattrib->mesh_frame_mode = ae_need ? MESH_BMCAST_PX_DATA : MESH_BMCAST_DATA;
  3433. _rtw_memcpy(xattrib->ra, mda, ETH_ALEN);
  3434. } else {
  3435. xattrib->mesh_frame_mode = ae_need ? MESH_UCAST_PX_DATA : MESH_UCAST_DATA;
  3436. _rtw_memcpy(xattrib->ra, fwd_ra, ETH_ALEN);
  3437. }
  3438. *fwd_frame = xframe;
  3439. }
  3440. act |= RTW_RX_MSDU_ACT_FORWARD;
  3441. if (is_mda_bmc)
  3442. minfo->mshstats.fwded_mcast++;
  3443. else
  3444. minfo->mshstats.fwded_unicast++;
  3445. minfo->mshstats.fwded_frames++;
  3446. exit:
  3447. return act;
  3448. }
  3449. void dump_mesh_stats(void *sel, _adapter *adapter)
  3450. {
  3451. struct rtw_mesh_info *minfo = &adapter->mesh_info;
  3452. struct rtw_mesh_stats *stats = &minfo->mshstats;
  3453. RTW_PRINT_SEL(sel, "fwd_bmc:%u\n", stats->fwded_mcast);
  3454. RTW_PRINT_SEL(sel, "fwd_uc:%u\n", stats->fwded_unicast);
  3455. RTW_PRINT_SEL(sel, "drop_ttl:%u\n", stats->dropped_frames_ttl);
  3456. RTW_PRINT_SEL(sel, "drop_no_route:%u\n", stats->dropped_frames_no_route);
  3457. RTW_PRINT_SEL(sel, "drop_congestion:%u\n", stats->dropped_frames_congestion);
  3458. RTW_PRINT_SEL(sel, "drop_dup:%u\n", stats->dropped_frames_duplicate);
  3459. RTW_PRINT_SEL(sel, "mrc_del_qlen:%u\n", stats->mrc_del_qlen);
  3460. }
  3461. #endif /* CONFIG_RTW_MESH */