platform.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. /*
  2. ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/platform.c#3
  3. */
  4. /*! \file "platform.c"
  5. \brief This file including the protocol layer privacy function.
  6. This file provided the macros and functions library support for the
  7. protocol layer security setting from wlan_oid.c and for parse.c and
  8. rsn.c and nic_privacy.c
  9. */
  10. /*
  11. ** Log: platform.c
  12. **
  13. ** 09 17 2012 cm.chang
  14. ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
  15. ** Duplicate source from MT6620 v2.3 driver branch
  16. ** (Davinci label: MT6620_WIFI_Driver_V2_3_120913_1942_As_MT6630_Base)
  17. **
  18. ** 08 24 2012 cp.wu
  19. ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
  20. ** .
  21. *
  22. * 11 14 2011 cm.chang
  23. * NULL
  24. * Fix compiling warning
  25. *
  26. * 11 10 2011 cp.wu
  27. * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
  28. * 1. eliminaite direct calls to printk in porting layer.
  29. * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
  30. *
  31. * 09 13 2011 jeffrey.chang
  32. * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection
  33. * fix the pointer casting
  34. *
  35. * 06 29 2011 george.huang
  36. * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6
  37. * .
  38. *
  39. * 06 28 2011 george.huang
  40. * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6
  41. * remove un-used code
  42. *
  43. * 05 11 2011 jeffrey.chang
  44. * NULL
  45. * fix build error
  46. *
  47. * 05 09 2011 jeffrey.chang
  48. * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change
  49. * support ARP filter through kernel notifier
  50. *
  51. * 04 08 2011 pat.lu
  52. * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
  53. * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver
  54. *
  55. * 03 22 2011 pat.lu
  56. * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
  57. * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
  58. *
  59. * 03 21 2011 cp.wu
  60. * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
  61. * improve portability for awareness of early version of linux kernel and wireless extension.
  62. *
  63. * 03 18 2011 jeffrey.chang
  64. * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
  65. * remove early suspend functions
  66. *
  67. * 03 03 2011 jeffrey.chang
  68. * NULL
  69. * add the ARP filter callback
  70. *
  71. * 02 15 2011 jeffrey.chang
  72. * NULL
  73. * to support early suspend in android
  74. *
  75. * 02 01 2011 cp.wu
  76. * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1
  77. * branch
  78. * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/...
  79. *
  80. * 11 01 2010 cp.wu
  81. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver]
  82. * Add implementation for querying current TX rate from firmware auto rate module
  83. * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
  84. * 2) Remove CNM CH-RECOVER event handling
  85. * 3) cfg read/write API renamed with kal prefix for unified naming rules.
  86. *
  87. * 10 18 2010 cp.wu
  88. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver]
  89. * The mac address is all zero at android
  90. * complete implementation of Android NVRAM access
  91. *
  92. * 10 05 2010 cp.wu
  93. * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
  94. * 1) add NVRAM access API
  95. * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
  96. * 3) add OID implementation for NVRAM read/write service
  97. *
  98. **
  99. */
  100. /*******************************************************************************
  101. * C O M P I L E R F L A G S
  102. ********************************************************************************
  103. */
  104. /*******************************************************************************
  105. * E X T E R N A L R E F E R E N C E S
  106. ********************************************************************************
  107. */
  108. #include <linux/version.h>
  109. #include <linux/init.h>
  110. #include <linux/types.h>
  111. #include <linux/module.h>
  112. #include <linux/fs.h>
  113. #include <linux/uaccess.h>
  114. #include "gl_os.h"
  115. #if CFG_ENABLE_EARLY_SUSPEND
  116. #include <linux/earlysuspend.h>
  117. #endif
  118. /*******************************************************************************
  119. * C O N S T A N T S
  120. ********************************************************************************
  121. */
  122. #define WIFI_NVRAM_FILE_NAME "/data/nvram/APCFG/APRDEB/WIFI"
  123. #define WIFI_NVRAM_CUSTOM_NAME "/data/nvram/APCFG/APRDEB/WIFI_CUSTOM"
  124. /*******************************************************************************
  125. * D A T A T Y P E S
  126. ********************************************************************************
  127. */
  128. /*******************************************************************************
  129. * P U B L I C D A T A
  130. ********************************************************************************
  131. */
  132. /*******************************************************************************
  133. * P R I V A T E D A T A
  134. ********************************************************************************
  135. */
  136. /*******************************************************************************
  137. * M A C R O S
  138. ********************************************************************************
  139. */
  140. /*******************************************************************************
  141. * F U N C T I O N D E C L A R A T I O N S
  142. ********************************************************************************
  143. */
  144. /*******************************************************************************
  145. * F U N C T I O N S
  146. ********************************************************************************
  147. */
  148. static int netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
  149. {
  150. struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
  151. struct net_device *prDev = ifa->ifa_dev->dev;
  152. P_GLUE_INFO_T prGlueInfo = NULL;
  153. if (prDev == NULL) {
  154. /* DBGLOG(REQ, INFO, ("netdev_event: device is empty.\n")); */
  155. return NOTIFY_DONE;
  156. }
  157. if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) {
  158. /* DBGLOG(REQ, INFO, ("netdev_event: xxx\n")); */
  159. return NOTIFY_DONE;
  160. }
  161. #if 0 /* CFG_SUPPORT_PASSPOINT */
  162. {
  163. /* DBGLOG(REQ, INFO, "[netdev_event] IPV4_DAD is unlock now!!\n"); */
  164. prGlueInfo->fgIsDad = FALSE;
  165. }
  166. #endif /* CFG_SUPPORT_PASSPOINT */
  167. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  168. if (prGlueInfo == NULL) {
  169. DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n");
  170. return NOTIFY_DONE;
  171. }
  172. if (prGlueInfo->fgIsInSuspendMode == FALSE) {
  173. /* DBGLOG(REQ, INFO,
  174. ("netdev_event: PARAM_MEDIA_STATE_DISCONNECTED. (%d)\n", prGlueInfo->eParamMediaStateIndicated)); */
  175. return NOTIFY_DONE;
  176. }
  177. kalSetNetAddressFromInterface(prGlueInfo, prDev, TRUE);
  178. return NOTIFY_DONE;
  179. }
  180. #if 0 /* CFG_SUPPORT_PASSPOINT */
  181. static int net6dev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
  182. {
  183. struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
  184. struct net_device *prDev = ifa->idev->dev;
  185. P_GLUE_INFO_T prGlueInfo = NULL;
  186. if (prDev == NULL) {
  187. DBGLOG(REQ, INFO, "net6dev_event: device is empty.\n");
  188. return NOTIFY_DONE;
  189. }
  190. if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) {
  191. DBGLOG(REQ, INFO, "net6dev_event: xxx\n");
  192. return NOTIFY_DONE;
  193. }
  194. if (strncmp(prDev->name, "p2p", 3) == 0) {
  195. /* because we store the address of prGlueInfo in p2p's private date of net device */
  196. /* *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo; */
  197. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  198. } else { /* wlan0 */
  199. prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev);
  200. }
  201. if (prGlueInfo == NULL) {
  202. DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n");
  203. return NOTIFY_DONE;
  204. }
  205. /* DBGLOG(REQ, INFO, "[net6dev_event] IPV6_DAD is unlock now!!\n"); */
  206. prGlueInfo->fgIs6Dad = FALSE;
  207. return NOTIFY_DONE;
  208. }
  209. #endif /* CFG_SUPPORT_PASSPOINT */
  210. static struct notifier_block inetaddr_notifier = {
  211. .notifier_call = netdev_event,
  212. };
  213. #if 0 /* CFG_SUPPORT_PASSPOINT */
  214. static struct notifier_block inet6addr_notifier = {
  215. .notifier_call = net6dev_event,
  216. };
  217. #endif /* CFG_SUPPORT_PASSPOINT */
  218. void wlanRegisterNotifier(void)
  219. {
  220. register_inetaddr_notifier(&inetaddr_notifier);
  221. #if 0 /* CFG_SUPPORT_PASSPOINT */
  222. register_inet6addr_notifier(&inet6addr_notifier);
  223. #endif /* CFG_SUPPORT_PASSPOINT */
  224. }
  225. void wlanUnregisterNotifier(void)
  226. {
  227. unregister_inetaddr_notifier(&inetaddr_notifier);
  228. #if 0 /* CFG_SUPPORT_PASSPOINT */
  229. unregister_inetaddr_notifier(&inet6addr_notifier);
  230. #endif /* CFG_SUPPORT_PASSPOINT */
  231. }
  232. #if CFG_ENABLE_EARLY_SUSPEND
  233. /*----------------------------------------------------------------------------*/
  234. /*!
  235. * \brief This function will register platform driver to os
  236. *
  237. * \param[in] wlanSuspend Function pointer to platform suspend function
  238. * \param[in] wlanResume Function pointer to platform resume function
  239. *
  240. * \return The result of registering earlysuspend
  241. */
  242. /*----------------------------------------------------------------------------*/
  243. int glRegisterEarlySuspend(struct early_suspend *prDesc,
  244. early_suspend_callback wlanSuspend, late_resume_callback wlanResume)
  245. {
  246. int ret = 0;
  247. if (NULL != wlanSuspend)
  248. prDesc->suspend = wlanSuspend;
  249. else {
  250. DBGLOG(REQ, INFO, "glRegisterEarlySuspend wlanSuspend ERROR.\n");
  251. ret = -1;
  252. }
  253. if (NULL != wlanResume)
  254. prDesc->resume = wlanResume;
  255. else {
  256. DBGLOG(REQ, INFO, "glRegisterEarlySuspend wlanResume ERROR.\n");
  257. ret = -1;
  258. }
  259. register_early_suspend(prDesc);
  260. return ret;
  261. }
  262. /*----------------------------------------------------------------------------*/
  263. /*!
  264. * \brief This function will un-register platform driver to os
  265. *
  266. * \return The result of un-registering earlysuspend
  267. */
  268. /*----------------------------------------------------------------------------*/
  269. int glUnregisterEarlySuspend(struct early_suspend *prDesc)
  270. {
  271. int ret = 0;
  272. unregister_early_suspend(prDesc);
  273. prDesc->suspend = NULL;
  274. prDesc->resume = NULL;
  275. return ret;
  276. }
  277. #endif
  278. /*----------------------------------------------------------------------------*/
  279. /*!
  280. * \brief Utility function for reading data from files on NVRAM-FS
  281. *
  282. * \param[in]
  283. * filename
  284. * len
  285. * offset
  286. * \param[out]
  287. * buf
  288. * \return
  289. * actual length of data being read
  290. */
  291. /*----------------------------------------------------------------------------*/
  292. static int nvram_read(char *filename, char *buf, ssize_t len, int offset)
  293. {
  294. #if CFG_SUPPORT_NVRAM
  295. struct file *fd;
  296. int retLen = -1;
  297. mm_segment_t old_fs = get_fs();
  298. set_fs(KERNEL_DS);
  299. fd = filp_open(filename, O_RDONLY, 0644);
  300. if (IS_ERR(fd)) {
  301. DBGLOG(INIT, INFO, "[nvram_read] : failed to open!!\n");
  302. return -1;
  303. }
  304. do {
  305. if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) {
  306. DBGLOG(INIT, INFO, "[nvram_read] : file can not be read!!\n");
  307. break;
  308. }
  309. if (fd->f_pos != offset) {
  310. if (fd->f_op->llseek) {
  311. if (fd->f_op->llseek(fd, offset, 0) != offset) {
  312. DBGLOG(INIT, INFO, "[nvram_read] : failed to seek!!\n");
  313. break;
  314. }
  315. } else {
  316. fd->f_pos = offset;
  317. }
  318. }
  319. retLen = fd->f_op->read(fd, buf, len, &fd->f_pos);
  320. } while (FALSE);
  321. filp_close(fd, NULL);
  322. set_fs(old_fs);
  323. return retLen;
  324. #else /* !CFG_SUPPORT_NVRAM */
  325. return -EIO;
  326. #endif
  327. }
  328. /*----------------------------------------------------------------------------*/
  329. /*!
  330. * \brief Utility function for writing data to files on NVRAM-FS
  331. *
  332. * \param[in]
  333. * filename
  334. * buf
  335. * len
  336. * offset
  337. * \return
  338. * actual length of data being written
  339. */
  340. /*----------------------------------------------------------------------------*/
  341. static int nvram_write(char *filename, char *buf, ssize_t len, int offset)
  342. {
  343. #if CFG_SUPPORT_NVRAM
  344. struct file *fd;
  345. int retLen = -1;
  346. mm_segment_t old_fs = get_fs();
  347. set_fs(KERNEL_DS);
  348. fd = filp_open(filename, O_WRONLY | O_CREAT, 0644);
  349. if (IS_ERR(fd)) {
  350. DBGLOG(INIT, INFO, "[nvram_write] : failed to open!!\n");
  351. return -1;
  352. }
  353. do {
  354. if ((fd->f_op == NULL) || (fd->f_op->write == NULL)) {
  355. DBGLOG(INIT, INFO, "[nvram_write] : file can not be write!!\n");
  356. break;
  357. }
  358. /* End of if */
  359. if (fd->f_pos != offset) {
  360. if (fd->f_op->llseek) {
  361. if (fd->f_op->llseek(fd, offset, 0) != offset) {
  362. DBGLOG(INIT, INFO, "[nvram_write] : failed to seek!!\n");
  363. break;
  364. }
  365. } else {
  366. fd->f_pos = offset;
  367. }
  368. }
  369. retLen = fd->f_op->write(fd, buf, len, &fd->f_pos);
  370. } while (FALSE);
  371. filp_close(fd, NULL);
  372. set_fs(old_fs);
  373. return retLen;
  374. #else /* !CFG_SUPPORT_NVRAMS */
  375. return -EIO;
  376. #endif
  377. }
  378. /*----------------------------------------------------------------------------*/
  379. /*!
  380. * \brief API for reading data on NVRAM
  381. *
  382. * \param[in]
  383. * prGlueInfo
  384. * u4Offset
  385. * \param[out]
  386. * pu2Data
  387. * \return
  388. * TRUE
  389. * FALSE
  390. */
  391. /*----------------------------------------------------------------------------*/
  392. BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data)
  393. {
  394. if (pu2Data == NULL)
  395. return FALSE;
  396. if (nvram_read(WIFI_NVRAM_FILE_NAME,
  397. (char *)pu2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) {
  398. return FALSE;
  399. } else {
  400. return TRUE;
  401. }
  402. }
  403. /*----------------------------------------------------------------------------*/
  404. /*!
  405. * \brief API for writing data on NVRAM
  406. *
  407. * \param[in]
  408. * prGlueInfo
  409. * u4Offset
  410. * u2Data
  411. * \return
  412. * TRUE
  413. * FALSE
  414. */
  415. /*----------------------------------------------------------------------------*/
  416. BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, UINT_32 u4Offset, UINT_16 u2Data)
  417. {
  418. if (nvram_write(WIFI_NVRAM_FILE_NAME,
  419. (char *)&u2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) {
  420. return FALSE;
  421. } else {
  422. return TRUE;
  423. }
  424. }