gl_cfg80211.c 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779
  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. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  14. ** correct calls to wlanoidSetBssid()
  15. **
  16. ** 08 28 2013 cp.wu
  17. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  18. ** fix typo
  19. **
  20. ** 08 28 2013 cp.wu
  21. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  22. ** add more protection in case cfg80211_sched_scan_request->match_sets[] == NULL
  23. **
  24. ** 08 28 2013 cp.wu
  25. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  26. ** fix for KE issues because referring to wrong data member
  27. **
  28. ** 08 23 2013 wh.su
  29. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  30. ** Add GTK re-key driver handle function
  31. **
  32. ** 08 19 2013 cp.wu
  33. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  34. ** use kalMemFree() instead of kfree()
  35. **
  36. ** 08 19 2013 cp.wu
  37. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  38. ** change to use dynamic-allocated memory for schedule scan to avoid stack overflow
  39. **
  40. ** 08 15 2013 cp.wu
  41. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  42. ** enlarge match_ssid_num to 16 for PNO support
  43. **
  44. ** 08 12 2013 cp.wu
  45. ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
  46. ** 1. fix on cancel_remain_on_channel() interface
  47. ** 2. queue initialization for another linux kal API
  48. **
  49. ** 08 09 2013 cp.wu
  50. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  51. ** 1. integrate scheduled scan functionality
  52. ** 2. condition compilation for linux-3.4 & linux-3.8 compatibility
  53. ** 3. correct CMD queue access to reduce lock scope
  54. **
  55. ** 07 30 2013 cp.wu
  56. ** [BORA00002725] [MT6630][Wi-Fi] Add MGMT TX/RX support for Linux port
  57. ** add kernel version awareness for building success between different version of linux kernel
  58. **
  59. ** 07 29 2013 cp.wu
  60. ** [BORA00002725] [MT6630][Wi-Fi] Add MGMT TX/RX support for Linux port
  61. ** Preparation for porting remain_on_channel support
  62. **
  63. ** 07 23 2013 wh.su
  64. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  65. ** Sync the latest jb2.mp 11w code as draft version
  66. ** Not the CM bit for avoid wapi 1x drop at re-key
  67. **
  68. ** 07 05 2013 wh.su
  69. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  70. ** Fix to let the wpa-psk ok
  71. **
  72. ** 07 02 2013 wh.su
  73. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  74. ** Refine security BMC wlan index assign
  75. ** Fix some compiling warning
  76. **
  77. ** 07 01 2013 wh.su
  78. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  79. ** Add some debug code, fixed some compiling warning
  80. **
  81. ** 03 20 2013 wh.su
  82. ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
  83. ** Add the security code for wlan table assign operation
  84. **
  85. ** 11 15 2012 cp.wu
  86. ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
  87. ** sync..
  88. **
  89. ** 09 17 2012 cm.chang
  90. ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
  91. ** Duplicate source from MT6620 v2.3 driver branch
  92. ** (Davinci label: MT6620_WIFI_Driver_V2_3_120913_1942_As_MT6630_Base)
  93. **
  94. ** 08 30 2012 cp.wu
  95. ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
  96. ** check pending scan only by the pointer instead of fgIsRegistered flag.
  97. **
  98. ** 08 24 2012 cp.wu
  99. ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
  100. ** .
  101. **
  102. ** 08 24 2012 cp.wu
  103. ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
  104. ** cfg80211 support merge back from ALPS.JB to DaVinci - MT6620 Driver v2.3 branch.
  105. *
  106. **
  107. */
  108. /*******************************************************************************
  109. * C O M P I L E R F L A G S
  110. ********************************************************************************
  111. */
  112. /*******************************************************************************
  113. * E X T E R N A L R E F E R E N C E S
  114. ********************************************************************************
  115. */
  116. #include "gl_os.h"
  117. #include "debug.h"
  118. #include "wlan_lib.h"
  119. #include "gl_wext.h"
  120. #include "precomp.h"
  121. #include <linux/can/netlink.h>
  122. #include <net/netlink.h>
  123. #include <net/cfg80211.h>
  124. #include "gl_cfg80211.h"
  125. /*******************************************************************************
  126. * C O N S T A N T S
  127. ********************************************************************************
  128. */
  129. /*******************************************************************************
  130. * D A T A T Y P E S
  131. ********************************************************************************
  132. */
  133. /*******************************************************************************
  134. * P U B L I C D A T A
  135. ********************************************************************************
  136. */
  137. /*******************************************************************************
  138. * P R I V A T E D A T A
  139. ********************************************************************************
  140. */
  141. /*******************************************************************************
  142. * M A C R O S
  143. ********************************************************************************
  144. */
  145. /*******************************************************************************
  146. * F U N C T I O N D E C L A R A T I O N S
  147. ********************************************************************************
  148. */
  149. /*******************************************************************************
  150. * F U N C T I O N S
  151. ********************************************************************************
  152. */
  153. /*----------------------------------------------------------------------------*/
  154. /*!
  155. * @brief This routine is responsible for change STA type between
  156. * 1. Infrastructure Client (Non-AP STA)
  157. * 2. Ad-Hoc IBSS
  158. *
  159. * @param
  160. *
  161. * @retval 0: successful
  162. * others: failure
  163. */
  164. /*----------------------------------------------------------------------------*/
  165. int
  166. mtk_cfg80211_change_iface(struct wiphy *wiphy,
  167. struct net_device *ndev, enum nl80211_iftype type, u32 *flags, struct vif_params *params)
  168. {
  169. P_GLUE_INFO_T prGlueInfo = NULL;
  170. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  171. ENUM_PARAM_OP_MODE_T eOpMode;
  172. UINT_32 u4BufLen;
  173. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  174. ASSERT(prGlueInfo);
  175. if (type == NL80211_IFTYPE_STATION)
  176. eOpMode = NET_TYPE_INFRA;
  177. else if (type == NL80211_IFTYPE_ADHOC)
  178. eOpMode = NET_TYPE_IBSS;
  179. else
  180. return -EINVAL;
  181. rStatus = kalIoctl(prGlueInfo,
  182. wlanoidSetInfrastructureMode, &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, &u4BufLen);
  183. if (rStatus != WLAN_STATUS_SUCCESS) {
  184. DBGLOG(REQ, WARN,
  185. "set infrastructure mode error:%lx\n", rStatus);
  186. }
  187. /* reset wpa info */
  188. prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
  189. prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
  190. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
  191. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
  192. prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
  193. #if CFG_SUPPORT_802_11W
  194. prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
  195. #endif
  196. return 0;
  197. }
  198. /*----------------------------------------------------------------------------*/
  199. /*!
  200. * @brief This routine is responsible for adding key
  201. *
  202. * @param
  203. *
  204. * @retval 0: successful
  205. * others: failure
  206. */
  207. /*----------------------------------------------------------------------------*/
  208. int
  209. mtk_cfg80211_add_key(struct wiphy *wiphy,
  210. struct net_device *ndev,
  211. u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params)
  212. {
  213. PARAM_KEY_T rKey;
  214. P_GLUE_INFO_T prGlueInfo = NULL;
  215. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  216. INT_32 i4Rslt = -EINVAL;
  217. UINT_32 u4BufLen = 0;
  218. UINT_8 tmp1[8], tmp2[8];
  219. const UINT_8 aucBCAddr[] = BC_MAC_ADDR;
  220. const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR;
  221. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  222. ASSERT(prGlueInfo);
  223. #if DBG
  224. DBGLOG(RSN, TRACE, "mtk_cfg80211_add_key\n");
  225. if (mac_addr) {
  226. DBGLOG(RSN, TRACE,
  227. "keyIdx = %d pairwise = %d mac = " MACSTR "\n", key_index, pairwise, MAC2STR(mac_addr));
  228. } else {
  229. DBGLOG(RSN, TRACE, "keyIdx = %d pairwise = %d null mac\n", key_index, pairwise);
  230. }
  231. DBGLOG(RSN, TRACE, "Cipher = %x\n", params->cipher);
  232. DBGLOG_MEM8(RSN, TRACE, params->key, params->key_len);
  233. #endif
  234. kalMemZero(&rKey, sizeof(PARAM_KEY_T));
  235. rKey.u4KeyIndex = key_index;
  236. if (mac_addr) {
  237. if (EQUAL_MAC_ADDR(mac_addr, aucZeroMacAddr))
  238. COPY_MAC_ADDR(rKey.arBSSID, aucBCAddr);
  239. else
  240. COPY_MAC_ADDR(rKey.arBSSID, mac_addr);
  241. if (pairwise) {
  242. /* if (!((rKey.arBSSID[0] */
  243. /* & rKey.arBSSID[1] */
  244. /* & rKey.arBSSID[2] */
  245. /* & rKey.arBSSID[3] */
  246. /* & rKey.arBSSID[4] */
  247. /* & rKey.arBSSID[5]) == 0xFF)) { */
  248. /* rKey.u4KeyIndex |= BIT(31); */
  249. /* } */
  250. rKey.u4KeyIndex |= BIT(31);
  251. rKey.u4KeyIndex |= BIT(30);
  252. }
  253. } else { /* Group key */
  254. COPY_MAC_ADDR(rKey.arBSSID, aucBCAddr);
  255. }
  256. if (params->key) {
  257. kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len);
  258. if (params->key_len == 32) {
  259. kalMemCopy(tmp1, &params->key[16], 8);
  260. kalMemCopy(tmp2, &params->key[24], 8);
  261. kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8);
  262. kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8);
  263. }
  264. }
  265. rKey.u4KeyLength = params->key_len;
  266. rKey.u4Length = ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength;
  267. rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, &u4BufLen);
  268. if (rStatus == WLAN_STATUS_SUCCESS)
  269. i4Rslt = 0;
  270. return i4Rslt;
  271. }
  272. /*----------------------------------------------------------------------------*/
  273. /*!
  274. * @brief This routine is responsible for getting key for specified STA
  275. *
  276. * @param
  277. *
  278. * @retval 0: successful
  279. * others: failure
  280. */
  281. /*----------------------------------------------------------------------------*/
  282. int
  283. mtk_cfg80211_get_key(struct wiphy *wiphy,
  284. struct net_device *ndev,
  285. u8 key_index,
  286. bool pairwise,
  287. const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *))
  288. {
  289. P_GLUE_INFO_T prGlueInfo = NULL;
  290. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  291. ASSERT(prGlueInfo);
  292. #if 1
  293. DBGLOG(INIT, INFO, "--> %s()\n", __func__);
  294. #endif
  295. /* not implemented */
  296. return -EINVAL;
  297. }
  298. /*----------------------------------------------------------------------------*/
  299. /*!
  300. * @brief This routine is responsible for removing key for specified STA
  301. *
  302. * @param
  303. *
  304. * @retval 0: successful
  305. * others: failure
  306. */
  307. /*----------------------------------------------------------------------------*/
  308. int mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr)
  309. {
  310. P_GLUE_INFO_T prGlueInfo = NULL;
  311. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  312. PARAM_REMOVE_KEY_T rRemoveKey;
  313. UINT_32 u4BufLen = 0;
  314. INT_32 i4Rslt = -EINVAL;
  315. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  316. ASSERT(prGlueInfo);
  317. #if DBG
  318. DBGLOG(RSN, TRACE, "mtk_cfg80211_del_key\n");
  319. if (mac_addr) {
  320. DBGLOG(RSN, TRACE,
  321. "keyIdx = %d pairwise = %d mac = " MACSTR "\n", key_index, pairwise, MAC2STR(mac_addr));
  322. } else {
  323. DBGLOG(RSN, TRACE, "keyIdx = %d pairwise = %d null mac\n", key_index, pairwise);
  324. }
  325. #endif
  326. kalMemZero(&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T));
  327. if (mac_addr)
  328. COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr);
  329. rRemoveKey.u4KeyIndex = key_index;
  330. rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T);
  331. rStatus = kalIoctl(prGlueInfo,
  332. wlanoidSetRemoveKey, &rRemoveKey, rRemoveKey.u4Length, FALSE, FALSE, TRUE, &u4BufLen);
  333. if (rStatus != WLAN_STATUS_SUCCESS) {
  334. /* ToDo:: DBGLOG */
  335. DBGLOG(REQ, WARN, "remove key error:%lx\n", rStatus);
  336. } else
  337. i4Rslt = 0;
  338. return i4Rslt;
  339. }
  340. /*----------------------------------------------------------------------------*/
  341. /*!
  342. * @brief This routine is responsible for setting default key on an interface
  343. *
  344. * @param
  345. *
  346. * @retval 0: successful
  347. * others: failure
  348. */
  349. /*----------------------------------------------------------------------------*/
  350. int
  351. mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast)
  352. {
  353. P_GLUE_INFO_T prGlueInfo = NULL;
  354. PARAM_DEFAULT_KEY_T rDefaultKey;
  355. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  356. INT_32 i4Rst = -EINVAL;
  357. UINT_32 u4BufLen = 0;
  358. BOOLEAN fgDef = FALSE, fgMgtDef = FALSE;
  359. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  360. ASSERT(prGlueInfo);
  361. #if DBG
  362. DBGLOG(RSN, TRACE, "mtk_cfg80211_set_default_key\n");
  363. DBGLOG(RSN, TRACE, "keyIdx = %d unicast = %d multicast = %d\n", key_index, unicast, multicast);
  364. #endif
  365. rDefaultKey.ucKeyID = key_index;
  366. rDefaultKey.ucUnicast = unicast;
  367. rDefaultKey.ucMulticast = multicast;
  368. if (rDefaultKey.ucUnicast && !rDefaultKey.ucMulticast)
  369. return WLAN_STATUS_SUCCESS;
  370. if (rDefaultKey.ucUnicast && rDefaultKey.ucMulticast)
  371. fgDef = TRUE;
  372. if (!rDefaultKey.ucUnicast && rDefaultKey.ucMulticast)
  373. fgMgtDef = TRUE;
  374. rStatus = kalIoctl(prGlueInfo,
  375. wlanoidSetDefaultKey,
  376. &rDefaultKey, sizeof(PARAM_DEFAULT_KEY_T), FALSE, FALSE, TRUE, &u4BufLen);
  377. if (rStatus == WLAN_STATUS_SUCCESS)
  378. i4Rst = 0;
  379. return i4Rst;
  380. }
  381. /*----------------------------------------------------------------------------*/
  382. /*!
  383. * @brief This routine is responsible for getting station information such as RSSI
  384. *
  385. * @param
  386. *
  387. * @retval 0: successful
  388. * others: failure
  389. */
  390. /*----------------------------------------------------------------------------*/
  391. int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo)
  392. {
  393. P_GLUE_INFO_T prGlueInfo = NULL;
  394. WLAN_STATUS rStatus;
  395. PARAM_MAC_ADDRESS arBssid;
  396. UINT_32 u4BufLen, u4Rate;
  397. INT_32 i4Rssi;
  398. PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics;
  399. UINT_32 u4TotalError;
  400. struct net_device_stats *prDevStats;
  401. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  402. ASSERT(prGlueInfo);
  403. kalMemZero(arBssid, MAC_ADDR_LEN);
  404. wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen);
  405. /* 1. check BSSID */
  406. if (UNEQUAL_MAC_ADDR(arBssid, mac)) {
  407. /* wrong MAC address */
  408. DBGLOG(REQ, WARN,
  409. "incorrect BSSID: [" MACSTR "] currently connected BSSID[" MACSTR "]\n",
  410. MAC2STR(mac), MAC2STR(arBssid));
  411. return -ENOENT;
  412. }
  413. /* 2. fill TX rate */
  414. if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) {
  415. /* not connected */
  416. DBGLOG(REQ, WARN, "not yet connected\n");
  417. } else {
  418. rStatus = kalIoctl(prGlueInfo,
  419. wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, &u4BufLen);
  420. sinfo->filled |= STATION_INFO_TX_BITRATE;
  421. if ((rStatus != WLAN_STATUS_SUCCESS) || (u4Rate == 0)) {
  422. /*
  423. DBGLOG(REQ, WARN, "unable to retrieve link speed\n"));
  424. */
  425. DBGLOG(REQ, WARN, "last link speed\n");
  426. sinfo->txrate.legacy = prGlueInfo->u4LinkSpeedCache;
  427. } else {
  428. /*
  429. sinfo->filled |= STATION_INFO_TX_BITRATE;
  430. */
  431. sinfo->txrate.legacy = u4Rate / 1000; /* convert from 100bps to 100kbps */
  432. prGlueInfo->u4LinkSpeedCache = u4Rate / 1000;
  433. }
  434. }
  435. /* 3. fill RSSI */
  436. if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) {
  437. /* not connected */
  438. DBGLOG(REQ, WARN, "not yet connected\n");
  439. } else {
  440. rStatus = kalIoctl(prGlueInfo,
  441. wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, FALSE, FALSE, &u4BufLen);
  442. sinfo->filled |= STATION_INFO_SIGNAL;
  443. if ((rStatus != WLAN_STATUS_SUCCESS) || (i4Rssi == PARAM_WHQL_RSSI_MIN_DBM)
  444. || (i4Rssi == PARAM_WHQL_RSSI_MAX_DBM)) {
  445. DBGLOG(REQ, WARN, "last rssi\n");
  446. sinfo->signal = prGlueInfo->i4RssiCache;
  447. } else {
  448. sinfo->signal = i4Rssi; /* dBm */
  449. prGlueInfo->i4RssiCache = i4Rssi;
  450. }
  451. }
  452. /* Get statistics from net_dev */
  453. prDevStats = (struct net_device_stats *)kalGetStats(ndev);
  454. if (prDevStats) {
  455. /* 4. fill RX_PACKETS */
  456. sinfo->filled |= STATION_INFO_RX_PACKETS;
  457. sinfo->rx_packets = prDevStats->rx_packets;
  458. /* 5. fill TX_PACKETS */
  459. sinfo->filled |= STATION_INFO_TX_PACKETS;
  460. sinfo->tx_packets = prDevStats->tx_packets;
  461. /* 6. fill TX_FAILED */
  462. kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics));
  463. COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, arBssid);
  464. rQueryStaStatistics.ucReadClear = TRUE;
  465. rStatus = kalIoctl(prGlueInfo,
  466. wlanoidQueryStaStatistics,
  467. &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, &u4BufLen);
  468. if (rStatus != WLAN_STATUS_SUCCESS) {
  469. DBGLOG(REQ, WARN, "unable to retrieve link speed\n");
  470. } else {
  471. DBGLOG(REQ, INFO, "BSSID: [" MACSTR "] TxFailCount %d LifeTimeOut %d\n",
  472. MAC2STR(arBssid), rQueryStaStatistics.u4TxFailCount,
  473. rQueryStaStatistics.u4TxLifeTimeoutCount);
  474. u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount;
  475. prDevStats->tx_errors += u4TotalError;
  476. }
  477. sinfo->filled |= STATION_INFO_TX_FAILED;
  478. sinfo->tx_failed = prDevStats->tx_errors;
  479. }
  480. return 0;
  481. }
  482. /*----------------------------------------------------------------------------*/
  483. /*!
  484. * @brief This routine is responsible for getting statistics for Link layer statistics
  485. *
  486. * @param
  487. *
  488. * @retval 0: successful
  489. * others: failure
  490. */
  491. /*------------------------------------------------------------------------*/
  492. int mtk_cfg80211_get_link_statistics(struct wiphy *wiphy, struct net_device *ndev, u8 *mac, struct station_info *sinfo)
  493. {
  494. P_GLUE_INFO_T prGlueInfo = NULL;
  495. WLAN_STATUS rStatus;
  496. PARAM_MAC_ADDRESS arBssid;
  497. UINT_32 u4BufLen;
  498. INT_32 i4Rssi;
  499. PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics;
  500. PARAM_GET_BSS_STATISTICS rQueryBssStatistics;
  501. struct net_device_stats *prDevStats;
  502. P_NETDEV_PRIVATE_GLUE_INFO prNetDevPrivate = (P_NETDEV_PRIVATE_GLUE_INFO) NULL;
  503. UINT_8 ucBssIndex;
  504. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  505. ASSERT(prGlueInfo);
  506. kalMemZero(arBssid, MAC_ADDR_LEN);
  507. wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen);
  508. /* 1. check BSSID */
  509. if (UNEQUAL_MAC_ADDR(arBssid, mac)) {
  510. /* wrong MAC address */
  511. DBGLOG(REQ, WARN,
  512. "incorrect BSSID: [" MACSTR "] currently connected BSSID[" MACSTR "]\n",
  513. MAC2STR(mac),
  514. MAC2STR(arBssid));
  515. return -ENOENT;
  516. }
  517. /* 2. fill RSSI */
  518. if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) {
  519. /* not connected */
  520. DBGLOG(REQ, WARN, "not yet connected\n");
  521. } else {
  522. rStatus = kalIoctl(prGlueInfo,
  523. wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, FALSE, FALSE, &u4BufLen);
  524. if (rStatus != WLAN_STATUS_SUCCESS)
  525. DBGLOG(REQ, WARN, "unable to retrieve rssi\n");
  526. }
  527. /* Get statistics from net_dev */
  528. prDevStats = (struct net_device_stats *)kalGetStats(ndev);
  529. /*3. get link layer statistics from Driver and FW */
  530. if (prDevStats) {
  531. /* 3.1 get per-STA link statistics */
  532. kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics));
  533. COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, arBssid);
  534. rQueryStaStatistics.ucLlsReadClear = FALSE; /* dont clear for get BSS statistic */
  535. rStatus = kalIoctl(prGlueInfo,
  536. wlanoidQueryStaStatistics,
  537. &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, &u4BufLen);
  538. if (rStatus != WLAN_STATUS_SUCCESS)
  539. DBGLOG(REQ, WARN, "unable to retrieve per-STA link statistics\n");
  540. /*3.2 get per-BSS link statistics */
  541. if (rStatus == WLAN_STATUS_SUCCESS) {
  542. /* get Bss Index from ndev */
  543. prNetDevPrivate = (P_NETDEV_PRIVATE_GLUE_INFO) netdev_priv(ndev);
  544. ASSERT(prNetDevPrivate->prGlueInfo == prGlueInfo);
  545. ucBssIndex = prNetDevPrivate->ucBssIdx;
  546. kalMemZero(&rQueryBssStatistics, sizeof(rQueryBssStatistics));
  547. rQueryBssStatistics.ucBssIndex = ucBssIndex;
  548. rStatus = kalIoctl(prGlueInfo,
  549. wlanoidQueryBssStatistics,
  550. &rQueryBssStatistics,
  551. sizeof(rQueryBssStatistics), TRUE, FALSE, TRUE, &u4BufLen);
  552. } else {
  553. DBGLOG(REQ, WARN, "unable to retrieve per-BSS link statistics\n");
  554. }
  555. }
  556. return 0;
  557. }
  558. /*----------------------------------------------------------------------------*/
  559. /*!
  560. * @brief This routine is responsible for requesting to do a scan
  561. *
  562. * @param
  563. *
  564. * @retval 0: successful
  565. * others: failure
  566. */
  567. /*----------------------------------------------------------------------------*/
  568. int mtk_cfg80211_scan(struct wiphy *wiphy,
  569. struct cfg80211_scan_request *request)
  570. {
  571. P_GLUE_INFO_T prGlueInfo = NULL;
  572. WLAN_STATUS rStatus;
  573. UINT_32 i, u4BufLen;
  574. PARAM_SCAN_REQUEST_ADV_T rScanRequest;
  575. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  576. ASSERT(prGlueInfo);
  577. /* check if there is any pending scan/sched_scan not yet finished */
  578. if (prGlueInfo->prScanRequest != NULL)
  579. return -EBUSY;
  580. if (request->n_ssids == 0) {
  581. rScanRequest.u4SsidNum = 0;
  582. } else if (request->n_ssids <= SCN_SSID_MAX_NUM) {
  583. rScanRequest.u4SsidNum = request->n_ssids;
  584. for (i = 0; i < request->n_ssids; i++) {
  585. COPY_SSID(rScanRequest.rSsid[i].aucSsid,
  586. rScanRequest.rSsid[i].u4SsidLen, request->ssids[i].ssid, request->ssids[i].ssid_len);
  587. }
  588. } else {
  589. return -EINVAL;
  590. }
  591. rScanRequest.u4IELength = request->ie_len;
  592. if (request->ie_len > 0)
  593. rScanRequest.pucIE = (PUINT_8) (request->ie);
  594. rStatus = kalIoctl(prGlueInfo,
  595. wlanoidSetBssidListScanAdv,
  596. &rScanRequest, sizeof(PARAM_SCAN_REQUEST_ADV_T), FALSE, FALSE, FALSE, &u4BufLen);
  597. if (rStatus != WLAN_STATUS_SUCCESS) {
  598. DBGLOG(REQ, WARN, "scan error:%lx\n", rStatus);
  599. return -EINVAL;
  600. }
  601. prGlueInfo->prScanRequest = request;
  602. return 0;
  603. }
  604. static UINT_8 wepBuf[48];
  605. /*----------------------------------------------------------------------------*/
  606. /*!
  607. * @brief This routine is responsible for requesting to connect to
  608. * the ESS with the specified parameters
  609. *
  610. * @param
  611. *
  612. * @retval 0: successful
  613. * others: failure
  614. */
  615. /*----------------------------------------------------------------------------*/
  616. int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme)
  617. {
  618. P_GLUE_INFO_T prGlueInfo = NULL;
  619. WLAN_STATUS rStatus;
  620. UINT_32 u4BufLen;
  621. ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
  622. ENUM_PARAM_AUTH_MODE_T eAuthMode;
  623. UINT_32 cipher;
  624. PARAM_CONNECT_T rNewSsid;
  625. BOOLEAN fgCarryWPSIE = FALSE;
  626. ENUM_PARAM_OP_MODE_T eOpMode;
  627. UINT_32 i, u4AkmSuite = 0;
  628. P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry;
  629. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  630. ASSERT(prGlueInfo);
  631. if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH)
  632. eOpMode = NET_TYPE_AUTO_SWITCH;
  633. else
  634. eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode;
  635. rStatus = kalIoctl(prGlueInfo,
  636. wlanoidSetInfrastructureMode, &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, &u4BufLen);
  637. if (rStatus != WLAN_STATUS_SUCCESS) {
  638. DBGLOG(REQ, ERROR, "wlanoidSetInfrastructureMode fail 0x%lx\n", rStatus);
  639. return -EFAULT;
  640. }
  641. /* after set operation mode, key table are cleared */
  642. /* reset wpa info */
  643. prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
  644. prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
  645. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
  646. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
  647. prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
  648. #if CFG_SUPPORT_802_11W
  649. prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
  650. switch (sme->mfp) {
  651. case NL80211_MFP_NO:
  652. prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
  653. break;
  654. case NL80211_MFP_REQUIRED:
  655. prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_REQUIRED;
  656. break;
  657. default:
  658. prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
  659. break;
  660. }
  661. /* DBGLOG(SCN, INFO, ("MFP=%d\n", prGlueInfo->rWpaInfo.u4Mfp)); */
  662. #endif
  663. if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
  664. prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA;
  665. else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
  666. prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2;
  667. else
  668. prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
  669. switch (sme->auth_type) {
  670. case NL80211_AUTHTYPE_OPEN_SYSTEM:
  671. prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
  672. break;
  673. case NL80211_AUTHTYPE_SHARED_KEY:
  674. prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY;
  675. break;
  676. default:
  677. prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY;
  678. break;
  679. }
  680. if (sme->crypto.n_ciphers_pairwise) {
  681. /* DBGLOG(SCN, INFO, ("[wlan] cipher pairwise (%x)\n", sme->crypto.ciphers_pairwise[0])); */
  682. prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] =
  683. sme->crypto.ciphers_pairwise[0];
  684. switch (sme->crypto.ciphers_pairwise[0]) {
  685. case WLAN_CIPHER_SUITE_WEP40:
  686. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40;
  687. break;
  688. case WLAN_CIPHER_SUITE_WEP104:
  689. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104;
  690. break;
  691. case WLAN_CIPHER_SUITE_TKIP:
  692. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP;
  693. break;
  694. case WLAN_CIPHER_SUITE_CCMP:
  695. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
  696. break;
  697. case WLAN_CIPHER_SUITE_AES_CMAC:
  698. prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
  699. break;
  700. default:
  701. DBGLOG(REQ, WARN, "invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]);
  702. return -EINVAL;
  703. }
  704. }
  705. if (sme->crypto.cipher_group) {
  706. prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group;
  707. switch (sme->crypto.cipher_group) {
  708. case WLAN_CIPHER_SUITE_WEP40:
  709. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40;
  710. break;
  711. case WLAN_CIPHER_SUITE_WEP104:
  712. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104;
  713. break;
  714. case WLAN_CIPHER_SUITE_TKIP:
  715. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP;
  716. break;
  717. case WLAN_CIPHER_SUITE_CCMP:
  718. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP;
  719. break;
  720. case WLAN_CIPHER_SUITE_AES_CMAC:
  721. prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP;
  722. break;
  723. default:
  724. DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group);
  725. return -EINVAL;
  726. }
  727. }
  728. /* DBGLOG(SCN, INFO, ("akm_suites=%x\n", sme->crypto.akm_suites[0])); */
  729. if (sme->crypto.n_akm_suites) {
  730. prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] =
  731. sme->crypto.akm_suites[0];
  732. if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) {
  733. switch (sme->crypto.akm_suites[0]) {
  734. case WLAN_AKM_SUITE_8021X:
  735. eAuthMode = AUTH_MODE_WPA;
  736. u4AkmSuite = WPA_AKM_SUITE_802_1X;
  737. break;
  738. case WLAN_AKM_SUITE_PSK:
  739. eAuthMode = AUTH_MODE_WPA_PSK;
  740. u4AkmSuite = WPA_AKM_SUITE_PSK;
  741. break;
  742. default:
  743. DBGLOG(REQ, WARN, "invalid auth mode (%d)\n", eAuthMode);
  744. return -EINVAL;
  745. }
  746. } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) {
  747. switch (sme->crypto.akm_suites[0]) {
  748. case WLAN_AKM_SUITE_8021X:
  749. eAuthMode = AUTH_MODE_WPA2;
  750. u4AkmSuite = RSN_AKM_SUITE_802_1X;
  751. break;
  752. case WLAN_AKM_SUITE_PSK:
  753. eAuthMode = AUTH_MODE_WPA2_PSK;
  754. u4AkmSuite = RSN_AKM_SUITE_PSK;
  755. break;
  756. #if CFG_SUPPORT_802_11W
  757. /* Notice:: Need kernel patch!! */
  758. case WLAN_AKM_SUITE_8021X_SHA256:
  759. eAuthMode = AUTH_MODE_WPA2;
  760. u4AkmSuite = RSN_AKM_SUITE_802_1X_SHA256;
  761. break;
  762. case WLAN_AKM_SUITE_PSK_SHA256:
  763. eAuthMode = AUTH_MODE_WPA2_PSK;
  764. u4AkmSuite = RSN_AKM_SUITE_PSK_SHA256;
  765. break;
  766. #endif
  767. default:
  768. DBGLOG(REQ, WARN, "invalid auth mode (%d)\n", eAuthMode);
  769. return -EINVAL;
  770. }
  771. }
  772. }
  773. if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
  774. eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ?
  775. AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH;
  776. }
  777. prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy;
  778. prGlueInfo->fgWpsActive = FALSE;
  779. #if CFG_SUPPORT_PASSPOINT
  780. prGlueInfo->fgConnectHS20AP = FALSE;
  781. #endif /* CFG_SUPPORT_PASSPOINT */
  782. if (sme->ie && sme->ie_len > 0) {
  783. WLAN_STATUS rStatus;
  784. UINT_32 u4BufLen;
  785. PUINT_8 prDesiredIE = NULL;
  786. PUINT_8 pucIEStart = (PUINT_8)sme->ie;
  787. #if CFG_SUPPORT_WAPI
  788. rStatus = kalIoctl(prGlueInfo,
  789. wlanoidSetWapiAssocInfo, pucIEStart, sme->ie_len, FALSE, FALSE, FALSE, &u4BufLen);
  790. if (rStatus != WLAN_STATUS_SUCCESS)
  791. DBGLOG(REQ, TRACE, "[wapi] set wapi assoc info error:%lx\n", rStatus);
  792. #endif
  793. #if CFG_SUPPORT_WPS2
  794. if (wextSrchDesiredWPSIE(pucIEStart, sme->ie_len, 0xDD, (PUINT_8 *) &prDesiredIE)) {
  795. prGlueInfo->fgWpsActive = TRUE;
  796. fgCarryWPSIE = TRUE;
  797. rStatus = kalIoctl(prGlueInfo,
  798. wlanoidSetWSCAssocInfo,
  799. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, &u4BufLen);
  800. if (rStatus != WLAN_STATUS_SUCCESS)
  801. DBGLOG(SEC, WARN, "[WSC] set WSC assoc info error:%lx\n", rStatus);
  802. }
  803. #endif
  804. #if CFG_SUPPORT_PASSPOINT
  805. if (wextSrchDesiredHS20IE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
  806. rStatus = kalIoctl(prGlueInfo,
  807. wlanoidSetHS20Info,
  808. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, &u4BufLen);
  809. #if 0
  810. if (rStatus != WLAN_STATUS_SUCCESS)
  811. DBGLOG(INIT, INFO, "[HS20] set HS20 assoc info error:%lx\n", rStatus);
  812. #endif
  813. }
  814. if (wextSrchDesiredInterworkingIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
  815. rStatus = kalIoctl(prGlueInfo,
  816. wlanoidSetInterworkingInfo,
  817. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, &u4BufLen);
  818. #if 0
  819. if (rStatus != WLAN_STATUS_SUCCESS)
  820. DBGLOG(INIT, INFO, "[HS20] set Interworking assoc info error:%lx\n", rStatus);
  821. #endif
  822. }
  823. if (wextSrchDesiredRoamingConsortiumIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) {
  824. rStatus = kalIoctl(prGlueInfo,
  825. wlanoidSetRoamingConsortiumIEInfo,
  826. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, &u4BufLen);
  827. #if 0
  828. if (rStatus != WLAN_STATUS_SUCCESS)
  829. DBGLOG(INIT, INFO, "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus);
  830. #endif
  831. }
  832. #endif /* CFG_SUPPORT_PASSPOINT */
  833. }
  834. /* clear WSC Assoc IE buffer in case WPS IE is not detected */
  835. if (fgCarryWPSIE == FALSE) {
  836. kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200);
  837. prGlueInfo->u2WSCAssocInfoIELen = 0;
  838. }
  839. rStatus = kalIoctl(prGlueInfo,
  840. wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, &u4BufLen);
  841. if (rStatus != WLAN_STATUS_SUCCESS)
  842. DBGLOG(REQ, WARN, "set auth mode error:%lx\n", rStatus);
  843. /* Enable the specific AKM suite only. */
  844. for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) {
  845. prEntry = &prGlueInfo->prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i];
  846. if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite)
  847. prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE;
  848. else
  849. prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = FALSE;
  850. }
  851. cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise;
  852. if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) {
  853. if (cipher & IW_AUTH_CIPHER_CCMP) {
  854. eEncStatus = ENUM_ENCRYPTION3_ENABLED;
  855. } else if (cipher & IW_AUTH_CIPHER_TKIP) {
  856. eEncStatus = ENUM_ENCRYPTION2_ENABLED;
  857. } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
  858. eEncStatus = ENUM_ENCRYPTION1_ENABLED;
  859. } else if (cipher & IW_AUTH_CIPHER_NONE) {
  860. if (prGlueInfo->rWpaInfo.fgPrivacyInvoke)
  861. eEncStatus = ENUM_ENCRYPTION1_ENABLED;
  862. else
  863. eEncStatus = ENUM_ENCRYPTION_DISABLED;
  864. } else {
  865. eEncStatus = ENUM_ENCRYPTION_DISABLED;
  866. }
  867. } else {
  868. eEncStatus = ENUM_ENCRYPTION_DISABLED;
  869. }
  870. rStatus = kalIoctl(prGlueInfo,
  871. wlanoidSetEncryptionStatus, &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, &u4BufLen);
  872. if (rStatus != WLAN_STATUS_SUCCESS)
  873. DBGLOG(REQ, WARN, "set encryption mode error:%lx\n", rStatus);
  874. if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
  875. P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
  876. kalMemSet(prWepKey, 0, sizeof(PARAM_WEP_T));
  877. prWepKey->u4Length = 12 + sme->key_len;
  878. prWepKey->u4KeyLength = (UINT_32) sme->key_len;
  879. prWepKey->u4KeyIndex = (UINT_32) sme->key_idx;
  880. prWepKey->u4KeyIndex |= BIT(31);
  881. if (prWepKey->u4KeyLength > 32) {
  882. DBGLOG(REQ, WARN, "Too long key length (%lu)\n", prWepKey->u4KeyLength);
  883. return -EINVAL;
  884. }
  885. kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength);
  886. rStatus = kalIoctl(prGlueInfo,
  887. wlanoidSetAddWep, prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen);
  888. if (rStatus != WLAN_STATUS_SUCCESS) {
  889. DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%lx\n", rStatus);
  890. return -EFAULT;
  891. }
  892. }
  893. rNewSsid.u4CenterFreq = sme->channel ? sme->channel->center_freq : 0;
  894. rNewSsid.pucBssid = (UINT_8 *)sme->bssid;
  895. rNewSsid.pucSsid = (UINT_8 *)sme->ssid;
  896. rNewSsid.u4SsidLen = sme->ssid_len;
  897. rStatus = kalIoctl(prGlueInfo, wlanoidSetConnect, (PVOID)&rNewSsid, sizeof(PARAM_CONNECT_T),
  898. FALSE, FALSE, TRUE, &u4BufLen);
  899. if (rStatus != WLAN_STATUS_SUCCESS) {
  900. DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus);
  901. return -EINVAL;
  902. }
  903. #if 0
  904. if (sme->bssid != NULL && 1 /* prGlueInfo->fgIsBSSIDSet */) {
  905. /* connect by BSSID */
  906. if (sme->ssid_len > 0) {
  907. P_CONNECTION_SETTINGS_T prConnSettings = NULL;
  908. prConnSettings = &(prGlueInfo->prAdapter->rWifiVar.rConnSettings);
  909. /* prGlueInfo->fgIsSSIDandBSSIDSet = TRUE; */
  910. COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, sme->ssid, sme->ssid_len);
  911. }
  912. rStatus = kalIoctl(prGlueInfo,
  913. wlanoidSetBssid,
  914. (PVOID) sme->bssid, MAC_ADDR_LEN, FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  915. if (rStatus != WLAN_STATUS_SUCCESS) {
  916. DBGLOG(REQ, WARN, "set BSSID:%lx\n", rStatus);
  917. return -EINVAL;
  918. }
  919. } else if (sme->ssid_len > 0) {
  920. /* connect by SSID */
  921. COPY_SSID(rNewSsid.aucSsid, rNewSsid.u4SsidLen, sme->ssid, sme->ssid_len);
  922. rStatus = kalIoctl(prGlueInfo,
  923. wlanoidSetSsid,
  924. (PVOID)&rNewSsid, sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen);
  925. if (rStatus != WLAN_STATUS_SUCCESS) {
  926. DBGLOG(REQ, WARN, "set SSID:%lx\n", rStatus);
  927. return -EINVAL;
  928. }
  929. }
  930. #endif
  931. return 0;
  932. }
  933. /*----------------------------------------------------------------------------*/
  934. /*!
  935. * @brief This routine is responsible for requesting to disconnect from
  936. * currently connected ESS
  937. *
  938. * @param
  939. *
  940. * @retval 0: successful
  941. * others: failure
  942. */
  943. /*----------------------------------------------------------------------------*/
  944. int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code)
  945. {
  946. P_GLUE_INFO_T prGlueInfo = NULL;
  947. WLAN_STATUS rStatus;
  948. UINT_32 u4BufLen;
  949. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  950. ASSERT(prGlueInfo);
  951. rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, &u4BufLen);
  952. if (rStatus != WLAN_STATUS_SUCCESS) {
  953. DBGLOG(REQ, WARN, "disassociate error:%lx\n", rStatus);
  954. return -EFAULT;
  955. }
  956. return 0;
  957. }
  958. /*----------------------------------------------------------------------------*/
  959. /*!
  960. * @brief This routine is responsible for requesting to join an IBSS group
  961. *
  962. * @param
  963. *
  964. * @retval 0: successful
  965. * others: failure
  966. */
  967. /*----------------------------------------------------------------------------*/
  968. int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params)
  969. {
  970. PARAM_SSID_T rNewSsid;
  971. P_GLUE_INFO_T prGlueInfo = NULL;
  972. UINT_32 u4ChnlFreq; /* Store channel or frequency information */
  973. UINT_32 u4BufLen = 0;
  974. WLAN_STATUS rStatus;
  975. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  976. ASSERT(prGlueInfo);
  977. /* set channel */
  978. if (params->channel_fixed) {
  979. u4ChnlFreq = params->chandef.center_freq1;
  980. rStatus = kalIoctl(prGlueInfo,
  981. wlanoidSetFrequency,
  982. &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen);
  983. if (rStatus != WLAN_STATUS_SUCCESS)
  984. return -EFAULT;
  985. }
  986. /* set SSID */
  987. kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len);
  988. rStatus = kalIoctl(prGlueInfo,
  989. wlanoidSetSsid, (PVOID)&rNewSsid, sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, &u4BufLen);
  990. if (rStatus != WLAN_STATUS_SUCCESS) {
  991. DBGLOG(REQ, WARN, "set SSID:%lx\n", rStatus);
  992. return -EFAULT;
  993. }
  994. return 0;
  995. return -EINVAL;
  996. }
  997. /*----------------------------------------------------------------------------*/
  998. /*!
  999. * @brief This routine is responsible for requesting to leave from IBSS group
  1000. *
  1001. * @param
  1002. *
  1003. * @retval 0: successful
  1004. * others: failure
  1005. */
  1006. /*----------------------------------------------------------------------------*/
  1007. int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
  1008. {
  1009. P_GLUE_INFO_T prGlueInfo = NULL;
  1010. WLAN_STATUS rStatus;
  1011. UINT_32 u4BufLen;
  1012. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1013. ASSERT(prGlueInfo);
  1014. rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, &u4BufLen);
  1015. if (rStatus != WLAN_STATUS_SUCCESS) {
  1016. DBGLOG(REQ, WARN, "disassociate error:%lx\n", rStatus);
  1017. return -EFAULT;
  1018. }
  1019. return 0;
  1020. }
  1021. /*----------------------------------------------------------------------------*/
  1022. /*!
  1023. * @brief This routine is responsible for requesting to configure
  1024. * WLAN power managemenet
  1025. *
  1026. * @param
  1027. *
  1028. * @retval 0: successful
  1029. * others: failure
  1030. */
  1031. /*----------------------------------------------------------------------------*/
  1032. int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout)
  1033. {
  1034. P_GLUE_INFO_T prGlueInfo = NULL;
  1035. WLAN_STATUS rStatus;
  1036. UINT_32 u4BufLen;
  1037. PARAM_POWER_MODE_T rPowerMode;
  1038. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1039. if (!prGlueInfo)
  1040. return -EFAULT;
  1041. if (!prGlueInfo->prAdapter->prAisBssInfo)
  1042. return -EFAULT;
  1043. if (enabled) {
  1044. if (timeout == -1)
  1045. rPowerMode.ePowerMode = Param_PowerModeFast_PSP;
  1046. else
  1047. rPowerMode.ePowerMode = Param_PowerModeMAX_PSP;
  1048. } else {
  1049. rPowerMode.ePowerMode = Param_PowerModeCAM;
  1050. }
  1051. rPowerMode.ucBssIdx = prGlueInfo->prAdapter->prAisBssInfo->ucBssIndex;
  1052. rStatus = kalIoctl(prGlueInfo,
  1053. wlanoidSet802dot11PowerSaveProfile,
  1054. &rPowerMode, sizeof(PARAM_POWER_MODE_T), FALSE, FALSE, TRUE, &u4BufLen);
  1055. if (rStatus != WLAN_STATUS_SUCCESS) {
  1056. DBGLOG(REQ, WARN, "set_power_mgmt error:%lx\n", rStatus);
  1057. return -EFAULT;
  1058. }
  1059. return 0;
  1060. }
  1061. /*----------------------------------------------------------------------------*/
  1062. /*!
  1063. * @brief This routine is responsible for requesting to cache
  1064. * a PMKID for a BSSID
  1065. *
  1066. * @param
  1067. *
  1068. * @retval 0: successful
  1069. * others: failure
  1070. */
  1071. /*----------------------------------------------------------------------------*/
  1072. int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa)
  1073. {
  1074. P_GLUE_INFO_T prGlueInfo = NULL;
  1075. WLAN_STATUS rStatus;
  1076. UINT_32 u4BufLen;
  1077. P_PARAM_PMKID_T prPmkid;
  1078. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1079. ASSERT(prGlueInfo);
  1080. prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE);
  1081. if (!prPmkid) {
  1082. DBGLOG(INIT, INFO, "Can not alloc memory for IW_PMKSA_ADD\n");
  1083. return -ENOMEM;
  1084. }
  1085. prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T);
  1086. prPmkid->u4BSSIDInfoCount = 1;
  1087. kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, pmksa->bssid, 6);
  1088. kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, pmksa->pmkid, IW_PMKID_LEN);
  1089. rStatus = kalIoctl(prGlueInfo, wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, &u4BufLen);
  1090. if (rStatus != WLAN_STATUS_SUCCESS)
  1091. DBGLOG(INIT, INFO, "add pmkid error:%lx\n", rStatus);
  1092. kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T));
  1093. return 0;
  1094. }
  1095. /*----------------------------------------------------------------------------*/
  1096. /*!
  1097. * @brief This routine is responsible for requesting to remove
  1098. * a cached PMKID for a BSSID
  1099. *
  1100. * @param
  1101. *
  1102. * @retval 0: successful
  1103. * others: failure
  1104. */
  1105. /*----------------------------------------------------------------------------*/
  1106. int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa)
  1107. {
  1108. return 0;
  1109. }
  1110. /*----------------------------------------------------------------------------*/
  1111. /*!
  1112. * @brief This routine is responsible for requesting to flush
  1113. * all cached PMKID
  1114. *
  1115. * @param
  1116. *
  1117. * @retval 0: successful
  1118. * others: failure
  1119. */
  1120. /*----------------------------------------------------------------------------*/
  1121. int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
  1122. {
  1123. P_GLUE_INFO_T prGlueInfo = NULL;
  1124. WLAN_STATUS rStatus;
  1125. UINT_32 u4BufLen;
  1126. P_PARAM_PMKID_T prPmkid;
  1127. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1128. ASSERT(prGlueInfo);
  1129. prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE);
  1130. if (!prPmkid) {
  1131. DBGLOG(INIT, INFO, "Can not alloc memory for IW_PMKSA_FLUSH\n");
  1132. return -ENOMEM;
  1133. }
  1134. prPmkid->u4Length = 8;
  1135. prPmkid->u4BSSIDInfoCount = 0;
  1136. rStatus = kalIoctl(prGlueInfo, wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, &u4BufLen);
  1137. if (rStatus != WLAN_STATUS_SUCCESS)
  1138. DBGLOG(INIT, INFO, "flush pmkid error:%lx\n", rStatus);
  1139. kalMemFree(prPmkid, VIR_MEM_TYPE, 8);
  1140. return 0;
  1141. }
  1142. /*----------------------------------------------------------------------------*/
  1143. /*!
  1144. * @brief This routine is responsible for setting the rekey data
  1145. *
  1146. * @param
  1147. *
  1148. * @retval 0: successful
  1149. * others: failure
  1150. */
  1151. /*----------------------------------------------------------------------------*/
  1152. int mtk_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_gtk_rekey_data *data)
  1153. {
  1154. P_GLUE_INFO_T prGlueInfo = NULL;
  1155. WLAN_STATUS rStatus;
  1156. UINT_32 u4BufLen;
  1157. P_PARAM_GTK_REKEY_DATA prGtkData;
  1158. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1159. ASSERT(prGlueInfo);
  1160. prGtkData = (P_PARAM_GTK_REKEY_DATA) kalMemAlloc(sizeof(PARAM_GTK_REKEY_DATA), VIR_MEM_TYPE);
  1161. if (!prGtkData) {
  1162. DBGLOG(INIT, INFO, "Can not alloc memory for PARAM_GTK_REKEY_DATA\n");
  1163. return -ENOMEM;
  1164. }
  1165. DBGLOG(RSN, TRACE, "cfg80211_set_rekey_data!\n");
  1166. kalMemCopy(prGtkData, data, sizeof(PARAM_GTK_REKEY_DATA));
  1167. rStatus = kalIoctl(prGlueInfo,
  1168. wlanoidSetGtkRekeyData,
  1169. prGtkData, sizeof(PARAM_GTK_REKEY_DATA), FALSE, FALSE, TRUE, &u4BufLen);
  1170. if (rStatus != WLAN_STATUS_SUCCESS)
  1171. DBGLOG(INIT, INFO, "set GTK rekey data error:%lx\n", rStatus);
  1172. kalMemFree(prGtkData, VIR_MEM_TYPE, sizeof(PARAM_GTK_REKEY_DATA));
  1173. return 0;
  1174. }
  1175. void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy,
  1176. IN struct wireless_dev *wdev,
  1177. IN u16 frame_type, IN bool reg)
  1178. {
  1179. #if 0
  1180. P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL;
  1181. #endif
  1182. P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL;
  1183. do {
  1184. DBGLOG(INIT, TRACE, "mtk_cfg80211_mgmt_frame_register\n");
  1185. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1186. switch (frame_type) {
  1187. case MAC_FRAME_PROBE_REQ:
  1188. if (reg) {
  1189. prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ;
  1190. DBGLOG(INIT, TRACE, "Open packet filer probe request\n");
  1191. } else {
  1192. prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ;
  1193. DBGLOG(INIT, TRACE, "Close packet filer probe request\n");
  1194. }
  1195. break;
  1196. case MAC_FRAME_ACTION:
  1197. if (reg) {
  1198. prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME;
  1199. DBGLOG(INIT, TRACE, "Open packet filer action frame.\n");
  1200. } else {
  1201. prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME;
  1202. DBGLOG(INIT, TRACE, "Close packet filer action frame.\n");
  1203. }
  1204. break;
  1205. default:
  1206. DBGLOG(INIT, TRACE, "Ask frog to add code for mgmt:%x\n", frame_type);
  1207. break;
  1208. }
  1209. if (prGlueInfo->prAdapter != NULL) {
  1210. set_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag);
  1211. /* wake up main thread */
  1212. wake_up_interruptible(&prGlueInfo->waitq);
  1213. if (in_interrupt())
  1214. DBGLOG(INIT, TRACE, "It is in interrupt level\n");
  1215. }
  1216. #if 0
  1217. prMgmtFrameRegister =
  1218. (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter,
  1219. RAM_TYPE_MSG, sizeof(MSG_P2P_MGMT_FRAME_REGISTER_T));
  1220. if (prMgmtFrameRegister == NULL) {
  1221. ASSERT(FALSE);
  1222. break;
  1223. }
  1224. prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER;
  1225. prMgmtFrameRegister->u2FrameType = frame_type;
  1226. prMgmtFrameRegister->fgIsRegister = reg;
  1227. mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF);
  1228. #endif
  1229. } while (FALSE);
  1230. } /* mtk_cfg80211_mgmt_frame_register */
  1231. /*----------------------------------------------------------------------------*/
  1232. /*!
  1233. * @brief This routine is responsible for requesting to stay on a
  1234. * specified channel
  1235. *
  1236. * @param
  1237. *
  1238. * @retval 0: successful
  1239. * others: failure
  1240. */
  1241. /*----------------------------------------------------------------------------*/
  1242. int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy,
  1243. struct wireless_dev *wdev,
  1244. struct ieee80211_channel *chan,
  1245. unsigned int duration, u64 *cookie)
  1246. {
  1247. P_GLUE_INFO_T prGlueInfo = NULL;
  1248. INT_32 i4Rslt = -EINVAL;
  1249. P_MSG_REMAIN_ON_CHANNEL_T prMsgChnlReq = (P_MSG_REMAIN_ON_CHANNEL_T) NULL;
  1250. do {
  1251. if ((wiphy == NULL)
  1252. || (wdev == NULL)
  1253. || (chan == NULL)
  1254. || (cookie == NULL)) {
  1255. break;
  1256. }
  1257. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1258. ASSERT(prGlueInfo);
  1259. #if 1
  1260. DBGLOG(INIT, INFO, "--> %s()\n", __func__);
  1261. #endif
  1262. *cookie = prGlueInfo->u8Cookie++;
  1263. prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_REMAIN_ON_CHANNEL_T));
  1264. if (prMsgChnlReq == NULL) {
  1265. ASSERT(FALSE);
  1266. i4Rslt = -ENOMEM;
  1267. break;
  1268. }
  1269. prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_AIS_REMAIN_ON_CHANNEL;
  1270. prMsgChnlReq->u8Cookie = *cookie;
  1271. prMsgChnlReq->u4DurationMs = duration;
  1272. prMsgChnlReq->ucChannelNum = nicFreq2ChannelNum(chan->center_freq * 1000);
  1273. switch (chan->band) {
  1274. case IEEE80211_BAND_2GHZ:
  1275. prMsgChnlReq->eBand = BAND_2G4;
  1276. break;
  1277. case IEEE80211_BAND_5GHZ:
  1278. prMsgChnlReq->eBand = BAND_5G;
  1279. break;
  1280. default:
  1281. prMsgChnlReq->eBand = BAND_2G4;
  1282. break;
  1283. }
  1284. prMsgChnlReq->eSco = CHNL_EXT_SCN;
  1285. mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF);
  1286. i4Rslt = 0;
  1287. } while (FALSE);
  1288. return i4Rslt;
  1289. }
  1290. /*----------------------------------------------------------------------------*/
  1291. /*!
  1292. * @brief This routine is responsible for requesting to cancel staying
  1293. * on a specified channel
  1294. *
  1295. * @param
  1296. *
  1297. * @retval 0: successful
  1298. * others: failure
  1299. */
  1300. /*----------------------------------------------------------------------------*/
  1301. int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
  1302. struct wireless_dev *wdev,
  1303. u64 cookie)
  1304. {
  1305. P_GLUE_INFO_T prGlueInfo = NULL;
  1306. INT_32 i4Rslt = -EINVAL;
  1307. P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prMsgChnlAbort = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) NULL;
  1308. do {
  1309. if ((wiphy == NULL)
  1310. || (wdev == NULL)
  1311. ) {
  1312. break;
  1313. }
  1314. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1315. ASSERT(prGlueInfo);
  1316. prMsgChnlAbort =
  1317. cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_CANCEL_REMAIN_ON_CHANNEL_T));
  1318. if (prMsgChnlAbort == NULL) {
  1319. ASSERT(FALSE);
  1320. i4Rslt = -ENOMEM;
  1321. break;
  1322. }
  1323. prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL;
  1324. prMsgChnlAbort->u8Cookie = cookie;
  1325. mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF);
  1326. i4Rslt = 0;
  1327. } while (FALSE);
  1328. return i4Rslt;
  1329. }
  1330. /*----------------------------------------------------------------------------*/
  1331. /*!
  1332. * @brief This routine is responsible for requesting to send a management frame
  1333. *
  1334. * @param
  1335. *
  1336. * @retval 0: successful
  1337. * others: failure
  1338. */
  1339. /*----------------------------------------------------------------------------*/
  1340. int mtk_cfg80211_mgmt_tx(struct wiphy *wiphy,
  1341. struct wireless_dev *wdev,
  1342. struct cfg80211_mgmt_tx_params *params,
  1343. u64 *cookie)
  1344. {
  1345. P_GLUE_INFO_T prGlueInfo = NULL;
  1346. INT_32 i4Rslt = -EINVAL;
  1347. P_MSG_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_MGMT_TX_REQUEST_T) NULL;
  1348. P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL;
  1349. PUINT_8 pucFrameBuf = (PUINT_8) NULL;
  1350. do {
  1351. if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL))
  1352. break;
  1353. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1354. ASSERT(prGlueInfo);
  1355. *cookie = prGlueInfo->u8Cookie++;
  1356. /* Channel & Channel Type & Wait time are ignored. */
  1357. prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_MGMT_TX_REQUEST_T));
  1358. if (prMsgTxReq == NULL) {
  1359. ASSERT(FALSE);
  1360. i4Rslt = -ENOMEM;
  1361. break;
  1362. }
  1363. prMsgTxReq->fgNoneCckRate = FALSE;
  1364. prMsgTxReq->fgIsWaitRsp = TRUE;
  1365. prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD));
  1366. prMsgTxReq->prMgmtMsduInfo = prMgmtFrame;
  1367. if (prMsgTxReq->prMgmtMsduInfo == NULL) {
  1368. ASSERT(FALSE);
  1369. i4Rslt = -ENOMEM;
  1370. break;
  1371. }
  1372. prMsgTxReq->u8Cookie = *cookie;
  1373. prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_AIS_MGMT_TX;
  1374. pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD);
  1375. kalMemCopy(pucFrameBuf, params->buf, params->len);
  1376. prMgmtFrame->u2FrameLength = params->len;
  1377. mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF);
  1378. i4Rslt = 0;
  1379. } while (FALSE);
  1380. if ((i4Rslt != 0) && (prMsgTxReq != NULL)) {
  1381. if (prMsgTxReq->prMgmtMsduInfo != NULL)
  1382. cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo);
  1383. cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq);
  1384. }
  1385. return i4Rslt;
  1386. }
  1387. /*----------------------------------------------------------------------------*/
  1388. /*!
  1389. * @brief This routine is responsible for requesting to cancel the wait time
  1390. * from transmitting a management frame on another channel
  1391. *
  1392. * @param
  1393. *
  1394. * @retval 0: successful
  1395. * others: failure
  1396. */
  1397. /*----------------------------------------------------------------------------*/
  1398. int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
  1399. struct wireless_dev *wdev,
  1400. u64 cookie)
  1401. {
  1402. P_GLUE_INFO_T prGlueInfo = NULL;
  1403. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1404. ASSERT(prGlueInfo);
  1405. #if 1
  1406. DBGLOG(INIT, INFO, "--> %s()\n", __func__);
  1407. #endif
  1408. /* not implemented */
  1409. return -EINVAL;
  1410. }
  1411. #if CONFIG_NL80211_TESTMODE
  1412. #if CFG_SUPPORT_PASSPOINT
  1413. int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
  1414. {
  1415. P_GLUE_INFO_T prGlueInfo = NULL;
  1416. struct wpa_driver_hs20_data_s *prParams = NULL;
  1417. WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
  1418. int fgIsValid = 0;
  1419. UINT_32 u4SetInfoLen = 0;
  1420. ASSERT(wiphy);
  1421. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1422. #if 1
  1423. DBGLOG(INIT, INFO, "--> %s()\n", __func__);
  1424. #endif
  1425. if (data && len)
  1426. prParams = (struct wpa_driver_hs20_data_s *)data;
  1427. if (prParams) {
  1428. int i;
  1429. DBGLOG(INIT, INFO, "[%s] Cmd Type (%d)\n", __func__, prParams->CmdType);
  1430. switch (prParams->CmdType) {
  1431. case HS20_CMD_ID_SET_BSSID_POOL:
  1432. DBGLOG(INIT, INFO,
  1433. "[%s] fgBssidPoolIsEnable (%d)\n", __func__,
  1434. prParams->hs20_set_bssid_pool.fgBssidPoolIsEnable);
  1435. DBGLOG(INIT, INFO,
  1436. "[%s] ucNumBssidPool (%d)\n", __func__,
  1437. prParams->hs20_set_bssid_pool.ucNumBssidPool);
  1438. for (i = 0; i < prParams->hs20_set_bssid_pool.ucNumBssidPool; i++) {
  1439. DBGLOG(INIT, INFO, "[%s][%d][" MACSTR "]\n", __func__, i,
  1440. MAC2STR(prParams->hs20_set_bssid_pool.arBssidPool[i]));
  1441. }
  1442. rstatus = kalIoctl(prGlueInfo,
  1443. (PFN_OID_HANDLER_FUNC) wlanoidSetHS20BssidPool,
  1444. &prParams->hs20_set_bssid_pool,
  1445. sizeof(struct param_hs20_set_bssid_pool), FALSE, FALSE, TRUE, &u4SetInfoLen);
  1446. break;
  1447. default:
  1448. DBGLOG(INIT, INFO, "[%s] Unknown Cmd Type (%d)\n", __func__, prParams->CmdType);
  1449. rstatus = WLAN_STATUS_FAILURE;
  1450. }
  1451. }
  1452. if (WLAN_STATUS_SUCCESS != rstatus)
  1453. fgIsValid = -EFAULT;
  1454. return fgIsValid;
  1455. }
  1456. #endif /* CFG_SUPPORT_PASSPOINT */
  1457. #if CFG_SUPPORT_WAPI
  1458. int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len)
  1459. {
  1460. P_GLUE_INFO_T prGlueInfo = NULL;
  1461. P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) NULL;
  1462. struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL;
  1463. WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
  1464. int fgIsValid = 0;
  1465. UINT_32 u4BufLen = 0;
  1466. P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf;
  1467. memset(keyStructBuf, 0, sizeof(keyStructBuf));
  1468. ASSERT(wiphy);
  1469. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1470. #if 1
  1471. DBGLOG(INIT, INFO, "--> %s()\n", __func__);
  1472. #endif
  1473. if (data && len)
  1474. prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) data;
  1475. if (prParams)
  1476. prIWEncExt = (struct iw_encode_exts *)&prParams->ext;
  1477. else
  1478. return -EINVAL;
  1479. if ((prIWEncExt != NULL) && (prIWEncExt->alg == IW_ENCODE_ALG_SMS4)) {
  1480. /* KeyID */
  1481. prWpiKey->ucKeyID = prParams->key_index;
  1482. prWpiKey->ucKeyID--;
  1483. if (prWpiKey->ucKeyID > 1) {
  1484. /* key id is out of range */
  1485. return -EINVAL;
  1486. }
  1487. if (prIWEncExt->key_len != 32) {
  1488. /* key length not valid */
  1489. return -EINVAL;
  1490. }
  1491. if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
  1492. prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY;
  1493. prWpiKey->eDirection = ENUM_WPI_RX;
  1494. } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
  1495. prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY;
  1496. prWpiKey->eDirection = ENUM_WPI_RX_TX;
  1497. }
  1498. /* #if CFG_SUPPORT_WAPI */
  1499. /* handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL); */
  1500. /* #endif */
  1501. /* PN */
  1502. memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE * 2);
  1503. /* BSSID */
  1504. memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6);
  1505. memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16);
  1506. prWpiKey->u4LenWPIEK = 16;
  1507. memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16);
  1508. prWpiKey->u4LenWPICK = 16;
  1509. rstatus = kalIoctl(prGlueInfo,
  1510. wlanoidSetWapiKey, prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, &u4BufLen);
  1511. if (rstatus != WLAN_STATUS_SUCCESS)
  1512. fgIsValid = -EFAULT;
  1513. }
  1514. return fgIsValid;
  1515. }
  1516. #endif
  1517. int
  1518. mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
  1519. {
  1520. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  1521. INT_32 i4Status = -EINVAL;
  1522. UINT_32 u4BufLen;
  1523. UINT_32 u4LinkScore;
  1524. UINT_32 u4TotalError;
  1525. UINT_32 u4TxExceedThresholdCount;
  1526. UINT_32 u4TxTotalCount;
  1527. UINT_8 u1buf = 0;
  1528. P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL;
  1529. PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics;
  1530. struct sk_buff *skb;
  1531. ASSERT(wiphy);
  1532. ASSERT(prGlueInfo);
  1533. if (data && len)
  1534. prParams = (P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS) data;
  1535. if (!prParams) {
  1536. DBGLOG(QM, TRACE, "%s prParams is NULL\n", __func__);
  1537. return -EINVAL;
  1538. }
  1539. if (!prParams->aucMacAddr) {
  1540. DBGLOG(QM, TRACE, "%s MAC Address is NULL\n", __func__);
  1541. return -EINVAL;
  1542. }
  1543. skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1);
  1544. if (!skb) {
  1545. DBGLOG(QM, TRACE, "%s allocate skb failed:%lx\n", __func__, rStatus);
  1546. return -ENOMEM;
  1547. }
  1548. DBGLOG(QM, TRACE, "Get [" MACSTR "] STA statistics\n",
  1549. MAC2STR(prParams->aucMacAddr));
  1550. kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics));
  1551. COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, prParams->aucMacAddr);
  1552. rQueryStaStatistics.ucReadClear = TRUE;
  1553. rStatus = kalIoctl(prGlueInfo,
  1554. wlanoidQueryStaStatistics,
  1555. &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, &u4BufLen);
  1556. /* Calcute Link Score */
  1557. u4TxExceedThresholdCount = rQueryStaStatistics.u4TxExceedThresholdCount;
  1558. u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount;
  1559. u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount;
  1560. /* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only */
  1561. /* u4LinkScore 0~9 , Drop packet ratio 0~9 and all packets exceed threshold */
  1562. if (u4TxTotalCount) {
  1563. if (u4TxExceedThresholdCount <= u4TxTotalCount)
  1564. u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) / u4TxTotalCount));
  1565. else
  1566. u4LinkScore = 0;
  1567. } else {
  1568. u4LinkScore = 90;
  1569. }
  1570. u4LinkScore += 10;
  1571. if (u4LinkScore == 10) {
  1572. if (u4TotalError <= u4TxTotalCount)
  1573. u4LinkScore = (10 - ((u4TotalError * 10) / u4TxTotalCount));
  1574. else
  1575. u4LinkScore = 0;
  1576. }
  1577. if (u4LinkScore > 100)
  1578. u4LinkScore = 100;
  1579. do {
  1580. u1buf = 0;
  1581. if (!NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, &u1buf))
  1582. break;
  1583. u1buf = NL80211_DRIVER_TESTMODE_VERSION;
  1584. if (!NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, &u1buf))
  1585. break;
  1586. if (!NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, prParams->aucMacAddr))
  1587. break;
  1588. if (!NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, &u4LinkScore))
  1589. break;
  1590. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, &rQueryStaStatistics.u4Flag))
  1591. break;
  1592. /* FW part STA link status */
  1593. if (!NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_PER, &rQueryStaStatistics.ucPer))
  1594. break;
  1595. if (!NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, &rQueryStaStatistics.ucRcpi))
  1596. break;
  1597. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, &rQueryStaStatistics.u4PhyMode))
  1598. break;
  1599. if (!NLA_PUT_U16(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, &rQueryStaStatistics.u2LinkSpeed))
  1600. break;
  1601. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, &rQueryStaStatistics.u4TxFailCount))
  1602. break;
  1603. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT,
  1604. &rQueryStaStatistics.u4TxLifeTimeoutCount))
  1605. break;
  1606. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME,
  1607. &rQueryStaStatistics.u4TxAverageAirTime))
  1608. break;
  1609. /* Driver part link status */
  1610. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, &rQueryStaStatistics.u4TxTotalCount))
  1611. break;
  1612. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT,
  1613. &rQueryStaStatistics.u4TxExceedThresholdCount))
  1614. break;
  1615. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME,
  1616. &rQueryStaStatistics.u4TxAverageProcessTime))
  1617. break;
  1618. /* Network counter */
  1619. if (!NLA_PUT(skb,
  1620. NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY,
  1621. sizeof(rQueryStaStatistics.au4TcResourceEmptyCount),
  1622. rQueryStaStatistics.au4TcResourceEmptyCount))
  1623. break;
  1624. /* Sta queue length */
  1625. if (!NLA_PUT(skb,
  1626. NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY,
  1627. sizeof(rQueryStaStatistics.au4TcQueLen), rQueryStaStatistics.au4TcQueLen))
  1628. break;
  1629. /* Global QM counter */
  1630. if (!NLA_PUT(skb,
  1631. NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY,
  1632. sizeof(rQueryStaStatistics.au4TcAverageQueLen), rQueryStaStatistics.au4TcAverageQueLen))
  1633. break;
  1634. if (!NLA_PUT(skb,
  1635. NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY,
  1636. sizeof(rQueryStaStatistics.au4TcCurrentQueLen), rQueryStaStatistics.au4TcCurrentQueLen))
  1637. break;
  1638. /* Reserved field */
  1639. if (!NLA_PUT(skb,
  1640. NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY,
  1641. sizeof(rQueryStaStatistics.au4Reserved), rQueryStaStatistics.au4Reserved))
  1642. break;
  1643. i4Status = cfg80211_testmode_reply(skb);
  1644. } while (0);
  1645. return i4Status;
  1646. }
  1647. int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len)
  1648. {
  1649. P_GLUE_INFO_T prGlueInfo = NULL;
  1650. P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL;
  1651. WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
  1652. int fgIsValid = 0;
  1653. UINT_32 u4SetInfoLen = 0;
  1654. ASSERT(wiphy);
  1655. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1656. if (data && len)
  1657. prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data;
  1658. if (prParams) {
  1659. if (prParams->set == 1) {
  1660. rstatus = kalIoctl(prGlueInfo,
  1661. (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite,
  1662. &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, &u4SetInfoLen);
  1663. }
  1664. }
  1665. DBGLOG(REQ, TRACE, "prParams=%p, status=%u\n", prParams, rstatus);
  1666. if (WLAN_STATUS_SUCCESS != rstatus)
  1667. fgIsValid = -EFAULT;
  1668. return fgIsValid;
  1669. }
  1670. int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len)
  1671. {
  1672. P_GLUE_INFO_T prGlueInfo = NULL;
  1673. P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) NULL;
  1674. INT_32 i4Status = -EINVAL;
  1675. ASSERT(wiphy);
  1676. ASSERT(wdev);
  1677. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1678. if (data && len)
  1679. prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) data;
  1680. else {
  1681. DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_cmd, data is NULL\n");
  1682. return i4Status;
  1683. }
  1684. /* Clear the version byte */
  1685. prParams->index = prParams->index & ~BITS(24, 31);
  1686. if (prParams) {
  1687. switch (prParams->index) {
  1688. case TESTMODE_CMD_ID_SW_CMD: /* SW cmd */
  1689. i4Status = mtk_cfg80211_testmode_sw_cmd(wiphy, data, len);
  1690. break;
  1691. case TESTMODE_CMD_ID_WAPI: /* WAPI */
  1692. #if CFG_SUPPORT_WAPI
  1693. i4Status = mtk_cfg80211_testmode_set_key_ext(wiphy, data, len);
  1694. #endif
  1695. break;
  1696. case 0x10:
  1697. i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo);
  1698. break;
  1699. #if CFG_SUPPORT_PASSPOINT
  1700. case TESTMODE_CMD_ID_HS20:
  1701. i4Status = mtk_cfg80211_testmode_hs20_cmd(wiphy, data, len);
  1702. break;
  1703. #endif /* CFG_SUPPORT_PASSPOINT */
  1704. default:
  1705. i4Status = -EINVAL;
  1706. break;
  1707. }
  1708. if (i4Status != 0)
  1709. DBGLOG(REQ, TRACE, "prParams->index=%d, status=%d\n", prParams->index, i4Status);
  1710. }
  1711. return i4Status;
  1712. }
  1713. #endif
  1714. int
  1715. mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy,
  1716. IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request)
  1717. {
  1718. P_GLUE_INFO_T prGlueInfo = NULL;
  1719. WLAN_STATUS rStatus;
  1720. UINT_32 i, u4BufLen;
  1721. P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest;
  1722. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1723. ASSERT(prGlueInfo);
  1724. /* check if there is any pending scan/sched_scan not yet finished */
  1725. if (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL) {
  1726. DBGLOG(SCN, INFO, "(prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)\n");
  1727. return -EBUSY;
  1728. } else if (request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM) {
  1729. DBGLOG(SCN, INFO, "(request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM)\n");
  1730. /* invalid scheduled scan request */
  1731. return -EINVAL;
  1732. } else if (!request->n_ssids || !request->n_match_sets) {
  1733. /* invalid scheduled scan request */
  1734. return -EINVAL;
  1735. }
  1736. prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) kalMemAlloc(sizeof(PARAM_SCHED_SCAN_REQUEST), VIR_MEM_TYPE);
  1737. if (prSchedScanRequest == NULL) {
  1738. DBGLOG(SCN, INFO, "(prSchedScanRequest == NULL) kalMemAlloc fail\n");
  1739. return -ENOMEM;
  1740. }
  1741. prSchedScanRequest->u4SsidNum = request->n_match_sets;
  1742. for (i = 0; i < request->n_match_sets; i++) {
  1743. if (request->match_sets == NULL || &(request->match_sets[i]) == NULL) {
  1744. prSchedScanRequest->arSsid[i].u4SsidLen = 0;
  1745. } else {
  1746. COPY_SSID(prSchedScanRequest->arSsid[i].aucSsid,
  1747. prSchedScanRequest->arSsid[i].u4SsidLen,
  1748. request->match_sets[i].ssid.ssid, request->match_sets[i].ssid.ssid_len);
  1749. }
  1750. }
  1751. prSchedScanRequest->u4IELength = request->ie_len;
  1752. if (request->ie_len > 0)
  1753. prSchedScanRequest->pucIE = (PUINT_8) (request->ie);
  1754. prSchedScanRequest->u2ScanInterval = (UINT_16) (request->interval);
  1755. rStatus = kalIoctl(prGlueInfo,
  1756. wlanoidSetStartSchedScan,
  1757. prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST), FALSE, FALSE, TRUE, &u4BufLen);
  1758. kalMemFree(prSchedScanRequest, VIR_MEM_TYPE, sizeof(PARAM_SCHED_SCAN_REQUEST));
  1759. if (rStatus != WLAN_STATUS_SUCCESS) {
  1760. DBGLOG(REQ, WARN, "scheduled scan error:%lx\n", rStatus);
  1761. return -EINVAL;
  1762. }
  1763. prGlueInfo->prSchedScanRequest = request;
  1764. return 0;
  1765. }
  1766. int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev)
  1767. {
  1768. P_GLUE_INFO_T prGlueInfo = NULL;
  1769. WLAN_STATUS rStatus;
  1770. UINT_32 u4BufLen;
  1771. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1772. ASSERT(prGlueInfo);
  1773. /* check if there is any pending scan/sched_scan not yet finished */
  1774. if (prGlueInfo->prSchedScanRequest == NULL)
  1775. return -EBUSY;
  1776. rStatus = kalIoctl(prGlueInfo, wlanoidSetStopSchedScan, NULL, 0, FALSE, FALSE, TRUE, &u4BufLen);
  1777. if (rStatus == WLAN_STATUS_FAILURE) {
  1778. DBGLOG(REQ, WARN, "scheduled scan error:%lx\n", rStatus);
  1779. return -EINVAL;
  1780. }
  1781. return 0;
  1782. }
  1783. /*----------------------------------------------------------------------------*/
  1784. /*!
  1785. * @brief This routine is responsible for handling association request
  1786. *
  1787. * @param
  1788. *
  1789. * @retval 0: successful
  1790. * others: failure
  1791. */
  1792. /*----------------------------------------------------------------------------*/
  1793. int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req)
  1794. {
  1795. P_GLUE_INFO_T prGlueInfo = NULL;
  1796. PARAM_MAC_ADDRESS arBssid;
  1797. #if CFG_SUPPORT_PASSPOINT
  1798. PUINT_8 prDesiredIE = NULL;
  1799. #endif /* CFG_SUPPORT_PASSPOINT */
  1800. WLAN_STATUS rStatus;
  1801. UINT_32 u4BufLen;
  1802. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1803. ASSERT(prGlueInfo);
  1804. kalMemZero(arBssid, MAC_ADDR_LEN);
  1805. wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen);
  1806. /* 1. check BSSID */
  1807. if (UNEQUAL_MAC_ADDR(arBssid, req->bss->bssid)) {
  1808. /* wrong MAC address */
  1809. DBGLOG(REQ, WARN,
  1810. "incorrect BSSID: [" MACSTR "] currently connected BSSID[" MACSTR "]\n",
  1811. MAC2STR(req->bss->bssid),
  1812. MAC2STR(arBssid));
  1813. return -ENOENT;
  1814. }
  1815. if (req->ie && req->ie_len > 0) {
  1816. #if CFG_SUPPORT_PASSPOINT
  1817. if (wextSrchDesiredHS20IE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) {
  1818. rStatus = kalIoctl(prGlueInfo,
  1819. wlanoidSetHS20Info,
  1820. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, &u4BufLen);
  1821. if (rStatus != WLAN_STATUS_SUCCESS) {
  1822. /* DBGLOG(REQ, TRACE,
  1823. ("[HS20] set HS20 assoc info error:%lx\n", rStatus)); */
  1824. }
  1825. }
  1826. if (wextSrchDesiredInterworkingIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) {
  1827. rStatus = kalIoctl(prGlueInfo,
  1828. wlanoidSetInterworkingInfo,
  1829. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, &u4BufLen);
  1830. if (rStatus != WLAN_STATUS_SUCCESS) {
  1831. /* DBGLOG(REQ, TRACE,
  1832. ("[HS20] set Interworking assoc info error:%lx\n", rStatus)); */
  1833. }
  1834. }
  1835. if (wextSrchDesiredRoamingConsortiumIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) {
  1836. rStatus = kalIoctl(prGlueInfo,
  1837. wlanoidSetRoamingConsortiumIEInfo,
  1838. prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, &u4BufLen);
  1839. if (rStatus != WLAN_STATUS_SUCCESS) {
  1840. /* DBGLOG(REQ, TRACE,
  1841. ("[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus)); */
  1842. }
  1843. }
  1844. #endif /* CFG_SUPPORT_PASSPOINT */
  1845. }
  1846. rStatus = kalIoctl(prGlueInfo,
  1847. wlanoidSetBssid, (PVOID) req->bss->bssid, MAC_ADDR_LEN, FALSE, FALSE, TRUE, &u4BufLen);
  1848. if (rStatus != WLAN_STATUS_SUCCESS) {
  1849. DBGLOG(REQ, WARN, "set BSSID:%lx\n", rStatus);
  1850. return -EINVAL;
  1851. }
  1852. return 0;
  1853. }
  1854. #if CFG_SUPPORT_NFC_BEAM_PLUS
  1855. int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
  1856. {
  1857. #define NL80211_TESTMODE_P2P_SCANDONE_INVALID 0
  1858. #define NL80211_TESTMODE_P2P_SCANDONE_STATUS 1
  1859. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  1860. INT_32 i4Status = -EINVAL, READY_TO_BEAM = 0;
  1861. UINT_8 u1Buf = 0;
  1862. struct sk_buff *skb;
  1863. ASSERT(wiphy);
  1864. ASSERT(prGlueInfo);
  1865. skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(UINT_32));
  1866. /* READY_TO_BEAM = */
  1867. /* (UINT_32)(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone) */
  1868. /* &(!prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); */
  1869. READY_TO_BEAM = 1;
  1870. /* DBGLOG(QM, TRACE, */
  1871. /* ("NFC:GOInitialDone[%d] and P2PScanning[%d]\n", */
  1872. /* prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone, */
  1873. /* prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest)); */
  1874. if (!skb) {
  1875. DBGLOG(QM, TRACE, "%s allocate skb failed:%lx\n", __func__, rStatus);
  1876. return -ENOMEM;
  1877. }
  1878. if (!NLA_PUT_U8(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, &u1Buf))
  1879. return i4Status;
  1880. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, &READY_TO_BEAM))
  1881. return i4Status;
  1882. i4Status = cfg80211_testmode_reply(skb);
  1883. return i4Status;
  1884. }
  1885. #endif
  1886. #if CFG_SUPPORT_TDLS
  1887. /*----------------------------------------------------------------------------*/
  1888. /*!
  1889. * @brief This routine is responsible for changing a station information
  1890. *
  1891. * @param
  1892. *
  1893. * @retval 0: successful
  1894. * others: failure
  1895. */
  1896. /*----------------------------------------------------------------------------*/
  1897. int
  1898. mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac,
  1899. struct station_parameters *params)
  1900. {
  1901. /* return 0; */
  1902. /* from supplicant -- wpa_supplicant_tdls_peer_addset() */
  1903. P_GLUE_INFO_T prGlueInfo = NULL;
  1904. CMD_PEER_UPDATE_T rCmdUpdate;
  1905. WLAN_STATUS rStatus;
  1906. UINT_32 u4BufLen, u4Temp;
  1907. ADAPTER_T *prAdapter;
  1908. P_BSS_INFO_T prAisBssInfo;
  1909. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  1910. ASSERT(prGlueInfo);
  1911. /* make up command */
  1912. prAdapter = prGlueInfo->prAdapter;
  1913. prAisBssInfo = prAdapter->prAisBssInfo;
  1914. if (params == NULL)
  1915. return 0;
  1916. else if (params->supported_rates == NULL)
  1917. return 0;
  1918. /* init */
  1919. kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate));
  1920. kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6);
  1921. if (params->supported_rates != NULL) {
  1922. u4Temp = params->supported_rates_len;
  1923. if (u4Temp > CMD_PEER_UPDATE_SUP_RATE_MAX)
  1924. u4Temp = CMD_PEER_UPDATE_SUP_RATE_MAX;
  1925. kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, u4Temp);
  1926. rCmdUpdate.u2SupRateLen = u4Temp;
  1927. }
  1928. /*
  1929. In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM
  1930. So force to support UAPSD here.
  1931. */
  1932. rCmdUpdate.UapsdBitmap = 0x0F; /*params->uapsd_queues; */
  1933. rCmdUpdate.UapsdMaxSp = 0; /*params->max_sp; */
  1934. rCmdUpdate.u2Capability = params->capability;
  1935. if (params->ext_capab != NULL) {
  1936. u4Temp = params->ext_capab_len;
  1937. if (u4Temp > CMD_PEER_UPDATE_EXT_CAP_MAXLEN)
  1938. u4Temp = CMD_PEER_UPDATE_EXT_CAP_MAXLEN;
  1939. kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp);
  1940. rCmdUpdate.u2ExtCapLen = u4Temp;
  1941. }
  1942. if (params->ht_capa != NULL) {
  1943. rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info;
  1944. rCmdUpdate.rHtCap.ucAmpduParamsInfo = params->ht_capa->ampdu_params_info;
  1945. rCmdUpdate.rHtCap.u2ExtHtCapInfo = params->ht_capa->extended_ht_cap_info;
  1946. rCmdUpdate.rHtCap.u4TxBfCapInfo = params->ht_capa->tx_BF_cap_info;
  1947. rCmdUpdate.rHtCap.ucAntennaSelInfo = params->ht_capa->antenna_selection_info;
  1948. kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask,
  1949. params->ht_capa->mcs.rx_mask, sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask));
  1950. rCmdUpdate.rHtCap.rMCS.u2RxHighest = params->ht_capa->mcs.rx_highest;
  1951. rCmdUpdate.rHtCap.rMCS.ucTxParams = params->ht_capa->mcs.tx_params;
  1952. rCmdUpdate.fgIsSupHt = TRUE;
  1953. }
  1954. /* vht */
  1955. if (params->vht_capa != NULL) {
  1956. /* rCmdUpdate.rVHtCap */
  1957. /* rCmdUpdate.rVHtCap */
  1958. }
  1959. /* update a TDLS peer record */
  1960. /* sanity check */
  1961. if ((params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
  1962. rCmdUpdate.eStaType = STA_TYPE_DLS_PEER;
  1963. rStatus = kalIoctl(prGlueInfo, cnmPeerUpdate, &rCmdUpdate, sizeof(CMD_PEER_UPDATE_T), FALSE, FALSE, FALSE,
  1964. /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */
  1965. &u4BufLen);
  1966. if (rStatus != WLAN_STATUS_SUCCESS)
  1967. return -EINVAL;
  1968. /* for Ch Sw AP prohibit case */
  1969. if (prAisBssInfo->fgTdlsIsChSwProhibited) {
  1970. /* disable TDLS ch sw function */
  1971. rStatus = kalIoctl(prGlueInfo,
  1972. TdlsSendChSwControlCmd,
  1973. &TdlsSendChSwControlCmd, sizeof(CMD_TDLS_CH_SW_T), FALSE, FALSE, FALSE,
  1974. /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */
  1975. &u4BufLen);
  1976. }
  1977. return 0;
  1978. }
  1979. /*----------------------------------------------------------------------------*/
  1980. /*!
  1981. * @brief This routine is responsible for adding a station information
  1982. *
  1983. * @param
  1984. *
  1985. * @retval 0: successful
  1986. * others: failure
  1987. */
  1988. /*----------------------------------------------------------------------------*/
  1989. int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev,
  1990. const u8 *mac, struct station_parameters *params)
  1991. {
  1992. /* return 0; */
  1993. /* from supplicant -- wpa_supplicant_tdls_peer_addset() */
  1994. P_GLUE_INFO_T prGlueInfo = NULL;
  1995. CMD_PEER_ADD_T rCmdCreate;
  1996. ADAPTER_T *prAdapter;
  1997. WLAN_STATUS rStatus;
  1998. UINT_32 u4BufLen;
  1999. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  2000. ASSERT(prGlueInfo);
  2001. /* make up command */
  2002. prAdapter = prGlueInfo->prAdapter;
  2003. /* init */
  2004. kalMemZero(&rCmdCreate, sizeof(rCmdCreate));
  2005. kalMemCopy(rCmdCreate.aucPeerMac, mac, 6);
  2006. /* create a TDLS peer record */
  2007. if ((params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) {
  2008. rCmdCreate.eStaType = STA_TYPE_DLS_PEER;
  2009. rStatus = kalIoctl(prGlueInfo, cnmPeerAdd, &rCmdCreate, sizeof(CMD_PEER_ADD_T), FALSE, FALSE, FALSE,
  2010. /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */
  2011. &u4BufLen);
  2012. if (rStatus != WLAN_STATUS_SUCCESS)
  2013. return -EINVAL;
  2014. }
  2015. return 0;
  2016. }
  2017. /*----------------------------------------------------------------------------*/
  2018. /*!
  2019. * @brief This routine is responsible for deleting a station information
  2020. *
  2021. * @param
  2022. *
  2023. * @retval 0: successful
  2024. * others: failure
  2025. *
  2026. * @other
  2027. * must implement if you have add_station().
  2028. */
  2029. /*----------------------------------------------------------------------------*/
  2030. int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac)
  2031. {
  2032. /* fgIsTDLSlinkEnable = 0; */
  2033. /* return 0; */
  2034. /* from supplicant -- wpa_supplicant_tdls_peer_addset() */
  2035. P_GLUE_INFO_T prGlueInfo = NULL;
  2036. ADAPTER_T *prAdapter;
  2037. STA_RECORD_T *prStaRec;
  2038. u8 deleteMac[MAC_ADDR_LEN];
  2039. prAdapter = prGlueInfo->prAdapter;
  2040. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  2041. ASSERT(prGlueInfo);
  2042. /* For kernel 3.18 modification, we trasfer to local buff to query sta */
  2043. memset(deleteMac, 0, MAC_ADDR_LEN);
  2044. memcpy(&deleteMac, mac, MAC_ADDR_LEN);
  2045. prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) prAdapter->prAisBssInfo->ucBssIndex, deleteMac);
  2046. if (prStaRec != NULL)
  2047. cnmStaRecFree(prAdapter, prStaRec);
  2048. return 0;
  2049. }
  2050. /*----------------------------------------------------------------------------*/
  2051. /*!
  2052. * \brief This routine is called to transmit a TDLS data frame from nl80211.
  2053. *
  2054. * \param[in] pvAdapter Pointer to the Adapter structure.
  2055. * \param[in]
  2056. * \param[in]
  2057. * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
  2058. *
  2059. * \retval WLAN_STATUS_SUCCESS
  2060. * \retval WLAN_STATUS_INVALID_LENGTH
  2061. */
  2062. /*----------------------------------------------------------------------------*/
  2063. int
  2064. mtk_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
  2065. const u8 *peer, u8 action_code, u8 dialog_token,
  2066. u16 status_code, u32 peer_capability,
  2067. bool initiator, const u8 *buf, size_t len)
  2068. {
  2069. GLUE_INFO_T *prGlueInfo;
  2070. TDLS_CMD_LINK_MGT_T rCmdMgt;
  2071. UINT_32 u4BufLen;
  2072. /* sanity check */
  2073. if ((wiphy == NULL) || (peer == NULL) || (buf == NULL))
  2074. return -EINVAL;
  2075. /* init */
  2076. prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy);
  2077. if (prGlueInfo == NULL)
  2078. return -EINVAL;
  2079. kalMemZero(&rCmdMgt, sizeof(rCmdMgt));
  2080. rCmdMgt.u2StatusCode = status_code;
  2081. rCmdMgt.u4SecBufLen = len;
  2082. rCmdMgt.ucDialogToken = dialog_token;
  2083. rCmdMgt.ucActionCode = action_code;
  2084. kalMemCopy(&(rCmdMgt.aucPeer), peer, 6);
  2085. kalMemCopy(&(rCmdMgt.aucSecBuf), buf, len);
  2086. kalIoctl(prGlueInfo, TdlsexLinkMgt, &rCmdMgt, sizeof(TDLS_CMD_LINK_MGT_T), FALSE, FALSE, FALSE,
  2087. /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */
  2088. &u4BufLen);
  2089. return 0;
  2090. }
  2091. /*----------------------------------------------------------------------------*/
  2092. /*!
  2093. * \brief This routine is called to hadel TDLS link from nl80211.
  2094. *
  2095. * \param[in] pvAdapter Pointer to the Adapter structure.
  2096. * \param[in]
  2097. * \param[in]
  2098. * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
  2099. *
  2100. * \retval WLAN_STATUS_SUCCESS
  2101. * \retval WLAN_STATUS_INVALID_LENGTH
  2102. */
  2103. /*----------------------------------------------------------------------------*/
  2104. int mtk_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
  2105. const u8 *peer, enum nl80211_tdls_operation oper)
  2106. {
  2107. P_GLUE_INFO_T prGlueInfo = NULL;
  2108. UINT_32 u4BufLen;
  2109. ADAPTER_T *prAdapter;
  2110. TDLS_CMD_LINK_OPER_T rCmdOper;
  2111. prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
  2112. ASSERT(prGlueInfo);
  2113. prAdapter = prGlueInfo->prAdapter;
  2114. kalMemZero(&rCmdOper, sizeof(rCmdOper));
  2115. kalMemCopy(rCmdOper.aucPeerMac, peer, 6);
  2116. rCmdOper.oper = oper;
  2117. kalIoctl(prGlueInfo, TdlsexLinkOper, &rCmdOper, sizeof(TDLS_CMD_LINK_OPER_T), FALSE, FALSE, FALSE,
  2118. /* FALSE, //6628 -> 6630 fgIsP2pOid-> x */
  2119. &u4BufLen);
  2120. return 0;
  2121. }
  2122. #if CFG_AUTO_CHANNEL_SEL_SUPPORT
  2123. int
  2124. mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo)
  2125. {
  2126. #define MAXMUN_2_4G_CHA_NUM 14
  2127. #define CHN_DIRTY_WEIGHT_UPPERBOUND 4
  2128. BOOLEAN fgIsReady = FALSE;
  2129. BOOLEAN fgIsPureAP;
  2130. UINT_8 ucIdx = 0, ucMax_24G_Chn_List = 11, ucChValidCnt = 0, ucDefaultIdx = 0;
  2131. UINT_16 u2APNumScore = 0, u2UpThsrold = 0, u2LowThsrold = 0, ucInnerIdx = 0;
  2132. INT_32 i4Status = -EINVAL;
  2133. UINT_32 u4BufLen;
  2134. UINT_32 AcsChnRepot[4];
  2135. UINT_32 u4TempSafeChannelBitmask = 0;
  2136. UINT_8 u1Buf = 0;
  2137. struct sk_buff *skb;
  2138. WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
  2139. PARAM_GET_CHN_LOAD rQueryLTEChn;
  2140. PARAM_PREFER_CHN_INFO PreferChannels[2] = { {0, 0, {0} }, };
  2141. PARAM_PREFER_CHN_INFO ar2_4G_ChannelLoadingWeightScore[MAXMUN_2_4G_CHA_NUM] = { {0, 0, {0} }, };
  2142. /* P_DOMAIN_INFO_ENTRY prDomainInfo = NULL; */
  2143. /* RF_CHANNEL_INFO_T aucChannelList[14]; */
  2144. P_PARAM_GET_CHN_LOAD prGetChnLoad;
  2145. ASSERT(wiphy);
  2146. ASSERT(prGlueInfo);
  2147. fgIsPureAP = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->fgIsApMode;
  2148. /* Prepare Reply skb buffer */
  2149. skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1);
  2150. if (!skb) {
  2151. DBGLOG(QM, TRACE, "%s allocate skb failed:%lx\n", __func__, rStatus);
  2152. return -ENOMEM;
  2153. }
  2154. DBGLOG(P2P, INFO, "[Auto Channel]Get LTE Channels\n");
  2155. kalMemZero(&rQueryLTEChn, sizeof(rQueryLTEChn));
  2156. /* Query LTE Safe Channels */
  2157. rStatus = kalIoctl(prGlueInfo,
  2158. wlanoidQueryACSChannelList, &rQueryLTEChn, sizeof(rQueryLTEChn), TRUE, FALSE, TRUE,
  2159. /* TRUE, //6628 -> 6630 fgIsP2pOid-> x */
  2160. &u4BufLen);
  2161. /* u4SafeChannelBitmask[0] -> 2G4 */
  2162. /* u4SafeChannelBitmask[1/2/3] -> 5G */
  2163. u4TempSafeChannelBitmask = rQueryLTEChn.rLteSafeChnList.u4SafeChannelBitmask[0];
  2164. DBGLOG(P2P, INFO,
  2165. " rLteSafeChnList.u4SafeChannelBitmask=%08x\n",
  2166. rQueryLTEChn.rLteSafeChnList.u4SafeChannelBitmask[0]);
  2167. #if 0
  2168. if (fgIsPureAP) {
  2169. AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = 0x20; /* Channel 6 */
  2170. } else
  2171. #endif
  2172. {
  2173. /* Get the Maximun channel List in 2.4G Bands */
  2174. /* Determin if countryCode is valid */
  2175. /* whatever case only support ch 1~11 */
  2176. /* if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.u2CountryCode != 0x0000) { */
  2177. /* prDomainInfo = rlmDomainGetDomainInfo(prGlueInfo->prAdapter); */
  2178. /* ASSERT(prDomainInfo); */
  2179. /* 2. Get current domain channel list */
  2180. /* kalMemZero(aucChannelList, sizeof(aucChannelList)); */
  2181. /* rlmDomainGetChnlList(prGlueInfo->prAdapter, */
  2182. /* BAND_2G4, */
  2183. /* 14, */
  2184. /* &ucMax_24G_Chn_List, */
  2185. /* aucChannelList); */
  2186. /* } else { */
  2187. ucMax_24G_Chn_List = 11;
  2188. /* } */
  2189. DBGLOG(P2P, INFO, "ucMax_24G_Chn_List=%d\n", ucMax_24G_Chn_List);
  2190. prGetChnLoad = (P_PARAM_GET_CHN_LOAD) &(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo);
  2191. for (ucIdx = 0; ucIdx < ucMax_24G_Chn_List; ucIdx++) {
  2192. DBGLOG(P2P, INFO,
  2193. "[Auto Channel][Ori_AP_Num] ch[%d]=%d\n", ucIdx + 1,
  2194. prGetChnLoad->rEachChnLoad[ucIdx].u2APNum);
  2195. }
  2196. ucDefaultIdx = 0;
  2197. for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) {
  2198. #if 1
  2199. u2APNumScore = prGetChnLoad->rEachChnLoad[ucIdx].u2APNum * CHN_DIRTY_WEIGHT_UPPERBOUND;
  2200. u2UpThsrold = u2LowThsrold = 3;
  2201. if (ucIdx < 3) {
  2202. u2UpThsrold = ucIdx;
  2203. u2LowThsrold = 3;
  2204. } else if (ucIdx >= (ucMax_24G_Chn_List - 3)) {
  2205. u2UpThsrold = 3;
  2206. u2LowThsrold = ucMax_24G_Chn_List - (ucIdx + 1);
  2207. }
  2208. for (ucInnerIdx = 0; ucInnerIdx < u2LowThsrold; ucInnerIdx++) {
  2209. u2APNumScore +=
  2210. (prGetChnLoad->rEachChnLoad[ucIdx + ucInnerIdx + 1].u2APNum *
  2211. (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx));
  2212. }
  2213. for (ucInnerIdx = 0; ucInnerIdx < u2UpThsrold; ucInnerIdx++) {
  2214. u2APNumScore +=
  2215. (prGetChnLoad->rEachChnLoad[ucIdx - ucInnerIdx - 1].u2APNum *
  2216. (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx));
  2217. }
  2218. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
  2219. DBGLOG(P2P, INFO, "[Auto Channel]chn=%d score=%d\n", ucIdx + 1, u2APNumScore);
  2220. #else
  2221. if (ucIdx == 0) {
  2222. /* ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum =
  2223. (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum +
  2224. prGetChnLoad->rEachChnLoad[ucIdx+1].u2APNum*0.75); */
  2225. u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16)
  2226. ((3 *
  2227. (prGetChnLoad->
  2228. rEachChnLoad[ucIdx +
  2229. 1].
  2230. u2APNum +
  2231. prGetChnLoad->
  2232. rEachChnLoad[ucIdx +
  2233. 2].
  2234. u2APNum)) / 4)));
  2235. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
  2236. DBGLOG(P2P, INFO,
  2237. "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx,
  2238. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum,
  2239. prGetChnLoad->rEachChnLoad[ucIdx].u2APNum,
  2240. prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum);
  2241. }
  2242. if ((ucIdx > 0) && (ucIdx < (MAXMUN_2_4G_CHA_NUM - 1))) {
  2243. u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16)
  2244. ((3 *
  2245. (prGetChnLoad->
  2246. rEachChnLoad[ucIdx +
  2247. 1].
  2248. u2APNum +
  2249. prGetChnLoad->
  2250. rEachChnLoad[ucIdx -
  2251. 1].
  2252. u2APNum)) / 4)));
  2253. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
  2254. DBGLOG(P2P, INFO,
  2255. "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d+0.75*%d\n", ucIdx,
  2256. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum,
  2257. prGetChnLoad->rEachChnLoad[ucIdx].u2APNum,
  2258. prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum,
  2259. prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum);
  2260. }
  2261. if (ucIdx == (MAXMUN_2_4G_CHA_NUM - 1)) {
  2262. u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum +
  2263. ((UINT_16) ((3 * prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum) / 4)));
  2264. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore;
  2265. DBGLOG(P2P, INFO,
  2266. "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx,
  2267. ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum,
  2268. prGetChnLoad->rEachChnLoad[ucIdx].u2APNum,
  2269. prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum);
  2270. }
  2271. #endif
  2272. }
  2273. fgIsReady = prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit;
  2274. PreferChannels[0].ucChannel = 0; /* default channel : ch1 */
  2275. PreferChannels[1].ucChannel = 0; /* default channel : ch1 */
  2276. PreferChannels[0].u2APNum = 0xFFFF; /* default channel score : 0xFFFF */
  2277. PreferChannels[1].u2APNum = 0xFFFF; /* default channel score : 0xFFFF */
  2278. /* (u4TempSafeChannelBitmask & BIT(1) == 1) -> 2G Ch1 is valid */
  2279. if (u4TempSafeChannelBitmask == 0) {
  2280. DBGLOG(P2P, WARN, " Can't get any safe channel from fw!?\n");
  2281. u4TempSafeChannelBitmask = BITS(1, (ucMax_24G_Chn_List));
  2282. }
  2283. DBGLOG(P2P, INFO, " SafeChannelBitmask=%08x\n", u4TempSafeChannelBitmask);
  2284. ucChValidCnt = 0;
  2285. for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) {
  2286. if (!(u4TempSafeChannelBitmask & BIT(ucIdx + 1)))
  2287. continue;
  2288. if (PreferChannels[0].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum) {
  2289. PreferChannels[1].ucChannel = PreferChannels[0].ucChannel;
  2290. PreferChannels[1].u2APNum = PreferChannels[0].u2APNum;
  2291. PreferChannels[0].ucChannel = ucIdx;
  2292. PreferChannels[0].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum;
  2293. } else {
  2294. if (PreferChannels[1].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum) {
  2295. PreferChannels[1].ucChannel = ucIdx;
  2296. PreferChannels[1].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum;
  2297. }
  2298. }
  2299. ucChValidCnt++;
  2300. }
  2301. AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = fgIsReady ? BIT(31) : 0;
  2302. if (ucChValidCnt >= 1) {
  2303. if (ucChValidCnt == 1) {
  2304. PreferChannels[1].ucChannel = PreferChannels[0].ucChannel;
  2305. PreferChannels[1].u2APNum = PreferChannels[0].u2APNum;
  2306. }
  2307. AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] |=
  2308. (BIT(PreferChannels[1].ucChannel) | BIT(PreferChannels[0].ucChannel));
  2309. }
  2310. }
  2311. /* ToDo: Support 5G Channel Selection */
  2312. AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] = 0x11223344;
  2313. AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] = 0x55667788;
  2314. AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = 0x99AABBCC;
  2315. if (!NLA_PUT_U8(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, &u1Buf))
  2316. return i4Status;
  2317. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1,
  2318. &AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]))
  2319. return i4Status;
  2320. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34,
  2321. &AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]))
  2322. return i4Status;
  2323. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149,
  2324. &AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]))
  2325. return i4Status;
  2326. if (!NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184,
  2327. &AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]))
  2328. return i4Status;
  2329. DBGLOG(P2P, INFO, "[Auto Channel]Relpy AcsChanInfo[%x:%x:%x:%x]\n",
  2330. AcsChnRepot[0], AcsChnRepot[1], AcsChnRepot[2], AcsChnRepot[3]);
  2331. i4Status = cfg80211_testmode_reply(skb);
  2332. return i4Status;
  2333. }
  2334. #endif
  2335. #endif