gl_cfg80211.c 91 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963
  1. /*
  2. ** Id: @(#) gl_cfg80211.c@@
  3. */
  4. /*! \file gl_cfg80211.c
  5. \brief Main routines for supporintg MT6620 cfg80211 control interface
  6. This file contains the support routines of Linux driver for MediaTek Inc. 802.11
  7. Wireless LAN Adapters.
  8. */
  9. /*
  10. ** Log: gl_cfg80211.c
  11. **
  12. ** 09 05 2013 cp.wu
  13. ** correct length to pass to wlanoidSetBssid()
  14. **
  15. ** 09 04 2013 cp.wu
  16. ** fix typo
  17. **
  18. ** 09 03 2013 cp.wu
  19. ** add path for reassociation
  20. **
  21. ** 11 23 2012 yuche.tsai
  22. ** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely
  23. ** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed..
  24. **
  25. ** 09 12 2012 wcpadmin
  26. ** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
  27. ** .
  28. **
  29. ** 08 30 2012 chinglan.wang
  30. ** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only
  31. ** .
  32. *
  33. **
  34. */
  35. /*******************************************************************************
  36. * C O M P I L E R F L A G S
  37. ********************************************************************************
  38. */
  39. /*******************************************************************************
  40. * E X T E R N A L R E F E R E N C E S
  41. ********************************************************************************
  42. */
  43. #include "gl_os.h"
  44. #include "debug.h"
  45. #include "wlan_lib.h"
  46. #include "gl_wext.h"
  47. #include "precomp.h"
  48. #include <linux/can/netlink.h>
  49. #include <net/netlink.h>
  50. #include <net/cfg80211.h>
  51. #include "gl_cfg80211.h"
  52. #include "gl_vendor.h"
  53. /*******************************************************************************
  54. * C O N S T A N T S
  55. ********************************************************************************
  56. */
  57. /*******************************************************************************
  58. * D A T A T Y P E S
  59. ********************************************************************************
  60. */
  61. /*******************************************************************************
  62. * P U B L I C D A T A
  63. ********************************************************************************
  64. */
  65. /* workaround for some ANR CRs. if suppliant is blocked longer than 10s, wifi hal will tell wifiMonitor
  66. to teminate. for the case which can block supplicant 10s is to del key more than 5 times. the root cause
  67. is that there is no resource in TC4, so del key command was not able to set, and then oid
  68. timeout was happed. if we found the root cause why fw couldn't release TC resouce, we will remove this
  69. workaround */
  70. static UINT_8 gucKeyIndex = 255;
  71. P_SW_RFB_T g_arGscnResultsTempBuffer[MAX_BUFFERED_GSCN_RESULTS];
  72. UINT_8 g_GscanResultsTempBufferIndex = 0;
  73. UINT_8 g_arGscanResultsIndicateNumber[MAX_BUFFERED_GSCN_RESULTS] = { 0, 0, 0, 0, 0 };
  74. UINT_8 g_GetResultsBufferedCnt = 0;
  75. UINT_8 g_GetResultsCmdCnt = 0;
  76. /*******************************************************************************
  77. * P R I V A T E D A T A
  78. ********************************************************************************
  79. */
  80. /*******************************************************************************
  81. * M A C R O S
  82. ********************************************************************************
  83. */
  84. /*******************************************************************************
  85. * F U N C T I O N D E C L A R A T I O N S
  86. ********************************************************************************
  87. */
  88. /*******************************************************************************
  89. * F U N C T I O N S
  90. ********************************************************************************
  91. */
  92. /*----------------------------------------------------------------------------*/
  93. /*!
  94. * @brief This routine is responsible for change STA type between
  95. * 1. Infrastructure Client (Non-AP STA)
  96. * 2. Ad-Hoc IBSS
  97. *
  98. * @param
  99. *
  100. * @retval 0: successful
  101. * others: failure
  102. */
  103. /*----------------------------------------------------------------------------*/
  104. int
  105. mtk_cfg80211_change_iface(struct wiphy *wiphy,
  106. struct net_device *ndev, enum nl80211_iftype type, u32 *flags, struct vif_params *params)
  107. {
  108. P_GLUE_INFO_T prGlueInfo = NULL;
  109. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  110. ENUM_PARAM_OP_MODE_T eOpMode;
  111. UINT_32 u4BufLen;
  112. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  113. ASSERT(prGlueInfo);
  114. if (type == NL80211_IFTYPE_STATION)
  115. eOpMode = NET_TYPE_INFRA;
  116. else if (type == NL80211_IFTYPE_ADHOC)
  117. eOpMode = NET_TYPE_IBSS;
  118. else
  119. return -EINVAL;
  120. rStatus = kalIoctl(prGlueInfo,
  121. wlanoidSetInfrastructureMode,
  122. &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  123. if (rStatus != WLAN_STATUS_SUCCESS)
  124. DBGLOG(REQ, WARN, "set infrastructure mode error:%x\n", rStatus);
  125. /* reset wpa info */
  126. prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
  127. prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
  128. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
  129. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
  130. prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
  131. #if CFG_SUPPORT_802_11W
  132. prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
  133. #endif
  134. return 0;
  135. }
  136. /*----------------------------------------------------------------------------*/
  137. /*!
  138. * @brief This routine is responsible for adding key
  139. *
  140. * @param
  141. *
  142. * @retval 0: successful
  143. * others: failure
  144. */
  145. /*----------------------------------------------------------------------------*/
  146. int
  147. mtk_cfg80211_add_key(struct wiphy *wiphy,
  148. struct net_device *ndev,
  149. u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params)
  150. {
  151. PARAM_KEY_T rKey;
  152. P_GLUE_INFO_T prGlueInfo = NULL;
  153. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  154. INT_32 i4Rslt = -EINVAL;
  155. UINT_32 u4BufLen = 0;
  156. UINT_8 tmp1[8];
  157. UINT_8 tmp2[8];
  158. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  159. ASSERT(prGlueInfo);
  160. kalMemZero(&rKey, sizeof(PARAM_KEY_T));
  161. rKey.u4KeyIndex = key_index;
  162. if (mac_addr) {
  163. COPY_MAC_ADDR(rKey.arBSSID, mac_addr);
  164. if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) &&
  165. (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) {
  166. rKey.arBSSID[0] = 0xff;
  167. rKey.arBSSID[1] = 0xff;
  168. rKey.arBSSID[2] = 0xff;
  169. rKey.arBSSID[3] = 0xff;
  170. rKey.arBSSID[4] = 0xff;
  171. rKey.arBSSID[5] = 0xff;
  172. }
  173. if (rKey.arBSSID[0] != 0xFF) {
  174. rKey.u4KeyIndex |= BIT(31);
  175. if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) ||
  176. (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00))
  177. rKey.u4KeyIndex |= BIT(30);
  178. }
  179. } else {
  180. rKey.arBSSID[0] = 0xff;
  181. rKey.arBSSID[1] = 0xff;
  182. rKey.arBSSID[2] = 0xff;
  183. rKey.arBSSID[3] = 0xff;
  184. rKey.arBSSID[4] = 0xff;
  185. rKey.arBSSID[5] = 0xff;
  186. /* rKey.u4KeyIndex |= BIT(31);//Enable BIT 31 will make tx use bc key id,should use pairwise key id 0 */
  187. }
  188. if (params->key) {
  189. /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */
  190. kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len);
  191. if (params->key_len == 32) {
  192. kalMemCopy(tmp1, &params->key[16], 8);
  193. kalMemCopy(tmp2, &params->key[24], 8);
  194. kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8);
  195. kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8);
  196. }
  197. }
  198. rKey.u4KeyLength = params->key_len;
  199. rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength;
  200. rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  201. if (rStatus == WLAN_STATUS_SUCCESS)
  202. i4Rslt = 0;
  203. return i4Rslt;
  204. }
  205. /*----------------------------------------------------------------------------*/
  206. /*!
  207. * @brief This routine is responsible for getting key for specified STA
  208. *
  209. * @param
  210. *
  211. * @retval 0: successful
  212. * others: failure
  213. */
  214. /*----------------------------------------------------------------------------*/
  215. int
  216. mtk_cfg80211_get_key(struct wiphy *wiphy,
  217. struct net_device *ndev,
  218. u8 key_index,
  219. bool pairwise,
  220. const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *))
  221. {
  222. P_GLUE_INFO_T prGlueInfo = NULL;
  223. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  224. ASSERT(prGlueInfo);
  225. DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
  226. /* not implemented */
  227. return -EINVAL;
  228. }
  229. /*----------------------------------------------------------------------------*/
  230. /*!
  231. * @brief This routine is responsible for removing key for specified STA
  232. *
  233. * @param
  234. *
  235. * @retval 0: successful
  236. * others: failure
  237. */
  238. /*----------------------------------------------------------------------------*/
  239. int mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr)
  240. {
  241. P_GLUE_INFO_T prGlueInfo = NULL;
  242. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  243. PARAM_REMOVE_KEY_T rRemoveKey;
  244. UINT_32 u4BufLen = 0;
  245. INT_32 i4Rslt = -EINVAL;
  246. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  247. ASSERT(prGlueInfo);
  248. kalMemZero(&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T));
  249. if (mac_addr)
  250. COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr);
  251. else if (key_index <= gucKeyIndex) { /* new operation, reset gucKeyIndex */
  252. gucKeyIndex = 255;
  253. } else { /* bypass the next remove key operation */
  254. gucKeyIndex = key_index;
  255. return -EBUSY;
  256. }
  257. rRemoveKey.u4KeyIndex = key_index;
  258. rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T);
  259. rStatus = kalIoctl(prGlueInfo,
  260. wlanoidSetRemoveKey, &rRemoveKey, rRemoveKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  261. if (rStatus != WLAN_STATUS_SUCCESS) {
  262. DBGLOG(REQ, WARN, "remove key error:%x\n", rStatus);
  263. if (WLAN_STATUS_FAILURE == rStatus && mac_addr) {
  264. i4Rslt = -EBUSY;
  265. gucKeyIndex = key_index;
  266. }
  267. } else {
  268. gucKeyIndex = 255;
  269. i4Rslt = 0;
  270. }
  271. return i4Rslt;
  272. }
  273. /*----------------------------------------------------------------------------*/
  274. /*!
  275. * @brief This routine is responsible for setting default key on an interface
  276. *
  277. * @param
  278. *
  279. * @retval 0: successful
  280. * others: failure
  281. */
  282. /*----------------------------------------------------------------------------*/
  283. int
  284. mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast)
  285. {
  286. P_GLUE_INFO_T prGlueInfo = NULL;
  287. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  288. ASSERT(prGlueInfo);
  289. DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
  290. /* not implemented */
  291. return WLAN_STATUS_SUCCESS;
  292. }
  293. /*----------------------------------------------------------------------------*/
  294. /*!
  295. * @brief This routine is responsible for setting set_default_mgmt_ke on an interface
  296. *
  297. * @param
  298. *
  299. * @retval 0: successful
  300. * others: failure
  301. */
  302. /*----------------------------------------------------------------------------*/
  303. int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index)
  304. {
  305. return 0;
  306. }
  307. /*----------------------------------------------------------------------------*/
  308. /*!
  309. * @brief This routine is responsible for getting station information such as RSSI
  310. *
  311. * @param
  312. *
  313. * @retval 0: successful
  314. * others: failure
  315. */
  316. /*----------------------------------------------------------------------------*/
  317. int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo)
  318. {
  319. #define LINKSPEED_MAX_RANGE_11BGN 3000
  320. P_GLUE_INFO_T prGlueInfo = NULL;
  321. WLAN_STATUS rStatus;
  322. PARAM_MAC_ADDRESS arBssid;
  323. UINT_32 u4BufLen;
  324. UINT_32 u4Rate = 0;
  325. UINT_32 u8diffTxBad, u8diffRetry;
  326. INT_32 i4Rssi = 0;
  327. PARAM_802_11_STATISTICS_STRUCT_T rStatistics;
  328. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  329. ASSERT(prGlueInfo);
  330. kalMemZero(arBssid, MAC_ADDR_LEN);
  331. wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen);
  332. /* 1. check BSSID */
  333. if (UNEQUAL_MAC_ADDR(arBssid, mac)) {
  334. /* wrong MAC address */
  335. DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n",
  336. mac, arBssid);
  337. return -ENOENT;
  338. }
  339. /* 2. fill TX rate */
  340. if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) {
  341. /* not connected */
  342. DBGLOG(REQ, WARN, "not yet connected\n");
  343. } else {
  344. rStatus = kalIoctl(prGlueInfo,
  345. wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
  346. sinfo->filled |= STATION_INFO_TX_BITRATE;
  347. if ((rStatus != WLAN_STATUS_SUCCESS) || (u4Rate == 0)) {
  348. /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n")); */
  349. DBGLOG(REQ, WARN, "last link speed\n");
  350. sinfo->txrate.legacy = prGlueInfo->u4LinkSpeedCache;
  351. } else {
  352. /* sinfo->filled |= STATION_INFO_TX_BITRATE; */
  353. sinfo->txrate.legacy = u4Rate / 1000; /* convert from 100bps to 100kbps */
  354. prGlueInfo->u4LinkSpeedCache = u4Rate / 1000;
  355. }
  356. }
  357. /* 3. fill RSSI */
  358. if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) {
  359. /* not connected */
  360. DBGLOG(REQ, WARN, "not yet connected\n");
  361. } else {
  362. rStatus = kalIoctl(prGlueInfo,
  363. wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, FALSE, FALSE, FALSE, &u4BufLen);
  364. sinfo->filled |= STATION_INFO_SIGNAL;
  365. if (rStatus != WLAN_STATUS_SUCCESS || (i4Rssi == PARAM_WHQL_RSSI_MIN_DBM)
  366. || (i4Rssi == PARAM_WHQL_RSSI_MAX_DBM)) {
  367. /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n"); */
  368. DBGLOG(REQ, WARN, "last rssi\n");
  369. sinfo->signal = prGlueInfo->i4RssiCache;
  370. } else {
  371. /* in the cfg80211 layer, the signal is a signed char variable. */
  372. sinfo->signal = i4Rssi; /* dBm */
  373. prGlueInfo->i4RssiCache = i4Rssi;
  374. }
  375. sinfo->rx_packets = prGlueInfo->rNetDevStats.rx_packets;
  376. /* 4. Fill Tx OK and Tx Bad */
  377. sinfo->filled |= STATION_INFO_TX_PACKETS;
  378. sinfo->filled |= STATION_INFO_TX_FAILED;
  379. {
  380. WLAN_STATUS rStatus;
  381. kalMemZero(&rStatistics, sizeof(rStatistics));
  382. /* Get Tx OK/Fail cnt from AIS statistic counter */
  383. rStatus = kalIoctl(prGlueInfo,
  384. wlanoidQueryStatisticsPL,
  385. &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen);
  386. if (rStatus != WLAN_STATUS_SUCCESS) {
  387. DBGLOG(REQ, WARN, "unable to retrieive statistic\n");
  388. } else {
  389. INT_32 i4RssiThreshold = -85; /* set rssi threshold -85dBm */
  390. UINT_32 u4LinkspeedThreshold = 55; /* set link speed threshold 5.5Mbps */
  391. BOOLEAN fgWeighted = 0;
  392. /* calculate difference */
  393. u8diffTxBad = rStatistics.rFailedCount.QuadPart - prGlueInfo->u8Statistic[0];
  394. u8diffRetry = rStatistics.rRetryCount.QuadPart - prGlueInfo->u8Statistic[1];
  395. /* restore counters */
  396. prGlueInfo->u8Statistic[0] = rStatistics.rFailedCount.QuadPart;
  397. prGlueInfo->u8Statistic[1] = rStatistics.rRetryCount.QuadPart;
  398. /* check threshold is valid */
  399. if (prGlueInfo->fgPoorlinkValid) {
  400. if (prGlueInfo->i4RssiThreshold)
  401. i4RssiThreshold = prGlueInfo->i4RssiThreshold;
  402. if (prGlueInfo->u4LinkspeedThreshold)
  403. u4LinkspeedThreshold = prGlueInfo->u4LinkspeedThreshold;
  404. }
  405. /* add weighted to fail counter */
  406. if (sinfo->txrate.legacy < u4LinkspeedThreshold || sinfo->signal < i4RssiThreshold) {
  407. prGlueInfo->u8TotalFailCnt += (u8diffTxBad * 16 + u8diffRetry);
  408. fgWeighted = 1;
  409. } else {
  410. prGlueInfo->u8TotalFailCnt += u8diffTxBad;
  411. }
  412. /* report counters */
  413. prGlueInfo->rNetDevStats.tx_packets = rStatistics.rTransmittedFragmentCount.QuadPart;
  414. prGlueInfo->rNetDevStats.tx_errors = prGlueInfo->u8TotalFailCnt;
  415. sinfo->tx_packets = prGlueInfo->rNetDevStats.tx_packets;
  416. sinfo->tx_failed = prGlueInfo->rNetDevStats.tx_errors;
  417. /* Good Fail Bad Difference retry difference Linkspeed Rate Weighted */
  418. DBGLOG(REQ, TRACE,
  419. "Poorlink State TxOK(%d) TxFail(%d) Bad(%d) Retry(%d)",
  420. sinfo->tx_packets,
  421. sinfo->tx_failed,
  422. (int)u8diffTxBad,
  423. (int)u8diffRetry);
  424. DBGLOG(REQ, TRACE,
  425. "Rate(%d) Signal(%d) Weight(%d) QuadPart(%d)\n",
  426. sinfo->txrate.legacy,
  427. sinfo->signal,
  428. (int)fgWeighted,
  429. (int)rStatistics.rMultipleRetryCount.QuadPart);
  430. }
  431. }
  432. }
  433. return 0;
  434. }
  435. /*----------------------------------------------------------------------------*/
  436. /*!
  437. * @brief This routine is responsible for adding a station information
  438. *
  439. * @param
  440. *
  441. * @retval 0: successful
  442. * others: failure
  443. */
  444. /*----------------------------------------------------------------------------*/
  445. int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
  446. const u8 *mac, struct station_parameters *params)
  447. {
  448. #if (CFG_SUPPORT_TDLS == 1)
  449. /*
  450. EX: In supplicant,
  451. (Supplicant) wpa_tdls_process_tpk_m3() ->
  452. (Supplicant) wpa_tdls_enable_link() ->
  453. (Supplicant) wpa_sm_tdls_peer_addset() ->
  454. (Supplicant) ..tdls_peer_addset() ->
  455. (Supplicant) wpa_supplicant_tdls_peer_addset() ->
  456. (Supplicant) wpa_drv_sta_add() ->
  457. (Supplicant) ..sta_add() ->
  458. (Supplicant) wpa_driver_nl80211_sta_add() ->
  459. (NL80211) nl80211_set_station() ->
  460. (Driver) mtk_cfg80211_change_station()
  461. if nl80211_set_station fails, supplicant will tear down the link.
  462. */
  463. P_GLUE_INFO_T prGlueInfo;
  464. TDLS_CMD_PEER_UPDATE_T rCmdUpdate;
  465. WLAN_STATUS rStatus;
  466. UINT_32 u4BufLen, u4Temp;
  467. /* sanity check */
  468. if ((wiphy == NULL) || (mac == NULL) || (params == NULL))
  469. return -EINVAL;
  470. DBGLOG(TDLS, INFO, "%s: 0x%p 0x%x\n", __func__, params->supported_rates, params->sta_flags_set);
  471. if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
  472. return -EOPNOTSUPP;
  473. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  474. if (prGlueInfo == NULL)
  475. return -EINVAL;
  476. /* TODO: check if we are station mode, not AP mode */
  477. /* init */
  478. kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate));
  479. kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6);
  480. if (params->supported_rates != NULL) {
  481. u4Temp = params->supported_rates_len;
  482. if (u4Temp > TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX) {
  483. u4Temp = TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX;
  484. DBGLOG(TDLS, ERROR, "%s sup rate too long: %d\n", __func__, params->supported_rates_len);
  485. }
  486. kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, u4Temp);
  487. rCmdUpdate.u2SupRateLen = u4Temp;
  488. }
  489. /*
  490. In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM
  491. So force to support UAPSD here.
  492. */
  493. rCmdUpdate.UapsdBitmap = 0x0F; /*params->uapsd_queues; */
  494. rCmdUpdate.UapsdMaxSp = 0; /*params->max_sp; */
  495. DBGLOG(TDLS, INFO, "%s: UapsdBitmap=0x%x UapsdMaxSp=%d\n",
  496. __func__, rCmdUpdate.UapsdBitmap, rCmdUpdate.UapsdMaxSp);
  497. rCmdUpdate.u2Capability = params->capability;
  498. if (params->ext_capab != NULL) {
  499. u4Temp = params->ext_capab_len;
  500. if (u4Temp > TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN) {
  501. u4Temp = TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN;
  502. DBGLOG(TDLS, ERROR, "%s ext_capab too long: %d\n", __func__, params->ext_capab_len);
  503. }
  504. kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp);
  505. rCmdUpdate.u2ExtCapLen = u4Temp;
  506. }
  507. if (params->ht_capa != NULL) {
  508. DBGLOG(TDLS, INFO, "%s: peer is 11n device\n", __func__);
  509. rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info;
  510. rCmdUpdate.rHtCap.ucAmpduParamsInfo = params->ht_capa->ampdu_params_info;
  511. rCmdUpdate.rHtCap.u2ExtHtCapInfo = params->ht_capa->extended_ht_cap_info;
  512. rCmdUpdate.rHtCap.u4TxBfCapInfo = params->ht_capa->tx_BF_cap_info;
  513. rCmdUpdate.rHtCap.ucAntennaSelInfo = params->ht_capa->antenna_selection_info;
  514. kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask,
  515. params->ht_capa->mcs.rx_mask, sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask));
  516. rCmdUpdate.rHtCap.rMCS.u2RxHighest = params->ht_capa->mcs.rx_highest;
  517. rCmdUpdate.rHtCap.rMCS.ucTxParams = params->ht_capa->mcs.tx_params;
  518. rCmdUpdate.fgIsSupHt = TRUE;
  519. }
  520. /* update a TDLS peer record */
  521. rStatus = kalIoctl(prGlueInfo,
  522. TdlsexPeerUpdate,
  523. &rCmdUpdate, sizeof(TDLS_CMD_PEER_UPDATE_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
  524. if (rStatus != WLAN_STATUS_SUCCESS) {
  525. DBGLOG(TDLS, ERROR, "%s update error:%x\n", __func__, rStatus);
  526. return -EINVAL;
  527. }
  528. #endif /* CFG_SUPPORT_TDLS */
  529. return 0;
  530. }
  531. /*----------------------------------------------------------------------------*/
  532. /*!
  533. * @brief This routine is responsible for adding a station information
  534. *
  535. * @param
  536. *
  537. * @retval 0: successful
  538. * others: failure
  539. */
  540. /*----------------------------------------------------------------------------*/
  541. int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev,
  542. const u8 *mac, struct station_parameters *params)
  543. {
  544. #if (CFG_SUPPORT_TDLS == 1)
  545. /* from supplicant -- wpa_supplicant_tdls_peer_addset() */
  546. P_GLUE_INFO_T prGlueInfo;
  547. TDLS_CMD_PEER_ADD_T rCmdCreate;
  548. WLAN_STATUS rStatus;
  549. UINT_32 u4BufLen;
  550. if ((wiphy == NULL) || (mac == NULL) || (params == NULL))
  551. return -EINVAL;
  552. /*
  553. wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0,
  554. NULL, 0);
  555. wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
  556. u16 aid, u16 capability, const u8 *supp_rates,
  557. size_t supp_rates_len,
  558. const struct ieee80211_ht_capabilities *ht_capab,
  559. const struct ieee80211_vht_capabilities *vht_capab,
  560. u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
  561. Only MAC address of the peer is valid.
  562. */
  563. DBGLOG(TDLS, INFO, "%s: 0x%p %d\n", __func__, params->supported_rates, params->supported_rates_len);
  564. /* sanity check */
  565. if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
  566. return -EOPNOTSUPP;
  567. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  568. if (prGlueInfo == NULL)
  569. return -EINVAL;
  570. /* TODO: check if we are station mode, not AP mode */
  571. /* init */
  572. kalMemZero(&rCmdCreate, sizeof(rCmdCreate));
  573. kalMemCopy(rCmdCreate.aucPeerMac, mac, 6);
  574. #if 0
  575. rCmdCreate.eNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
  576. rCmdCreate.u2CapInfo = params->capability;
  577. DBGLOG(TDLS, INFO, "<tdls_cmd> %s: capability = 0x%x\n", __func__, rCmdCreate.u2CapInfo);
  578. if ((params->supported_rates != NULL) && (params->supported_rates_len != 0)) {
  579. UINT32 u4Idx;
  580. DBGLOG(TDLS, INFO, "<tdls_cmd> %s: sup rate = 0x", __func__);
  581. rIeSup.ucId = ELEM_ID_SUP_RATES;
  582. rIeSup.ucLength = params->supported_rates_len;
  583. for (u4Idx = 0; u4Idx < rIeSup.ucLength; u4Idx++) {
  584. rIeSup.aucSupportedRates[u4Idx] = params->supported_rates[u4Idx];
  585. DBGLOG(TDLS, INFO, "%x ", rIeSup.aucSupportedRates[u4Idx]);
  586. }
  587. DBGLOG(TDLS, INFO, "\n");
  588. rateGetRateSetFromIEs(&rIeSup,
  589. NULL,
  590. &rCmdCreate.u2OperationalRateSet,
  591. &rCmdCreate.u2BSSBasicRateSet, &rCmdCreate.fgIsUnknownBssBasicRate);
  592. }
  593. /* phy type */
  594. #endif
  595. /* create a TDLS peer record */
  596. rStatus = kalIoctl(prGlueInfo,
  597. TdlsexPeerAdd,
  598. &rCmdCreate, sizeof(TDLS_CMD_PEER_ADD_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
  599. if (rStatus != WLAN_STATUS_SUCCESS) {
  600. DBGLOG(TDLS, ERROR, "%s create error:%x\n", __func__, rStatus);
  601. return -EINVAL;
  602. }
  603. #endif /* CFG_SUPPORT_TDLS */
  604. return 0;
  605. }
  606. /*----------------------------------------------------------------------------*/
  607. /*!
  608. * @brief This routine is responsible for deleting a station information
  609. *
  610. * @param
  611. *
  612. * @retval 0: successful
  613. * others: failure
  614. *
  615. * @other
  616. * must implement if you have add_station().
  617. */
  618. /*----------------------------------------------------------------------------*/
  619. int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac)
  620. {
  621. return 0;
  622. }
  623. /*----------------------------------------------------------------------------*/
  624. /*!
  625. * @brief This routine is responsible for requesting to do a scan
  626. *
  627. * @param
  628. *
  629. * @retval 0: successful
  630. * others: failure
  631. */
  632. /*----------------------------------------------------------------------------*/
  633. static PARAM_SCAN_REQUEST_EXT_T rScanRequest;
  634. int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
  635. {
  636. P_GLUE_INFO_T prGlueInfo = NULL;
  637. WLAN_STATUS rStatus;
  638. UINT_32 u4BufLen;
  639. /* PARAM_SCAN_REQUEST_EXT_T rScanRequest; */
  640. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  641. ASSERT(prGlueInfo);
  642. DBGLOG(REQ, TRACE, "mtk_cfg80211_scan\n");
  643. kalMemZero(&rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T));
  644. /* check if there is any pending scan not yet finished */
  645. if (prGlueInfo->prScanRequest != NULL) {
  646. DBGLOG(REQ, ERROR, "prGlueInfo->prScanRequest != NULL\n");
  647. return -EBUSY;
  648. }
  649. if (request->n_ssids == 0) {
  650. rScanRequest.rSsid.u4SsidLen = 0;
  651. } else if (request->n_ssids == 1) {
  652. COPY_SSID(rScanRequest.rSsid.aucSsid, rScanRequest.rSsid.u4SsidLen, request->ssids[0].ssid,
  653. request->ssids[0].ssid_len);
  654. } else {
  655. DBGLOG(REQ, ERROR, "request->n_ssids:%d\n", request->n_ssids);
  656. return -EINVAL;
  657. }
  658. if (request->ie_len > 0) {
  659. rScanRequest.u4IELength = request->ie_len;
  660. rScanRequest.pucIE = (PUINT_8) (request->ie);
  661. } else {
  662. rScanRequest.u4IELength = 0;
  663. }
  664. prGlueInfo->prScanRequest = request;
  665. rStatus = kalIoctl(prGlueInfo,
  666. wlanoidSetBssidListScanExt,
  667. &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
  668. if (rStatus != WLAN_STATUS_SUCCESS) {
  669. prGlueInfo->prScanRequest = NULL;
  670. DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus);
  671. return -EINVAL;
  672. }
  673. return 0;
  674. }
  675. static UINT_8 wepBuf[48];
  676. /*----------------------------------------------------------------------------*/
  677. /*!
  678. * @brief This routine is responsible for requesting to connect to
  679. * the ESS with the specified parameters
  680. *
  681. * @param
  682. *
  683. * @retval 0: successful
  684. * others: failure
  685. */
  686. /*----------------------------------------------------------------------------*/
  687. int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme)
  688. {
  689. P_GLUE_INFO_T prGlueInfo = NULL;
  690. WLAN_STATUS rStatus;
  691. UINT_32 u4BufLen;
  692. ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
  693. ENUM_PARAM_AUTH_MODE_T eAuthMode;
  694. UINT_32 cipher;
  695. PARAM_CONNECT_T rNewSsid;
  696. BOOLEAN fgCarryWPSIE = FALSE;
  697. ENUM_PARAM_OP_MODE_T eOpMode;
  698. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  699. ASSERT(prGlueInfo);
  700. DBGLOG(REQ, TRACE, "[wlan] mtk_cfg80211_connect %p %zu\n", sme->ie, sme->ie_len);
  701. if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH)
  702. eOpMode = NET_TYPE_AUTO_SWITCH;
  703. else
  704. eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode;
  705. rStatus = kalIoctl(prGlueInfo,
  706. wlanoidSetInfrastructureMode,
  707. &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  708. if (rStatus != WLAN_STATUS_SUCCESS) {
  709. DBGLOG(REQ, ERROR, "wlanoidSetInfrastructureMode fail 0x%x\n", rStatus);
  710. return -EFAULT;
  711. }
  712. /* after set operation mode, key table are cleared */
  713. /* reset wpa info */
  714. prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
  715. prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
  716. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
  717. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
  718. prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
  719. #if CFG_SUPPORT_802_11W
  720. prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
  721. #endif
  722. if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
  723. prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA;
  724. else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
  725. prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2;
  726. else
  727. prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
  728. switch (sme->auth_type) {
  729. case NL80211_AUTHTYPE_OPEN_SYSTEM:
  730. prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
  731. break;
  732. case NL80211_AUTHTYPE_SHARED_KEY:
  733. prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY;
  734. break;
  735. default:
  736. prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY;
  737. break;
  738. }
  739. if (sme->crypto.n_ciphers_pairwise) {
  740. prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] =
  741. sme->crypto.ciphers_pairwise[0];
  742. switch (sme->crypto.ciphers_pairwise[0]) {
  743. case WLAN_CIPHER_SUITE_WEP40:
  744. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40;
  745. break;
  746. case WLAN_CIPHER_SUITE_WEP104:
  747. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104;
  748. break;
  749. case WLAN_CIPHER_SUITE_TKIP:
  750. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP;
  751. break;
  752. case WLAN_CIPHER_SUITE_CCMP:
  753. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
  754. break;
  755. case WLAN_CIPHER_SUITE_AES_CMAC:
  756. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
  757. break;
  758. default:
  759. DBGLOG(REQ, WARN, "invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]);
  760. return -EINVAL;
  761. }
  762. }
  763. if (sme->crypto.cipher_group) {
  764. prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group;
  765. switch (sme->crypto.cipher_group) {
  766. case WLAN_CIPHER_SUITE_WEP40:
  767. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40;
  768. break;
  769. case WLAN_CIPHER_SUITE_WEP104:
  770. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104;
  771. break;
  772. case WLAN_CIPHER_SUITE_TKIP:
  773. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP;
  774. break;
  775. case WLAN_CIPHER_SUITE_CCMP:
  776. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP;
  777. break;
  778. case WLAN_CIPHER_SUITE_AES_CMAC:
  779. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP;
  780. break;
  781. default:
  782. DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group);
  783. return -EINVAL;
  784. }
  785. }
  786. if (sme->crypto.n_akm_suites) {
  787. prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] =
  788. sme->crypto.akm_suites[0];
  789. if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) {
  790. switch (sme->crypto.akm_suites[0]) {
  791. case WLAN_AKM_SUITE_8021X:
  792. eAuthMode = AUTH_MODE_WPA;
  793. break;
  794. case WLAN_AKM_SUITE_PSK:
  795. eAuthMode = AUTH_MODE_WPA_PSK;
  796. break;
  797. default:
  798. DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group);
  799. return -EINVAL;
  800. }
  801. } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) {
  802. switch (sme->crypto.akm_suites[0]) {
  803. case WLAN_AKM_SUITE_8021X:
  804. eAuthMode = AUTH_MODE_WPA2;
  805. break;
  806. case WLAN_AKM_SUITE_PSK:
  807. eAuthMode = AUTH_MODE_WPA2_PSK;
  808. break;
  809. default:
  810. DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group);
  811. return -EINVAL;
  812. }
  813. }
  814. }
  815. if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
  816. eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ?
  817. AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH;
  818. }
  819. prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy;
  820. prGlueInfo->fgWpsActive = FALSE;
  821. #if CFG_SUPPORT_HOTSPOT_2_0
  822. prGlueInfo->fgConnectHS20AP = FALSE;
  823. #endif
  824. if (sme->ie && sme->ie_len > 0) {
  825. WLAN_STATUS rStatus;
  826. UINT_32 u4BufLen;
  827. PUINT_8 prDesiredIE = NULL;
  828. PUINT_8 pucIEStart = (PUINT_8)sme->ie;
  829. #if CFG_SUPPORT_WAPI
  830. if (wextSrchDesiredWAPIIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
  831. rStatus = kalIoctl(prGlueInfo,
  832. wlanoidSetWapiAssocInfo,
  833. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
  834. if (rStatus != WLAN_STATUS_SUCCESS)
  835. DBGLOG(SEC, WARN, "[wapi] set wapi assoc info error:%x\n", rStatus);
  836. }
  837. #endif
  838. DBGLOG(REQ, TRACE, "[wlan] wlanoidSetWapiAssocInfo: .fgWapiMode = %d\n",
  839. prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode);
  840. #if CFG_SUPPORT_WPS2
  841. if (wextSrchDesiredWPSIE(pucIEStart, sme->ie_len, 0xDD, (PUINT_8 *) &prDesiredIE)) {
  842. prGlueInfo->fgWpsActive = TRUE;
  843. fgCarryWPSIE = TRUE;
  844. rStatus = kalIoctl(prGlueInfo,
  845. wlanoidSetWSCAssocInfo,
  846. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
  847. if (rStatus != WLAN_STATUS_SUCCESS)
  848. DBGLOG(SEC, WARN, "WSC] set WSC assoc info error:%x\n", rStatus);
  849. }
  850. #endif
  851. #if CFG_SUPPORT_HOTSPOT_2_0
  852. if (wextSrchDesiredHS20IE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
  853. rStatus = kalIoctl(prGlueInfo,
  854. wlanoidSetHS20Info,
  855. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  856. if (rStatus != WLAN_STATUS_SUCCESS) {
  857. /* Do nothing */
  858. /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */
  859. }
  860. }
  861. if (wextSrchDesiredInterworkingIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
  862. rStatus = kalIoctl(prGlueInfo,
  863. wlanoidSetInterworkingInfo,
  864. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  865. if (rStatus != WLAN_STATUS_SUCCESS) {
  866. /* Do nothing */
  867. /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */
  868. }
  869. }
  870. if (wextSrchDesiredRoamingConsortiumIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
  871. rStatus = kalIoctl(prGlueInfo,
  872. wlanoidSetRoamingConsortiumIEInfo,
  873. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  874. if (rStatus != WLAN_STATUS_SUCCESS) {
  875. /* Do nothing */
  876. /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */
  877. }
  878. }
  879. #endif
  880. }
  881. /* clear WSC Assoc IE buffer in case WPS IE is not detected */
  882. if (fgCarryWPSIE == FALSE) {
  883. kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200);
  884. prGlueInfo->u2WSCAssocInfoIELen = 0;
  885. }
  886. rStatus = kalIoctl(prGlueInfo,
  887. wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
  888. if (rStatus != WLAN_STATUS_SUCCESS)
  889. DBGLOG(REQ, WARN, "set auth mode error:%x\n", rStatus);
  890. cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise;
  891. if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) {
  892. if (cipher & IW_AUTH_CIPHER_CCMP) {
  893. eEncStatus = ENUM_ENCRYPTION3_ENABLED;
  894. } else if (cipher & IW_AUTH_CIPHER_TKIP) {
  895. eEncStatus = ENUM_ENCRYPTION2_ENABLED;
  896. } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
  897. eEncStatus = ENUM_ENCRYPTION1_ENABLED;
  898. } else if (cipher & IW_AUTH_CIPHER_NONE) {
  899. if (prGlueInfo->rWpaInfo.fgPrivacyInvoke)
  900. eEncStatus = ENUM_ENCRYPTION1_ENABLED;
  901. else
  902. eEncStatus = ENUM_ENCRYPTION_DISABLED;
  903. } else {
  904. eEncStatus = ENUM_ENCRYPTION_DISABLED;
  905. }
  906. } else {
  907. eEncStatus = ENUM_ENCRYPTION_DISABLED;
  908. }
  909. rStatus = kalIoctl(prGlueInfo,
  910. wlanoidSetEncryptionStatus,
  911. &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
  912. if (rStatus != WLAN_STATUS_SUCCESS)
  913. DBGLOG(REQ, WARN, "set encryption mode error:%x\n", rStatus);
  914. if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
  915. P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
  916. prWepKey->u4Length = 12 + sme->key_len;
  917. prWepKey->u4KeyLength = (UINT_32) sme->key_len;
  918. prWepKey->u4KeyIndex = (UINT_32) sme->key_idx;
  919. prWepKey->u4KeyIndex |= BIT(31);
  920. if (prWepKey->u4KeyLength > 32) {
  921. DBGLOG(REQ, ERROR, "Too long key length (%u)\n", prWepKey->u4KeyLength);
  922. return -EINVAL;
  923. }
  924. kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength);
  925. rStatus = kalIoctl(prGlueInfo,
  926. wlanoidSetAddWep,
  927. prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  928. if (rStatus != WLAN_STATUS_SUCCESS) {
  929. DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus);
  930. return -EFAULT;
  931. }
  932. }
  933. if (sme->channel)
  934. rNewSsid.u4CenterFreq = sme->channel->center_freq;
  935. else
  936. rNewSsid.u4CenterFreq = 0;
  937. rNewSsid.pucBssid = (UINT_8 *)sme->bssid;
  938. rNewSsid.pucSsid = (UINT_8 *)sme->ssid;
  939. rNewSsid.u4SsidLen = sme->ssid_len;
  940. rStatus = kalIoctl(prGlueInfo,
  941. wlanoidSetConnect,
  942. (PVOID)(&rNewSsid), sizeof(PARAM_CONNECT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  943. if (rStatus != WLAN_STATUS_SUCCESS) {
  944. DBGLOG(REQ, ERROR, "set SSID:%x\n", rStatus);
  945. return -EINVAL;
  946. }
  947. return 0;
  948. }
  949. /*----------------------------------------------------------------------------*/
  950. /*!
  951. * @brief This routine is responsible for requesting to disconnect from
  952. * currently connected ESS
  953. *
  954. * @param
  955. *
  956. * @retval 0: successful
  957. * others: failure
  958. */
  959. /*----------------------------------------------------------------------------*/
  960. int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code)
  961. {
  962. P_GLUE_INFO_T prGlueInfo = NULL;
  963. WLAN_STATUS rStatus;
  964. UINT_32 u4BufLen;
  965. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  966. ASSERT(prGlueInfo);
  967. rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  968. if (rStatus != WLAN_STATUS_SUCCESS) {
  969. DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus);
  970. return -EFAULT;
  971. }
  972. return 0;
  973. }
  974. /*----------------------------------------------------------------------------*/
  975. /*!
  976. * @brief This routine is responsible for requesting to join an IBSS group
  977. *
  978. * @param
  979. *
  980. * @retval 0: successful
  981. * others: failure
  982. */
  983. /*----------------------------------------------------------------------------*/
  984. int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params)
  985. {
  986. PARAM_SSID_T rNewSsid;
  987. P_GLUE_INFO_T prGlueInfo = NULL;
  988. UINT_32 u4ChnlFreq; /* Store channel or frequency information */
  989. UINT_32 u4BufLen = 0;
  990. WLAN_STATUS rStatus;
  991. struct ieee80211_channel *channel = NULL;
  992. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  993. ASSERT(prGlueInfo);
  994. /* set channel */
  995. if (params->chandef.chan)
  996. channel = params->chandef.chan;
  997. if (channel) {
  998. u4ChnlFreq = nicChannelNum2Freq(channel->hw_value);
  999. rStatus = kalIoctl(prGlueInfo,
  1000. wlanoidSetFrequency,
  1001. &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
  1002. if (rStatus != WLAN_STATUS_SUCCESS)
  1003. return -EFAULT;
  1004. }
  1005. /* set SSID */
  1006. kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len);
  1007. rStatus = kalIoctl(prGlueInfo,
  1008. wlanoidSetSsid,
  1009. (PVOID)(&rNewSsid), sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  1010. if (rStatus != WLAN_STATUS_SUCCESS) {
  1011. DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus);
  1012. return -EFAULT;
  1013. }
  1014. return 0;
  1015. return -EINVAL;
  1016. }
  1017. /*----------------------------------------------------------------------------*/
  1018. /*!
  1019. * @brief This routine is responsible for requesting to leave from IBSS group
  1020. *
  1021. * @param
  1022. *
  1023. * @retval 0: successful
  1024. * others: failure
  1025. */
  1026. /*----------------------------------------------------------------------------*/
  1027. int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
  1028. {
  1029. P_GLUE_INFO_T prGlueInfo = NULL;
  1030. WLAN_STATUS rStatus;
  1031. UINT_32 u4BufLen;
  1032. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1033. ASSERT(prGlueInfo);
  1034. rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  1035. if (rStatus != WLAN_STATUS_SUCCESS) {
  1036. DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus);
  1037. return -EFAULT;
  1038. }
  1039. return 0;
  1040. }
  1041. /*----------------------------------------------------------------------------*/
  1042. /*!
  1043. * @brief This routine is responsible for requesting to configure
  1044. * WLAN power managemenet
  1045. *
  1046. * @param
  1047. *
  1048. * @retval 0: successful
  1049. * others: failure
  1050. */
  1051. /*----------------------------------------------------------------------------*/
  1052. int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout)
  1053. {
  1054. P_GLUE_INFO_T prGlueInfo = NULL;
  1055. WLAN_STATUS rStatus;
  1056. UINT_32 u4BufLen;
  1057. PARAM_POWER_MODE ePowerMode;
  1058. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1059. ASSERT(prGlueInfo);
  1060. if (enabled) {
  1061. if (timeout == -1)
  1062. ePowerMode = Param_PowerModeFast_PSP;
  1063. else
  1064. ePowerMode = Param_PowerModeMAX_PSP;
  1065. } else {
  1066. ePowerMode = Param_PowerModeCAM;
  1067. }
  1068. rStatus = kalIoctl(prGlueInfo,
  1069. wlanoidSet802dot11PowerSaveProfile,
  1070. &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  1071. if (rStatus != WLAN_STATUS_SUCCESS) {
  1072. DBGLOG(REQ, WARN, "set_power_mgmt error:%x\n", rStatus);
  1073. return -EFAULT;
  1074. }
  1075. return 0;
  1076. }
  1077. /*----------------------------------------------------------------------------*/
  1078. /*!
  1079. * @brief This routine is responsible for requesting to cache
  1080. * a PMKID for a BSSID
  1081. *
  1082. * @param
  1083. *
  1084. * @retval 0: successful
  1085. * others: failure
  1086. */
  1087. /*----------------------------------------------------------------------------*/
  1088. int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa)
  1089. {
  1090. P_GLUE_INFO_T prGlueInfo = NULL;
  1091. WLAN_STATUS rStatus;
  1092. UINT_32 u4BufLen;
  1093. P_PARAM_PMKID_T prPmkid;
  1094. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1095. ASSERT(prGlueInfo);
  1096. prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE);
  1097. if (!prPmkid) {
  1098. DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n");
  1099. return -ENOMEM;
  1100. }
  1101. prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T);
  1102. prPmkid->u4BSSIDInfoCount = 1;
  1103. kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, pmksa->bssid, 6);
  1104. kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, pmksa->pmkid, IW_PMKID_LEN);
  1105. rStatus = kalIoctl(prGlueInfo,
  1106. wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
  1107. if (rStatus != WLAN_STATUS_SUCCESS)
  1108. DBGLOG(REQ, WARN, "add pmkid error:%x\n", rStatus);
  1109. kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T));
  1110. return 0;
  1111. }
  1112. /*----------------------------------------------------------------------------*/
  1113. /*!
  1114. * @brief This routine is responsible for requesting to remove
  1115. * a cached PMKID for a BSSID
  1116. *
  1117. * @param
  1118. *
  1119. * @retval 0: successful
  1120. * others: failure
  1121. */
  1122. /*----------------------------------------------------------------------------*/
  1123. int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa)
  1124. {
  1125. return 0;
  1126. }
  1127. /*----------------------------------------------------------------------------*/
  1128. /*!
  1129. * @brief This routine is responsible for requesting to flush
  1130. * all cached PMKID
  1131. *
  1132. * @param
  1133. *
  1134. * @retval 0: successful
  1135. * others: failure
  1136. */
  1137. /*----------------------------------------------------------------------------*/
  1138. int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
  1139. {
  1140. P_GLUE_INFO_T prGlueInfo = NULL;
  1141. WLAN_STATUS rStatus;
  1142. UINT_32 u4BufLen;
  1143. P_PARAM_PMKID_T prPmkid;
  1144. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1145. ASSERT(prGlueInfo);
  1146. prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE);
  1147. if (!prPmkid) {
  1148. DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_FLUSH\n");
  1149. return -ENOMEM;
  1150. }
  1151. prPmkid->u4Length = 8;
  1152. prPmkid->u4BSSIDInfoCount = 0;
  1153. rStatus = kalIoctl(prGlueInfo,
  1154. wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen);
  1155. if (rStatus != WLAN_STATUS_SUCCESS)
  1156. DBGLOG(REQ, WARN, "flush pmkid error:%x\n", rStatus);
  1157. kalMemFree(prPmkid, VIR_MEM_TYPE, 8);
  1158. return 0;
  1159. }
  1160. void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy,
  1161. IN struct wireless_dev *wdev,
  1162. IN u16 frame_type, IN bool reg)
  1163. {
  1164. #if 0
  1165. P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL;
  1166. #endif
  1167. P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
  1168. do {
  1169. DBGLOG(REQ, LOUD, "mtk_cfg80211_mgmt_frame_register\n");
  1170. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1171. switch (frame_type) {
  1172. case MAC_FRAME_PROBE_REQ:
  1173. if (reg) {
  1174. prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ;
  1175. DBGLOG(REQ, LOUD, "Open packet filer probe request\n");
  1176. } else {
  1177. prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ;
  1178. DBGLOG(REQ, LOUD, "Close packet filer probe request\n");
  1179. }
  1180. break;
  1181. case MAC_FRAME_ACTION:
  1182. if (reg) {
  1183. prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME;
  1184. DBGLOG(REQ, LOUD, "Open packet filer action frame.\n");
  1185. } else {
  1186. prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME;
  1187. DBGLOG(REQ, LOUD, "Close packet filer action frame.\n");
  1188. }
  1189. break;
  1190. default:
  1191. DBGLOG(REQ, TRACE, "Ask frog to add code for mgmt:%x\n", frame_type);
  1192. break;
  1193. }
  1194. if (prGlueInfo->prAdapter != NULL) {
  1195. /* prGlueInfo->ulFlag |= GLUE_FLAG_FRAME_FILTER_AIS; */
  1196. set_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag);
  1197. /* wake up main thread */
  1198. wake_up_interruptible(&prGlueInfo->waitq);
  1199. if (in_interrupt())
  1200. DBGLOG(REQ, TRACE, "It is in interrupt level\n");
  1201. }
  1202. #if 0
  1203. prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter,
  1204. RAM_TYPE_MSG,
  1205. sizeof
  1206. (MSG_P2P_MGMT_FRAME_REGISTER_T));
  1207. if (prMgmtFrameRegister == NULL) {
  1208. ASSERT(FALSE);
  1209. break;
  1210. }
  1211. prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER;
  1212. prMgmtFrameRegister->u2FrameType = frame_type;
  1213. prMgmtFrameRegister->fgIsRegister = reg;
  1214. mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF);
  1215. #endif
  1216. } while (FALSE);
  1217. } /* mtk_cfg80211_mgmt_frame_register */
  1218. /*----------------------------------------------------------------------------*/
  1219. /*!
  1220. * @brief This routine is responsible for requesting to stay on a
  1221. * specified channel
  1222. *
  1223. * @param
  1224. *
  1225. * @retval 0: successful
  1226. * others: failure
  1227. */
  1228. /*----------------------------------------------------------------------------*/
  1229. int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy,
  1230. struct wireless_dev *wdev,
  1231. struct ieee80211_channel *chan,
  1232. unsigned int duration, u64 *cookie)
  1233. {
  1234. P_GLUE_INFO_T prGlueInfo = NULL;
  1235. INT_32 i4Rslt = -EINVAL;
  1236. P_MSG_REMAIN_ON_CHANNEL_T prMsgChnlReq = (P_MSG_REMAIN_ON_CHANNEL_T) NULL;
  1237. do {
  1238. if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL))
  1239. break;
  1240. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1241. ASSERT(prGlueInfo);
  1242. #if 1
  1243. DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
  1244. #endif
  1245. *cookie = prGlueInfo->u8Cookie++;
  1246. prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_REMAIN_ON_CHANNEL_T));
  1247. if (prMsgChnlReq == NULL) {
  1248. ASSERT(FALSE);
  1249. i4Rslt = -ENOMEM;
  1250. break;
  1251. }
  1252. prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_AIS_REMAIN_ON_CHANNEL;
  1253. prMsgChnlReq->u8Cookie = *cookie;
  1254. prMsgChnlReq->u4DurationMs = duration;
  1255. prMsgChnlReq->ucChannelNum = nicFreq2ChannelNum(chan->center_freq * 1000);
  1256. switch (chan->band) {
  1257. case IEEE80211_BAND_2GHZ:
  1258. prMsgChnlReq->eBand = BAND_2G4;
  1259. break;
  1260. case IEEE80211_BAND_5GHZ:
  1261. prMsgChnlReq->eBand = BAND_5G;
  1262. break;
  1263. default:
  1264. prMsgChnlReq->eBand = BAND_2G4;
  1265. break;
  1266. }
  1267. mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF);
  1268. i4Rslt = 0;
  1269. } while (FALSE);
  1270. return i4Rslt;
  1271. }
  1272. /*----------------------------------------------------------------------------*/
  1273. /*!
  1274. * @brief This routine is responsible for requesting to cancel staying
  1275. * on a specified channel
  1276. *
  1277. * @param
  1278. *
  1279. * @retval 0: successful
  1280. * others: failure
  1281. */
  1282. /*----------------------------------------------------------------------------*/
  1283. int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
  1284. struct wireless_dev *wdev,
  1285. u64 cookie)
  1286. {
  1287. P_GLUE_INFO_T prGlueInfo = NULL;
  1288. INT_32 i4Rslt = -EINVAL;
  1289. P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prMsgChnlAbort = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) NULL;
  1290. do {
  1291. if ((wiphy == NULL) || (wdev == NULL))
  1292. break;
  1293. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1294. ASSERT(prGlueInfo);
  1295. #if 1
  1296. DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
  1297. #endif
  1298. prMsgChnlAbort =
  1299. cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_CANCEL_REMAIN_ON_CHANNEL_T));
  1300. if (prMsgChnlAbort == NULL) {
  1301. ASSERT(FALSE);
  1302. i4Rslt = -ENOMEM;
  1303. break;
  1304. }
  1305. prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL;
  1306. prMsgChnlAbort->u8Cookie = cookie;
  1307. mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF);
  1308. i4Rslt = 0;
  1309. } while (FALSE);
  1310. return i4Rslt;
  1311. }
  1312. /*----------------------------------------------------------------------------*/
  1313. /*!
  1314. * @brief This routine is responsible for requesting to send a management frame
  1315. *
  1316. * @param
  1317. *
  1318. * @retval 0: successful
  1319. * others: failure
  1320. */
  1321. /*----------------------------------------------------------------------------*/
  1322. int
  1323. mtk_cfg80211_mgmt_tx(struct wiphy *wiphy,
  1324. struct wireless_dev *wdev,
  1325. struct cfg80211_mgmt_tx_params *params,
  1326. u64 *cookie)
  1327. {
  1328. P_GLUE_INFO_T prGlueInfo = NULL;
  1329. INT_32 i4Rslt = -EINVAL;
  1330. P_MSG_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_MGMT_TX_REQUEST_T) NULL;
  1331. P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL;
  1332. PUINT_8 pucFrameBuf = (PUINT_8) NULL;
  1333. do {
  1334. #if 1
  1335. DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
  1336. #endif
  1337. if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL))
  1338. break;
  1339. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1340. ASSERT(prGlueInfo);
  1341. *cookie = prGlueInfo->u8Cookie++;
  1342. /* Channel & Channel Type & Wait time are ignored. */
  1343. prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_MGMT_TX_REQUEST_T));
  1344. if (prMsgTxReq == NULL) {
  1345. ASSERT(FALSE);
  1346. i4Rslt = -ENOMEM;
  1347. break;
  1348. }
  1349. prMsgTxReq->fgNoneCckRate = FALSE;
  1350. prMsgTxReq->fgIsWaitRsp = TRUE;
  1351. prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD));
  1352. prMsgTxReq->prMgmtMsduInfo = prMgmtFrame;
  1353. if (prMsgTxReq->prMgmtMsduInfo == NULL) {
  1354. ASSERT(FALSE);
  1355. i4Rslt = -ENOMEM;
  1356. break;
  1357. }
  1358. prMsgTxReq->u8Cookie = *cookie;
  1359. prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_AIS_MGMT_TX;
  1360. pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD);
  1361. kalMemCopy(pucFrameBuf, params->buf, params->len);
  1362. prMgmtFrame->u2FrameLength = params->len;
  1363. mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF);
  1364. i4Rslt = 0;
  1365. } while (FALSE);
  1366. if ((i4Rslt != 0) && (prMsgTxReq != NULL)) {
  1367. if (prMsgTxReq->prMgmtMsduInfo != NULL)
  1368. cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo);
  1369. cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq);
  1370. }
  1371. return i4Rslt;
  1372. }
  1373. /*----------------------------------------------------------------------------*/
  1374. /*!
  1375. * @brief This routine is responsible for requesting to cancel the wait time
  1376. * from transmitting a management frame on another channel
  1377. *
  1378. * @param
  1379. *
  1380. * @retval 0: successful
  1381. * others: failure
  1382. */
  1383. /*----------------------------------------------------------------------------*/
  1384. int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
  1385. struct wireless_dev *wdev,
  1386. u64 cookie)
  1387. {
  1388. P_GLUE_INFO_T prGlueInfo = NULL;
  1389. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1390. ASSERT(prGlueInfo);
  1391. DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
  1392. /* not implemented */
  1393. return -EINVAL;
  1394. }
  1395. /*----------------------------------------------------------------------------*/
  1396. /*!
  1397. * @brief This routine is responsible for handling sched_scan start/stop request
  1398. *
  1399. * @param
  1400. *
  1401. * @retval 0: successful
  1402. * others: failure
  1403. */
  1404. /*----------------------------------------------------------------------------*/
  1405. int
  1406. mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy,
  1407. IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request)
  1408. {
  1409. P_GLUE_INFO_T prGlueInfo = NULL;
  1410. WLAN_STATUS rStatus;
  1411. UINT_32 i, u4BufLen;
  1412. P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest;
  1413. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1414. ASSERT(prGlueInfo);
  1415. /* check if there is any pending scan/sched_scan not yet finished */
  1416. if (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL) {
  1417. DBGLOG(SCN, ERROR, "(prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)\n");
  1418. return -EBUSY;
  1419. } else if (request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM) {
  1420. DBGLOG(SCN, ERROR, "(request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM)\n");
  1421. /* invalid scheduled scan request */
  1422. return -EINVAL;
  1423. } else if (/* !request->n_ssids || */!request->n_match_sets) {
  1424. /* invalid scheduled scan request */
  1425. return -EINVAL;
  1426. }
  1427. prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) kalMemAlloc(sizeof(PARAM_SCHED_SCAN_REQUEST), VIR_MEM_TYPE);
  1428. if (prSchedScanRequest == NULL) {
  1429. DBGLOG(SCN, ERROR, "(prSchedScanRequest == NULL) kalMemAlloc fail\n");
  1430. return -ENOMEM;
  1431. }
  1432. kalMemZero(prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST));
  1433. prSchedScanRequest->u4SsidNum = request->n_match_sets;
  1434. for (i = 0; i < request->n_match_sets; i++) {
  1435. if (request->match_sets == NULL || &(request->match_sets[i]) == NULL) {
  1436. prSchedScanRequest->arSsid[i].u4SsidLen = 0;
  1437. } else {
  1438. COPY_SSID(prSchedScanRequest->arSsid[i].aucSsid,
  1439. prSchedScanRequest->arSsid[i].u4SsidLen,
  1440. request->match_sets[i].ssid.ssid, request->match_sets[i].ssid.ssid_len);
  1441. }
  1442. }
  1443. prSchedScanRequest->u4IELength = request->ie_len;
  1444. if (request->ie_len > 0)
  1445. prSchedScanRequest->pucIE = (PUINT_8) (request->ie);
  1446. prSchedScanRequest->u2ScanInterval = (UINT_16) (request->interval);
  1447. rStatus = kalIoctl(prGlueInfo,
  1448. wlanoidSetStartSchedScan,
  1449. prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  1450. kalMemFree(prSchedScanRequest, VIR_MEM_TYPE, sizeof(PARAM_SCHED_SCAN_REQUEST));
  1451. if (rStatus != WLAN_STATUS_SUCCESS) {
  1452. DBGLOG(SCN, ERROR, "scheduled scan error:%x\n", rStatus);
  1453. return -EINVAL;
  1454. }
  1455. prGlueInfo->prSchedScanRequest = request;
  1456. return 0;
  1457. }
  1458. int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev)
  1459. {
  1460. P_GLUE_INFO_T prGlueInfo = NULL;
  1461. WLAN_STATUS rStatus;
  1462. UINT_32 u4BufLen;
  1463. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1464. ASSERT(prGlueInfo);
  1465. /* check if there is any pending scan/sched_scan not yet finished */
  1466. if (prGlueInfo->prSchedScanRequest == NULL) {
  1467. DBGLOG(SCN, ERROR, "prGlueInfo->prSchedScanRequest == NULL\n");
  1468. return -EBUSY;
  1469. }
  1470. rStatus = kalIoctl(prGlueInfo, wlanoidSetStopSchedScan, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  1471. if (rStatus != WLAN_STATUS_SUCCESS) {
  1472. DBGLOG(SCN, ERROR, "scheduled scan error, rStatus: %d\n", rStatus);
  1473. return -EINVAL;
  1474. }
  1475. /* 1. reset first for newly incoming request */
  1476. /* GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */
  1477. if (prGlueInfo->prSchedScanRequest != NULL)
  1478. prGlueInfo->prSchedScanRequest = NULL;
  1479. /* GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */
  1480. DBGLOG(SCN, TRACE, "start work queue to send event\n");
  1481. schedule_delayed_work(&sched_workq, 0);
  1482. DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n");
  1483. return 0;
  1484. }
  1485. /*----------------------------------------------------------------------------*/
  1486. /*!
  1487. * @brief This routine is responsible for handling association request
  1488. *
  1489. * @param
  1490. *
  1491. * @retval 0: successful
  1492. * others: failure
  1493. */
  1494. /*----------------------------------------------------------------------------*/
  1495. int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req)
  1496. {
  1497. P_GLUE_INFO_T prGlueInfo = NULL;
  1498. PARAM_MAC_ADDRESS arBssid;
  1499. #if CFG_SUPPORT_HOTSPOT_2_0
  1500. PUINT_8 prDesiredIE = NULL;
  1501. #endif
  1502. WLAN_STATUS rStatus;
  1503. UINT_32 u4BufLen;
  1504. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1505. ASSERT(prGlueInfo);
  1506. kalMemZero(arBssid, MAC_ADDR_LEN);
  1507. wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen);
  1508. /* 1. check BSSID */
  1509. if (UNEQUAL_MAC_ADDR(arBssid, req->bss->bssid)) {
  1510. /* wrong MAC address */
  1511. DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n",
  1512. req->bss->bssid, arBssid);
  1513. return -ENOENT;
  1514. }
  1515. if (req->ie && req->ie_len > 0) {
  1516. #if CFG_SUPPORT_HOTSPOT_2_0
  1517. if (wextSrchDesiredHS20IE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) {
  1518. rStatus = kalIoctl(prGlueInfo,
  1519. wlanoidSetHS20Info,
  1520. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  1521. if (rStatus != WLAN_STATUS_SUCCESS) {
  1522. /* Do nothing */
  1523. /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */
  1524. }
  1525. }
  1526. if (wextSrchDesiredInterworkingIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) {
  1527. rStatus = kalIoctl(prGlueInfo,
  1528. wlanoidSetInterworkingInfo,
  1529. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  1530. if (rStatus != WLAN_STATUS_SUCCESS) {
  1531. /* Do nothing */
  1532. /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */
  1533. }
  1534. }
  1535. if (wextSrchDesiredRoamingConsortiumIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) {
  1536. rStatus = kalIoctl(prGlueInfo,
  1537. wlanoidSetRoamingConsortiumIEInfo,
  1538. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  1539. if (rStatus != WLAN_STATUS_SUCCESS) {
  1540. /* Do nothing */
  1541. /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */
  1542. }
  1543. }
  1544. #endif
  1545. }
  1546. rStatus = kalIoctl(prGlueInfo,
  1547. wlanoidSetBssid,
  1548. (PVOID) req->bss->bssid, MAC_ADDR_LEN, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  1549. if (rStatus != WLAN_STATUS_SUCCESS) {
  1550. DBGLOG(REQ, WARN, "set BSSID:%x\n", rStatus);
  1551. return -EINVAL;
  1552. }
  1553. return 0;
  1554. }
  1555. #if CONFIG_NL80211_TESTMODE
  1556. /*
  1557. #define NLA_PUT(skb, attrtype, attrlen, data) \
  1558. do { \
  1559. if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \
  1560. goto nla_put_failure; \
  1561. } while (0)
  1562. #define NLA_PUT_TYPE(skb, type, attrtype, value) \
  1563. do { \
  1564. type __tmp = value; \
  1565. NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \
  1566. } while (0)
  1567. #define NLA_PUT_U8(skb, attrtype, value) \
  1568. NLA_PUT_TYPE(skb, u8, attrtype, value)
  1569. #define NLA_PUT_U16(skb, attrtype, value) \
  1570. NLA_PUT_TYPE(skb, u16, attrtype, value)
  1571. #define NLA_PUT_U32(skb, attrtype, value) \
  1572. NLA_PUT_TYPE(skb, u32, attrtype, value)
  1573. #define NLA_PUT_U64(skb, attrtype, value) \
  1574. NLA_PUT_TYPE(skb, u64, attrtype, value)
  1575. */
  1576. #if CFG_SUPPORT_WAPI
  1577. int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len)
  1578. {
  1579. P_GLUE_INFO_T prGlueInfo = NULL;
  1580. P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) NULL;
  1581. struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL;
  1582. WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
  1583. int fgIsValid = 0;
  1584. UINT_32 u4BufLen = 0;
  1585. P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf;
  1586. memset(keyStructBuf, 0, sizeof(keyStructBuf));
  1587. ASSERT(wiphy);
  1588. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1589. DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
  1590. if (data && len) {
  1591. prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) data;
  1592. } else {
  1593. DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_key_ext, data is NULL\n");
  1594. return -EINVAL;
  1595. }
  1596. if (prParams)
  1597. prIWEncExt = (struct iw_encode_exts *)&prParams->ext;
  1598. if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) {
  1599. /* KeyID */
  1600. prWpiKey->ucKeyID = prParams->key_index;
  1601. prWpiKey->ucKeyID--;
  1602. if (prWpiKey->ucKeyID > 1) {
  1603. /* key id is out of range */
  1604. /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */
  1605. return -EINVAL;
  1606. }
  1607. if (prIWEncExt->key_len != 32) {
  1608. /* key length not valid */
  1609. /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */
  1610. return -EINVAL;
  1611. }
  1612. /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */
  1613. if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
  1614. prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY;
  1615. prWpiKey->eDirection = ENUM_WPI_RX;
  1616. } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
  1617. prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY;
  1618. prWpiKey->eDirection = ENUM_WPI_RX_TX;
  1619. }
  1620. /* #if CFG_SUPPORT_WAPI */
  1621. /* handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL); */
  1622. /* #endif */
  1623. /* PN */
  1624. memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE);
  1625. memcpy(prWpiKey->aucPN + IW_ENCODE_SEQ_MAX_SIZE, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE);
  1626. /* BSSID */
  1627. memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6);
  1628. memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16);
  1629. prWpiKey->u4LenWPIEK = 16;
  1630. memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16);
  1631. prWpiKey->u4LenWPICK = 16;
  1632. rstatus = kalIoctl(prGlueInfo,
  1633. wlanoidSetWapiKey,
  1634. prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  1635. if (rstatus != WLAN_STATUS_SUCCESS) {
  1636. /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */
  1637. fgIsValid = -EFAULT;
  1638. }
  1639. }
  1640. return fgIsValid;
  1641. }
  1642. #endif
  1643. int
  1644. mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
  1645. {
  1646. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  1647. INT_32 i4Status = -EINVAL;
  1648. UINT_32 u4BufLen;
  1649. UINT_32 u4LinkScore;
  1650. UINT_32 u4TotalError;
  1651. UINT_32 u4TxExceedThresholdCount;
  1652. UINT_32 u4TxTotalCount;
  1653. P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL;
  1654. PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics;
  1655. struct sk_buff *skb;
  1656. ASSERT(wiphy);
  1657. ASSERT(prGlueInfo);
  1658. if (data && len) {
  1659. prParams = (P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS) data;
  1660. } else {
  1661. DBGLOG(QM, ERROR, "mtk_cfg80211_testmode_get_sta_statistics, data is NULL\n");
  1662. return -EINVAL;
  1663. }
  1664. /*
  1665. if (!prParams->aucMacAddr) {
  1666. DBGLOG(QM, INFO, "%s MAC Address is NULL\n", __func__);
  1667. return -EINVAL;
  1668. }
  1669. */
  1670. skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1);
  1671. if (!skb) {
  1672. DBGLOG(QM, ERROR, "%s allocate skb failed:%x\n", __func__, rStatus);
  1673. return -ENOMEM;
  1674. }
  1675. DBGLOG(QM, TRACE, "Get [ %pM ] STA statistics\n", prParams->aucMacAddr);
  1676. kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics));
  1677. COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, prParams->aucMacAddr);
  1678. rStatus = kalIoctl(prGlueInfo,
  1679. wlanoidQueryStaStatistics,
  1680. &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, TRUE, &u4BufLen);
  1681. /* Calcute Link Score */
  1682. u4TxExceedThresholdCount = rQueryStaStatistics.u4TxExceedThresholdCount;
  1683. u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount;
  1684. u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount;
  1685. /* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only */
  1686. /* u4LinkScore 0~9 , Drop packet ratio 0~9 and all packets exceed threshold */
  1687. if (u4TxTotalCount) {
  1688. if (u4TxExceedThresholdCount <= u4TxTotalCount)
  1689. u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) / u4TxTotalCount));
  1690. else
  1691. u4LinkScore = 0;
  1692. } else {
  1693. u4LinkScore = 90;
  1694. }
  1695. u4LinkScore += 10;
  1696. if (u4LinkScore == 10) {
  1697. if (u4TotalError <= u4TxTotalCount)
  1698. u4LinkScore = (10 - ((u4TotalError * 10) / u4TxTotalCount));
  1699. else
  1700. u4LinkScore = 0;
  1701. }
  1702. if (u4LinkScore > 100)
  1703. u4LinkScore = 100;
  1704. /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/
  1705. {
  1706. unsigned char __tmp = 0;
  1707. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0))
  1708. goto nla_put_failure;
  1709. }
  1710. /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, NL80211_DRIVER_TESTMODE_VERSION);*/
  1711. {
  1712. unsigned char __tmp = NL80211_DRIVER_TESTMODE_VERSION;
  1713. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, sizeof(unsigned char), &__tmp) < 0))
  1714. goto nla_put_failure;
  1715. }
  1716. /* NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, u4LinkScore); */
  1717. {
  1718. unsigned char __tmp = u4LinkScore;
  1719. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE,
  1720. sizeof(unsigned char), &__tmp) < 0))
  1721. goto nla_put_failure;
  1722. }
  1723. /*NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, prParams->aucMacAddr);*/
  1724. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, &prParams->aucMacAddr) < 0))
  1725. goto nla_put_failure;
  1726. /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, rQueryStaStatistics.u4Flag);*/
  1727. {
  1728. unsigned int __tmp = rQueryStaStatistics.u4Flag;
  1729. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG,
  1730. sizeof(unsigned int), &__tmp) < 0))
  1731. goto nla_put_failure;
  1732. }
  1733. /* FW part STA link status */
  1734. /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_PER, rQueryStaStatistics.ucPer);*/
  1735. {
  1736. unsigned char __tmp = rQueryStaStatistics.ucPer;
  1737. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PER, sizeof(unsigned char), &__tmp) < 0))
  1738. goto nla_put_failure;
  1739. }
  1740. /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, rQueryStaStatistics.ucRcpi);*/
  1741. {
  1742. unsigned char __tmp = rQueryStaStatistics.ucRcpi;
  1743. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, sizeof(unsigned char), &__tmp) < 0))
  1744. goto nla_put_failure;
  1745. }
  1746. /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, rQueryStaStatistics.u4PhyMode);*/
  1747. {
  1748. unsigned int __tmp = rQueryStaStatistics.u4PhyMode;
  1749. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE,
  1750. sizeof(unsigned int), &__tmp) < 0))
  1751. goto nla_put_failure;
  1752. }
  1753. /*NLA_PUT_U16(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, rQueryStaStatistics.u2LinkSpeed);*/
  1754. {
  1755. unsigned short __tmp = rQueryStaStatistics.u2LinkSpeed;
  1756. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE,
  1757. sizeof(unsigned short), &__tmp) < 0))
  1758. goto nla_put_failure;
  1759. }
  1760. /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, rQueryStaStatistics.u4TxFailCount);*/
  1761. {
  1762. unsigned int __tmp = rQueryStaStatistics.u4TxFailCount;
  1763. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT,
  1764. sizeof(unsigned int), &__tmp) < 0))
  1765. goto nla_put_failure;
  1766. }
  1767. /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, rQueryStaStatistics.u4TxLifeTimeoutCount);*/
  1768. {
  1769. unsigned int __tmp = rQueryStaStatistics.u4TxLifeTimeoutCount;
  1770. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT,
  1771. sizeof(unsigned int), &__tmp) < 0))
  1772. goto nla_put_failure;
  1773. }
  1774. /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, rQueryStaStatistics.u4TxAverageAirTime);*/
  1775. {
  1776. unsigned int __tmp = rQueryStaStatistics.u4TxAverageAirTime;
  1777. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME,
  1778. sizeof(unsigned int), &__tmp) < 0))
  1779. goto nla_put_failure;
  1780. }
  1781. /* Driver part link status */
  1782. /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, rQueryStaStatistics.u4TxTotalCount);*/
  1783. {
  1784. unsigned int __tmp = rQueryStaStatistics.u4TxTotalCount;
  1785. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT,
  1786. sizeof(unsigned int), &__tmp) < 0))
  1787. goto nla_put_failure;
  1788. }
  1789. /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT,
  1790. rQueryStaStatistics.u4TxExceedThresholdCount);*/
  1791. {
  1792. unsigned int __tmp = rQueryStaStatistics.u4TxExceedThresholdCount;
  1793. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT,
  1794. sizeof(unsigned int), &__tmp) < 0))
  1795. goto nla_put_failure;
  1796. }
  1797. /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME,
  1798. rQueryStaStatistics.u4TxAverageProcessTime);*/
  1799. {
  1800. unsigned int __tmp = rQueryStaStatistics.u4TxAverageProcessTime;
  1801. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME,
  1802. sizeof(unsigned int), &__tmp) < 0))
  1803. goto nla_put_failure;
  1804. }
  1805. /* Network counter */
  1806. /*NLA_PUT(skb,
  1807. NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY,
  1808. sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), rQueryStaStatistics.au4TcResourceEmptyCount);*/
  1809. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY,
  1810. sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), &rQueryStaStatistics.au4TcResourceEmptyCount) < 0))
  1811. goto nla_put_failure;
  1812. /* Sta queue length */
  1813. /*NLA_PUT(skb,
  1814. NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY,
  1815. sizeof(rQueryStaStatistics.au4TcQueLen), rQueryStaStatistics.au4TcQueLen);*/
  1816. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY,
  1817. sizeof(rQueryStaStatistics.au4TcQueLen), &rQueryStaStatistics.au4TcQueLen) < 0))
  1818. goto nla_put_failure;
  1819. /* Global QM counter */
  1820. /*NLA_PUT(skb,
  1821. NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY,
  1822. sizeof(rQueryStaStatistics.au4TcAverageQueLen), rQueryStaStatistics.au4TcAverageQueLen);*/
  1823. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY,
  1824. sizeof(rQueryStaStatistics.au4TcAverageQueLen), &rQueryStaStatistics.au4TcAverageQueLen) < 0))
  1825. goto nla_put_failure;
  1826. /*NLA_PUT(skb,
  1827. NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY,
  1828. sizeof(rQueryStaStatistics.au4TcCurrentQueLen), rQueryStaStatistics.au4TcCurrentQueLen);*/
  1829. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY,
  1830. sizeof(rQueryStaStatistics.au4TcCurrentQueLen), &rQueryStaStatistics.au4TcCurrentQueLen) < 0))
  1831. goto nla_put_failure;
  1832. /* Reserved field */
  1833. /*NLA_PUT(skb,
  1834. NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY,
  1835. sizeof(rQueryStaStatistics.au4Reserved), rQueryStaStatistics.au4Reserved);*/
  1836. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY,
  1837. sizeof(rQueryStaStatistics.au4Reserved), &rQueryStaStatistics.au4Reserved) < 0))
  1838. goto nla_put_failure;
  1839. DBGLOG(QM, INFO, "%02x:%02x:%02x:%02x:%02x:%02x TxExTC %d TxTC %d TxFC %d TxLT %d LINKSCORE %d Per %d Rcpi %d ",
  1840. prParams->aucMacAddr[0],
  1841. prParams->aucMacAddr[1],
  1842. prParams->aucMacAddr[2],
  1843. prParams->aucMacAddr[3],
  1844. prParams->aucMacAddr[4],
  1845. prParams->aucMacAddr[5],
  1846. rQueryStaStatistics.u4TxExceedThresholdCount,
  1847. rQueryStaStatistics.u4TxTotalCount,
  1848. rQueryStaStatistics.u4TxFailCount,
  1849. rQueryStaStatistics.u4TxLifeTimeoutCount,
  1850. u4LinkScore,
  1851. rQueryStaStatistics.ucPer,
  1852. rQueryStaStatistics.ucRcpi);
  1853. DBGLOG(QM, INFO, "PhyMode %d LinkSpeed %d Flag %d TxAvgPT %d TCReEC0 %d TCReEC1 %d TCReEC2 %d TCReEC3 %d ",
  1854. rQueryStaStatistics.u4PhyMode,
  1855. rQueryStaStatistics.u2LinkSpeed,
  1856. rQueryStaStatistics.u4Flag,
  1857. rQueryStaStatistics.u4TxAverageProcessTime,
  1858. rQueryStaStatistics.au4TcResourceEmptyCount[0],
  1859. rQueryStaStatistics.au4TcResourceEmptyCount[1],
  1860. rQueryStaStatistics.au4TcResourceEmptyCount[2],
  1861. rQueryStaStatistics.au4TcResourceEmptyCount[3]);
  1862. DBGLOG(QM, INFO, "TcQlen0 %d TcQlen1 %d TcQlen2 %d TcQlen3 %d CQlen0 %d CQlen1 %d CQlen2 %d CQlen3 %d\n",
  1863. rQueryStaStatistics.au4TcQueLen[0],
  1864. rQueryStaStatistics.au4TcQueLen[1],
  1865. rQueryStaStatistics.au4TcQueLen[2],
  1866. rQueryStaStatistics.au4TcQueLen[3],
  1867. rQueryStaStatistics.au4TcCurrentQueLen[0],
  1868. rQueryStaStatistics.au4TcCurrentQueLen[1],
  1869. rQueryStaStatistics.au4TcCurrentQueLen[2],
  1870. rQueryStaStatistics.au4TcCurrentQueLen[3]);
  1871. i4Status = cfg80211_testmode_reply(skb);
  1872. nla_put_failure:
  1873. return i4Status;
  1874. }
  1875. int
  1876. mtk_cfg80211_testmode_get_link_detection(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
  1877. {
  1878. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  1879. INT_32 i4Status = -EINVAL;
  1880. UINT_32 u4BufLen;
  1881. PARAM_802_11_STATISTICS_STRUCT_T rStatistics;
  1882. struct sk_buff *skb;
  1883. ASSERT(wiphy);
  1884. ASSERT(prGlueInfo);
  1885. skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1);
  1886. if (!skb) {
  1887. DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus);
  1888. return -ENOMEM;
  1889. }
  1890. kalMemZero(&rStatistics, sizeof(rStatistics));
  1891. rStatus = kalIoctl(prGlueInfo,
  1892. wlanoidQueryStatistics,
  1893. &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen);
  1894. /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/
  1895. {
  1896. unsigned char __tmp = 0;
  1897. if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0))
  1898. goto nla_put_failure;
  1899. }
  1900. /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, rStatistics.rFailedCount.QuadPart);*/
  1901. {
  1902. u64 __tmp = rStatistics.rFailedCount.QuadPart;
  1903. if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT,
  1904. sizeof(u64), &__tmp) < 0))
  1905. goto nla_put_failure;
  1906. }
  1907. /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, rStatistics.rRetryCount.QuadPart);*/
  1908. {
  1909. u64 __tmp = rStatistics.rFailedCount.QuadPart;
  1910. if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT,
  1911. sizeof(u64), &__tmp) < 0))
  1912. goto nla_put_failure;
  1913. }
  1914. /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, rStatistics.rMultipleRetryCount.QuadPart);*/
  1915. {
  1916. u64 __tmp = rStatistics.rMultipleRetryCount.QuadPart;
  1917. if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT,
  1918. sizeof(u64), &__tmp) < 0))
  1919. goto nla_put_failure;
  1920. }
  1921. /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, rStatistics.rACKFailureCount.QuadPart);*/
  1922. {
  1923. u64 __tmp = rStatistics.rACKFailureCount.QuadPart;
  1924. if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT,
  1925. sizeof(u64), &__tmp) < 0))
  1926. goto nla_put_failure;
  1927. }
  1928. /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, rStatistics.rFCSErrorCount.QuadPart);*/
  1929. {
  1930. u64 __tmp = rStatistics.rFCSErrorCount.QuadPart;
  1931. if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT,
  1932. sizeof(u64), &__tmp) < 0))
  1933. goto nla_put_failure;
  1934. }
  1935. i4Status = cfg80211_testmode_reply(skb);
  1936. skb = NULL;
  1937. nla_put_failure:
  1938. if (skb != NULL)
  1939. kfree_skb(skb);
  1940. return i4Status;
  1941. }
  1942. int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
  1943. {
  1944. P_GLUE_INFO_T prGlueInfo = NULL;
  1945. P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL;
  1946. WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
  1947. int fgIsValid = 0;
  1948. UINT_32 u4SetInfoLen = 0;
  1949. ASSERT(wiphy);
  1950. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1951. DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
  1952. if (data && len)
  1953. prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data;
  1954. if (prParams) {
  1955. if (prParams->set == 1) {
  1956. rstatus = kalIoctl(prGlueInfo,
  1957. (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite,
  1958. &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
  1959. }
  1960. }
  1961. if (WLAN_STATUS_SUCCESS != rstatus)
  1962. fgIsValid = -EFAULT;
  1963. return fgIsValid;
  1964. }
  1965. #if CFG_SUPPORT_HOTSPOT_2_0
  1966. int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
  1967. {
  1968. P_GLUE_INFO_T prGlueInfo = NULL;
  1969. struct wpa_driver_hs20_data_s *prParams = NULL;
  1970. WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
  1971. int fgIsValid = 0;
  1972. UINT_32 u4SetInfoLen = 0;
  1973. ASSERT(wiphy);
  1974. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1975. DBGLOG(REQ, TRACE, "--> %s()\n", __func__);
  1976. if (data && len) {
  1977. prParams = (struct wpa_driver_hs20_data_s *)data;
  1978. DBGLOG(REQ, TRACE, "[%s] Cmd Type (%d)\n", __func__, prParams->CmdType);
  1979. }
  1980. if (prParams) {
  1981. int i;
  1982. switch (prParams->CmdType) {
  1983. case HS20_CMD_ID_SET_BSSID_POOL:
  1984. DBGLOG(REQ, TRACE, "fgBssidPoolIsEnable=%d, ucNumBssidPool=%d\n",
  1985. prParams->hs20_set_bssid_pool.fgBssidPoolIsEnable,
  1986. prParams->hs20_set_bssid_pool.ucNumBssidPool);
  1987. for (i = 0; i < prParams->hs20_set_bssid_pool.ucNumBssidPool; i++) {
  1988. DBGLOG(REQ, TRACE, "[%d][ %pM ]\n", i,
  1989. (prParams->hs20_set_bssid_pool.arBssidPool[i]));
  1990. }
  1991. rstatus = kalIoctl(prGlueInfo,
  1992. (PFN_OID_HANDLER_FUNC) wlanoidSetHS20BssidPool,
  1993. &prParams->hs20_set_bssid_pool,
  1994. sizeof(struct param_hs20_set_bssid_pool),
  1995. FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
  1996. break;
  1997. default:
  1998. DBGLOG(REQ, TRACE, "[%s] Unknown Cmd Type (%d)\n", __func__, prParams->CmdType);
  1999. rstatus = WLAN_STATUS_FAILURE;
  2000. }
  2001. }
  2002. if (WLAN_STATUS_SUCCESS != rstatus)
  2003. fgIsValid = -EFAULT;
  2004. return fgIsValid;
  2005. }
  2006. #endif
  2007. int
  2008. mtk_cfg80211_testmode_set_poorlink_param(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
  2009. {
  2010. int fgIsValid = 0;
  2011. P_NL80211_DRIVER_POORLINK_PARAMS prParams = NULL;
  2012. ASSERT(wiphy);
  2013. ASSERT(prGlueInfo);
  2014. if (data && len) {
  2015. prParams = (P_NL80211_DRIVER_POORLINK_PARAMS) data;
  2016. } else {
  2017. DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_poorlink_param, data is NULL\n");
  2018. return -EINVAL;
  2019. }
  2020. if (prParams->ucLinkSpeed)
  2021. prGlueInfo->u4LinkspeedThreshold = prParams->ucLinkSpeed * 10;
  2022. if (prParams->cRssi)
  2023. prGlueInfo->i4RssiThreshold = prParams->cRssi;
  2024. if (!prGlueInfo->fgPoorlinkValid)
  2025. prGlueInfo->fgPoorlinkValid = 1;
  2026. #if 0
  2027. DBGLOG(REQ, TRACE, "poorlink set param valid(%d)rssi(%d)linkspeed(%d)\n",
  2028. prGlueInfo->fgPoorlinkValid, prGlueInfo->i4RssiThreshold, prGlueInfo->u4LinkspeedThreshold);
  2029. #endif
  2030. return fgIsValid;
  2031. }
  2032. int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len)
  2033. {
  2034. P_GLUE_INFO_T prGlueInfo = NULL;
  2035. P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) NULL;
  2036. INT_32 i4Status = -EINVAL;
  2037. #if CFG_SUPPORT_HOTSPOT_2_0
  2038. BOOLEAN fgIsValid = 0;
  2039. #endif
  2040. ASSERT(wiphy);
  2041. ASSERT(wdev);
  2042. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  2043. if (data && len) {
  2044. prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) data;
  2045. } else {
  2046. DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_cmd, data is NULL\n");
  2047. return i4Status;
  2048. }
  2049. /* Clear the version byte */
  2050. prParams->index = prParams->index & ~BITS(24, 31);
  2051. if (prParams) {
  2052. switch (prParams->index) {
  2053. case TESTMODE_CMD_ID_SW_CMD: /* SW cmd */
  2054. i4Status = mtk_cfg80211_testmode_sw_cmd(wiphy, data, len);
  2055. break;
  2056. case TESTMODE_CMD_ID_WAPI: /* WAPI */
  2057. #if CFG_SUPPORT_WAPI
  2058. i4Status = mtk_cfg80211_testmode_set_key_ext(wiphy, data, len);
  2059. #endif
  2060. break;
  2061. case TESTMODE_CMD_ID_SUSPEND:
  2062. {
  2063. P_NL80211_DRIVER_SUSPEND_PARAMS prParams = (P_NL80211_DRIVER_SUSPEND_PARAMS) data;
  2064. if (prParams->suspend == 1) {
  2065. wlanHandleSystemSuspend();
  2066. if (prGlueInfo->prAdapter->fgIsP2PRegistered)
  2067. p2pHandleSystemSuspend();
  2068. i4Status = 0;
  2069. } else if (prParams->suspend == 0) {
  2070. wlanHandleSystemResume();
  2071. if (prGlueInfo->prAdapter->fgIsP2PRegistered)
  2072. p2pHandleSystemResume();
  2073. i4Status = 0;
  2074. }
  2075. break;
  2076. }
  2077. case TESTMODE_CMD_ID_STATISTICS:
  2078. i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo);
  2079. break;
  2080. case TESTMODE_CMD_ID_LINK_DETECT:
  2081. i4Status = mtk_cfg80211_testmode_get_link_detection(wiphy, data, len, prGlueInfo);
  2082. break;
  2083. case TESTMODE_CMD_ID_POORLINK:
  2084. i4Status = mtk_cfg80211_testmode_set_poorlink_param(wiphy, data, len, prGlueInfo);
  2085. break;
  2086. #if CFG_SUPPORT_HOTSPOT_2_0
  2087. case TESTMODE_CMD_ID_HS20:
  2088. if (mtk_cfg80211_testmode_hs20_cmd(wiphy, data, len))
  2089. fgIsValid = TRUE;
  2090. break;
  2091. #endif
  2092. default:
  2093. i4Status = -EINVAL;
  2094. break;
  2095. }
  2096. }
  2097. return i4Status;
  2098. }
  2099. int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
  2100. {
  2101. #define NL80211_TESTMODE_P2P_SCANDONE_INVALID 0
  2102. #define NL80211_TESTMODE_P2P_SCANDONE_STATUS 1
  2103. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  2104. INT_32 i4Status = -EINVAL, READY_TO_BEAM = 0;
  2105. /* P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; */
  2106. struct sk_buff *skb;
  2107. ASSERT(wiphy);
  2108. ASSERT(prGlueInfo);
  2109. skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(UINT_32));
  2110. READY_TO_BEAM =
  2111. (UINT_32) (prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.
  2112. fgIsGOInitialDone) &
  2113. (!prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest);
  2114. DBGLOG(QM, TRACE,
  2115. "NFC:GOInitialDone[%d] and P2PScanning[%d]\n",
  2116. prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone,
  2117. prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest);
  2118. if (!skb) {
  2119. DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus);
  2120. return -ENOMEM;
  2121. }
  2122. /*NLA_PUT_U8(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, 0);*/
  2123. {
  2124. unsigned char __tmp = 0;
  2125. if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, sizeof(unsigned char), &__tmp) < 0))
  2126. goto nla_put_failure;
  2127. }
  2128. /*NLA_PUT_U32(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, READY_TO_BEAM);*/
  2129. {
  2130. unsigned int __tmp = READY_TO_BEAM;
  2131. if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, sizeof(unsigned int), &__tmp) < 0))
  2132. goto nla_put_failure;
  2133. }
  2134. i4Status = cfg80211_testmode_reply(skb);
  2135. skb = NULL;
  2136. nla_put_failure:
  2137. if (skb != NULL)
  2138. kfree_skb(skb);
  2139. return i4Status;
  2140. }
  2141. #if CFG_AUTO_CHANNEL_SEL_SUPPORT
  2142. int
  2143. mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
  2144. {
  2145. #define MAXMUN_2_4G_CHA_NUM 14
  2146. #define CHN_DIRTY_WEIGHT_UPPERBOUND 4
  2147. BOOLEAN fgIsReady = FALSE, fgIsFistRecord = TRUE;
  2148. BOOLEAN fgIsPureAP, fgIsLteSafeChn = FALSE;
  2149. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  2150. UINT_8 ucIdx = 0, ucMax_24G_Chn_List = 11, ucDefaultIdx = 0, ucArrayIdx = 0;
  2151. UINT_16 u2APNumScore = 0, u2UpThreshold = 0, u2LowThreshold = 0, ucInnerIdx = 0;
  2152. INT_32 i4Status = -EINVAL;
  2153. UINT_32 u4BufLen, u4LteSafeChnBitMask_2_4G = 0;
  2154. UINT32 AcsChnReport[4];
  2155. /*RF_CHANNEL_INFO_T aucChannelList[MAXMUN_2_4G_CHA_NUM];*/
  2156. struct sk_buff *skb;
  2157. /*PARAM_GET_CHN_LOAD rQueryLTEChn;*/
  2158. P_PARAM_GET_CHN_LOAD prQueryLTEChn;
  2159. PARAM_PREFER_CHN_INFO rPreferChannels[2], ar2_4G_ChannelLoadingWeightScore[MAXMUN_2_4G_CHA_NUM];
  2160. P_PARAM_CHN_LOAD_INFO prChnLoad;
  2161. P_PARAM_GET_CHN_LOAD prGetChnLoad;
  2162. P_DOMAIN_INFO_ENTRY prDomainInfo;
  2163. /*
  2164. P_PARAM_GET_CHN_LOAD prParams = NULL;
  2165. */
  2166. ASSERT(wiphy);
  2167. ASSERT(prGlueInfo);
  2168. kalMemZero(rPreferChannels, sizeof(rPreferChannels));
  2169. fgIsPureAP = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode;
  2170. #if 0
  2171. if (data && len)
  2172. prParams = (P_NL80211_DRIVER_GET_LTE_PARAMS) data;
  2173. #endif
  2174. skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(AcsChnReport) + sizeof(UINT8) + 1);
  2175. if (!skb) {
  2176. DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus);
  2177. return -ENOMEM;
  2178. }
  2179. DBGLOG(P2P, INFO, "[Auto Channel]Get LTE Channels\n");
  2180. prQueryLTEChn = kalMemAlloc(sizeof(PARAM_GET_CHN_LOAD), VIR_MEM_TYPE);
  2181. if (prQueryLTEChn == NULL) {
  2182. DBGLOG(QM, TRACE, "alloc QueryLTEChn fail\n");
  2183. kalMemFree(skb, VIR_MEM_TYPE, sizeof(struct sk_buff));
  2184. return -ENOMEM;
  2185. }
  2186. kalMemZero(prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD));
  2187. /* Query LTE Safe Channels */
  2188. prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]
  2189. = 0xFFFFFFFF;
  2190. prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]
  2191. = 0xFFFFFFFF;
  2192. prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]
  2193. = 0xFFFFFFFF;
  2194. prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] =
  2195. 0xFFFFFFFF;
  2196. rStatus = kalIoctl(prGlueInfo, wlanoidQueryACSChannelList, prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD),
  2197. TRUE, FALSE, TRUE, TRUE, &u4BufLen);
  2198. #if 0
  2199. if (fgIsPureAP) {
  2200. AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = 0x20; /* Channel 6 */
  2201. } else
  2202. #endif
  2203. {
  2204. fgIsReady = prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit;
  2205. rPreferChannels[0].u2APNum = 0xFFFF;
  2206. rPreferChannels[1].u2APNum = 0xFFFF;
  2207. /* 4 In LTE Mode, Hotspot pick up channels from ch4. */
  2208. ucDefaultIdx = 0;
  2209. /*
  2210. if (fgIsPureAP) {
  2211. ucDefaultIdx=3; //SKIP LTE Channels 1~3
  2212. }
  2213. */
  2214. /* 4 Get the Maximun channel List in 2.4G Bands */
  2215. prDomainInfo = rlmDomainGetDomainInfo(prGlueInfo->prAdapter);
  2216. ASSERT(prDomainInfo);
  2217. /* 4 ToDo: Enable Step 2 only if we could get Country Code from framework */
  2218. /* 4 2. Get current domain channel list */
  2219. #if 0
  2220. rlmDomainGetChnlList(prGlueInfo->prAdapter,
  2221. BAND_2G4, MAXMUN_2_4G_CHA_NUM, &ucMax_24G_Chn_List, aucChannelList);
  2222. #endif
  2223. prGetChnLoad = (P_PARAM_GET_CHN_LOAD) &(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo);
  2224. for (ucIdx = 0; ucIdx < ucMax_24G_Chn_List; ucIdx++) {
  2225. DBGLOG(P2P, INFO,
  2226. "[Auto Channel] ch[%d]=%d\n", ucIdx,
  2227. prGetChnLoad->rEachChnLoad[ucIdx + ucInnerIdx].u2APNum);
  2228. }
  2229. /*Calculate Each Channel Direty Score */
  2230. for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) {
  2231. #if 1
  2232. u2APNumScore = prGetChnLoad->rEachChnLoad[ucIdx].u2APNum * CHN_DIRTY_WEIGHT_UPPERBOUND;
  2233. u2UpThreshold = u2LowThreshold = 3;
  2234. if (ucIdx < 3) {
  2235. u2UpThreshold = ucIdx;
  2236. u2LowThreshold = 3;
  2237. } else if (ucIdx >= (ucMax_24G_Chn_List - 3)) {
  2238. u2UpThreshold = 3;
  2239. u2LowThreshold = ucMax_24G_Chn_List - (ucIdx + 1);
  2240. }
  2241. /*Calculate Lower Channel Dirty Score */
  2242. for (ucInnerIdx = 0; ucInnerIdx < u2LowThreshold; ucInnerIdx++) {
  2243. ucArrayIdx = ucIdx + ucInnerIdx + 1;
  2244. if (ucArrayIdx < MAX_AUTO_CHAL_NUM) {
  2245. u2APNumScore +=
  2246. (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum *
  2247. (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx));
  2248. }
  2249. }
  2250. /*Calculate Upper Channel Dirty Score */
  2251. for (ucInnerIdx = 0; ucInnerIdx < u2UpThreshold; ucInnerIdx++) {
  2252. ucArrayIdx = ucIdx - ucInnerIdx - 1;
  2253. if (ucArrayIdx < MAX_AUTO_CHAL_NUM) {
  2254. u2APNumScore +=
  2255. (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum *
  2256. (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx));
  2257. }
  2258. }
  2259. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
  2260. DBGLOG(P2P, INFO, "[Auto Channel]chn=%d score=%d\n", ucIdx, u2APNumScore);
  2261. #else
  2262. if (ucIdx == 0) {
  2263. /* ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum =
  2264. (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum +
  2265. prGetChnLoad->rEachChnLoad[ucIdx+1].u2APNum*0.75); */
  2266. u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16)
  2267. ((3 *
  2268. (prGetChnLoad->
  2269. rEachChnLoad[ucIdx +
  2270. 1].
  2271. u2APNum +
  2272. prGetChnLoad->
  2273. rEachChnLoad[ucIdx +
  2274. 2].
  2275. u2APNum)) / 4)));
  2276. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
  2277. DBGLOG(P2P, INFO,
  2278. "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx,
  2279. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum,
  2280. prGetChnLoad->rEachChnLoad[ucIdx].u2APNum,
  2281. prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum));
  2282. }
  2283. if ((ucIdx > 0) && (ucIdx < (MAXMUN_2_4G_CHA_NUM - 1))) {
  2284. u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16)
  2285. ((3 *
  2286. (prGetChnLoad->
  2287. rEachChnLoad[ucIdx +
  2288. 1].
  2289. u2APNum +
  2290. prGetChnLoad->
  2291. rEachChnLoad[ucIdx -
  2292. 1].
  2293. u2APNum)) / 4)));
  2294. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
  2295. DBGLOG(P2P, INFO,
  2296. "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d+0.75*%d\n", ucIdx,
  2297. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum,
  2298. prGetChnLoad->rEachChnLoad[ucIdx].u2APNum,
  2299. prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum,
  2300. prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum));
  2301. }
  2302. if (ucIdx == (MAXMUN_2_4G_CHA_NUM - 1)) {
  2303. u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum +
  2304. ((UINT_16) ((3 * prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum) / 4)));
  2305. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
  2306. DBGLOG(P2P, INFO,
  2307. "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx,
  2308. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum,
  2309. prGetChnLoad->rEachChnLoad[ucIdx].u2APNum,
  2310. prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum));
  2311. }
  2312. #endif
  2313. }
  2314. u4LteSafeChnBitMask_2_4G =
  2315. prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1];
  2316. /*Find out the best channel */
  2317. for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) {
  2318. /* 4 Skip LTE Unsafe Channel */
  2319. fgIsLteSafeChn = ((u4LteSafeChnBitMask_2_4G & BIT(ucIdx + 1)) >> ucIdx);
  2320. if (!fgIsLteSafeChn)
  2321. continue;
  2322. prChnLoad =
  2323. (P_PARAM_CHN_LOAD_INFO) &(prGlueInfo->prAdapter->rWifiVar.
  2324. rChnLoadInfo.rEachChnLoad[ucIdx]);
  2325. if (rPreferChannels[0].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum) {
  2326. rPreferChannels[1].ucChannel = rPreferChannels[0].ucChannel;
  2327. rPreferChannels[1].u2APNum = rPreferChannels[0].u2APNum;
  2328. rPreferChannels[0].ucChannel = ucIdx;
  2329. rPreferChannels[0].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum;
  2330. } else {
  2331. if (rPreferChannels[1].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum
  2332. || fgIsFistRecord == 1) {
  2333. fgIsFistRecord = FALSE;
  2334. rPreferChannels[1].ucChannel = ucIdx;
  2335. rPreferChannels[1].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum;
  2336. }
  2337. }
  2338. }
  2339. /* AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1] =
  2340. BITS((rQueryLTEChn.rLteSafeChnList.ucChannelLow-1),(rQueryLTEChn.rLteSafeChnList.ucChannelHigh-1)); */
  2341. AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = fgIsReady ? BIT(31) : 0;
  2342. AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] |= BIT(rPreferChannels[0].ucChannel);
  2343. }
  2344. /* ToDo: Support 5G Channel Selection */
  2345. AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] = 0x11223344;
  2346. AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] = 0x55667788;
  2347. AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = 0x99AABBCC;
  2348. /*NLA_PUT_U8(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, 0);*/
  2349. {
  2350. unsigned char __tmp = 0;
  2351. if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, sizeof(unsigned char), &__tmp) < 0))
  2352. goto nla_put_failure;
  2353. }
  2354. /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1,
  2355. AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]);*/
  2356. {
  2357. unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1];
  2358. if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1,
  2359. sizeof(unsigned int), &__tmp) < 0))
  2360. goto nla_put_failure;
  2361. }
  2362. /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34,
  2363. AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]);*/
  2364. {
  2365. unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1];
  2366. if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34,
  2367. sizeof(unsigned int), &__tmp) < 0))
  2368. goto nla_put_failure;
  2369. }
  2370. /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149,
  2371. AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]);*/
  2372. {
  2373. unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1];
  2374. if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149,
  2375. sizeof(unsigned int), &__tmp) < 0))
  2376. goto nla_put_failure;
  2377. }
  2378. /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184,
  2379. AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]);*/
  2380. {
  2381. unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1];
  2382. if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184,
  2383. sizeof(unsigned int), &__tmp) < 0))
  2384. goto nla_put_failure;
  2385. }
  2386. DBGLOG(P2P, INFO,
  2387. "[Auto Channel]Relpy AcsChanInfo[%x:%x:%x:%x]\n", AcsChnReport[0], AcsChnReport[1], AcsChnReport[2],
  2388. AcsChnReport[3]);
  2389. i4Status = cfg80211_testmode_reply(skb);
  2390. /*need confirm cfg80211_testmode_reply will free skb*/
  2391. skb = NULL;
  2392. /*kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD));*/
  2393. nla_put_failure:
  2394. kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD));
  2395. if (skb != NULL)
  2396. kfree_skb(skb);
  2397. return i4Status;
  2398. }
  2399. #endif
  2400. #endif
  2401. /*----------------------------------------------------------------------------*/
  2402. /*!
  2403. * @brief cfg80211 suspend callback, will be invoked in wiphy_suspend
  2404. *
  2405. * @param wiphy: pointer to wiphy
  2406. * wow: pointer to cfg80211_wowlan
  2407. *
  2408. * @retval 0: successful
  2409. * others: failure
  2410. */
  2411. /*----------------------------------------------------------------------------*/
  2412. int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
  2413. {
  2414. P_GLUE_INFO_T prGlueInfo = NULL;
  2415. if (kalHaltTryLock())
  2416. return 0;
  2417. if (kalIsHalted() || !wiphy)
  2418. goto end;
  2419. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  2420. set_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prGlueInfo->prAdapter->ulSuspendFlag);
  2421. set_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prGlueInfo->prAdapter->ulSuspendFlag);
  2422. end:
  2423. kalHaltUnlock();
  2424. return 0;
  2425. }
  2426. /*----------------------------------------------------------------------------*/
  2427. /*!
  2428. * @brief cfg80211 resume callback, will be invoked in wiphy_resume.
  2429. *
  2430. * @param wiphy: pointer to wiphy
  2431. *
  2432. * @retval 0: successful
  2433. * others: failure
  2434. */
  2435. /*----------------------------------------------------------------------------*/
  2436. int mtk_cfg80211_resume(struct wiphy *wiphy)
  2437. {
  2438. P_GLUE_INFO_T prGlueInfo = NULL;
  2439. P_BSS_DESC_T *pprBssDesc = NULL;
  2440. P_ADAPTER_T prAdapter = NULL;
  2441. UINT_8 i = 0;
  2442. if (kalHaltTryLock())
  2443. return 0;
  2444. if (kalIsHalted() || !wiphy)
  2445. goto end;
  2446. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  2447. prAdapter = prGlueInfo->prAdapter;
  2448. clear_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag);
  2449. pprBssDesc = &prAdapter->rWifiVar.rScanInfo.rNloParam.aprPendingBssDescToInd[0];
  2450. for (; i < SCN_SSID_MATCH_MAX_NUM; i++) {
  2451. if (pprBssDesc[i] == NULL)
  2452. break;
  2453. if (pprBssDesc[i]->u2RawLength == 0)
  2454. continue;
  2455. kalIndicateBssInfo(prGlueInfo,
  2456. (PUINT_8) pprBssDesc[i]->aucRawBuf,
  2457. pprBssDesc[i]->u2RawLength,
  2458. pprBssDesc[i]->ucChannelNum,
  2459. RCPI_TO_dBm(pprBssDesc[i]->ucRCPI));
  2460. }
  2461. DBGLOG(SCN, INFO, "pending %d sched scan results\n", i);
  2462. if (i > 0)
  2463. kalMemZero(&pprBssDesc[0], i * sizeof(P_BSS_DESC_T));
  2464. end:
  2465. kalHaltUnlock();
  2466. return 0;
  2467. }