Advertisement
Guest User

Untitled

a guest
Aug 15th, 2017
1,070
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 219.28 KB | None | 0 0
  1. commit 4129e1b35461013b1f27131d23c20114599906c6
  2. Author: Arnd Bergmann <arnd@arndb.de>
  3. Date:   Tue Feb 10 08:36:05 2015 +0100
  4.  
  5.     import
  6.  
  7. commit 4129e1b35461013b1f27131d23c20114599906c6
  8. Author: Arnd Bergmann <arnd@arndb.de>
  9. Date:   Tue Feb 10 08:36:05 2015 +0100
  10.  
  11.     import
  12.  
  13.  drivers/net/wireless/sprdwl/Kconfig                |    7 +
  14.  drivers/net/wireless/sprdwl/Makefile               |   11 +
  15.  .../net/wireless/sprdwl/sprdwl_mem_alloc/Kconfig   |    3 +
  16.  .../net/wireless/sprdwl/sprdwl_mem_alloc/Makefile  |    1 +
  17.  .../sprdwl/sprdwl_mem_alloc/sprdwl_mem_alloc.c     |  103 +
  18.  drivers/net/wireless/sprdwl/wlan_cfg80211.c        | 2742 ++++++++++++++++++++
  19.  drivers/net/wireless/sprdwl/wlan_cfg80211.h        |  132 +
  20.  drivers/net/wireless/sprdwl/wlan_cmd.c             |  920 +++++++
  21.  drivers/net/wireless/sprdwl/wlan_cmd.h             |  352 +++
  22.  drivers/net/wireless/sprdwl/wlan_common.h          |  275 ++
  23.  drivers/net/wireless/sprdwl/wlan_core.c            | 1228 +++++++++
  24.  drivers/net/wireless/sprdwl/wlan_event_q.c         |  123 +
  25.  drivers/net/wireless/sprdwl/wlan_event_q.h         |   49 +
  26.  drivers/net/wireless/sprdwl/wlan_fifo.c            |  326 +++
  27.  drivers/net/wireless/sprdwl/wlan_fifo.h            |  106 +
  28.  drivers/net/wireless/sprdwl/wlan_hostapd_conf.c    |  227 ++
  29.  drivers/net/wireless/sprdwl/wlan_npi.c             |  173 ++
  30.  drivers/net/wireless/sprdwl/wlan_wapi.c            |  666 +++++
  31.  drivers/net/wireless/sprdwl/wlan_wapi.h            |  158 ++
  32.  19 files changed, 7602 insertions(+)
  33.  
  34.  
  35. diff --git a/drivers/net/wireless/sprdwl/Kconfig b/drivers/net/wireless/sprdwl/Kconfig
  36. new file mode 100644
  37. index 0000000..07c7927
  38. --- /dev/null
  39. +++ b/drivers/net/wireless/sprdwl/Kconfig
  40. @@ -0,0 +1,7 @@
  41. +config SPRDWL
  42. +   tristate "SPRDWL Wireless Network Support"
  43. +   depends on CFG80211
  44. +   ---help---
  45. +     Say Y to enable built-in wireless MAC controller in the
  46. +     Spreadtrum SC88xx based System-on-Chip devices.
  47. +
  48. diff --git a/drivers/net/wireless/sprdwl/Makefile b/drivers/net/wireless/sprdwl/Makefile
  49. new file mode 100644
  50. index 0000000..e3c81de
  51. --- /dev/null
  52. +++ b/drivers/net/wireless/sprdwl/Makefile
  53. @@ -0,0 +1,11 @@
  54. +#ccflags-y += -Werror
  55. +ccflags-y += -fno-PIC
  56. +
  57. +obj-$(CONFIG_SPRDWL) += sprdwl.o
  58. +
  59. +sprdwl-objs:= wlan_core.o wlan_fifo.o \
  60. +             wlan_event_q.o wlan_cmd.o \
  61. +             wlan_npi.o wlan_hostapd_conf.o \
  62. +             wlan_cfg80211.o wlan_wapi.o \
  63. +             $(sprdwl-y)
  64. +
  65. diff --git a/drivers/net/wireless/sprdwl/sprdwl_mem_alloc/Kconfig b/drivers/net/wireless/sprdwl/sprdwl_mem_alloc/Kconfig
  66. new file mode 100644
  67. index 0000000..8380941
  68. --- /dev/null
  69. +++ b/drivers/net/wireless/sprdwl/sprdwl_mem_alloc/Kconfig
  70. @@ -0,0 +1,3 @@
  71. +config SPRDWL_MEM_ALLOC
  72. +   bool "sprdwl mem alloc "
  73. +   default y
  74. diff --git a/drivers/net/wireless/sprdwl/sprdwl_mem_alloc/Makefile b/drivers/net/wireless/sprdwl/sprdwl_mem_alloc/Makefile
  75. new file mode 100644
  76. index 0000000..c1fcb11
  77. --- /dev/null
  78. +++ b/drivers/net/wireless/sprdwl/sprdwl_mem_alloc/Makefile
  79. @@ -0,0 +1 @@
  80. +obj-$(CONFIG_SPRDWL_MEM_ALLOC) += sprdwl_mem_alloc.o
  81. \ No newline at end of file
  82. diff --git a/drivers/net/wireless/sprdwl/sprdwl_mem_alloc/sprdwl_mem_alloc.c b/drivers/net/wireless/sprdwl/sprdwl_mem_alloc/sprdwl_mem_alloc.c
  83. new file mode 100644
  84. index 0000000..4b8e662
  85. --- /dev/null
  86. +++ b/drivers/net/wireless/sprdwl/sprdwl_mem_alloc/sprdwl_mem_alloc.c
  87. @@ -0,0 +1,103 @@
  88. +#include <linux/proc_fs.h>
  89. +#include <linux/sipc.h>
  90. +#include <linux/mutex.h>
  91. +#include <linux/spinlock.h>
  92. +#include <linux/ieee80211.h>
  93. +#include <linux/printk.h>
  94. +#include <linux/inetdevice.h>
  95. +#include <linux/spinlock.h>
  96. +#include <net/cfg80211.h>
  97. +#include <linux/kernel.h>
  98. +#include <linux/errno.h>
  99. +#include <linux/module.h>
  100. +#include <linux/netdevice.h>
  101. +#include <linux/skbuff.h>
  102. +#include <net/ieee80211_radiotap.h>
  103. +#include <linux/etherdevice.h>
  104. +#include <linux/wireless.h>
  105. +#include <net/iw_handler.h>
  106. +#include <linux/string.h>
  107. +#include <linux/delay.h>
  108. +#include <linux/interrupt.h>
  109. +#include <linux/init.h>
  110. +#include <linux/wakelock.h>
  111. +#include <linux/workqueue.h>
  112. +#include <linux/ipv6.h>
  113. +#include <linux/ip.h>
  114. +#include <linux/inetdevice.h>
  115. +#include <asm/byteorder.h>
  116. +#include <linux/platform_device.h>
  117. +#include <linux/atomic.h>
  118. +#include <linux/wait.h>
  119. +#include <linux/semaphore.h>
  120. +#include <linux/vmalloc.h>
  121. +#include <linux/kthread.h>
  122. +#include <linux/time.h>
  123. +#include <linux/delay.h>
  124. +#include <linux/timer.h>
  125. +#include <linux/completion.h>
  126. +#include <asm/atomic.h>
  127. +#include <linux/ieee80211.h>
  128. +#include <linux/delay.h>
  129. +
  130. +#define WIFI_MEM_BLOCK_NUM   (2)
  131. +
  132. +typedef struct
  133. +{
  134. +        int            status;
  135. +        unsigned char *mem;
  136. +}m_mem_t;
  137. +
  138. +static m_mem_t wifi_mem[WIFI_MEM_BLOCK_NUM] = {0};
  139. +unsigned char *wifi_256k_alloc(void)
  140. +{
  141. +   unsigned char *p= NULL;
  142. +   int i;
  143. +   for(i=0; i< WIFI_MEM_BLOCK_NUM; i++)
  144. +   {
  145. +       if( (0 == wifi_mem[i].status) &&  (NULL != wifi_mem[i].mem) )
  146. +       {
  147. +           p = wifi_mem[i].mem;
  148. +           wifi_mem[i].status = 1;
  149. +           printk("\001" "0" "[wifi_256k_alloc][%d][0x%x]\n", i, wifi_mem[i].mem );
  150. +           break;
  151. +       }
  152. +   }
  153. +   return p;
  154. +}
  155. +EXPORT_SYMBOL_GPL(wifi_256k_alloc);
  156. +
  157. +int wifi_256k_free(unsigned char *mem)
  158. +{
  159. +   int i;
  160. +   for(i=0; i< WIFI_MEM_BLOCK_NUM; i++)
  161. +   {
  162. +       if(mem == wifi_mem[i].mem)
  163. +       {
  164. +           wifi_mem[i].status = 0;
  165. +           printk("\001" "0" "[wifi_256k_free][%d][0x%x]\n", i, wifi_mem[i].mem );
  166. +           return 0;
  167. +       }
  168. +   }
  169. +   return -1;
  170. +}
  171. +EXPORT_SYMBOL_GPL(wifi_256k_free);
  172. +
  173. +static int sprdwl_mem_alloc(void)
  174. +{
  175. +   int i;
  176. +   printk("[%s]\n", __func__);
  177. +   for(i = 0; i < WIFI_MEM_BLOCK_NUM; i++)
  178. +   {
  179. +       wifi_mem[i].mem = kmalloc( 256*1024, GFP_ATOMIC);
  180. +       printk("\001" "0" "[wifi_mem][%d][0x%x]\n", i, wifi_mem[i].mem );
  181. +   }
  182. +   return 0;
  183. +}
  184. +
  185. +arch_initcall(sprdwl_mem_alloc);
  186. +
  187. +MODULE_AUTHOR("jinglong.chen");
  188. +MODULE_DESCRIPTION("256k mem alloc");
  189. +MODULE_LICENSE("GPL");
  190. +
  191. diff --git a/drivers/net/wireless/sprdwl/wlan_cfg80211.c b/drivers/net/wireless/sprdwl/wlan_cfg80211.c
  192. new file mode 100644
  193. index 0000000..3d66142
  194. --- /dev/null
  195. +++ b/drivers/net/wireless/sprdwl/wlan_cfg80211.c
  196. @@ -0,0 +1,2742 @@
  197. +/*
  198. + * Copyright (C) 2014 Spreadtrum Communications Inc.
  199. + *
  200. + * Authors:<jinglong.chen@spreadtrum.com>
  201. + * Owner:
  202. + *      jinglong.chen
  203. + *
  204. + * This software is licensed under the terms of the GNU General Public
  205. + * License version 2, as published by the Free Software Foundation, and
  206. + * may be copied, distributed, and modified under those terms.
  207. + *
  208. + * This program is distributed in the hope that it will be useful,
  209. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  210. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  211. + * GNU General Public License for more details.
  212. + */
  213. +
  214. +#include "wlan_common.h"
  215. +#include "wlan_cfg80211.h"
  216. +#include "wlan_cmd.h"
  217. +
  218. +#define RATETAB_ENT(_rate, _rateid, _flags)                \
  219. +{                                  \
  220. +   .bitrate    = (_rate),                  \
  221. +   .hw_value   = (_rateid),                    \
  222. +   .flags      = (_flags),                 \
  223. +}
  224. +
  225. +#define CHAN2G(_channel, _freq, _flags) {              \
  226. +   .band           = IEEE80211_BAND_2GHZ,          \
  227. +   .center_freq        = (_freq),              \
  228. +   .hw_value       = (_channel),               \
  229. +   .flags          = (_flags),             \
  230. +   .max_antenna_gain   = 0,                    \
  231. +   .max_power      = 30,                   \
  232. +}
  233. +
  234. +#define CHAN5G(_channel, _flags) {                 \
  235. +   .band           = IEEE80211_BAND_5GHZ,          \
  236. +   .center_freq        = 5000 + (5 * (_channel)),      \
  237. +   .hw_value       = (_channel),               \
  238. +   .flags          = (_flags),             \
  239. +   .max_antenna_gain   = 0,                    \
  240. +   .max_power      = 30,                   \
  241. +}
  242. +
  243. +static struct ieee80211_rate itm_rates[] =
  244. +{
  245. +   RATETAB_ENT(10, 0x1, 0),
  246. +   RATETAB_ENT(20, 0x2, 0),
  247. +   RATETAB_ENT(55, 0x5, 0),
  248. +   RATETAB_ENT(110, 0xb, 0),
  249. +   RATETAB_ENT(60, 0x6, 0),
  250. +   RATETAB_ENT(90, 0x9, 0),
  251. +   RATETAB_ENT(120, 0xc, 0),
  252. +   RATETAB_ENT(180, 0x12, 0),
  253. +   RATETAB_ENT(240, 0x18, 0),
  254. +   RATETAB_ENT(360, 0x24, 0),
  255. +   RATETAB_ENT(480, 0x30, 0),
  256. +   RATETAB_ENT(540, 0x36, 0),
  257. +
  258. +   RATETAB_ENT(65, 0x80, 0),
  259. +   RATETAB_ENT(130, 0x81, 0),
  260. +   RATETAB_ENT(195, 0x82, 0),
  261. +   RATETAB_ENT(260, 0x83, 0),
  262. +   RATETAB_ENT(390, 0x84, 0),
  263. +   RATETAB_ENT(520, 0x85, 0),
  264. +   RATETAB_ENT(585, 0x86, 0),
  265. +   RATETAB_ENT(650, 0x87, 0),
  266. +   RATETAB_ENT(130, 0x88, 0),
  267. +   RATETAB_ENT(260, 0x89, 0),
  268. +   RATETAB_ENT(390, 0x8a, 0),
  269. +   RATETAB_ENT(520, 0x8b, 0),
  270. +   RATETAB_ENT(780, 0x8c, 0),
  271. +   RATETAB_ENT(1040, 0x8d, 0),
  272. +   RATETAB_ENT(1170, 0x8e, 0),
  273. +   RATETAB_ENT(1300, 0x8f, 0),
  274. +};
  275. +
  276. +#define ITM_G_RATE_NUM 28
  277. +#define itm_g_rates        (itm_rates)
  278. +#define ITM_A_RATE_NUM 24
  279. +#define itm_a_rates        (itm_rates + 4)
  280. +
  281. +#define itm_g_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
  282. +           IEEE80211_HT_CAP_SGI_20      | \
  283. +           IEEE80211_HT_CAP_SGI_40)
  284. +
  285. +static struct ieee80211_channel itm_2ghz_channels[] =
  286. +{
  287. +   CHAN2G(1, 2412, 0),
  288. +   CHAN2G(2, 2417, 0),
  289. +   CHAN2G(3, 2422, 0),
  290. +   CHAN2G(4, 2427, 0),
  291. +   CHAN2G(5, 2432, 0),
  292. +   CHAN2G(6, 2437, 0),
  293. +   CHAN2G(7, 2442, 0),
  294. +   CHAN2G(8, 2447, 0),
  295. +   CHAN2G(9, 2452, 0),
  296. +   CHAN2G(10, 2457, 0),
  297. +   CHAN2G(11, 2462, 0),
  298. +   CHAN2G(12, 2467, 0),
  299. +   CHAN2G(13, 2472, 0),
  300. +   CHAN2G(14, 2484, 0),
  301. +};
  302. +
  303. +static struct ieee80211_channel itm_5ghz_channels[] =
  304. +{
  305. +   CHAN5G(34, 0), CHAN5G(36, 0),
  306. +   CHAN5G(38, 0), CHAN5G(40, 0),
  307. +   CHAN5G(42, 0), CHAN5G(44, 0),
  308. +   CHAN5G(46, 0), CHAN5G(48, 0),
  309. +   CHAN5G(52, 0), CHAN5G(56, 0),
  310. +   CHAN5G(60, 0), CHAN5G(64, 0),
  311. +   CHAN5G(100, 0), CHAN5G(104, 0),
  312. +   CHAN5G(108, 0), CHAN5G(112, 0),
  313. +   CHAN5G(116, 0), CHAN5G(120, 0),
  314. +   CHAN5G(124, 0), CHAN5G(128, 0),
  315. +   CHAN5G(132, 0), CHAN5G(136, 0),
  316. +   CHAN5G(140, 0), CHAN5G(149, 0),
  317. +   CHAN5G(153, 0), CHAN5G(157, 0),
  318. +   CHAN5G(161, 0), CHAN5G(165, 0),
  319. +   CHAN5G(184, 0), CHAN5G(188, 0),
  320. +   CHAN5G(192, 0), CHAN5G(196, 0),
  321. +   CHAN5G(200, 0), CHAN5G(204, 0),
  322. +   CHAN5G(208, 0), CHAN5G(212, 0),
  323. +   CHAN5G(216, 0),
  324. +};
  325. +
  326. +static struct ieee80211_supported_band itm_band_2ghz = {
  327. +   .n_channels = ARRAY_SIZE(itm_2ghz_channels),
  328. +   .channels = itm_2ghz_channels,
  329. +   .n_bitrates = ITM_G_RATE_NUM,
  330. +   .bitrates = itm_g_rates,
  331. +   .ht_cap.cap = itm_g_htcap,
  332. +   .ht_cap.ht_supported = true,
  333. +};
  334. +
  335. +/*static struct ieee80211_supported_band itm_band_5ghz = {
  336. +   .n_channels = ARRAY_SIZE(itm_5ghz_channels),
  337. +   .channels = itm_5ghz_channels,
  338. +   .n_bitrates = ITM_A_RATE_NUM,
  339. +   .bitrates = itm_a_rates,
  340. +   .ht_cap.cap = itm_g_htcap,
  341. +   .ht_cap.ht_supported = true,
  342. +};*/
  343. +
  344. +static const u32 itm_cipher_suites[] = {
  345. +   WLAN_CIPHER_SUITE_WEP40,
  346. +   WLAN_CIPHER_SUITE_WEP104,
  347. +   WLAN_CIPHER_SUITE_TKIP,
  348. +   WLAN_CIPHER_SUITE_CCMP,
  349. +   WLAN_CIPHER_SUITE_SMS4,
  350. +#ifdef BSS_ACCESS_POINT_MODE
  351. +   WLAN_CIPHER_SUITE_ITM_CCMP,
  352. +   WLAN_CIPHER_SUITE_ITM_TKIP,
  353. +#endif
  354. +};
  355. +
  356. +/* Supported mgmt frame types to be advertised to cfg80211 */
  357. +static const struct ieee80211_txrx_stypes
  358. +itm_mgmt_stypes[NUM_NL80211_IFTYPES] = {
  359. +   [NL80211_IFTYPE_STATION] = {
  360. +                   .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  361. +                   BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
  362. +                   .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  363. +                   BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
  364. +                   },
  365. +   [NL80211_IFTYPE_AP] = {
  366. +                  .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  367. +                  BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
  368. +                  .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  369. +                  BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
  370. +                  },
  371. +   [NL80211_IFTYPE_P2P_CLIENT] = {
  372. +                      .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  373. +                      BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
  374. +                      .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  375. +                      BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
  376. +                      },
  377. +   [NL80211_IFTYPE_P2P_GO] = {
  378. +                  .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  379. +                  BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
  380. +                  .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  381. +                  BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
  382. +                  },
  383. +/* Supported mgmt frame types for p2p*/
  384. +   [NL80211_IFTYPE_ADHOC] = {
  385. +                 .tx = 0xffff,
  386. +                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
  387. +                 },
  388. +   [NL80211_IFTYPE_STATION] = {
  389. +                   .tx = 0xffff,
  390. +                   .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  391. +                   BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  392. +                   },
  393. +   [NL80211_IFTYPE_AP] = {
  394. +                  .tx = 0xffff,
  395. +                  .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  396. +                  BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  397. +                  BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  398. +                  BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  399. +                  BIT(IEEE80211_STYPE_AUTH >> 4) |
  400. +                  BIT(IEEE80211_STYPE_DEAUTH >> 4) |
  401. +                  BIT(IEEE80211_STYPE_ACTION >> 4)
  402. +                  },
  403. +   [NL80211_IFTYPE_AP_VLAN] = {
  404. +                   /* copy AP */
  405. +                   .tx = 0xffff,
  406. +                   .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  407. +                   BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  408. +                   BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  409. +                   BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  410. +                   BIT(IEEE80211_STYPE_AUTH >> 4) |
  411. +                   BIT(IEEE80211_STYPE_DEAUTH >> 4) |
  412. +                   BIT(IEEE80211_STYPE_ACTION >> 4)
  413. +                   },
  414. +   [NL80211_IFTYPE_P2P_CLIENT] = {
  415. +                      .tx = 0xffff,
  416. +                      .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  417. +                      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  418. +                      },
  419. +   [NL80211_IFTYPE_P2P_GO] = {
  420. +                  .tx = 0xffff,
  421. +                  .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  422. +                  BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  423. +                  BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  424. +                  BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  425. +                  BIT(IEEE80211_STYPE_AUTH >> 4) |
  426. +                  BIT(IEEE80211_STYPE_DEAUTH >> 4) |
  427. +                  BIT(IEEE80211_STYPE_ACTION >> 4)
  428. +                  },
  429. +};
  430. +
  431. +#define WLAN_EID_VENDOR_SPECIFIC 221
  432. +
  433. +void get_ssid(unsigned char *data, unsigned char *ssid)
  434. +{
  435. +    unsigned char len = 0;
  436. +    unsigned char i   = 0;
  437. +    unsigned char j   = 0;
  438. +  
  439. +    len = data[37];
  440. +    j   = 38;
  441. +  
  442. +    if(len >= 33)
  443. +       len = 0;
  444. +
  445. +    for(i = 0; i < len; i++, j++)
  446. +        ssid[i] = data[j];
  447. +    ssid[len] = '\0';
  448. +}
  449. +
  450. +void get_bssid(unsigned char *data, unsigned char *bssid)
  451. +{
  452. +    if(1 ==  ( (data[1] & 0x02) >> 1 ) )
  453. +        memcpy(bssid, data + 10, 6);
  454. +    else if( (data[1] & 0x01) == 1)
  455. +        memcpy(bssid, data + 4, 6);
  456. +    else
  457. +        memcpy(bssid, data + 16, 6);
  458. +   return;
  459. +}
  460. +
  461. +#ifdef WIFI_DIRECT_SUPPORT
  462. +
  463. +struct ieee80211_channel global_channel;
  464. +u64 global_cookie;
  465. +
  466. +static int get_file_size(struct file *f)
  467. +{
  468. +   int error = -EBADF;
  469. +   struct kstat stat;
  470. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  471. +   error = vfs_getattr(&f->f_path, &stat);
  472. +#else
  473. +   error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, &stat);
  474. +#endif
  475. +   if (error == 0) {
  476. +       return stat.size;
  477. +   } else {
  478. +       pr_err("get conf file stat error\n");
  479. +       return error;
  480. +   }
  481. +}
  482. +#define P2P_MODE_PATH "/data/misc/wifi/fwpath"
  483. +int itm_get_p2p_mode_from_file(void)
  484. +{
  485. +   struct file *fp = 0;
  486. +   mm_segment_t fs;
  487. +   int size = 0;
  488. +   loff_t pos = 0;
  489. +   u8 *buf;
  490. +   int ret = false;
  491. +   fp = filp_open(P2P_MODE_PATH, O_RDONLY, 0);
  492. +   if (IS_ERR(fp)){
  493. +       pr_err("open %s file error\n", P2P_MODE_PATH);
  494. +       goto end;
  495. +   }
  496. +   fs = get_fs();
  497. +   set_fs(KERNEL_DS);
  498. +   size = get_file_size(fp);
  499. +   if (size <= 0) {
  500. +       pr_err("load file:%s error\n", P2P_MODE_PATH);
  501. +       goto error;
  502. +   }
  503. +   buf = kzalloc(size + 1, GFP_KERNEL);
  504. +   vfs_read(fp, buf, size, &pos);
  505. +   if(strcmp(buf, "p2p_mode") == 0)
  506. +       ret = true;
  507. +   kfree(buf);
  508. +error:
  509. +   filp_close(fp, NULL);
  510. +   set_fs(fs);
  511. +end:
  512. +   return ret;
  513. +}
  514. +
  515. +static bool itm_find_p2p_ie(const u8 *ie, size_t ie_len, u8 *p2p_ie,
  516. +               size_t *p2p_ie_len)
  517. +{
  518. +   bool flags = false;
  519. +   size_t index = 0;
  520. +/*Find out P2P IE.*/
  521. +
  522. +   if (NULL == ie || ie_len <= 0 || NULL == p2p_ie)
  523. +       return flags;
  524. +
  525. +   while (index < ie_len) {
  526. +       if (P2P_IE_ID == ie[index]) {
  527. +           *p2p_ie_len = ie[index + 1];
  528. +           if (ie_len >= *p2p_ie_len &&
  529. +               P2P_IE_OUI_BYTE0 == ie[index + 2] &&
  530. +               P2P_IE_OUI_BYTE1 == ie[index + 3] &&
  531. +               P2P_IE_OUI_BYTE2 == ie[index + 4] &&
  532. +               P2P_IE_OUI_TYPE == ie[index + 5]) {
  533. +               memcpy(p2p_ie, ie + index, *p2p_ie_len + 2);
  534. +               *p2p_ie_len += 2;
  535. +               return true;
  536. +           }
  537. +       }
  538. +       index++;
  539. +   }
  540. +
  541. +   return false;
  542. +}
  543. +
  544. +static int wlan_cfg80211_remain_on_channel(struct wiphy *wiphy,
  545. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  546. +                          struct wireless_dev *dev,
  547. +#else
  548. +                          struct net_device *dev,
  549. +#endif
  550. +                          struct ieee80211_channel
  551. +                          *channel,
  552. +                          unsigned int duration,
  553. +                          u64 *cookie)
  554. +{
  555. +   wlan_vif_t *vif;
  556. +   unsigned char   vif_id;
  557. +   int             ret;
  558. +  
  559. +   enum nl80211_channel_type channel_type = 0;
  560. +   vif = ndev_to_vif(dev->netdev);
  561. +   vif_id = vif->id;
  562. +   if(ITM_NONE_MODE == vif->mode)
  563. +       return -EAGAIN;
  564. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  565. +   memcpy(&global_channel, channel, sizeof(struct ieee80211_channel));
  566. +   global_cookie = *cookie;
  567. +
  568. +   /* send remain chan */
  569. +   ret = wlan_cmd_remain_chan(vif_id, channel,  channel_type, duration, cookie);
  570. +   if(OK != ret)
  571. +       return -1;
  572. +  
  573. +   /* report remain chan */
  574. +   cfg80211_ready_on_channel(dev, *cookie, channel, duration, GFP_KERNEL);
  575. +   return 0;
  576. +}
  577. +
  578. +static int wlan_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
  579. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  580. +                             struct wireless_dev *dev,
  581. +#else
  582. +                             struct net_device *dev,
  583. +#endif
  584. +                             u64 cookie)
  585. +{
  586. +   int             ret;
  587. +   wlan_vif_t *vif;
  588. +   unsigned char   vif_id;
  589. +   vif = ndev_to_vif(dev->netdev);
  590. +   vif_id = vif->id;
  591. +   if(ITM_NONE_MODE == vif->mode)
  592. +       return -EAGAIN;
  593. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  594. +   ret = wlan_cmd_cancel_remain_chan(vif_id, cookie);
  595. +   if (OK != ret)
  596. +       return ERROR;
  597. +   return OK;
  598. +}
  599. +
  600. +
  601. +static int wlan_cfg80211_del_station(struct wiphy *wiphy,  struct net_device *ndev, u8 *mac)
  602. +{
  603. +   return 0;
  604. +}
  605. +
  606. +static void register_frame_work_fun(struct work_struct * work)
  607. +{
  608. +   unsigned char vif_id;
  609. +   struct wlan_cmd_register_frame_t data;
  610. +    register_frame_param_t  *param = container_of(work, register_frame_param_t, work);
  611. +   data.type = cpu_to_le16(param->frame_type);
  612. +   data.reg = param->reg ? 1 : 0;
  613. +    param->frame_type = 0xffff;
  614. +    param->reg = 0;
  615. +   vif_id = ( (wlan_vif_t *)(param->vif) )->id;
  616. +   wlan_cmd_register_frame(vif_id, &data);
  617. +   return;
  618. +}
  619. +
  620. +void init_register_frame_param(wlan_vif_t *vif )
  621. +{
  622. +   register_frame_param_t *param;
  623. +   param = &(vif->cfg80211.register_frame);
  624. +    param->frame_type = 0xffff;
  625. +    param->reg = 0;
  626. +    param->vif= (void *)vif;
  627. +    INIT_WORK(&(param->work),register_frame_work_fun);
  628. +}
  629. +
  630. +static int  register_frame(wlan_vif_t *vif, unsigned short frame_type, bool reg)
  631. +{
  632. +    vif->cfg80211.register_frame.frame_type = frame_type;
  633. +    vif->cfg80211.register_frame.reg = reg;
  634. +    schedule_work(&(vif->cfg80211.register_frame.work));
  635. +    return 0;
  636. +}
  637. +
  638. +void cfg80211_report_remain_on_channel_expired(unsigned char vif_id, unsigned char *data, unsigned short len)
  639. +{
  640. +   wlan_vif_t *vif;
  641. +   vif = id_to_vif(vif_id);
  642. +   cfg80211_remain_on_channel_expired(& (vif->wdev), global_cookie, &global_channel, GFP_KERNEL);
  643. +   return ;
  644. +}
  645. +
  646. +
  647. +static void send_deauth_work_func(struct work_struct *work)
  648. +{
  649. +   wlan_vif_t *vif;
  650. +   wlan_cfg80211_t *cfg;
  651. +   struct deauth_info *info;
  652. +
  653. +   info = container_of(work, struct deauth_info, work);
  654. +   cfg = container_of(info, wlan_cfg80211_t, deauth_info);
  655. +   vif = container_of(cfg, wlan_vif_t, cfg80211);
  656. +   cfg80211_send_deauth(vif->ndev, info->mac, info->len);
  657. +
  658. +   return;
  659. +}
  660. +
  661. +void init_send_deauth_work(wlan_vif_t *vif)
  662. +{
  663. +   struct deauth_info *info;
  664. +   info = &vif->cfg80211.deauth_info;
  665. +   memset(info, 0, sizeof(*info));
  666. +   INIT_WORK(&info->work, send_deauth_work_func);
  667. +}
  668. +
  669. +void cfg80211_report_mgmt_deauth(unsigned char vif_id, unsigned char *data, unsigned short len)
  670. +{
  671. +   wlan_vif_t *vif;
  672. +   wlan_cfg80211_t *cfg;
  673. +
  674. +   vif = id_to_vif(vif_id);
  675. +   if (!vif) {
  676. +       ASSERT("%s vif is NULL\n", __func__);
  677. +       return;
  678. +   }
  679. +   cfg = &vif->cfg80211;
  680. +   memcpy(&cfg->deauth_info.len, data, 2);
  681. +   cfg->deauth_info.len = le16_to_cpu(cfg->deauth_info.len);
  682. +
  683. +   if (cfg->deauth_info.len != sizeof(cfg->deauth_info.mac)) {
  684. +       ASSERT("%s FIXME len:%d > max:%lu\n", __func__,
  685. +           cfg->deauth_info.len, sizeof(cfg->deauth_info.mac));
  686. +       return;
  687. +   }
  688. +   memcpy(cfg->deauth_info.mac, data + 2, cfg->deauth_info.len);
  689. +   schedule_work(&cfg->deauth_info.work);
  690. +}
  691. +
  692. +void cfg80211_report_mgmt_disassoc(unsigned char vif_id, unsigned char *data, unsigned short len )
  693. +{
  694. +   u8  *mac_ptr, *index;
  695. +   u16 mac_len;
  696. +   wlan_vif_t *vif = id_to_vif(vif_id);
  697. +  
  698. +   index = data;
  699. +   memcpy(&mac_len, index, 2);
  700. +   mac_len = le16_to_cpu(mac_len);
  701. +   index += 2;
  702. +   mac_ptr = index;
  703. +   cfg80211_send_disassoc(vif->ndev, mac_ptr, mac_len);
  704. +}
  705. +
  706. +void cfg80211_report_new_station(unsigned char vif_id, unsigned char *data, unsigned short len )
  707. +{
  708. +   u8  *req_ptr, *index;
  709. +   u16 req_len, mac_len;
  710. +   u8 *sta_mac;
  711. +   u32 event_len;
  712. +   int left;
  713. +   struct station_info sinfo;
  714. +   wlan_vif_t *vif = id_to_vif(vif_id);
  715. +  
  716. +   printkd("enter cfg80211_report_new_station\n");
  717. +
  718. +   event_len = len;
  719. +   index =  data;
  720. +  
  721. +   left = event_len;
  722. +
  723. +   /* The first byte of event data is mac */
  724. +   memcpy(&mac_len, index, 2);
  725. +   mac_len = le16_to_cpu(mac_len);
  726. +   index += 2;
  727. +   left -= 2;
  728. +
  729. +   if (mac_len != 6) {
  730. +       printkd( "channel len not equal 6 bytes\n");
  731. +       return;
  732. +   }
  733. +
  734. +   sta_mac = index;
  735. +   index += mac_len;
  736. +   left -= mac_len;
  737. +
  738. +   if (!left) {
  739. +       printkd("There is no associa req frame!\n");
  740. +       return;
  741. +   }
  742. +
  743. +   /* The second event data is associate request */
  744. +   memcpy(&req_len, index, 2);
  745. +   req_len = le16_to_cpu(req_len);
  746. +   index += 2;
  747. +   left -= 2;
  748. +
  749. +   req_ptr = index;
  750. +   left -= req_len;
  751. +
  752. +   memset(&sinfo, 0, sizeof(struct station_info));
  753. +   sinfo.assoc_req_ies = req_ptr;
  754. +   sinfo.assoc_req_ies_len = req_len;
  755. +   sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
  756. +
  757. +   cfg80211_new_sta(vif->ndev, sta_mac, &sinfo, GFP_KERNEL);
  758. +
  759. +   printkd("proccess new station event completed\n")
  760. +
  761. +}
  762. +
  763. +void cfg80211_report_frame(unsigned char vif_id, unsigned char *data, unsigned short len)
  764. +{
  765. +   unsigned short mac_len;
  766. +   unsigned char *mac_ptr = NULL;
  767. +   unsigned char channel=0,type=0;
  768. +   int freq;
  769. +   struct wlan_event_report_frame_t * report_frame = NULL;
  770. +   wlan_vif_t *vif = id_to_vif(vif_id);
  771. +  
  772. +   report_frame = (struct wlan_event_report_frame_t *)data;
  773. +   channel = report_frame->channel;
  774. +   type = report_frame->frame_type;
  775. +   freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
  776. +   mac_ptr = (unsigned char *) (report_frame +1);
  777. +   mac_len = le16_to_cpu(report_frame->frame_len);
  778. +   printkd("%s, frame_len:%d\n", __func__, mac_len);
  779. +   cfg80211_rx_mgmt(&(vif->wdev), freq, 0, mac_ptr, mac_len,GFP_KERNEL);
  780. +}
  781. +
  782. +#endif  /*WIFI_DIRECT_SUPPORT */
  783. +
  784. +static bool itm_is_wps_ie(const unsigned char *pos)
  785. +{
  786. +   return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
  787. +           pos[1] >= 4 &&
  788. +           pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
  789. +           pos[5] == 0x04);
  790. +}
  791. +
  792. +static bool itm_find_wpsie(const unsigned char *ies, size_t ies_len,
  793. +                           unsigned char *buf, size_t *wps_len)
  794. +{
  795. +   const unsigned char *pos;
  796. +   size_t len = 0;
  797. +   bool flags = false;
  798. +
  799. +   /*
  800. +    * Filter out RSN/WPA IE(s)
  801. +    */
  802. +   if (ies && ies_len)
  803. +   {
  804. +       pos = ies;
  805. +
  806. +       while (pos + 1 < ies + ies_len)
  807. +       {
  808. +           if (pos + 2 + pos[1] > ies + ies_len)
  809. +               break;
  810. +
  811. +           if (itm_is_wps_ie(pos))
  812. +           {
  813. +               memcpy(buf + len, pos, 2 + pos[1]);
  814. +               len += 2 + pos[1];
  815. +               flags = true;
  816. +           }
  817. +
  818. +           pos += 2 + pos[1];
  819. +       }
  820. +   }
  821. +
  822. +   *wps_len = len;
  823. +   return flags;
  824. +}
  825. +static bool itm_find_ft_ie(const unsigned char *ies, size_t ies_len, unsigned char *buf, size_t *ie_len)
  826. +{
  827. +   const unsigned char *pos;
  828. +   size_t len = 0;
  829. +   bool flags = false;
  830. +   if (ies && ies_len)
  831. +   {
  832. +       pos = ies;
  833. +       while (pos + 1 < ies + ies_len)
  834. +       {
  835. +           if (pos + 2 + pos[1] > ies + ies_len)
  836. +               break;
  837. +           if(  (WLAN_11R_FT_IE_ID == pos[0]) || (WLAN_11R_MD_IE_ID == pos[0]) )
  838. +           {
  839. +               memcpy(buf + len, pos, 2 + pos[1]);
  840. +               len += 2 + pos[1];
  841. +               flags = true;
  842. +           }
  843. +
  844. +           pos += 2 + pos[1];
  845. +       }
  846. +   }
  847. +   *ie_len = len;
  848. +   return flags;
  849. +}
  850. +static int itm_wlan_add_cipher_key(wlan_vif_t *vif, bool pairwise,  unsigned char key_index, unsigned int cipher, const unsigned char *key_seq,  const unsigned char *macaddr)
  851. +{
  852. +   unsigned char pn_key[16] = { 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
  853. +                                0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36
  854. +                              };
  855. +   int ret;
  856. +   unsigned char vif_id;
  857. +   vif_id = vif->id;
  858. +   printkd("%s()\n", __func__);
  859. +   if (vif->cfg80211.key_len[pairwise][0] || vif->cfg80211.key_len[pairwise][1] ||
  860. +           vif->cfg80211.key_len[pairwise][2] || vif->cfg80211.key_len[pairwise][3])
  861. +   {
  862. +       /* Only set wep keys if we have at least one of them.
  863. +          pairwise: 0:GTK 1:PTK */
  864. +       switch (cipher)
  865. +       {
  866. +       case WLAN_CIPHER_SUITE_WEP40:
  867. +           vif->cfg80211.cipher_type = WEP40;
  868. +           break;
  869. +       case WLAN_CIPHER_SUITE_WEP104:
  870. +           vif->cfg80211.cipher_type = WEP104;
  871. +           break;
  872. +       case WLAN_CIPHER_SUITE_TKIP:
  873. +           vif->cfg80211.cipher_type = TKIP;
  874. +           break;
  875. +       case WLAN_CIPHER_SUITE_CCMP:
  876. +           vif->cfg80211.cipher_type = CCMP;
  877. +           break;
  878. +       case WLAN_CIPHER_SUITE_SMS4:
  879. +           vif->cfg80211.cipher_type = WAPI;
  880. +           break;
  881. +       default:
  882. +           printkd( "Invalid cipher select: %d\n", vif->cfg80211.cipher_type);
  883. +           return -EINVAL;
  884. +       }
  885. +       memcpy(vif->cfg80211.key_txrsc[pairwise], pn_key, sizeof(pn_key));
  886. +       ret = wlan_cmd_add_key(vif_id,
  887. +                   vif->cfg80211.key[pairwise][key_index],
  888. +                   vif->cfg80211.key_len[pairwise][key_index],
  889. +                   pairwise, key_index, key_seq,
  890. +                   vif->cfg80211.cipher_type, macaddr);
  891. +       if (ret < 0)
  892. +       {
  893. +           printkd("wlan_cmd_add_key failed %d\n", ret);
  894. +           return ret;
  895. +       }
  896. +   }
  897. +   return 0;
  898. +}
  899. +
  900. +static int wlan_cfg80211_scan(struct wiphy *wiphy,
  901. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
  902. +                                        struct net_device *dev,
  903. +#endif
  904. +                                        struct cfg80211_scan_request *request)
  905. +{
  906. +   wlan_vif_t      *vif;
  907. +   unsigned char        vif_id;
  908. +   struct wireless_dev *wdev;
  909. +   struct cfg80211_ssid *ssids;
  910. +   struct wlan_cmd_scan_ssid *scan_ssids;
  911. +   int scan_ssids_len = 0;
  912. +   unsigned char *data = NULL;
  913. +   unsigned int i, n, j;
  914. +   int ret;
  915. +   unsigned char channels[16] = {0};
  916. +  
  917. +   ssids = request->ssids;
  918. +   wdev = request->wdev;
  919. +   vif = ndev_to_vif(wdev->netdev);
  920. +   vif_id = vif->id;
  921. +   if(ITM_NONE_MODE == vif->mode)
  922. +       return -EAGAIN;
  923. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  924. +   if (vif->cfg80211.scan_request)
  925. +   {
  926. +       printkd("Already scanning\n");
  927. +       return -EAGAIN;
  928. +   }
  929. +   /* check we are client side */
  930. +   switch (wdev->iftype)
  931. +   {
  932. +   case NL80211_IFTYPE_AP:
  933. +       break;
  934. +       /*  case NL80211_IFTYPE_P2P_CLIENT:
  935. +           case NL80211_IFTYPE_P2P_GO:
  936. +            */
  937. +   case NL80211_IFTYPE_STATION:
  938. +       break;
  939. +   case NL80211_IFTYPE_P2P_CLIENT:
  940. +   case NL80211_IFTYPE_P2P_GO:
  941. +   case NL80211_IFTYPE_P2P_DEVICE:
  942. +       break;
  943. +   default:
  944. +       {
  945. +           printkd("%s(), end\n", __func__);
  946. +           return -EOPNOTSUPP;
  947. +       }
  948. +   }
  949. +
  950. +   /* set wps ie */
  951. +   if (request->ie_len > 0)
  952. +   {
  953. +       if (request->ie_len > 255)
  954. +       {
  955. +           printkd("%s invalid ie len(%lu)\n", __func__, request->ie_len);
  956. +           return -EOPNOTSUPP;
  957. +       }
  958. +       ret = wlan_cmd_set_wps_ie(vif_id, WPS_REQ_IE, request->ie, request->ie_len);
  959. +       if (ret)
  960. +       {
  961. +           printkd("wlan_cmd_set_wps_ie failed with ret %d\n", ret);
  962. +           printkd("%s(), end\n", __func__);
  963. +           return ret;
  964. +       }
  965. +   }
  966. +   else
  967. +   {
  968. +       printkd("%s request->ie_len is 0\n", __func__);
  969. +   }
  970. +   n = min(request->n_ssids, 9);
  971. +   if (n)
  972. +   {
  973. +       data = kzalloc(512, GFP_KERNEL);
  974. +       if (!data)
  975. +       {
  976. +           printkd("%s failed to alloc for combo ssid\n", __func__);
  977. +           return -2;
  978. +       }
  979. +       scan_ssids = (struct wlan_cmd_scan_ssid *)data;
  980. +       for (i = 0; i < n; i++)
  981. +       {
  982. +           if (!ssids[i].ssid_len)
  983. +               continue;
  984. +           scan_ssids->len = ssids[i].ssid_len;
  985. +           memcpy(scan_ssids->ssid, ssids[i].ssid,
  986. +                  ssids[i].ssid_len);
  987. +           scan_ssids_len += (ssids[i].ssid_len
  988. +                              + sizeof(scan_ssids->len));
  989. +           scan_ssids = (struct wlan_cmd_scan_ssid *)
  990. +                        (data + scan_ssids_len);
  991. +       }
  992. +   }
  993. +
  994. +   n = min(request->n_channels, 4U);
  995. +   if(n > 15)
  996. +       n = 15;
  997. +   for (i = 0, j=0; i < n; i++)
  998. +   {
  999. +       int ch = request->channels[i]->hw_value;
  1000. +       if (ch == 0)
  1001. +       {
  1002. +           printkd("Scan requested for unknown frequency %dMhz\n", request->channels[i]->center_freq);
  1003. +           continue;
  1004. +       }
  1005. +       channels[j+1] = ch;
  1006. +       j++;
  1007. +   }
  1008. +   channels[0] = j;
  1009. +  
  1010. +   ret = wlan_cmd_scan(vif_id, data, channels, scan_ssids_len);
  1011. +   if (ret)
  1012. +   {
  1013. +       printkd("wlan_cmd_scan failed with ret %d\n", ret);
  1014. +       kfree(data);
  1015. +       return ret;
  1016. +   }
  1017. +
  1018. +   if (vif->cfg80211.scan_done_lock.link.next == LIST_POISON1 ||
  1019. +           vif->cfg80211.scan_done_lock.link.prev == LIST_POISON2)
  1020. +       wake_lock(&vif->cfg80211.scan_done_lock);
  1021. +   /* Arm scan timeout timer */
  1022. +   mod_timer(&vif->cfg80211.scan_timeout, jiffies + ITM_SCAN_TIMER_INTERVAL_MS * HZ / 1000);
  1023. +   vif->cfg80211.scan_request = request;
  1024. +   kfree(data);
  1025. +   printkd("%s(), ok!\n", __func__);
  1026. +   return 0;
  1027. +}
  1028. +
  1029. +static int wlan_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme)
  1030. +{
  1031. +   wlan_vif_t      *vif;
  1032. +   unsigned char        vif_id;
  1033. +   struct wireless_dev *wdev;
  1034. +   int ret;
  1035. +   unsigned int cipher = 0;
  1036. +   unsigned char key_mgmt = 0;
  1037. +   int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) ||  (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104);
  1038. +   bool is_wapi = false;
  1039. +   int auth_type = 0;
  1040. +   unsigned char *buf = NULL;
  1041. +   size_t wps_len = 0;
  1042. +   size_t p2p_len = 0;
  1043. +   size_t ftie_len = 0;
  1044. +   vif = ndev_to_vif(ndev);
  1045. +   vif_id = vif->id;
  1046. +   wdev = &(vif->wdev);
  1047. +   if(ITM_NONE_MODE == vif->mode)
  1048. +       return -EAGAIN;
  1049. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  1050. +   printkd("%s(), Begin connect: %s\n", __func__, sme->ssid);
  1051. +
  1052. +   /* To avoid confused wapi frame */
  1053. +   vif->cfg80211.cipher_type = NONE;
  1054. +   /* Get request status, type, bss, ie and so on */
  1055. +   /* Set appending ie */
  1056. +   /* Set wps ie */
  1057. +   if (sme->ie_len > 0)
  1058. +   {
  1059. +       if (sme->ie_len > 255)
  1060. +       {
  1061. +           printkd("%s invalid sme->len(%lu)\n",__func__, sme->ie_len);
  1062. +           return -EOPNOTSUPP;
  1063. +       }
  1064. +       buf = kmalloc(sme->ie_len, GFP_KERNEL);
  1065. +       if (NULL == buf)
  1066. +       {
  1067. +           printkd("%s(), end\n",__func__);
  1068. +           return -ENOMEM;
  1069. +       }
  1070. +       if (itm_find_wpsie(sme->ie, sme->ie_len, buf, &wps_len) == true)
  1071. +       {
  1072. +           ret = wlan_cmd_set_wps_ie(vif_id, WPS_ASSOC_IE, buf, wps_len);
  1073. +           if (ret)
  1074. +           {
  1075. +               printkd("wlan_cmd_set_wps_ie failed with ret %d\n", ret);
  1076. +               return ret;
  1077. +           }
  1078. +       }
  1079. +   }
  1080. +#ifdef WIFI_DIRECT_SUPPORT
  1081. +       if (itm_find_p2p_ie(sme->ie, sme->ie_len,  buf, &p2p_len) == true)
  1082. +       {  
  1083. +           ret = wlan_cmd_set_p2p_ie(vif_id,P2P_ASSOC_IE, buf, p2p_len);
  1084. +           if (ret)
  1085. +           {
  1086. +               printkd("wlan_cmd_set_p2p_ie failed with ret %d\n",ret);
  1087. +               return ret;
  1088. +           }
  1089. +       }
  1090. +#endif/*WIFI_DIRECT_SUPPORT*/
  1091. +#ifdef  WLAN_11R_SUPPORT
  1092. +       if( itm_find_ft_ie(sme->ie, sme->ie_len, buf, &ftie_len) )
  1093. +       {
  1094. +           ret = wlan_cmd_set_ft_ie(vif_id, buf, ftie_len);
  1095. +           if (ret)
  1096. +           {
  1097. +               printkd("wlan_cmd_set_ft_ie failed with ret %d\n",ret);
  1098. +           }
  1099. +       }  
  1100. +#endif
  1101. +   /* Set WPA version */
  1102. +   printkd("Set wpa_versions %#x\n",  sme->crypto.wpa_versions);
  1103. +   ret = wlan_cmd_set_wpa_version(vif_id, sme->crypto.wpa_versions);
  1104. +   if (ret < 0)
  1105. +   {
  1106. +       printkd("wlan_cmd_set_wpa_version failed with ret %d\n", ret);
  1107. +       printkd("%s(), end\n",__func__);
  1108. +       return ret;
  1109. +   }
  1110. +
  1111. +   /* Set Auth type */
  1112. +   printkd("Set auth_type %#x\n", sme->auth_type);
  1113. +   /* Set the authorisation */
  1114. +   if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
  1115. +           ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
  1116. +       auth_type = ITM_AUTH_OPEN;
  1117. +   else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
  1118. +            ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
  1119. +       auth_type = ITM_AUTH_SHARED;
  1120. +   ret = wlan_cmd_set_auth_type(vif_id, auth_type);
  1121. +   if (ret < 0)
  1122. +   {
  1123. +       printkd("wlan_cmd_set_auth_type failed with ret %d\n", ret);
  1124. +       return ret;
  1125. +   }
  1126. +   /* Set cipher - pairewise and group */
  1127. +   printkd("n_ciphers_pairwise %d\n",  sme->crypto.n_ciphers_pairwise);
  1128. +   if (sme->crypto.n_ciphers_pairwise)
  1129. +   {
  1130. +       switch (sme->crypto.ciphers_pairwise[0])
  1131. +       {
  1132. +       case WLAN_CIPHER_SUITE_WEP40:
  1133. +           cipher = WEP40;
  1134. +           break;
  1135. +       case WLAN_CIPHER_SUITE_WEP104:
  1136. +           cipher = WEP104;
  1137. +           break;
  1138. +       case WLAN_CIPHER_SUITE_TKIP:
  1139. +           cipher = TKIP;
  1140. +           break;
  1141. +       case WLAN_CIPHER_SUITE_CCMP:
  1142. +           cipher = CCMP;
  1143. +           break;
  1144. +           /* WAPI cipher is not processed by CP2 */
  1145. +       case WLAN_CIPHER_SUITE_SMS4:
  1146. +           cipher = WAPI;
  1147. +           is_wapi = true;
  1148. +           break;
  1149. +       default:
  1150. +           printkd("Unicast cipher suite 0x%x is not supported\n", sme->crypto.ciphers_pairwise[0]);
  1151. +           printkd("%s(), end\n",__func__);
  1152. +           return -ENOTSUPP;
  1153. +       }
  1154. +
  1155. +       if (is_wapi != true)
  1156. +       {
  1157. +           ret = wlan_cmd_set_cipher(vif_id, cipher, WIFI_CMD_SET_PAIRWISE_CIPHER);
  1158. +           if (ret < 0)
  1159. +           {
  1160. +               printkd( "set_cipher_cmd pairwise failed with ret %d\n", ret);
  1161. +               printkd("%s(), end\n",__func__);
  1162. +               return ret;
  1163. +           }
  1164. +       }
  1165. +   }
  1166. +   else
  1167. +   {
  1168. +       /*No pairewise cipher */
  1169. +       printkd("No pairewise cipher\n");
  1170. +   }
  1171. +
  1172. +   /* Set group cipher */
  1173. +   switch (sme->crypto.cipher_group)
  1174. +   {
  1175. +   case NONE:
  1176. +       cipher = NONE;
  1177. +       break;
  1178. +   case WLAN_CIPHER_SUITE_WEP40:
  1179. +       cipher = WEP40;
  1180. +       break;
  1181. +   case WLAN_CIPHER_SUITE_WEP104:
  1182. +       cipher = WEP104;
  1183. +       break;
  1184. +   case WLAN_CIPHER_SUITE_TKIP:
  1185. +       cipher = TKIP;
  1186. +       break;
  1187. +   case WLAN_CIPHER_SUITE_CCMP:
  1188. +       cipher = CCMP;
  1189. +       break;
  1190. +   default:
  1191. +       printkd("Group cipher suite 0x%x is not supported\n", sme->crypto.cipher_group);
  1192. +       printkd("%s(), end\n",__func__);
  1193. +       return -ENOTSUPP;
  1194. +   }
  1195. +
  1196. +   if (is_wapi != true)
  1197. +   {
  1198. +       ret = wlan_cmd_set_cipher(vif_id, cipher, WIFI_CMD_SET_GROUP_CIPHER);
  1199. +       if (ret < 0)
  1200. +       {
  1201. +           printkd("set_cipher_cmd group failed with ret %d\n", ret);
  1202. +           printkd("%s(), end\n",__func__);
  1203. +           return ret;
  1204. +       }
  1205. +   }
  1206. +
  1207. +   /* FIXME */
  1208. +   /* Set Auth type again because of CP2 process's differece */
  1209. +   printkd("Set auth_type %#x\n", sme->auth_type);
  1210. +   /* Set the authorisation */
  1211. +   if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
  1212. +           ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
  1213. +       auth_type = ITM_AUTH_OPEN;
  1214. +   else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
  1215. +            ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
  1216. +       auth_type = ITM_AUTH_SHARED;
  1217. +   ret = wlan_cmd_set_auth_type(vif_id, auth_type);
  1218. +   if (ret < 0)
  1219. +   {
  1220. +       printkd("wlan_cmd_set_auth_type failed with ret %d\n", ret);
  1221. +       printkd("%s(), end\n",__func__);
  1222. +       return ret;
  1223. +   }
  1224. +
  1225. +   /* Set auth key management (akm) */
  1226. +   printkd("akm_suites %#x\n", sme->crypto.n_akm_suites);
  1227. +   if (sme->crypto.n_akm_suites)
  1228. +   {
  1229. +       if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_PSK)
  1230. +           key_mgmt = AKM_SUITE_PSK;
  1231. +       else if(WLAN_AKM_SUITE_FT_PSK == sme->crypto.akm_suites[0])
  1232. +           key_mgmt = AKM_SUITE_FT_PSK;
  1233. +       else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
  1234. +           key_mgmt = AKM_SUITE_8021X;
  1235. +       /* WAPI akm is not processed by CP2 */
  1236. +       else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_CERT)
  1237. +           key_mgmt = AKM_SUITE_WAPI_CERT;
  1238. +       else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_PSK)
  1239. +           key_mgmt = AKM_SUITE_WAPI_PSK;
  1240. +       else if(WLAN_AKM_SUITE_FT_8021X == sme->crypto.akm_suites[0] )
  1241. +           key_mgmt = AKM_SUITE_FT_8021X;
  1242. +       else
  1243. +       {}
  1244. +       ret = wlan_cmd_set_key_management(vif_id, key_mgmt);
  1245. +       if (ret < 0)
  1246. +       {
  1247. +           printkd("wlan_cmd_set_key_management failed %d\n", ret);
  1248. +           printkd("%s(), end\n",__func__);
  1249. +           return ret;
  1250. +       }
  1251. +   }
  1252. +
  1253. +   /* Set PSK */
  1254. +   if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40 ||
  1255. +           sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104 ||
  1256. +           sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP40 ||
  1257. +           sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP104)
  1258. +   {
  1259. +       printkd( "Don't need to set PSK since driver is using WEP\n");
  1260. +       vif->cfg80211.key_index[GROUP] = sme->key_idx;
  1261. +       vif->cfg80211.key_len[GROUP][sme->key_idx] = sme->key_len;
  1262. +       memcpy(vif->cfg80211.key[GROUP][sme->key_idx], sme->key, sme->key_len);
  1263. +       ret = itm_wlan_add_cipher_key(vif, 0, sme->key_idx,  sme->crypto.ciphers_pairwise[0], NULL, NULL);
  1264. +       if (ret < 0)
  1265. +       {
  1266. +           printkd("itm_wlan_add_key failed %d\n", ret);
  1267. +           printkd("%s(), end\n",__func__);
  1268. +           return ret;
  1269. +       }
  1270. +   }
  1271. +   else
  1272. +   {
  1273. +       unsigned char psk[32];
  1274. +       int key_len = 0;
  1275. +       if (wdev->iftype == NL80211_IFTYPE_AP)
  1276. +       {
  1277. +           ret = hostap_conf_load(HOSTAP_CONF_FILE_NAME, psk);
  1278. +           if (ret)
  1279. +           {
  1280. +               printkd( "load hostap failed with ret %d\n",  ret);
  1281. +               printkd("%s(), end\n",__func__);
  1282. +               return ret;
  1283. +           }
  1284. +           key_len = sizeof(psk);
  1285. +       }
  1286. +       else
  1287. +       {
  1288. +           if (sme->key_len > 32)
  1289. +           {
  1290. +               printkd("Invalid key len (%d)\n", sme->key_len);
  1291. +               printkd("%s(), end\n",__func__);
  1292. +               return -EINVAL;
  1293. +           }
  1294. +           memcpy(psk, sme->key, sme->key_len);
  1295. +           key_len = sme->key_len;
  1296. +       }
  1297. +       ret = wlan_cmd_set_psk(vif_id, psk, key_len);
  1298. +       if (ret < 0)
  1299. +       {
  1300. +           printkd("set_psk_cmd failed with ret %d\n", ret);
  1301. +           printkd("%s(), end\n",__func__);
  1302. +           return ret;
  1303. +       }
  1304. +   }
  1305. +
  1306. +   /* Auth RX unencrypted EAPOL is not implemented, do nothing */
  1307. +   /* Set channel */
  1308. +   if (sme->channel != NULL)
  1309. +   {
  1310. +       printkd("Settting channel to %d\n",  ieee80211_frequency_to_channel(sme->channel->  center_freq));
  1311. +       ret = wlan_cmd_set_channel(vif_id, ieee80211_frequency_to_channel (sme->channel->center_freq));
  1312. +       if (ret < 0)
  1313. +       {
  1314. +           printkd("wlan_cmd_set_channel failed with ret %d\n", ret);
  1315. +           printkd("%s(), end\n",__func__);
  1316. +           return ret;
  1317. +       }
  1318. +   }
  1319. +   else
  1320. +   {
  1321. +       printkd("Channel is not specified\n");
  1322. +   }
  1323. +
  1324. +   /* Set BSSID */
  1325. +   if (sme->bssid != NULL)
  1326. +   {
  1327. +       ret = wlan_cmd_set_bssid(vif_id, sme->bssid);
  1328. +       if (ret < 0)
  1329. +       {
  1330. +           printkd("wlan_cmd_set_bssid failed with ret %d\n", ret);
  1331. +           printkd("%s(), end\n",__func__);
  1332. +           return ret;
  1333. +       }
  1334. +             memcpy(vif->cfg80211.bssid, sme->bssid, 6);
  1335. +   }
  1336. +   else
  1337. +   {
  1338. +       printkd("BSSID is not specified\n");
  1339. +   }
  1340. +
  1341. +   /* Special process for WEP(WEP key must be set before itm_set_essid) */
  1342. +   if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40 ||
  1343. +           sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104)
  1344. +   {
  1345. +       printkd("Setting WEP group cipher\n");
  1346. +       if (sme->key_len <= 0)
  1347. +       {
  1348. +           printkd("No key is specified\n");
  1349. +       }
  1350. +       else
  1351. +       {
  1352. +           if (sme->key_len != WLAN_KEY_LEN_WEP104 &&
  1353. +                   sme->key_len != WLAN_KEY_LEN_WEP40)
  1354. +           {
  1355. +               printkd("Invalid key length for WEP\n");
  1356. +               printkd("%s(), end\n",__func__);
  1357. +               return -EINVAL;
  1358. +           }
  1359. +
  1360. +           wlan_cmd_set_key(vif_id, sme->key_idx);
  1361. +       }
  1362. +   }
  1363. +   /* Set ESSID */
  1364. +   if (sme->ssid != NULL)
  1365. +   {
  1366. +       printkd("sme->ssid:%s\n",  sme->ssid);
  1367. +       ret = wlan_cmd_set_essid(vif_id, sme->ssid, (int)sme->ssid_len);
  1368. +       if (ret < 0)
  1369. +       {
  1370. +           printkd("wlan_cmd_set_essid failed with ret %d\n", ret);
  1371. +           printkd("%s(), end\n",__func__);
  1372. +           return ret;
  1373. +       }      
  1374. +       memcpy(vif->cfg80211.ssid, sme->ssid, sme->ssid_len);
  1375. +       vif->cfg80211.ssid_len = sme->ssid_len;    
  1376. +   }
  1377. +   vif->cfg80211.connect_status = ITM_CONNECTING;
  1378. +   printkd("%s(), ok\n",__func__);
  1379. +   return ret;
  1380. +}
  1381. +
  1382. +static int wlan_cfg80211_disconnect(struct wiphy *wiphy,
  1383. +                                        struct net_device *ndev,
  1384. +                                        unsigned short reason_code)
  1385. +{
  1386. +   wlan_vif_t      *vif;
  1387. +   unsigned char        vif_id;
  1388. +   int ret;
  1389. +   vif = ndev_to_vif(ndev);
  1390. +   vif_id = vif->id;
  1391. +
  1392. +   if(ITM_NONE_MODE == vif->mode)
  1393. +       return -EAGAIN;
  1394. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  1395. +   printkd("Begin disconnect: %s\n", vif->cfg80211.ssid);
  1396. +  
  1397. +   ret = wlan_cmd_disconnect(vif_id, reason_code);
  1398. +   if (ret < 0)
  1399. +   {
  1400. +       printkd("swifi_disconnect_cmd failed with ret %d\n", ret);
  1401. +   }
  1402. +   memset(vif->cfg80211.ssid, 0, sizeof(vif->cfg80211.ssid));
  1403. +   return ret;
  1404. +}
  1405. +
  1406. +static int wlan_cfg80211_add_key(struct wiphy *wiphy,
  1407. +                    struct net_device *netdev, u8 idx,
  1408. +                    bool pairwise, const u8 *mac_addr,
  1409. +                    struct key_params *params)
  1410. +{
  1411. +   wlan_vif_t      *vif;
  1412. +   unsigned char        vif_id;
  1413. +   int ret;
  1414. +   unsigned char key[32];
  1415. +   vif = ndev_to_vif(netdev);
  1416. +   vif_id = vif->id;
  1417. +   if(ITM_NONE_MODE == vif->mode)
  1418. +       return -EAGAIN;
  1419. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  1420. +   if ( vif->mode == ITM_AP_MODE && (vif->cfg80211.p2p_mode == false) ) {
  1421. +       printkd("%s line:%d\n", __func__, __LINE__);
  1422. +      
  1423. +       memset(&key[0], 0, 32);
  1424. +       ret = hostap_conf_load(HOSTAP_CONF_FILE_NAME, key);
  1425. +       if (ret != 0) {
  1426. +           printkd("%s failed to load hostapd conf!\n",  __func__);
  1427. +           return ret;
  1428. +       }
  1429. +       ret = wlan_cmd_set_psk(vif_id, key, sizeof(key));
  1430. +       if (ret < 0) {
  1431. +           printkd("%s failed to set psk!\n", __func__);
  1432. +           return ret;
  1433. +       }
  1434. +   }
  1435. +   else if ((vif->mode == ITM_STATION_MODE) || vif->mode == ITM_P2P_CLIENT_MODE || vif->mode == ITM_P2P_GO_MODE)
  1436. +   {
  1437. +       vif->cfg80211.key_index[pairwise] = idx;
  1438. +       vif->cfg80211.key_len[pairwise][idx] = params->key_len;
  1439. +       memcpy(vif->cfg80211.key[pairwise][idx], params->key, params->key_len);
  1440. +       ret = itm_wlan_add_cipher_key(vif, pairwise, idx, params->cipher, params->seq, mac_addr);
  1441. +       if (ret < 0)
  1442. +       {
  1443. +           printkd("%s failed to add cipher key!\n", __func__);
  1444. +           return ret;
  1445. +       }
  1446. +   }
  1447. +
  1448. +   return 0;
  1449. +}
  1450. +
  1451. +static int wlan_cfg80211_del_key(struct wiphy *wiphy,
  1452. +                                     struct net_device *ndev,
  1453. +                                     unsigned char key_index, bool pairwise,
  1454. +                                     const unsigned char *mac_addr)
  1455. +{
  1456. +   wlan_vif_t      *vif;
  1457. +   unsigned char        vif_id;
  1458. +
  1459. +   vif = ndev_to_vif(ndev);
  1460. +   vif_id = vif->id;
  1461. +   if(ITM_NONE_MODE == vif->mode)
  1462. +       return -EAGAIN;
  1463. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  1464. +   if (key_index > WLAN_MAX_KEY_INDEX)
  1465. +   {
  1466. +       printkd("key index %d out of bounds\n", key_index);
  1467. +       return -ENOENT;
  1468. +   }
  1469. +   if (!vif->cfg80211.key_len[pairwise][key_index])
  1470. +   {
  1471. +       printkd("index %d is empty\n", key_index);
  1472. +       return 0;
  1473. +   }
  1474. +   vif->cfg80211.key_len[pairwise][key_index] = 0;
  1475. +   vif->cfg80211.cipher_type = NONE;
  1476. +
  1477. +   return wlan_cmd_del_key(vif_id, key_index, mac_addr);
  1478. +}
  1479. +
  1480. +static int wlan_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, unsigned char key_index, bool unicast, bool multicast)
  1481. +{
  1482. +   int ret;
  1483. +   wlan_vif_t      *vif;
  1484. +   unsigned char        vif_id;
  1485. +   vif = ndev_to_vif(ndev);
  1486. +   vif_id = vif->id;
  1487. +   if(ITM_NONE_MODE == vif->mode)
  1488. +       return -EAGAIN;
  1489. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  1490. +   if (key_index < 0 || key_index > 3)
  1491. +   {
  1492. +       printkd("Invalid key index %d\n", key_index);
  1493. +       return -EINVAL;
  1494. +   }
  1495. +   ret = wlan_cmd_set_key(vif_id, key_index);
  1496. +   if (ret < 0)
  1497. +   {
  1498. +       printkd("wlan_cmd_set_key failed\n");
  1499. +       return ret;
  1500. +   }
  1501. +
  1502. +   return 0;
  1503. +}
  1504. +
  1505. +static int wlan_cfg80211_set_wiphy_params(struct wiphy *wiphy, unsigned int changed)
  1506. +{
  1507. +   int ret;
  1508. +   wlan_vif_t      *vif;
  1509. +   unsigned char        vif_id;
  1510. +   vif_id = NETIF_0_ID;
  1511. +   vif = id_to_vif(vif_id);
  1512. +   if(ITM_NONE_MODE == vif->mode)
  1513. +       return -EAGAIN;
  1514. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  1515. +   if (changed & WIPHY_PARAM_RTS_THRESHOLD)
  1516. +   {
  1517. +       ret = wlan_cmd_set_rts(vif_id, wiphy->rts_threshold);
  1518. +       if (ret != 0)
  1519. +       {
  1520. +           printkd("wlan_cmd_set_rts failed\n");
  1521. +           return -EIO;
  1522. +       }
  1523. +   }
  1524. +
  1525. +   if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
  1526. +   {
  1527. +       ret =
  1528. +           wlan_cmd_set_frag(vif_id, wiphy->frag_threshold);
  1529. +       if (ret != 0)
  1530. +       {
  1531. +           printkd("wlan_cmd_set_frag failed\n");
  1532. +           return -EIO;
  1533. +       }
  1534. +   }
  1535. +   return 0;
  1536. +}
  1537. +
  1538. +static int wlan_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, unsigned char *mac, struct station_info *sinfo)
  1539. +{
  1540. +   unsigned char signal, noise;
  1541. +   int rate, ret, i, failed;
  1542. +   wlan_vif_t    *vif;
  1543. +   unsigned char  vif_id;
  1544. +   static int cfg80211_get_station_time;
  1545. +   static char cfg80211_get_station_signal;
  1546. +   static int cfg80211_get_station_txrate;
  1547. +   static int cfg80211_get_station_txfailed;
  1548. +
  1549. +   vif = ndev_to_vif(dev);
  1550. +   vif_id = vif->id;
  1551. +   if(ITM_NONE_MODE == vif->mode)
  1552. +       return -EAGAIN;
  1553. +   if(NULL == sinfo)
  1554. +   {
  1555. +       printke("[%s][sinfo null]\n", __func__);
  1556. +       return -EAGAIN;
  1557. +   }
  1558. +  
  1559. +   sinfo->filled    |= STATION_INFO_TX_BYTES |  STATION_INFO_TX_PACKETS | STATION_INFO_RX_BYTES | STATION_INFO_RX_PACKETS;
  1560. +   sinfo->tx_bytes   = vif->ndev->stats.tx_bytes;
  1561. +   sinfo->tx_packets = vif->ndev->stats.tx_packets;
  1562. +   sinfo->rx_bytes   = vif->ndev->stats.rx_bytes;
  1563. +   sinfo->rx_packets = vif->ndev->stats.rx_packets;
  1564. +
  1565. +   if(0 != cfg80211_get_station_time)
  1566. +   {
  1567. +       sinfo->signal = cfg80211_get_station_signal;
  1568. +       sinfo->filled |= STATION_INFO_SIGNAL;
  1569. +       sinfo->txrate.legacy = cfg80211_get_station_txrate;
  1570. +       sinfo->filled |= STATION_INFO_TX_BITRATE;
  1571. +       sinfo->tx_failed = cfg80211_get_station_txfailed;
  1572. +       sinfo->filled |= STATION_INFO_TX_FAILED;
  1573. +       if ( 2 == cfg80211_get_station_time )
  1574. +       {
  1575. +           cfg80211_get_station_time = 0;
  1576. +       }
  1577. +       else
  1578. +       {
  1579. +           cfg80211_get_station_time ++;
  1580. +       }
  1581. +       return 0;
  1582. +   }
  1583. +
  1584. +   ret = wlan_cmd_get_rssi(vif_id, &signal, &noise);
  1585. +   if (OK == ret)
  1586. +   {
  1587. +       sinfo->signal  = signal;
  1588. +       sinfo->filled |= STATION_INFO_SIGNAL;
  1589. +   }
  1590. +   else
  1591. +   {
  1592. +       printkd("wlan_cmd_get_rssi error!\n");
  1593. +       return -EIO;
  1594. +   }
  1595. +
  1596. +   ret = wlan_cmd_get_txrate_txfailed(vif_id, &rate, &failed);
  1597. +   if (OK == ret)
  1598. +   {
  1599. +       sinfo->tx_failed = failed;
  1600. +       sinfo->filled |= STATION_INFO_TX_BITRATE | STATION_INFO_TX_FAILED;
  1601. +   }
  1602. +   else
  1603. +   {
  1604. +       printkd("wlan_cmd_get_txrate_txfailed error!\n");
  1605. +       return -EIO;
  1606. +   }
  1607. +
  1608. +   if (!(rate & 0x7f))
  1609. +   {
  1610. +       sinfo->txrate.legacy = 10;
  1611. +   }
  1612. +   else
  1613. +   {
  1614. +       for (i = 0; i < ARRAY_SIZE(itm_rates); i++)
  1615. +       {
  1616. +           if (rate == itm_rates[i].hw_value)
  1617. +           {
  1618. +               sinfo->txrate.legacy = itm_rates[i].bitrate;
  1619. +               if (rate & 0x80)
  1620. +               sinfo->txrate.mcs = itm_rates[i].hw_value;
  1621. +               break;
  1622. +           }
  1623. +       }
  1624. +       if (i >= ARRAY_SIZE(itm_rates))
  1625. +           sinfo->txrate.legacy = 10;
  1626. +   }
  1627. +   cfg80211_get_station_signal = sinfo->signal;
  1628. +   cfg80211_get_station_txrate = sinfo->txrate.legacy;
  1629. +   cfg80211_get_station_txfailed = sinfo->tx_failed;
  1630. +   cfg80211_get_station_time ++;
  1631. +
  1632. +   return 0;
  1633. +}
  1634. +
  1635. +static int wlan_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_pmksa *pmksa)
  1636. +{
  1637. +   int ret;
  1638. +   wlan_vif_t      *vif;
  1639. +   unsigned char        vif_id;
  1640. +   vif = ndev_to_vif(netdev);
  1641. +   vif_id = vif->id;
  1642. +   if(ITM_NONE_MODE == vif->mode)
  1643. +       return -EAGAIN;
  1644. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  1645. +   ret = wlan_cmd_pmksa(vif_id, pmksa->bssid, pmksa->pmkid, WIFI_CMD_SET_PMKSA);
  1646. +   return ret;
  1647. +}
  1648. +
  1649. +static int wlan_cfg80211_del_pmksa(struct wiphy *wiphy,
  1650. +                                       struct net_device *netdev,
  1651. +                                       struct cfg80211_pmksa *pmksa)
  1652. +{
  1653. +   int ret;
  1654. +   wlan_vif_t      *vif;
  1655. +   unsigned char        vif_id;
  1656. +   vif = ndev_to_vif(netdev);
  1657. +   vif_id = vif->id;
  1658. +   if(ITM_NONE_MODE == vif->mode)
  1659. +       return -EAGAIN;
  1660. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  1661. +   ret = wlan_cmd_pmksa(vif_id, pmksa->bssid, pmksa->pmkid, WIFI_CMD_DEL_PMKSA);
  1662. +   return ret;
  1663. +}
  1664. +
  1665. +static int wlan_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
  1666. +{
  1667. +   int ret;
  1668. +   wlan_vif_t      *vif;
  1669. +   unsigned char        vif_id;
  1670. +   vif = ndev_to_vif(netdev);
  1671. +   vif_id = vif->id;
  1672. +   if(ITM_NONE_MODE == vif->mode)
  1673. +       return -EAGAIN;
  1674. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  1675. +   ret = wlan_cmd_pmksa(vif_id, vif->cfg80211.bssid, NULL, WIFI_CMD_FLUSH_PMKSA);
  1676. +   return ret;
  1677. +}
  1678. +
  1679. +void cfg80211_report_connect_result(unsigned char vif_id, unsigned char *pData, int len)
  1680. +{
  1681. +   unsigned char *req_ie_ptr, *resp_ie_ptr, *bssid_ptr, *pos, *value_ptr;
  1682. +   unsigned char status_code;
  1683. +   unsigned short bssid_len;
  1684. +   unsigned char req_ie_len;
  1685. +   unsigned short resp_ie_len;
  1686. +   unsigned int event_len;
  1687. +   int left;
  1688. +   unsigned char reassociate_rsp_flag = 0;
  1689. +  
  1690. +   wlan_vif_t *vif = id_to_vif(vif_id);   
  1691. +   printkd("%s(), enter\n", __func__);
  1692. +   event_len = len;
  1693. +   /* status_len 2 + status_code 1 = 3 bytes */
  1694. +   if (event_len < 3)
  1695. +   {
  1696. +       printkd("filled event len(%d) is not a valid len\n", event_len);
  1697. +       goto out;
  1698. +   }
  1699. +   pos = kmalloc(event_len, GFP_KERNEL);
  1700. +   if (pos == NULL)
  1701. +   {
  1702. +       printkd("[%s][%d][%d]\n", __func__, __LINE__, event_len);
  1703. +       if(event_len > 16384)
  1704. +           BUG_ON(1);
  1705. +       goto out;
  1706. +   }
  1707. +   /* The first byte of event data is status and len */
  1708. +   memcpy(pos, pData, event_len);
  1709. +   /* msg byte format
  1710. +    * byte [0] the length for status_code,here is 1
  1711. +    * byte [1] reassociate_rsp_flag
  1712. +    * byte [2] status_code
  1713. +    * ..... other data
  1714. +    */
  1715. +   if (1 != *pos) {
  1716. +       ASSERT("msg first byte err:%d != 1", (int)*pos);
  1717. +       kfree(pos);
  1718. +       goto out;
  1719. +   }
  1720. +   reassociate_rsp_flag = *(pos + 1);
  1721. +   status_code = *(pos + 2);
  1722. +  
  1723. +   /* FIXME later the status code should be reported by CP2 */
  1724. +   if (status_code != 0)
  1725. +   {
  1726. +       printkd("%s, Connect is failled (%d)\n", __func__, status_code);
  1727. +       kfree(pos);
  1728. +       goto out;
  1729. +   }
  1730. +  
  1731. +   value_ptr = pos + 3;
  1732. +   left = event_len - 3;
  1733. +   /* BSSID is 6 + len is 2 = 8 */
  1734. +   if (left < 8)
  1735. +   {
  1736. +       printkd("%s(), Do not have a vaild bssid\n", __func__);
  1737. +       kfree(pos);
  1738. +       goto out;
  1739. +   }
  1740. +   memcpy(&bssid_len, value_ptr, 2);
  1741. +   bssid_len = le16_to_cpu(bssid_len);
  1742. +   left -= 2;
  1743. +   bssid_ptr = value_ptr + 2;
  1744. +   left -= bssid_len;
  1745. +
  1746. +   if (!left)
  1747. +   {
  1748. +       printkd("%s(), There is no req_ie frame!\n", __func__);
  1749. +       kfree(pos);
  1750. +       goto out;
  1751. +   }
  1752. +   req_ie_len = *(unsigned char *)(bssid_ptr + bssid_len);
  1753. +   left -= 1;
  1754. +   req_ie_ptr = bssid_ptr + bssid_len + 1;
  1755. +   left -= req_ie_len;
  1756. +   if (!left)
  1757. +   {
  1758. +       printkd("%s(), There is no resp_ie frame!\n", __func__);
  1759. +       kfree(pos);
  1760. +       goto out;
  1761. +   }
  1762. +   resp_ie_len = *(unsigned char *)(req_ie_ptr + req_ie_len) + *(unsigned char *)(req_ie_ptr + req_ie_len +1);
  1763. +   resp_ie_ptr = req_ie_ptr + req_ie_len + 2;
  1764. +
  1765. +   if ( (vif->cfg80211.connect_status == ITM_CONNECTING) || (1 == reassociate_rsp_flag) )
  1766. +   {
  1767. +       /* inform connect result to cfg80211 */
  1768. +       vif->cfg80211.connect_status = ITM_CONNECTED;
  1769. +       if(1 == reassociate_rsp_flag)
  1770. +       {
  1771. +           vif->wdev.sme_state = CFG80211_SME_CONNECTING;
  1772. +       }
  1773. +       cfg80211_connect_result(vif->ndev,  bssid_ptr, req_ie_ptr, req_ie_len,  resp_ie_ptr, resp_ie_len, WLAN_STATUS_SUCCESS, GFP_KERNEL);
  1774. +       kfree(pos);
  1775. +       if (!netif_carrier_ok(vif->ndev))
  1776. +       {
  1777. +           printkd("%s(), netif_carrier_on, ssid:%s\n", __func__, vif->cfg80211.ssid);
  1778. +           netif_carrier_on(vif->ndev);
  1779. +           netif_wake_queue(vif->ndev);
  1780. +       }
  1781. +   }
  1782. +   printkd("%s(), ok\n", __func__);
  1783. +   return;
  1784. +out:
  1785. +   if (vif->cfg80211.scan_request && (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 1))
  1786. +   {
  1787. +       del_timer_sync(&vif->cfg80211.scan_timeout);
  1788. +       cfg80211_scan_done(vif->cfg80211.scan_request, true);
  1789. +       vif->cfg80211.scan_request = NULL;
  1790. +       if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 &&
  1791. +               vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
  1792. +           wake_unlock(&vif->cfg80211.scan_done_lock);
  1793. +       atomic_dec(&vif->cfg80211.scan_status);
  1794. +   }
  1795. +   if (vif->cfg80211.connect_status == ITM_CONNECTING)
  1796. +   {
  1797. +       cfg80211_connect_result(vif->ndev, vif->cfg80211.bssid, NULL, 0,  NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE,  GFP_KERNEL);
  1798. +   }
  1799. +   else if (vif->cfg80211.connect_status == ITM_CONNECTED)
  1800. +   {
  1801. +       cfg80211_disconnected(vif->ndev, status_code, NULL, 0, GFP_KERNEL);
  1802. +   }
  1803. +
  1804. +   printkd("%s(), err\n", __func__);
  1805. +   return;
  1806. +}
  1807. +
  1808. +void cfg80211_report_disconnect_done(unsigned char vif_id, unsigned char *pData, int len)
  1809. +{
  1810. +   struct cfg80211_bss *bss = NULL;
  1811. +   unsigned short reason_code = 0;
  1812. +   bool found = false;
  1813. +   wlan_vif_t *vif = id_to_vif(vif_id);
  1814. +   printkd("%s()\n", __func__);
  1815. +   /* This should filled if disconnect reason is not only one */
  1816. +   memcpy(&reason_code, pData, 2);
  1817. +   reason_code = le16_to_cpu(reason_code);
  1818. +   if (vif->cfg80211.scan_request &&  (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 1))
  1819. +   {
  1820. +       del_timer_sync(&vif->cfg80211.scan_timeout);
  1821. +       cfg80211_scan_done(vif->cfg80211.scan_request, true);
  1822. +       vif->cfg80211.scan_request = NULL;
  1823. +       if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 &&  vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
  1824. +           wake_unlock(&vif->cfg80211.scan_done_lock);
  1825. +       atomic_dec(&vif->cfg80211.scan_status);
  1826. +   }
  1827. +   if (vif->cfg80211.connect_status == ITM_CONNECTING)
  1828. +   {
  1829. +       cfg80211_connect_result(vif->ndev,
  1830. +                               vif->cfg80211.bssid, NULL, 0,
  1831. +                               NULL, 0,
  1832. +                               WLAN_STATUS_UNSPECIFIED_FAILURE,
  1833. +                               GFP_KERNEL);
  1834. +   }
  1835. +   else if (vif->cfg80211.connect_status == ITM_CONNECTED)
  1836. +   {
  1837. +       if (reason_code == AP_LEAVING /*||
  1838. +           reason_code == AP_DEAUTH*/)
  1839. +       {
  1840. +           do
  1841. +           {
  1842. +               bss = cfg80211_get_bss(vif->wdev.wiphy, NULL,
  1843. +                                      vif->cfg80211.bssid, vif->cfg80211.ssid,
  1844. +                                      vif->cfg80211.ssid_len,
  1845. +                                      WLAN_CAPABILITY_ESS,
  1846. +                                      WLAN_CAPABILITY_ESS);
  1847. +               if (bss)
  1848. +               {
  1849. +                   cfg80211_unlink_bss(vif->wdev.wiphy,
  1850. +                                       bss);
  1851. +                   found = true;
  1852. +               }
  1853. +               else
  1854. +               {
  1855. +                   found = false;
  1856. +               }
  1857. +           }
  1858. +           while (found);
  1859. +       }
  1860. +       cfg80211_disconnected(vif->ndev, reason_code,
  1861. +                             NULL, 0, GFP_KERNEL);
  1862. +   }
  1863. +
  1864. +   vif->cfg80211.connect_status = ITM_DISCONNECTED;
  1865. +   if (netif_carrier_ok(vif->ndev))
  1866. +   {
  1867. +       printkd("netif_carrier_off\n");
  1868. +       netif_carrier_off(vif->ndev);
  1869. +       netif_stop_queue(vif->ndev);
  1870. +   }
  1871. +   return;
  1872. +}
  1873. +
  1874. +static void wlan_scan_timeout(unsigned long data)
  1875. +{
  1876. +   wlan_vif_t *vif = (wlan_vif_t *)data;
  1877. +
  1878. +   printkd("%s()\n", __func__);
  1879. +   if (vif->cfg80211.scan_request &&  (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 1))
  1880. +   {
  1881. +       printkd("scan timer expired!\n");
  1882. +       cfg80211_scan_done(vif->cfg80211.scan_request, true);
  1883. +       vif->cfg80211.scan_request = NULL;
  1884. +       if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
  1885. +           wake_unlock(&vif->cfg80211.scan_done_lock);
  1886. +       atomic_dec(&vif->cfg80211.scan_status);
  1887. +       printkd("%s()  end\n", __func__);
  1888. +
  1889. +       return;
  1890. +   }
  1891. +  
  1892. +   printkd("%s()  end, wrong scan timer expired!\n", __func__);
  1893. +   return;
  1894. +}
  1895. +
  1896. +void cfg80211_report_scan_done(unsigned char vif_id, unsigned char *pData, int len, bool aborted)
  1897. +{
  1898. +   struct ieee80211_mgmt *mgmt;
  1899. +   struct ieee80211_channel *channel;
  1900. +   struct ieee80211_supported_band *band;
  1901. +   struct wiphy *wiphy;
  1902. +   struct cfg80211_bss *itm_bss = NULL;
  1903. +   unsigned int mgmt_len = 0;
  1904. +   unsigned short channel_num = 0, channel_len;
  1905. +   unsigned short rssi_len;
  1906. +   short          rssi;
  1907. +   int            signal;
  1908. +   int freq;
  1909. +   unsigned int left = len;
  1910. +   wlan_vif_t *vif = id_to_vif(vif_id);
  1911. +   const unsigned char *pos = pData;
  1912. +
  1913. +   wiphy = vif->wdev.wiphy;
  1914. +   printkd("%s()\n", __func__);
  1915. +   if (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 0)
  1916. +   {
  1917. +       printkd( "scan event is aborted\n");
  1918. +       return;
  1919. +   }
  1920. +
  1921. +   if (!vif->cfg80211.scan_request)
  1922. +   {
  1923. +       printkd("vif->cfg80211.scan_request is null\n");
  1924. +       atomic_dec(&vif->cfg80211.scan_status);
  1925. +       return;
  1926. +   }
  1927. +
  1928. +   if (left < 10 || aborted)
  1929. +   {
  1930. +       printkd( "filled event len(%d) is not a valid len\n", len);
  1931. +       goto out;
  1932. +   }
  1933. +
  1934. +   mgmt = kmalloc(left, GFP_KERNEL);
  1935. +   if (mgmt == NULL)
  1936. +   {
  1937. +       printkd("[%s][%d]\n", __func__, left);
  1938. +       goto out;
  1939. +   }
  1940. +   while (left >= 10)
  1941. +   {
  1942. +       /* must use memcpy to protect unaligned */
  1943. +       /* The formate of frame is len(two bytes) + data */
  1944. +       memcpy(&channel_len, pos, 2);
  1945. +       channel_len = le16_to_cpu(channel_len);
  1946. +       pos += 2;
  1947. +       left -= 2;
  1948. +       if (channel_len > 2) {
  1949. +           ASSERT("channel_len %u > 2\n", channel_len);
  1950. +           kfree(mgmt);
  1951. +           goto out;
  1952. +       }
  1953. +       memcpy(&channel_num, pos, channel_len);
  1954. +       channel_num = le16_to_cpu(channel_num);
  1955. +       pos += channel_len;
  1956. +       left -= channel_len;
  1957. +       /* The second two value of frame is rssi */
  1958. +       memcpy(&rssi_len, pos, 2);
  1959. +       rssi_len = le16_to_cpu(rssi_len);
  1960. +       pos += 2;
  1961. +       left -= 2;
  1962. +       memcpy(&rssi, pos, rssi_len);
  1963. +       pos += rssi_len;
  1964. +       left -= rssi_len;
  1965. +       /* The third two value of frame is following data len */
  1966. +       memcpy(&mgmt_len, pos, 2);
  1967. +       mgmt_len = le16_to_cpu(mgmt_len);
  1968. +       pos += 2;
  1969. +       left -= 2;
  1970. +      
  1971. +       if (mgmt_len > left)
  1972. +       {
  1973. +           printkd("mgmt_len(0x%08x) > left(0x%08x)!\n", mgmt_len, left);
  1974. +           kfree(mgmt);
  1975. +           goto out;
  1976. +       }
  1977. +
  1978. +       /* The following is real data */
  1979. +       memcpy(mgmt, pos, mgmt_len);
  1980. +       left -= mgmt_len;
  1981. +       pos += mgmt_len;
  1982. +
  1983. +       /* FIXME Now only support 2GHZ */
  1984. +       band = wiphy->bands[IEEE80211_BAND_2GHZ];
  1985. +       freq = ieee80211_channel_to_frequency(channel_num, band->band);
  1986. +       channel = ieee80211_get_channel(wiphy, freq);
  1987. +       if (!channel)
  1988. +       {
  1989. +           printkd("freq is %d\n", freq);
  1990. +           continue;
  1991. +       }
  1992. +       signal = rssi;
  1993. +       //printkd("[report][%s][%d][%d]\n",ssid, channel_num, signal);
  1994. +       itm_bss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,  le16_to_cpu(mgmt_len), signal, GFP_KERNEL);
  1995. +
  1996. +       if (unlikely(!itm_bss))
  1997. +           printkd("cfg80211_inform_bss_frame error\n");
  1998. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  1999. +       cfg80211_put_bss(wiphy, itm_bss);
  2000. +#else
  2001. +       cfg80211_put_bss(itm_bss);
  2002. +#endif
  2003. +   }
  2004. +
  2005. +   if (left)
  2006. +   {
  2007. +       kfree(mgmt);
  2008. +       goto out;
  2009. +   }
  2010. +
  2011. +   kfree(mgmt);
  2012. +   del_timer_sync(&vif->cfg80211.scan_timeout);
  2013. +   cfg80211_scan_done(vif->cfg80211.scan_request, aborted);
  2014. +   vif->cfg80211.scan_request = NULL;
  2015. +   if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
  2016. +       wake_unlock(&vif->cfg80211.scan_done_lock);
  2017. +   atomic_dec(&vif->cfg80211.scan_status);
  2018. +
  2019. +   printkd("%s(), ok!\n", __func__);
  2020. +   return;
  2021. +
  2022. +out:
  2023. +   del_timer_sync(&vif->cfg80211.scan_timeout);
  2024. +   cfg80211_scan_done(vif->cfg80211.scan_request, true);
  2025. +   vif->cfg80211.scan_request = NULL;
  2026. +   if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 &&
  2027. +           vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
  2028. +       wake_unlock(&vif->cfg80211.scan_done_lock);
  2029. +   atomic_dec(&vif->cfg80211.scan_status);
  2030. +
  2031. +   printkd("%s(), err\n", __func__);
  2032. +   return;
  2033. +}
  2034. +
  2035. +void cfg80211_report_scan_frame(unsigned char vif_id, unsigned char *pData, int len)
  2036. +{
  2037. +   unsigned short frame_len;
  2038. +   unsigned short event_ops;
  2039. +   int i, report_null;
  2040. +   wlan_vif_t            *vif;
  2041. +   buf_scan_frame_t      *scan_buf;
  2042. +   struct wlan_event_scan_rsp *event;
  2043. +   unsigned char         *msa;
  2044. +   unsigned char          ssid[33] = {0};
  2045. +   unsigned char          bssid[6] = {0};
  2046. +
  2047. +   struct ieee80211_channel        *channel = NULL;
  2048. +   struct ieee80211_supported_band *band    = NULL;
  2049. +   struct wiphy        *wiphy   = NULL;
  2050. +   struct cfg80211_bss *itm_bss = NULL;
  2051. +   struct ieee80211_mgmt *mgmt = NULL;
  2052. +   u8 *ie;
  2053. +   size_t ielen;
  2054. +   u16 capability, beacon_interval;
  2055. +   int freq, signal;
  2056. +   u64 tsf;
  2057. +  
  2058. +   vif    = id_to_vif(vif_id);
  2059. +   wiphy  = vif->wdev.wiphy;
  2060. +   event  = (struct wlan_event_scan_rsp *)(pData);
  2061. +   frame_len = le16_to_cpu(event->frame_len);
  2062. +   /* 64bit */
  2063. +   event_ops = le16_to_cpu(event->ops);
  2064. +   if (frame_len + sizeof(*event) > len || event_ops > 2)
  2065. +   {
  2066. +       printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
  2067. +       return;
  2068. +   }
  2069. +   if (0 == event_ops)
  2070. +   {
  2071. +       if (frame_len < 37) {
  2072. +           printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
  2073. +           return;
  2074. +       }
  2075. +       msa = (unsigned char *)(event + 1);
  2076. +       get_ssid(msa,  ssid);
  2077. +       get_bssid(msa, bssid);
  2078. +       if(0 == strlen(ssid) )
  2079. +       {
  2080. +           printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
  2081. +           return;
  2082. +       }
  2083. +       if (1024 < frame_len)
  2084. +       {
  2085. +           printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
  2086. +           return;
  2087. +       }
  2088. +       for(i=0; i < MAX_SCAN_FRAME_BUF_NUM; i++)
  2089. +       {
  2090. +           scan_buf = (buf_scan_frame_t *)( vif->cfg80211.scan_frame_array + i*sizeof(buf_scan_frame_t) );
  2091. +           if(0xff != scan_buf->live)
  2092. +               continue;
  2093. +           if(0 != memcmp(bssid, scan_buf->bssid, 6) )
  2094. +               continue;
  2095. +           strcpy(scan_buf->ssid,  ssid );
  2096. +           memcpy(scan_buf->msa,   msa,  frame_len);
  2097. +           scan_buf->msa_len  = frame_len;
  2098. +           scan_buf->channel  = le16_to_cpu(event->channel);
  2099. +           scan_buf->signal   = (short)le16_to_cpu(event->signal);
  2100. +           scan_buf->live     = 0xff;
  2101. +           scan_buf->keep     = 1;
  2102. +           return;
  2103. +       }
  2104. +       for(i=0; i < MAX_SCAN_FRAME_BUF_NUM; i++)
  2105. +       {
  2106. +           scan_buf = (buf_scan_frame_t *)(vif->cfg80211.scan_frame_array + i*sizeof(buf_scan_frame_t) );
  2107. +           if(0xff  == scan_buf->live)
  2108. +               continue;
  2109. +           memcpy(scan_buf->bssid, bssid, 6);
  2110. +           strcpy(scan_buf->ssid,  ssid );
  2111. +           memcpy(scan_buf->msa,   msa, frame_len);
  2112. +           scan_buf->msa_len  = frame_len;
  2113. +           scan_buf->channel  = le16_to_cpu(event->channel);
  2114. +           scan_buf->signal   = (short)le16_to_cpu(event->signal);
  2115. +           scan_buf->keep     = 1;
  2116. +           scan_buf->live     = 0xff;
  2117. +           printkd("[netif:%d find_ssid][%s][%d][%d]\n",vif_id, scan_buf->ssid, scan_buf->channel, scan_buf->signal);
  2118. +           return;
  2119. +       }
  2120. +       return;
  2121. +   }
  2122. +   if (1 != event_ops)
  2123. +   {
  2124. +       printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
  2125. +       return;
  2126. +   }
  2127. +   if (!vif->cfg80211.scan_request)
  2128. +   {
  2129. +       printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
  2130. +       atomic_dec(&vif->cfg80211.scan_status);
  2131. +       return;
  2132. +   }  
  2133. +   if (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 0)
  2134. +   {
  2135. +       printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
  2136. +       return;
  2137. +   }
  2138. +   if (!vif->cfg80211.scan_request)
  2139. +   {
  2140. +       printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
  2141. +       atomic_dec(&vif->cfg80211.scan_status);
  2142. +       return;
  2143. +   }  
  2144. +   report_null = -1;
  2145. +   band = wiphy->bands[IEEE80211_BAND_2GHZ];
  2146. +   for (i = 0; i < MAX_SCAN_FRAME_BUF_NUM; i++) {
  2147. +       scan_buf = (buf_scan_frame_t *)( vif->cfg80211.scan_frame_array + i*sizeof(buf_scan_frame_t) );
  2148. +       if(0xff != scan_buf->live)
  2149. +           continue;
  2150. +       if(0 == scan_buf->keep)
  2151. +       {
  2152. +           printkd("[netif:%d leave_ssid][%s][%d][%d]\n",
  2153. +               vif_id, scan_buf->ssid,
  2154. +               le16_to_cpu(event->channel),
  2155. +               le16_to_cpu(event->signal));
  2156. +           memset((char *)scan_buf, 0, sizeof(buf_scan_frame_t) );
  2157. +           continue;
  2158. +       }
  2159. +       scan_buf->keep--;
  2160. +       freq = ieee80211_channel_to_frequency(scan_buf->channel, band->band);
  2161. +       channel = ieee80211_get_channel(wiphy, freq);
  2162. +       if (!channel)
  2163. +       {
  2164. +           printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
  2165. +           continue;
  2166. +       }
  2167. +       mgmt = (struct ieee80211_mgmt *)(&scan_buf->msa[0]);
  2168. +       tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
  2169. +       capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
  2170. +       beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
  2171. +       ie = mgmt->u.probe_resp.variable;
  2172. +       ielen = le16_to_cpu(scan_buf->msa_len) - offsetof(struct ieee80211_mgmt,
  2173. +                       u.probe_resp.variable);
  2174. +       signal = scan_buf->signal;
  2175. +       signal = signal*100;
  2176. +       wiphy_info(wiphy, "   %s, " MACSTR ", channel %2u, signal %d\n",
  2177. +             ieee80211_is_probe_resp(mgmt->frame_control)
  2178. +             ? "proberesp" : "beacon   ",
  2179. +             MAC2STR(mgmt->bssid), scan_buf->channel, scan_buf->signal);
  2180. +       itm_bss = cfg80211_inform_bss(wiphy, channel, mgmt->bssid,
  2181. +                     tsf, capability, beacon_interval, ie,
  2182. +                     ielen, signal, GFP_KERNEL);
  2183. +       if (unlikely(!itm_bss))
  2184. +           printkd("[%s %d][line %d err]\n", __func__, vif_id, __LINE__);
  2185. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  2186. +       cfg80211_put_bss(wiphy, itm_bss);
  2187. +#else
  2188. +       cfg80211_put_bss(itm_bss);
  2189. +#endif
  2190. +       report_null = 0;
  2191. +   }
  2192. +   if(-1 == report_null)
  2193. +   {
  2194. +       printkd("[%s %d][report-ssid][NULL]\n", __func__, vif_id);
  2195. +   }
  2196. +   del_timer_sync(&vif->cfg80211.scan_timeout);
  2197. +   cfg80211_scan_done(vif->cfg80211.scan_request, false);
  2198. +   vif->cfg80211.scan_request = NULL;
  2199. +   if (vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2)
  2200. +       wake_unlock(&vif->cfg80211.scan_done_lock);
  2201. +   atomic_dec(&vif->cfg80211.scan_status);
  2202. +   printkd("[%s %d] ok!\n", __func__, vif_id);
  2203. +   return;
  2204. +}
  2205. +
  2206. +void cfg80211_report_mic_failure(unsigned char vif_id,
  2207. +       unsigned char *pdata, int len)
  2208. +{
  2209. +   struct wlan_event_mic_failure *mic_failure;
  2210. +   wlan_vif_t *vif;
  2211. +
  2212. +   mic_failure = (struct wlan_event_mic_failure *)pdata;
  2213. +   vif = id_to_vif(vif_id);
  2214. +   if (vif) {
  2215. +       /* debug info,Pls remove it in the future */
  2216. +       printkd("[%s %d] is_mcast:0x%x key_id: 0x%x bssid: %x %x %x %x %x %x\n",
  2217. +           __func__, vif_id,
  2218. +           mic_failure->is_mcast, mic_failure->key_id,
  2219. +           vif->cfg80211.bssid[0], vif->cfg80211.bssid[1],
  2220. +           vif->cfg80211.bssid[2], vif->cfg80211.bssid[3],
  2221. +           vif->cfg80211.bssid[4], vif->cfg80211.bssid[5]);
  2222. +       cfg80211_michael_mic_failure(vif->ndev, vif->cfg80211.bssid,
  2223. +               (mic_failure->is_mcast ? NL80211_KEYTYPE_GROUP :
  2224. +                NL80211_KEYTYPE_PAIRWISE), mic_failure->key_id,
  2225. +               NULL, GFP_KERNEL);
  2226. +   }
  2227. +}
  2228. +
  2229. +static int wlan_cfg80211_mgmt_tx(struct wiphy *wiphy,
  2230. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  2231. +                    struct wireless_dev *wdev,
  2232. +#else
  2233. +                    struct net_device *ndev,
  2234. +#endif
  2235. +#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || \
  2236. +   defined(COMPAT_KERNEL_RELEASE))
  2237. +                    struct ieee80211_channel *chan,
  2238. +                    bool offchan,
  2239. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
  2240. +                    enum nl80211_channel_type channel_type,
  2241. +                    bool channel_type_valid,
  2242. +#endif
  2243. +                    unsigned int wait,
  2244. +#else  /*(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) */
  2245. +                    struct ieee80211_channel *chan,
  2246. +                    enum nl80211_channel_type channel_type,
  2247. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || \
  2248. +   defined(COMPAT_KERNEL_RELEASE)
  2249. +                    bool channel_type_valid,
  2250. +#endif
  2251. +#endif /*(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) */
  2252. +                    const u8 *buf, size_t len,
  2253. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
  2254. +                    bool no_cck,
  2255. +#endif
  2256. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
  2257. +                    bool dont_wait_for_ack,
  2258. +#endif
  2259. +                    u64 *cookie)
  2260. +{
  2261. +   int ret = -1;
  2262. +   wlan_vif_t      *vif;
  2263. +   unsigned char        vif_id;
  2264. +   vif = ndev_to_vif(wdev->netdev);
  2265. +   vif_id = vif->id;
  2266. +   if(ITM_NONE_MODE == vif->mode)
  2267. +       return -EAGAIN;
  2268. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  2269. +   if(len > 0)
  2270. +   {
  2271. +       ret = wlan_cmd_set_tx_mgmt(vif_id, chan, wait, buf, len);
  2272. +   }  
  2273. +   if(-1 == ret)
  2274. +       return -1;
  2275. +   cfg80211_mgmt_tx_status(&(vif->wdev), *cookie, buf, len, 1, GFP_KERNEL);       
  2276. +   return 0;
  2277. +}
  2278. +
  2279. +static void wlan_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
  2280. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  2281. +                         struct wireless_dev *wdev,
  2282. +#else
  2283. +                         struct net_device *ndev,
  2284. +#endif
  2285. +                         u16 frame_type, bool reg)
  2286. +{
  2287. +   wlan_vif_t      *vif;
  2288. +   unsigned char    vif_id;
  2289. +   vif = ndev_to_vif(wdev->netdev);
  2290. +   vif_id = vif->id;
  2291. +   if(ITM_NONE_MODE == vif->mode)
  2292. +       return ;
  2293. +   if(NETIF_0_ID == vif_id)
  2294. +       return;
  2295. +   printkd("[%s][%d]\n", __func__, vif_id);
  2296. +    register_frame(vif,frame_type,reg);
  2297. +   return;
  2298. +}
  2299. +
  2300. +static int wlan_change_beacon(wlan_vif_t *vif,struct cfg80211_beacon_data *beacon)
  2301. +{
  2302. +   u16 ie_len;
  2303. +   u8  *ie_ptr;
  2304. +   int ret = 0;
  2305. +   unsigned char  vif_id = vif->id;
  2306. +  
  2307. +   printkd("%s enter\n", __func__);
  2308. +#ifdef WIFI_DIRECT_SUPPORT
  2309. +   /* send beacon extra ies */
  2310. +   if (beacon->head != NULL) {
  2311. +       ie_len = beacon->head_len;
  2312. +       ie_ptr = kmalloc(ie_len, GFP_KERNEL);
  2313. +       if (ie_ptr == NULL)
  2314. +       {
  2315. +           printkd("[%s][%d][0x%p]\n", __func__, __LINE__, ie_ptr);
  2316. +           return -EINVAL;
  2317. +       }
  2318. +       memcpy(ie_ptr, beacon->head, ie_len);
  2319. +       printkd("begin send beacon head ies\n");
  2320. +
  2321. +       ret = wlan_cmd_set_p2p_ie(vif_id, P2P_BEACON_IE_HEAD, ie_ptr, ie_len);
  2322. +       if (ret) {
  2323. +           printkd(
  2324. +               "itm_wlan_set_p2p_ie beacon_ies head failed with ret %d\n",
  2325. +               ret);
  2326. +       } else {
  2327. +           printkd("send beacon head ies successfully\n");
  2328. +       }
  2329. +
  2330. +       kfree(ie_ptr);
  2331. +   }
  2332. +
  2333. +   /* send beacon extra ies */
  2334. +   if (beacon->tail != NULL) {
  2335. +       ie_len = beacon->tail_len;
  2336. +
  2337. +       ie_ptr = kmalloc(ie_len, GFP_KERNEL);
  2338. +       if (ie_ptr == NULL)
  2339. +       {
  2340. +           printkd("[%s][%d][0x%p]\n", __func__, __LINE__, ie_ptr);
  2341. +           return -EINVAL;
  2342. +       }
  2343. +       memcpy(ie_ptr, beacon->tail, ie_len);
  2344. +       printkd("begin send beacon tail ies\n");
  2345. +
  2346. +       ret = wlan_cmd_set_p2p_ie(vif_id,
  2347. +                         P2P_BEACON_IE_TAIL, ie_ptr, ie_len);
  2348. +       if (ret) {
  2349. +           printkd("wlan_cmd_set_p2p_ie beacon_ies tail failed with ret %d\n",ret);
  2350. +       } else {
  2351. +           printkd("send beacon tail ies successfully\n");
  2352. +       }
  2353. +
  2354. +       kfree(ie_ptr);
  2355. +   }
  2356. +
  2357. +   /* send probe response ies */
  2358. +
  2359. +   /* send beacon extra ies */
  2360. +   if (beacon->beacon_ies != NULL) {
  2361. +       ie_len = beacon->beacon_ies_len;
  2362. +
  2363. +       ie_ptr = kmalloc(ie_len, GFP_KERNEL);
  2364. +       if (ie_ptr == NULL)
  2365. +       {
  2366. +           printkd("[%s][%d][0x%p]\n", __func__, __LINE__, ie_ptr);
  2367. +           return -EINVAL;
  2368. +       }
  2369. +       memcpy(ie_ptr, beacon->beacon_ies, ie_len);
  2370. +       printkd("begin send beacon extra ies\n");
  2371. +
  2372. +       ret = wlan_cmd_set_p2p_ie(vif_id, P2P_BEACON_IE, ie_ptr, ie_len);
  2373. +       if (ret) {
  2374. +           printkd( "wlan_cmd_set_p2p_ie beacon_ies failed with ret %d\n",ret);
  2375. +       } else {
  2376. +           printkd("send beacon extra ies successfully\n");
  2377. +       }
  2378. +
  2379. +       kfree(ie_ptr);
  2380. +   }
  2381. +
  2382. +   /* send probe response ies */
  2383. +
  2384. +   if (beacon->proberesp_ies != NULL) {
  2385. +       printkd("%s line:%d\n", __func__, __LINE__);
  2386. +       ie_len = beacon->proberesp_ies_len;
  2387. +
  2388. +       ie_ptr = kmalloc(ie_len, GFP_KERNEL);
  2389. +       if (ie_ptr == NULL)
  2390. +       {
  2391. +           printkd("[%s][%d][0x%p]\n", __func__, __LINE__, ie_ptr);
  2392. +           return -EINVAL;
  2393. +       }
  2394. +       memcpy(ie_ptr, beacon->proberesp_ies, ie_len);
  2395. +       printkd("begin send probe response extra ies\n");
  2396. +
  2397. +       ret = wlan_cmd_set_p2p_ie(vif_id, P2P_PROBERESP_IE, ie_ptr, ie_len);
  2398. +       if (ret) {
  2399. +           printkd("wlan_cmd_set_p2p_ie proberesp_ies failed with ret %d\n",ret);
  2400. +       } else {
  2401. +           printkd("send probe response ies successfully\n");
  2402. +       }
  2403. +
  2404. +       kfree(ie_ptr);
  2405. +   }
  2406. +
  2407. +   /* send associate response ies */
  2408. +
  2409. +   if (beacon->assocresp_ies != NULL) {
  2410. +       printkd("%s line:%d\n", __func__, __LINE__);
  2411. +       ie_len = beacon->assocresp_ies_len;
  2412. +
  2413. +       ie_ptr = kmalloc(ie_len, GFP_KERNEL);
  2414. +       if (ie_ptr == NULL)
  2415. +       {
  2416. +           printkd("[%s][%d][0x%p]\n", __func__, __LINE__, ie_ptr);
  2417. +           return -EINVAL;
  2418. +       }
  2419. +       memcpy(ie_ptr, beacon->assocresp_ies, ie_len);
  2420. +       printkd("begin send associate response extra ies\n");
  2421. +
  2422. +       ret = wlan_cmd_set_p2p_ie(vif_id,  P2P_ASSOCRESP_IE, ie_ptr, ie_len);
  2423. +       if (ret) {
  2424. +           printkd( "wlan_cmd_set_p2p_ie assocresp_ies failed with ret %d\n",ret);
  2425. +       } else {
  2426. +           printkd("send associate response ies successfully\n");
  2427. +       }
  2428. +
  2429. +       kfree(ie_ptr);
  2430. +   }
  2431. +
  2432. +#endif             /*WIFI_DIRECT_SUPPORT */
  2433. +   return ret;
  2434. +}
  2435. +
  2436. +static int itm_wlan_start_ap(wlan_vif_t *vif, struct cfg80211_beacon_data *beacon)
  2437. +{
  2438. +   struct ieee80211_mgmt *mgmt;
  2439. +   u16 mgmt_len;
  2440. +   int ret;
  2441. +   unsigned char  vif_id = vif->id;
  2442. +   printkd("%s enter\n", __func__);
  2443. +   wlan_change_beacon(vif,beacon);
  2444. +   if (beacon->head == NULL)
  2445. +   {
  2446. +       printke("%s line:%d err\n", __func__, __LINE__);
  2447. +       return -EINVAL;
  2448. +   }
  2449. +   mgmt_len = beacon->head_len;
  2450. +   if (beacon->tail)
  2451. +       mgmt_len += beacon->tail_len;
  2452. +
  2453. +   mgmt = kmalloc(mgmt_len, GFP_KERNEL);
  2454. +   if (mgmt == NULL)
  2455. +   {
  2456. +       printkd("[%s][%d][0x%p]\n", __func__, __LINE__, mgmt);
  2457. +       return -EINVAL;
  2458. +   }
  2459. +   memcpy((u8 *)mgmt, beacon->head, beacon->head_len);
  2460. +   if (beacon->tail)
  2461. +       memcpy((u8 *)mgmt + beacon->head_len,  beacon->tail, beacon->tail_len);
  2462. +
  2463. +   ret = wlan_cmd_start_ap(vif_id, (unsigned char *)mgmt, mgmt_len);
  2464. +   kfree(mgmt);
  2465. +   if (ret != 0)
  2466. +   {
  2467. +       printke("%s line:%d err\n", __func__, __LINE__);
  2468. +   }
  2469. +   return ret;
  2470. +}
  2471. +
  2472. +
  2473. +static int wlan_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ap_settings *info)
  2474. +{
  2475. +   wlan_vif_t      *vif;
  2476. +   unsigned char        vif_id;
  2477. +   vif = ndev_to_vif(ndev);
  2478. +   vif_id = vif->id;
  2479. +   if(ITM_NONE_MODE == vif->mode)
  2480. +       return -EAGAIN;
  2481. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  2482. +   if (info->ssid == NULL)
  2483. +   {
  2484. +       printkd("%s line:%d\n", __func__, __LINE__);
  2485. +       return -EINVAL;
  2486. +   }
  2487. +   printkd("[cfg80211] \t ==>>>%s\n",__func__);
  2488. +   memcpy(vif->cfg80211.ssid, info->ssid, info->ssid_len);
  2489. +   vif->cfg80211.ssid_len = info->ssid_len;
  2490. +   return itm_wlan_start_ap(vif, &info->beacon);
  2491. +}
  2492. +
  2493. +static int wlan_cfg80211_stop_ap(struct wiphy *wiphy,
  2494. +                                     struct net_device *ndev)
  2495. +{
  2496. +   int ret;
  2497. +   wlan_vif_t      *vif;
  2498. +   unsigned char        vif_id;
  2499. +   vif = ndev_to_vif(ndev);
  2500. +   vif_id = vif->id;
  2501. +   if(ITM_NONE_MODE == vif->mode)
  2502. +       return -EAGAIN;
  2503. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  2504. +   ret = wlan_cmd_mac_close(vif_id, vif->mode);
  2505. +   return ret;
  2506. +}
  2507. +
  2508. +static int wlan_cfg80211_change_beacon(struct wiphy *wiphy,
  2509. +        struct net_device *ndev,
  2510. +        struct cfg80211_beacon_data *beacon)
  2511. +{
  2512. +   wlan_vif_t      *vif;
  2513. +   unsigned char        vif_id;
  2514. +   vif = ndev_to_vif(ndev);
  2515. +   vif_id = vif->id;
  2516. +   if(ITM_NONE_MODE == vif->mode)
  2517. +       return -EAGAIN;
  2518. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  2519. +#ifdef WIFI_DIRECT_SUPPORT
  2520. +   return wlan_change_beacon(vif, beacon);
  2521. +#else
  2522. +   return itm_wlan_start_ap(vif, beacon);
  2523. +#endif
  2524. +  
  2525. +}
  2526. +
  2527. +static int itm_wlan_change_mode(wlan_vif_t *vif, enum nl80211_iftype type)
  2528. +{
  2529. +   int mode;
  2530. +   int ret;
  2531. +   unsigned char vif_id = vif->id;
  2532. +   switch (type)
  2533. +   {
  2534. +   case NL80211_IFTYPE_STATION:
  2535. +       if(NETIF_0_ID == vif->id)
  2536. +           mode = ITM_STATION_MODE;
  2537. +       else
  2538. +           mode = ITM_P2P_CLIENT_MODE;
  2539. +       break;
  2540. +   case NL80211_IFTYPE_AP:
  2541. +       if(NETIF_0_ID == vif->id)
  2542. +           mode = ITM_AP_MODE;
  2543. +       else
  2544. +           mode = ITM_P2P_GO_MODE;
  2545. +       break;     
  2546. +   case NL80211_IFTYPE_P2P_CLIENT:
  2547. +       mode = ITM_P2P_CLIENT_MODE;
  2548. +       break;     
  2549. +   case NL80211_IFTYPE_P2P_GO:
  2550. +       mode = ITM_P2P_GO_MODE;
  2551. +       break;
  2552. +   default:
  2553. +       printkd("invalid interface type %u\n", type);
  2554. +       return -EOPNOTSUPP;
  2555. +   }
  2556. +   vif->wdev.iftype =  type;
  2557. +   if (mode == vif->mode)
  2558. +   {
  2559. +       printkd("not need change mode\n");
  2560. +       return 0;
  2561. +   }
  2562. +   vif->wdev.iftype = type;
  2563. +   vif->mode = mode;
  2564. +   printkd("[%s][%d][%d]\n", __func__, vif_id, mode );
  2565. +   ret = wlan_cmd_mac_open(vif_id, mode, vif->ndev->dev_addr );
  2566. +   if(OK != ret)
  2567. +       return -EIO;
  2568. +   vif->wdev.iftype = type;
  2569. +   vif->mode = mode;  
  2570. +   return OK;
  2571. +}
  2572. +
  2573. +static int wlan_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, enum nl80211_iftype type, unsigned int *flags, struct vif_params *params)
  2574. +{
  2575. +   wlan_vif_t      *vif;
  2576. +   unsigned char        vif_id;
  2577. +   vif = ndev_to_vif(ndev);
  2578. +   vif_id = vif->id;
  2579. +#ifdef WIFI_DIRECT_SUPPORT
  2580. +   if(NETIF_1_ID == vif_id)
  2581. +   {
  2582. +       vif->cfg80211.p2p_mode = itm_get_p2p_mode_from_file();
  2583. +       printkd("[%s][%d][%d]\n", __func__, vif_id, ( vif->cfg80211.p2p_mode ? 1:0)  );
  2584. +   }
  2585. +#endif /* WIFI_DIRECT_SUPPORT */  
  2586. +   return itm_wlan_change_mode(vif, type);
  2587. +}
  2588. +
  2589. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  2590. +static int wlan_cfg80211_set_channel(struct wiphy *wiphy,
  2591. +                    struct net_device *ndev,
  2592. +                    struct ieee80211_channel *channel)
  2593. +#else
  2594. +static int wlan_cfg80211_set_channel(struct wiphy *wiphy,
  2595. +                    struct net_device *ndev,
  2596. +                    struct ieee80211_channel *channel,
  2597. +                    enum nl80211_channel_type channel_type)
  2598. +#endif
  2599. +{
  2600. +   int ret = -ENOTSUPP;
  2601. +   wlan_vif_t      *vif;
  2602. +   unsigned char        vif_id;
  2603. +   vif = ndev_to_vif(ndev);
  2604. +   vif_id = vif->id;
  2605. +   if(ITM_NONE_MODE == vif->mode)
  2606. +       return -EAGAIN;
  2607. +   printkd("[%s][%d] enter\n", __func__, vif_id);
  2608. +   /*
  2609. +    * FIXME: To be handled properly when monitor mode is supported.
  2610. +    */
  2611. +   ret =  wlan_cmd_set_channel(vif_id, ieee80211_frequency_to_channel(channel->center_freq)  );
  2612. +   if (ret < 0)
  2613. +   {
  2614. +       printkd("wlan_cmd_set_channel failed with ret %d\n", ret);
  2615. +       return ret;
  2616. +   }
  2617. +
  2618. +   return 0;
  2619. +}
  2620. +int    wlan_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_update_ft_ies_params *ftie)
  2621. +{
  2622. +   wlan_vif_t      *vif;
  2623. +   unsigned char    vif_id;
  2624. +   vif = ndev_to_vif(ndev);
  2625. +   vif_id = vif->id;
  2626. +   printkd("%s enter\n", __func__);
  2627. +   return wlan_cmd_update_ft_ies(vif_id, ftie);   
  2628. +}
  2629. +
  2630. +int lte_concur_proc_open(struct inode *inode, struct file *filp)  
  2631. +{
  2632. +    return 0;
  2633. +}  
  2634. +
  2635. +int lte_concur_proc_release(struct inode *inode, struct file *filp)  
  2636. +{
  2637. +    return 0;
  2638. +}  
  2639. +/* support of 32bit userspace on 64bit platforms */
  2640. +#ifdef CONFIG_COMPAT
  2641. +#define COMPAT_LTE_CONCUR_REQ         _IO(0, LTE_CONCUR_REQ)
  2642. +long compat_lte_concur_proc_ioctl(struct file *file, unsigned int cmd,
  2643. +       unsigned long arg)
  2644. +{
  2645. +   switch (cmd) {
  2646. +       case COMPAT_LTE_CONCUR_REQ:
  2647. +           cmd = LTE_CONCUR_REQ;
  2648. +           break;
  2649. +   }
  2650. +   return lte_concur_proc_ioctl(file, cmd, arg);
  2651. +}
  2652. +#endif
  2653. +long lte_concur_proc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  2654. +{
  2655. +    int ret = 0;
  2656. +    lte_concur_data_t *val;
  2657. +    unsigned char buff[100];
  2658. +    int    len;
  2659. +
  2660. +   switch (cmd) {
  2661. +       case LTE_CONCUR_REQ:
  2662. +           if (copy_from_user(buff, (unsigned char *)arg,
  2663. +                              ((lte_concur_data_t *)arg)->size + sizeof(lte_concur_data_t))) {
  2664. +               return -EFAULT;
  2665. +           }
  2666. +
  2667. +           val = (lte_concur_data_t *)buff;
  2668. +           len = val->size;
  2669. +           ret = wlan_cmd_req_lte_concur(0, (unsigned char *)val + sizeof(lte_concur_data_t), len);
  2670. +           if (ret < 0) {
  2671. +               printkd("wlan_cmd_req_lte_concur failed with ret %d\n", ret);
  2672. +               return ret;
  2673. +           }
  2674. +           break;
  2675. +       default:
  2676. +           break;
  2677. +   }
  2678. +   return 0;
  2679. +}
  2680. +
  2681. +
  2682. +static struct cfg80211_ops wlan_cfg80211_ops =
  2683. +{
  2684. +   .scan = wlan_cfg80211_scan,
  2685. +   .connect = wlan_cfg80211_connect,
  2686. +   .disconnect = wlan_cfg80211_disconnect,
  2687. +   .add_key = wlan_cfg80211_add_key,
  2688. +   .del_key = wlan_cfg80211_del_key,
  2689. +   .set_default_key = wlan_cfg80211_set_default_key,
  2690. +   .set_wiphy_params = wlan_cfg80211_set_wiphy_params,
  2691. +   .get_station = wlan_cfg80211_get_station,
  2692. +   .set_pmksa = wlan_cfg80211_set_pmksa,
  2693. +   .del_pmksa = wlan_cfg80211_del_pmksa,
  2694. +   .flush_pmksa = wlan_cfg80211_flush_pmksa,
  2695. +   .start_ap = wlan_cfg80211_start_ap,
  2696. +   .change_beacon = wlan_cfg80211_change_beacon,
  2697. +   .stop_ap = wlan_cfg80211_stop_ap,
  2698. +   .mgmt_tx = wlan_cfg80211_mgmt_tx,
  2699. +   .mgmt_frame_register = wlan_cfg80211_mgmt_frame_register,
  2700. +   .change_virtual_intf = wlan_cfg80211_change_iface,
  2701. +   .update_ft_ies = wlan_cfg80211_update_ft_ies,
  2702. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  2703. +   .libertas_set_mesh_channel = wlan_cfg80211_set_channel,
  2704. +#else
  2705. +   .set_channel = wlan_cfg80211_set_channel,
  2706. +#endif
  2707. +
  2708. +#ifdef WIFI_DIRECT_SUPPORT
  2709. +   .remain_on_channel = wlan_cfg80211_remain_on_channel,
  2710. +   .cancel_remain_on_channel = wlan_cfg80211_cancel_remain_on_channel,
  2711. +   .del_station = wlan_cfg80211_del_station,
  2712. +#endif
  2713. +};
  2714. +
  2715. +/*Init wiphy parameters*/
  2716. +static void init_wiphy_parameters(struct wiphy *wiphy)
  2717. +{
  2718. +   wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
  2719. +   wiphy->mgmt_stypes = itm_mgmt_stypes;
  2720. +  
  2721. +   wiphy->max_scan_ssids = MAX_SITES_FOR_SCAN;
  2722. +   wiphy->max_scan_ie_len = SCAN_IE_LEN_MAX;
  2723. +   wiphy->max_num_pmkids = MAX_NUM_PMKIDS;
  2724. +
  2725. +   wiphy->interface_modes = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
  2726. +
  2727. +   wiphy->interface_modes |=   BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_DEVICE);
  2728. +   wiphy->max_remain_on_channel_duration = 5000;
  2729. +   wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
  2730. +   /* set AP SME flag, also needed by STA mode? */
  2731. +   wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
  2732. +   wiphy->ap_sme_capa = 1;
  2733. +
  2734. +   wiphy->software_iftypes =  BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_DEVICE) ;
  2735. +   /*Attach cipher suites */
  2736. +   wiphy->cipher_suites = itm_cipher_suites;
  2737. +   wiphy->n_cipher_suites = ARRAY_SIZE(itm_cipher_suites);
  2738. +   /*Attach bands */
  2739. +   wiphy->bands[IEEE80211_BAND_2GHZ] = &itm_band_2ghz;
  2740. +   //wiphy->bands[IEEE80211_BAND_5GHZ] = &itm_band_5ghz;
  2741. +
  2742. +   /*Default not in powersave state */
  2743. +   wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
  2744. +#if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  2745. +   /*Set WoWLAN flags */
  2746. +   wiphy->wowlan.flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT;
  2747. +#endif
  2748. +}
  2749. +
  2750. +int wlan_wiphy_new(wlan_info_t *wlan)
  2751. +{
  2752. +   int ret;
  2753. +   printke("%s enter\n", __func__);
  2754. +   wlan->wiphy = wiphy_new(&wlan_cfg80211_ops, 0);
  2755. +   if (wlan->wiphy == NULL)
  2756. +   {
  2757. +       ASSERT();
  2758. +       return ERROR;
  2759. +   }
  2760. +   *(wlan_info_t **)wiphy_priv(wlan->wiphy) = wlan;
  2761. +   set_wiphy_dev(wlan->wiphy, wlan->dev );
  2762. +   init_wiphy_parameters(wlan->wiphy);
  2763. +   ret = wiphy_register(wlan->wiphy);
  2764. +   if(ret < 0)
  2765. +   {
  2766. +       printke("%s err:%d\n", __func__, ret);
  2767. +       ASSERT();
  2768. +       goto  out_free_wiphy;
  2769. +   }
  2770. +   return OK;
  2771. +out_free_wiphy:
  2772. +   wiphy_free(wlan->wiphy);
  2773. +   return ERROR;
  2774. +}
  2775. +
  2776. +int wlan_wiphy_free(wlan_info_t *wlan)
  2777. +{
  2778. +   int i;
  2779. +   wlan_vif_t *vif;
  2780. +   if(NULL == wlan)
  2781. +       return ERROR;
  2782. +   for(i=0; i<2; i++)
  2783. +   {
  2784. +       vif = &(g_wlan.netif[i]);
  2785. +       if ( vif->cfg80211.scan_request && (atomic_add_unless(&vif->cfg80211.scan_status, 1, 1) == 1)  )
  2786. +       {
  2787. +           if (vif->cfg80211.scan_request->wiphy != vif->wdev.wiphy)
  2788. +           {
  2789. +               printkd("Scan request is from a wrong wiphy device\n");
  2790. +           }
  2791. +           else
  2792. +           {
  2793. +               /*If there's a pending scan request,abort it */
  2794. +               cfg80211_scan_done(vif->cfg80211.scan_request, 1);
  2795. +           }
  2796. +           vif->cfg80211.scan_request = NULL;
  2797. +           if ( vif->cfg80211.scan_done_lock.link.next != LIST_POISON1 && vif->cfg80211.scan_done_lock.link.prev != LIST_POISON2 )
  2798. +               wake_unlock(&vif->cfg80211.scan_done_lock);
  2799. +           atomic_dec(&vif->cfg80211.scan_status);
  2800. +       }
  2801. +       wake_lock_destroy(&vif->cfg80211.scan_done_lock);
  2802. +       del_timer_sync(&( vif->cfg80211.scan_timeout) );
  2803. +       vfree(vif->cfg80211.scan_frame_array);
  2804. +       vif->cfg80211.scan_frame_array = NULL;
  2805. +   }
  2806. +   wiphy_unregister(wlan->wiphy);
  2807. +   wiphy_free(wlan->wiphy);
  2808. +   wlan->wiphy = NULL;
  2809. +   return OK;
  2810. +}
  2811. +
  2812. +int mac_addr_cfg(wlan_vif_t *vif, unsigned char vif_id)
  2813. +{
  2814. +   struct file  *fp = 0;
  2815. +   mm_segment_t  fs;
  2816. +   loff_t       *pos;
  2817. +   bool          no_file = false;
  2818. +   unsigned char file_data[64] = { 0 };
  2819. +   unsigned char mac_addr[18] = { 0 };
  2820. +   unsigned char *tmp_p = NULL;
  2821. +   fs = get_fs();
  2822. +   set_fs(KERNEL_DS);
  2823. +  
  2824. +   fp = filp_open(ENG_MAC_ADDR_PATH, O_RDONLY, 0);
  2825. +   if (IS_ERR(fp))
  2826. +   {
  2827. +       random_ether_addr(vif->ndev->dev_addr);
  2828. +       fp = filp_open( ENG_MAC_ADDR_PATH, O_CREAT | O_RDWR, 0666 );
  2829. +       if (IS_ERR(fp) )
  2830. +       {
  2831. +           printke("%s %d err\n", __func__, __LINE__);
  2832. +           goto EXIT;
  2833. +       }
  2834. +       no_file = true;
  2835. +   }
  2836. +   pos = &(fp->f_pos);
  2837. +   if(false == no_file)
  2838. +   {
  2839. +       tmp_p = file_data;
  2840. +       vfs_read(fp, file_data, sizeof(file_data), pos);
  2841. +       memcpy(mac_addr, tmp_p, 18);
  2842. +       sscanf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
  2843. +              (unsigned int *)&(vif->ndev->dev_addr[0]),
  2844. +              (unsigned int *)&(vif->ndev->dev_addr[1]),
  2845. +              (unsigned int *)&(vif->ndev->dev_addr[2]),
  2846. +              (unsigned int *)&(vif->ndev->dev_addr[3]),
  2847. +              (unsigned int *)&(vif->ndev->dev_addr[4]),
  2848. +              (unsigned int *)&(vif->ndev->dev_addr[5]));
  2849. +   }
  2850. +   else
  2851. +   {
  2852. +       sprintf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
  2853. +                          vif->ndev->dev_addr[0],
  2854. +                          vif->ndev->dev_addr[1],
  2855. +                          vif->ndev->dev_addr[2],
  2856. +                          vif->ndev->dev_addr[3],
  2857. +                          vif->ndev->dev_addr[4],
  2858. +                          vif->ndev->dev_addr[4]       );
  2859. +       vfs_write(fp, mac_addr, 18, pos);
  2860. +       printke("[%s write addr:%s]\n", __func__, mac_addr);
  2861. +   }
  2862. +   vif->ndev->dev_addr[5] = vif->ndev->dev_addr[5] +  vif_id;
  2863. +  
  2864. +EXIT:
  2865. +   if( ! (IS_ERR(fp)) )
  2866. +   {
  2867. +       filp_close(fp, NULL);
  2868. +   }
  2869. +   set_fs(fs);
  2870. +   return OK;
  2871. +}
  2872. +
  2873. +int wlan_vif_init(wlan_vif_t  *vif, int type, const char *name, void *ops)
  2874. +{
  2875. +   int ret;
  2876. +   void **net_priv;
  2877. +   struct net_device *ndev;
  2878. +   unsigned char str[64] = {0};
  2879. +   ndev = alloc_netdev(sizeof(void *), name, ether_setup);
  2880. +   if (!ndev)
  2881. +   {
  2882. +       ASSERT();
  2883. +       return ERROR;
  2884. +   }
  2885. +   vif->ndev = ndev;
  2886. +   net_priv = netdev_priv(ndev);
  2887. +   *net_priv = vif;
  2888. +   ndev->netdev_ops = ops;
  2889. +   ndev->watchdog_timeo = 1*HZ;
  2890. +   ndev->ieee80211_ptr = &(vif->wdev);
  2891. +   vif->wdev.iftype = type;
  2892. +   init_register_frame_param(vif);
  2893. +   init_send_deauth_work(vif);
  2894. +   vif->wdev.wiphy = g_wlan.wiphy;
  2895. +   SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
  2896. +   vif->wdev.netdev = ndev;
  2897. +   init_timer(&(vif->cfg80211.scan_timeout));
  2898. +   vif->cfg80211.scan_timeout.data = (unsigned long)vif;
  2899. +   vif->cfg80211.scan_timeout.function = wlan_scan_timeout;
  2900. +   vif->cfg80211.scan_request = NULL;
  2901. +   vif->cfg80211.scan_frame_array = vmalloc( MAX_SCAN_FRAME_BUF_NUM * sizeof(buf_scan_frame_t) );
  2902. +   memset(vif->cfg80211.scan_frame_array, 0, MAX_SCAN_FRAME_BUF_NUM * sizeof(buf_scan_frame_t) );
  2903. +   atomic_set(&vif->cfg80211.scan_status, 0);
  2904. +   vif->cfg80211.connect_status = ITM_DISCONNECTED;
  2905. +   memset(vif->cfg80211.bssid, 0, sizeof(vif->cfg80211.bssid));
  2906. +   vif->mode = ITM_NONE_MODE;
  2907. +   wake_lock_init(&(vif->cfg80211.scan_done_lock), WAKE_LOCK_SUSPEND, "scan_lock");   
  2908. +   mac_addr_cfg(vif, vif->id);
  2909. +   ret = register_netdev(vif->ndev);
  2910. +   if(ret < 0 )
  2911. +   {
  2912. +       printkd("[%s][register_netdev err:%d]\n", __func__, ret);
  2913. +       return ERROR;
  2914. +   }
  2915. +   sprintf(str, "[%s][%d][%s][0x%p][addr]:", __func__, vif->id, vif->ndev->name, vif->ndev);
  2916. +   hex_dump(str, strlen(str), (unsigned char *)(&(vif->ndev->dev_addr[0])) ,  6 );
  2917. +   return OK;
  2918. +}
  2919. +
  2920. +int wlan_vif_free(wlan_vif_t *vif)
  2921. +{
  2922. +   if(NULL == vif->ndev)
  2923. +       return ERROR;
  2924. +   printkd("[unregister_netdev][%s][0x%p]\n", __func__, vif->ndev->name);
  2925. +   cancel_work_sync(&vif->cfg80211.deauth_info.work);
  2926. +   unregister_netdev(vif->ndev);
  2927. +   printkd("[free_netdev][%s][0x%p]\n", __func__, vif->ndev->name);
  2928. +   free_netdev(vif->ndev);
  2929. +   printkd("%s(), ok\n", __func__);
  2930. +   return OK;
  2931. +}
  2932. +
  2933. +wlan_vif_t *id_to_vif(unsigned char id)
  2934. +{
  2935. +   if( (NETIF_0_ID != id) && (NETIF_1_ID != id) )
  2936. +       return NULL;
  2937. +   return &(g_wlan.netif[id]);
  2938. +}
  2939. diff --git a/drivers/net/wireless/sprdwl/wlan_cfg80211.h b/drivers/net/wireless/sprdwl/wlan_cfg80211.h
  2940. new file mode 100644
  2941. index 0000000..c349473
  2942. --- /dev/null
  2943. +++ b/drivers/net/wireless/sprdwl/wlan_cfg80211.h
  2944. @@ -0,0 +1,132 @@
  2945. +#ifndef __WLAN_CFG80211_H__
  2946. +#define __WLAN_CFG80211_H__
  2947. +
  2948. +#define WIFI_DIRECT_SUPPORT
  2949. +#define WLAN_11R_SUPPORT
  2950. +
  2951. +#define IP_TYPE           0x0800
  2952. +/* auth type */
  2953. +#define ITM_AUTH_OPEN  0
  2954. +#define ITM_AUTH_SHARED    1
  2955. +/*cipher type*/
  2956. +#define NONE       0
  2957. +#define WEP40      1
  2958. +#define WEP104     2
  2959. +#define TKIP       3
  2960. +#define CCMP       4
  2961. +#define AP_TKIP        5
  2962. +#define AP_CCMP        6
  2963. +#define WAPI       7
  2964. +/*AKM suite*/
  2965. +#define AKM_SUITE_PSK      (1)
  2966. +#define AKM_SUITE_8021X        (2)
  2967. +#define AKM_SUITE_FT_8021X  (3)
  2968. +#define AKM_SUITE_FT_PSK    (4)
  2969. +#define AKM_SUITE_WAPI_PSK (4)
  2970. +#define AKM_SUITE_WAPI_CERT (12)
  2971. +
  2972. +#define P2P_IE_ID                   221
  2973. +#define WLAN_AKM_SUITE_FT_8021X        0x000FAC03
  2974. +#define WLAN_AKM_SUITE_FT_PSK      0x000FAC04
  2975. +#define WLAN_11R_MD_IE_ID   0x36
  2976. +#define WLAN_11R_FT_IE_ID   0x37
  2977. +#define P2P_IE_OUI_BYTE0 0x50
  2978. +#define P2P_IE_OUI_BYTE1 0x6F
  2979. +#define P2P_IE_OUI_BYTE2 0x9A
  2980. +#define P2P_IE_OUI_TYPE  0x09
  2981. +/*FIXME: determine the actual values for the macros below*/
  2982. +#define SCAN_IE_LEN_MAX            2304
  2983. +#define MAX_NUM_PMKIDS         4
  2984. +#define MAX_SITES_FOR_SCAN     12
  2985. +#define WLAN_MAX_SSID_SIZE     32
  2986. +#define WLAN_MAX_KEY_INDEX     3
  2987. +#define ITM_SCAN_TIMER_INTERVAL_MS 8000
  2988. +/* parise or group key type */
  2989. +#define GROUP              0
  2990. +#define PAIRWISE           1
  2991. +#define HOSTAP_CONF_FILE_NAME "/data/misc/wifi/hostapd.conf"
  2992. +#define ENG_MAC_ADDR_PATH     "/data/misc/wifi/wifimac.txt"
  2993. +
  2994. +#define MAX_SCAN_FRAME_BUF_NUM       (30)
  2995. +#define LTE_CONCUR_REQ               (100)
  2996. +
  2997. +enum wlan_mode
  2998. +{
  2999. +   ITM_NONE_MODE,
  3000. +   ITM_STATION_MODE,
  3001. +   ITM_AP_MODE,
  3002. +   ITM_NPI_MODE,
  3003. +   ITM_P2P_CLIENT_MODE,
  3004. +   ITM_P2P_GO_MODE,
  3005. +};
  3006. +
  3007. +enum WPS_TYPE
  3008. +{
  3009. +   WPS_REQ_IE=1,
  3010. +   WPS_ASSOC_IE,
  3011. +   P2P_ASSOC_IE,
  3012. +   P2P_BEACON_IE,
  3013. +   P2P_PROBERESP_IE,
  3014. +   P2P_ASSOCRESP_IE,
  3015. +   P2P_BEACON_IE_HEAD,
  3016. +   P2P_BEACON_IE_TAIL
  3017. +};
  3018. +
  3019. +enum wlan_state
  3020. +{
  3021. +   ITM_UNKOWN = 0,
  3022. +   ITM_SCANNING,
  3023. +   ITM_SCAN_ABORTING,
  3024. +   ITM_DISCONNECTED,
  3025. +   ITM_CONNECTING,
  3026. +   ITM_CONNECTED
  3027. +};
  3028. +
  3029. +struct hostap_conf
  3030. +{
  3031. +   char wpa_psk[128];
  3032. +   unsigned int len;
  3033. +};
  3034. +
  3035. +typedef struct android_wifi_priv_cmd
  3036. +{
  3037. +   char *buf;
  3038. +   int used_len;
  3039. +   int total_len;
  3040. +} android_wifi_priv_cmd;
  3041. +
  3042. +typedef struct
  3043. +{
  3044. +   unsigned char  live;
  3045. +   unsigned char  keep;
  3046. +   unsigned short channel;
  3047. +   signed   short signal;
  3048. +   unsigned short msa_len;
  3049. +   unsigned char  ssid[33];
  3050. +   unsigned char  bssid[6];
  3051. +   unsigned char  msa[1024];
  3052. +}buf_scan_frame_t;
  3053. +
  3054. +typedef struct
  3055. +{
  3056. +    unsigned int  size;
  3057. +}lte_concur_data_t;
  3058. +
  3059. +extern void cfg80211_report_connect_result(unsigned char vif_id, unsigned char *pData, int len);
  3060. +extern void cfg80211_report_disconnect_done(unsigned char vif_id, unsigned char *pData, int len);
  3061. +extern void cfg80211_report_scan_done(unsigned char vif_id, unsigned char *pData, int len, bool aborted);
  3062. +extern void cfg80211_report_mgmt_deauth(unsigned char vif_id, unsigned char *data, unsigned short len);
  3063. +extern void cfg80211_report_mgmt_disassoc(unsigned char vif_id, unsigned char *data, unsigned short len );
  3064. +extern void cfg80211_report_remain_on_channel_expired(unsigned char vif_id, unsigned char *data, unsigned short len);
  3065. +extern void cfg80211_report_new_station(unsigned char vif_id, unsigned char *data, unsigned short len );
  3066. +extern void cfg80211_report_frame(unsigned char vif_id, unsigned char *data, unsigned short len);
  3067. +extern void cfg80211_report_scan_frame(unsigned char vif_id, unsigned char *pData, int len);
  3068. +extern void cfg80211_report_mic_failure(unsigned char vif_id, unsigned char *pdata, int len);
  3069. +extern int lte_concur_proc_open(struct inode *inode, struct file *filp)  ;
  3070. +extern int lte_concur_proc_release(struct inode *inode, struct file *filp);
  3071. +extern long lte_concur_proc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
  3072. +#ifdef CONFIG_COMPAT
  3073. +extern long compat_lte_concur_proc_ioctl(struct file *file, unsigned int cmd,
  3074. +       unsigned long arg);
  3075. +#endif
  3076. +#endif
  3077. diff --git a/drivers/net/wireless/sprdwl/wlan_cmd.c b/drivers/net/wireless/sprdwl/wlan_cmd.c
  3078. new file mode 100644
  3079. index 0000000..00e1a40
  3080. --- /dev/null
  3081. +++ b/drivers/net/wireless/sprdwl/wlan_cmd.c
  3082. @@ -0,0 +1,920 @@
  3083. +/*
  3084. + * Copyright (C) 2014 Spreadtrum Communications Inc.
  3085. + *
  3086. + * Authors:<jinglong.chen@spreadtrum.com>
  3087. + * Owner:
  3088. + *      jinglong.chen
  3089. + *
  3090. + * This software is licensed under the terms of the GNU General Public
  3091. + * License version 2, as published by the Free Software Foundation, and
  3092. + * may be copied, distributed, and modified under those terms.
  3093. + *
  3094. + * This program is distributed in the hope that it will be useful,
  3095. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3096. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3097. + * GNU General Public License for more details.
  3098. + */
  3099. +
  3100. +#include "wlan_common.h"
  3101. +#include "wlan_cmd.h"
  3102. +#include "wlan_cfg80211.h"
  3103. +#define  CMD_WAIT_TIMEOUT  (3000)
  3104. +#define  CMD_ITEM(CMD)    { CMD,  (#CMD) }
  3105. +typedef struct
  3106. +{
  3107. +   unsigned short id;
  3108. +   char *cmd;
  3109. +}cmd_t;
  3110. +
  3111. +static cmd_t g_cmd_table[] =
  3112. +{
  3113. +   CMD_ITEM(WIFI_CMD_GET_MODE),  
  3114. +   CMD_ITEM(WIFI_CMD_GET_RSSI),        
  3115. +   CMD_ITEM(WIFI_CMD_GET_TXRATE_TXFAILED),        
  3116. +   CMD_ITEM(WIFI_CMD_SET_SCAN),          
  3117. +   CMD_ITEM(WIFI_CMD_SET_AUTH_TYPE),    
  3118. +   CMD_ITEM(WIFI_CMD_SET_WPA_VERSION),  
  3119. +   CMD_ITEM(WIFI_CMD_SET_PAIRWISE_CIPHER),
  3120. +   CMD_ITEM(WIFI_CMD_SET_GROUP_CIPHER),
  3121. +   CMD_ITEM(WIFI_CMD_SET_AKM_SUITE),    
  3122. +   CMD_ITEM(WIFI_CMD_SET_CHANNEL),      
  3123. +   CMD_ITEM(WIFI_CMD_SET_BSSID),        
  3124. +   CMD_ITEM(WIFI_CMD_SET_ESSID),        
  3125. +   CMD_ITEM(WIFI_CMD_KEY_ADD),          
  3126. +   CMD_ITEM(WIFI_CMD_KEY_DEL),          
  3127. +   CMD_ITEM(WIFI_CMD_KEY_SET),          
  3128. +   CMD_ITEM(WIFI_CMD_SET_DISCONNECT),    
  3129. +   CMD_ITEM(WIFI_CMD_SET_RTS_THRESHOLD),
  3130. +   CMD_ITEM(WIFI_CMD_SET_FRAG_THRESHOLD),
  3131. +   CMD_ITEM(WIFI_CMD_SET_PMKSA),        
  3132. +   CMD_ITEM(WIFI_CMD_DEL_PMKSA),        
  3133. +   CMD_ITEM(WIFI_CMD_FLUSH_PMKSA),      
  3134. +   CMD_ITEM(WIFI_CMD_SET_DEV_OPEN),      
  3135. +   CMD_ITEM(WIFI_CMD_SET_DEV_CLOSE),    
  3136. +   CMD_ITEM(WIFI_CMD_SET_PSK),          
  3137. +   CMD_ITEM(WIFI_CMD_START_BEACON),        
  3138. +   CMD_ITEM(WIFI_CMD_SET_WPS_IE),
  3139. +   CMD_ITEM(WIFI_CMD_TX_MGMT),
  3140. +   CMD_ITEM(WIFI_CMD_REMAIN_CHAN),
  3141. +   CMD_ITEM(WIFI_CMD_CANCEL_REMAIN_CHAN),
  3142. +   CMD_ITEM(WIFI_CMD_P2P_IE),
  3143. +   CMD_ITEM(WIFI_CMD_CHANGE_BEACON),
  3144. +   CMD_ITEM(WIFI_CMD_REGISTER_FRAME),
  3145. +   CMD_ITEM(WIFI_CMD_NPI_MSG),
  3146. +   CMD_ITEM(WIFI_CMD_SET_FT_IE),
  3147. +   CMD_ITEM(WIFI_EVENT_CONNECT),        
  3148. +   CMD_ITEM(WIFI_EVENT_DISCONNECT),      
  3149. +   CMD_ITEM(WIFI_EVENT_SCANDONE)
  3150. +   CMD_ITEM(WIFI_EVENT_MGMT_DEAUTH),
  3151. +   CMD_ITEM(WIFI_EVENT_MGMT_DISASSOC),
  3152. +   CMD_ITEM(WIFI_EVENT_REMAIN_ON_CHAN_EXPIRED),
  3153. +   CMD_ITEM(WIFI_EVENT_NEW_STATION),
  3154. +   CMD_ITEM(WIFI_EVENT_REPORT_FRAME),
  3155. +   CMD_ITEM(WIFI_EVENT_CONNECT_AP),
  3156. +   CMD_ITEM(WIFI_CMD_ASSERT),
  3157. +   CMD_ITEM(WIFI_EVENT_SDIO_SEQ_NUM),
  3158. +   CMD_ITEM(WIFI_CMD_MAX),
  3159. +   CMD_ITEM(WIFI_EVENT_REPORT_SCAN_FRAME),
  3160. +   CMD_ITEM(WIFI_CMD_SLEEP),
  3161. +   CMD_ITEM(WIFI_CMD_GET_IP),
  3162. +   CMD_ITEM(WIFI_EVENT_REPORT_MIC_FAIL),
  3163. +   CMD_ITEM(WIFI_CMD_REQ_LTE_CONCUR),
  3164. +};
  3165. +char * get_cmd_name(int id)
  3166. +{
  3167. +   int i;
  3168. +   int id_num = sizeof(g_cmd_table)/sizeof(cmd_t);
  3169. +   for( i=0; i < id_num; i++ )
  3170. +   {
  3171. +       if(id  == g_cmd_table[i].id )
  3172. +       {
  3173. +           return g_cmd_table[i].cmd;
  3174. +       }
  3175. +   }
  3176. +   return "NULL";
  3177. +}
  3178. +
  3179. +int wlan_cmd_init(void )
  3180. +{
  3181. +   wlan_cmd_t *cmd = &(g_wlan.cmd);
  3182. +   cmd->mem = kmalloc( 8* 1024,  GFP_KERNEL);
  3183. +   mutex_init( &(cmd->cmd_lock) );
  3184. +   init_waitqueue_head(&(cmd->waitQ));
  3185. +   cmd->wakeup = 0;
  3186. +   return OK;
  3187. +}
  3188. +
  3189. +int wlan_cmd_deinit(void )
  3190. +{
  3191. +   wlan_cmd_t *cmd = &(g_wlan.cmd);
  3192. +   if(NULL != cmd->mem)
  3193. +   {
  3194. +       kfree(cmd->mem);
  3195. +       cmd->mem = NULL;
  3196. +   }
  3197. +   mutex_destroy(&(cmd->cmd_lock));
  3198. +   return OK;
  3199. +  
  3200. +}
  3201. +
  3202. +int wlan_cmd_send_to_ic(unsigned char vif_id, unsigned char *pData, int len, int subtype)
  3203. +{
  3204. +  
  3205. +   tx_msg_t  *event;
  3206. +   m_event_t *event_q;
  3207. +   wlan_cmd_t *cmd;
  3208. +   cmd     = &(g_wlan.cmd);
  3209. +   event_q = &(g_wlan.netif[vif_id].event_q[EVENT_Q_ID_0]);
  3210. +   printkd("[SEND_CMD][%d][%s]\n",vif_id, get_cmd_name(subtype));
  3211. +   event = alloc_event(event_q);
  3212. +   if(NULL == event)
  3213. +   {
  3214. +       printke("%s alloc_event err\n", __func__);
  3215. +       return ERROR;
  3216. +   }
  3217. +   memset((unsigned char *)event,  0, sizeof(tx_msg_t) );
  3218. +   if((0 == len) || (NULL == pData))
  3219. +   {
  3220. +       event->hdr.mode = vif_id;
  3221. +       event->hdr.len = 0;
  3222. +       event->hdr.type = HOST_SC2331_CMD;
  3223. +       event->hdr.subtype = subtype;
  3224. +       event->slice[0].data = NULL;
  3225. +       event->slice[0].len = 0;
  3226. +   }
  3227. +   else
  3228. +   {
  3229. +       event->hdr.mode = vif_id;
  3230. +       event->hdr.len = len;
  3231. +       event->hdr.type = HOST_SC2331_CMD;
  3232. +       event->hdr.subtype = subtype;
  3233. +       event->slice[0].data = pData;
  3234. +       event->slice[0].len = len;
  3235. +   }
  3236. +   post_event( (unsigned char *)event, event_q );
  3237. +   core_up();
  3238. +   return OK;
  3239. +}
  3240. +
  3241. +int wlan_timeout_recv_rsp(unsigned char *r_buf, unsigned short *r_len, unsigned int timeout)
  3242. +{
  3243. +   int ret;
  3244. +   r_msg_hdr_t *msg;
  3245. +   wlan_cmd_t  *cmd = &(g_wlan.cmd);
  3246. +   ret = wait_event_timeout( cmd->waitQ,  ((1 == cmd->wakeup)||(1 == g_wlan.sync.exit)), msecs_to_jiffies(timeout) );
  3247. +   cmd->wakeup = 0;
  3248. +   msg = (r_msg_hdr_t *)(cmd->mem);   
  3249. +   if(0 == ret)
  3250. +   {
  3251. +       printke("[%s][%d][err]\n", __func__, __LINE__);
  3252. +       return -1;
  3253. +   }
  3254. +   if(*r_len < msg->len)
  3255. +   {
  3256. +       printke("[%s][%d][err]\n", __func__, __LINE__);
  3257. +       msg->len = *r_len;
  3258. +   }
  3259. +   *r_len = msg->len;
  3260. +   memcpy(r_buf, cmd->mem, sizeof(r_msg_hdr_t) + msg->len );
  3261. +   return 0;
  3262. +}
  3263. +
  3264. +int wlan_cmd_send_recv(unsigned char vif_id, unsigned char *pData, int len, int subtype, int timeout)
  3265. +{
  3266. +  
  3267. +   int ret = 0;   
  3268. +   r_msg_hdr_t *msg;
  3269. +   struct wlan_cmd_rsp_state_code *state;
  3270. +   wlan_cmd_t     *cmd = &(g_wlan.cmd);
  3271. +   unsigned char   r_buf[sizeof(r_msg_hdr_t) + sizeof(struct wlan_cmd_rsp_state_code) ] = {0};
  3272. +   unsigned short  r_len = sizeof(struct wlan_cmd_rsp_state_code) ;
  3273. +  
  3274. +   msg = (r_msg_hdr_t *)(&r_buf[0]);
  3275. +  
  3276. +   if(1 == g_wlan.sync.exit )
  3277. +   {
  3278. +       printke("%s, exit flag\n", __func__);
  3279. +       return ERROR;
  3280. +   }
  3281. +  
  3282. +   mutex_lock(&(cmd->cmd_lock));
  3283. +  
  3284. +   if( (NULL == pData) || (0 == len) )
  3285. +       ret = wlan_cmd_send_to_ic(vif_id, NULL, 0,  subtype);
  3286. +   else
  3287. +       ret = wlan_cmd_send_to_ic(vif_id, pData, len,  subtype);
  3288. +   if(OK != ret)
  3289. +       return ERROR;
  3290. +  
  3291. +   ret = wlan_timeout_recv_rsp(r_buf, &r_len, timeout);
  3292. +   if(-1 == ret)
  3293. +   {
  3294. +       printke("[SEND_CMD %s %d ERROR][rsp timeout]\n", get_cmd_name(subtype), vif_id);
  3295. +   }
  3296. +  
  3297. +   if( (SC2331_HOST_RSP != msg->type)  ||  (subtype !=  msg->subtype) )
  3298. +   {
  3299. +       printke("[SEND_CMD %s %d ERROR][rsp match %s]\n", get_cmd_name(subtype), vif_id, get_cmd_name(msg->subtype));
  3300. +       ret = -1;
  3301. +   }
  3302. +   mutex_unlock(&(cmd->cmd_lock));
  3303. +  
  3304. +   if(-1 == ret)
  3305. +   {
  3306. +       wlan_cmd_assert(vif_id, 0);
  3307. +       return ERROR;
  3308. +   }
  3309. +   /*TODO state is not use*/
  3310. +   state = (struct wlan_cmd_rsp_state_code *)( &r_buf[ sizeof(r_msg_hdr_t)]) ;
  3311. +  
  3312. +   return OK;
  3313. +}
  3314. +
  3315. +int wlan_cmd_start_ap(unsigned char vif_id, unsigned char *beacon, unsigned short len)
  3316. +{
  3317. +   int ret;
  3318. +   unsigned short dataLen;
  3319. +   struct wlan_cmd_beacon_t *beacon_ptr;
  3320. +   dataLen = sizeof(struct wlan_cmd_beacon_t) + len ;
  3321. +   beacon_ptr = kmalloc( dataLen, GFP_KERNEL);
  3322. +   beacon_ptr->len = cpu_to_le16(len);
  3323. +   memcpy(beacon_ptr->value, beacon, len);
  3324. +   ret = wlan_cmd_send_recv(vif_id, (unsigned char *)beacon_ptr, dataLen, WIFI_CMD_START_BEACON, CMD_WAIT_TIMEOUT);
  3325. +   return ret;
  3326. +}
  3327. +
  3328. +int wlan_cmd_register_frame(unsigned char vif_id, struct  wlan_cmd_register_frame_t *data)
  3329. +{
  3330. +   int ret;
  3331. +   struct wlan_cmd_register_frame_t *ptr;
  3332. +   unsigned short dataLen;
  3333. +   dataLen = sizeof(struct wlan_cmd_register_frame_t);
  3334. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3335. +   memcpy((unsigned char *)ptr, (unsigned char *)(data), dataLen);
  3336. +   ret = wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_REGISTER_FRAME, CMD_WAIT_TIMEOUT);
  3337. +   return ret;
  3338. +}
  3339. +
  3340. +int wlan_cmd_set_p2p_ie(unsigned char vif_id, u8 type, const u8 *ie, u16 len)
  3341. +{
  3342. +   struct wlan_cmd_p2p_ie_t *p2p_ptr;
  3343. +   int ret;
  3344. +   unsigned short dataLen;
  3345. +
  3346. +   if (type != P2P_ASSOC_IE && type != P2P_BEACON_IE &&
  3347. +       type != P2P_PROBERESP_IE && type != P2P_ASSOCRESP_IE &&
  3348. +       type !=P2P_BEACON_IE_HEAD && type  !=P2P_BEACON_IE_TAIL) {
  3349. +       printke("%s wrong ie type is %d\n",__func__, type);
  3350. +       return -EIO;
  3351. +   }
  3352. +   printkd("%s type:%d ie_len:%d\n", __func__,type, len);
  3353. +   dataLen = sizeof(struct wlan_cmd_p2p_ie_t) + len;
  3354. +   p2p_ptr = kmalloc( dataLen, GFP_KERNEL);
  3355. +   p2p_ptr->type = type;
  3356. +   p2p_ptr->len = cpu_to_le16(len);
  3357. +   memcpy(p2p_ptr->value, ie, len);
  3358. +   ret = wlan_cmd_send_recv(vif_id, (unsigned char *)p2p_ptr, dataLen, WIFI_CMD_P2P_IE, CMD_WAIT_TIMEOUT);
  3359. +   return ret;
  3360. +}
  3361. +
  3362. +int wlan_cmd_set_ft_ie(unsigned char vif_id, const unsigned char *ies, unsigned short len)
  3363. +{
  3364. +   unsigned char *ptr = NULL;
  3365. +   unsigned short dataLen = len + 2;
  3366. +  
  3367. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3368. +   *((unsigned short *)ptr) = len;
  3369. +   memcpy(ptr+2, ies, len);
  3370. +  
  3371. +   hex_dump("ftie:", strlen("ftie:"), ptr, dataLen);
  3372. +   return  wlan_cmd_send_recv(vif_id, ptr, dataLen, WIFI_CMD_SET_FT_IE, CMD_WAIT_TIMEOUT);
  3373. +}
  3374. +
  3375. +int wlan_cmd_set_tx_mgmt(unsigned char vif_id, struct ieee80211_channel *channel, unsigned int wait, const unsigned char *mac, size_t mac_len)
  3376. +{
  3377. +   unsigned short dataLen;
  3378. +   struct wlan_cmd_mgmt_tx_t *mgmt_tx;
  3379. +   int ret;
  3380. +   unsigned char send_chan;
  3381. +
  3382. +   dataLen = sizeof(struct wlan_cmd_mgmt_tx_t) + mac_len;
  3383. +   mgmt_tx = kmalloc( dataLen, GFP_KERNEL);
  3384. +    send_chan = ieee80211_frequency_to_channel(channel->center_freq);
  3385. +  
  3386. +  
  3387. +   mgmt_tx->chan = send_chan;
  3388. +   mgmt_tx->wait = cpu_to_le32(wait);
  3389. +   mgmt_tx->len = cpu_to_le32(mac_len);
  3390. +   memcpy(mgmt_tx->value, mac, mac_len);
  3391. +   ret = wlan_cmd_send_recv(vif_id, (unsigned char *)mgmt_tx, dataLen, WIFI_CMD_TX_MGMT, CMD_WAIT_TIMEOUT);
  3392. +   return ret;
  3393. +}
  3394. +
  3395. +
  3396. +
  3397. +int wlan_cmd_remain_chan(unsigned char vif_id, struct ieee80211_channel *channel,
  3398. +                            enum nl80211_channel_type channel_type,
  3399. +                             unsigned int duration, u64 *cookie)
  3400. +{
  3401. +   int ret;
  3402. +   unsigned short dataLen;
  3403. +   struct wlan_cmd_remain_chan_t  *remain_chan;
  3404. +  
  3405. +   dataLen = sizeof(struct wlan_cmd_remain_chan_t);
  3406. +   remain_chan = kmalloc( dataLen, GFP_KERNEL);
  3407. +  
  3408. +   remain_chan->chan = ieee80211_frequency_to_channel(channel->center_freq);;
  3409. +   remain_chan->chan_type = channel_type;
  3410. +   remain_chan->duraion = cpu_to_le32(duration);
  3411. +   remain_chan->cookie = cpu_to_le64(*cookie);
  3412. +  
  3413. +   ret = wlan_cmd_send_recv(vif_id, (unsigned char *)remain_chan, dataLen, WIFI_CMD_REMAIN_CHAN, CMD_WAIT_TIMEOUT);
  3414. +   return ret;
  3415. +}
  3416. +int wlan_cmd_cancel_remain_chan(unsigned char vif_id, u64 cookie)
  3417. +{
  3418. +  
  3419. +   int ret;
  3420. +   unsigned short dataLen;
  3421. +  
  3422. +   struct wlan_cmd_cancel_remain_chan_t *ptr;
  3423. +
  3424. +
  3425. +   dataLen = sizeof(struct wlan_cmd_cancel_remain_chan_t);
  3426. +
  3427. +   ptr =  kmalloc( dataLen, GFP_KERNEL);
  3428. +
  3429. +   ptr->cookie = cpu_to_le64(cookie);
  3430. +  
  3431. +   ret = wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_CANCEL_REMAIN_CHAN, CMD_WAIT_TIMEOUT);
  3432. +   return ret;
  3433. +}
  3434. +
  3435. +int wlan_cmd_scan(unsigned char vif_id, const unsigned char *ssid, const unsigned char *channels, int len)
  3436. +{
  3437. +   int dataLen;
  3438. +   struct wlan_cmd_scan *ptr;
  3439. +
  3440. +   dataLen = sizeof(struct wlan_cmd_scan) + len;
  3441. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3442. +   //memcpy((char *)ptr, channels, 16);
  3443. +   ptr->len = cpu_to_le32(len);
  3444. +   memcpy(ptr->ssid,  ssid, len);
  3445. +
  3446. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_SET_SCAN, CMD_WAIT_TIMEOUT);
  3447. +   return 0;
  3448. +}
  3449. +
  3450. +int wlan_cmd_set_wpa_version(unsigned char vif_id,  unsigned int wpa_version)
  3451. +{
  3452. +   int dataLen;
  3453. +   struct wlan_cmd_set_wpa_version *ptr;
  3454. +
  3455. +   dataLen = sizeof(struct wlan_cmd_set_wpa_version);
  3456. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3457. +
  3458. +   ptr->wpa_version = cpu_to_le32(wpa_version);
  3459. +
  3460. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_SET_WPA_VERSION, CMD_WAIT_TIMEOUT);
  3461. +   return 0;
  3462. +}
  3463. +
  3464. +int wlan_cmd_set_auth_type(unsigned char vif_id, unsigned int type)
  3465. +{
  3466. +   int dataLen;
  3467. +   struct wlan_cmd_set_auth_type *ptr;
  3468. +
  3469. +   dataLen = sizeof(struct wlan_cmd_set_auth_type);
  3470. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3471. +   ptr->type = cpu_to_le32(type);
  3472. +  
  3473. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_SET_AUTH_TYPE, CMD_WAIT_TIMEOUT);
  3474. +   return 0;
  3475. +}
  3476. +
  3477. +/* unicast cipher or group cipher */
  3478. +int wlan_cmd_set_cipher(unsigned char vif_id, unsigned int cipher, unsigned char cmd_id)
  3479. +{
  3480. +   int dataLen;
  3481. +   struct wlan_cmd_set_cipher *ptr;
  3482. +
  3483. +   dataLen = sizeof(struct wlan_cmd_set_cipher);
  3484. +   if ((cmd_id != WIFI_CMD_SET_PAIRWISE_CIPHER) && (cmd_id != WIFI_CMD_SET_GROUP_CIPHER))
  3485. +   {
  3486. +       printkd("not support this type cipher \n");
  3487. +       return -EINVAL;
  3488. +   }
  3489. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3490. +   ptr->cipher = cpu_to_le32(cipher);
  3491. +
  3492. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, cmd_id, CMD_WAIT_TIMEOUT);
  3493. +   return 0;
  3494. +
  3495. +}
  3496. +
  3497. +int wlan_cmd_set_key_management(unsigned char vif_id, unsigned char key_mgmt)
  3498. +{
  3499. +   int dataLen;
  3500. +   struct wlan_cmd_set_key_management *ptr;
  3501. +
  3502. +   dataLen = sizeof(struct wlan_cmd_set_key_management);
  3503. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3504. +   /*TODO key_mgmt is u8, but ptr->key_mgmt is __le32*/
  3505. +   ptr->key_mgmt = key_mgmt;
  3506. +
  3507. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_SET_AKM_SUITE, CMD_WAIT_TIMEOUT);
  3508. +   return 0;
  3509. +}
  3510. +
  3511. +int wlan_cmd_set_psk(unsigned char vif_id, const unsigned char *key, unsigned int key_len)
  3512. +{
  3513. +   int dataLen;
  3514. +   struct wlan_cmd_set_psk *ptr;
  3515. +
  3516. +   dataLen = sizeof(struct wlan_cmd_set_psk) + key_len ;
  3517. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3518. +   /*TODO key_len is u32, but ptr->len is __le16*/
  3519. +   ptr->len = (__le16)cpu_to_le32(key_len);
  3520. +   memcpy(ptr->key,  key, key_len);
  3521. +
  3522. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_SET_PSK, CMD_WAIT_TIMEOUT);
  3523. +
  3524. +   return 0;
  3525. +}
  3526. +
  3527. +int wlan_cmd_set_channel(unsigned char vif_id, unsigned int channel)
  3528. +{
  3529. +   int dataLen;
  3530. +   struct wlan_cmd_set_channel *ptr;
  3531. +
  3532. +   dataLen = sizeof(struct wlan_cmd_set_channel);
  3533. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3534. +   ptr->channel = cpu_to_le32(channel);
  3535. +
  3536. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_SET_CHANNEL, CMD_WAIT_TIMEOUT);
  3537. +   return 0;
  3538. +}
  3539. +
  3540. +int wlan_cmd_set_bssid(unsigned char vif_id, const unsigned char *addr)
  3541. +{
  3542. +   int dataLen;
  3543. +   struct wlan_cmd_set_bssid *ptr;
  3544. +
  3545. +   dataLen = sizeof(struct wlan_cmd_set_bssid);
  3546. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3547. +   memcpy(&(ptr->addr[0]),  addr,  6);
  3548. +
  3549. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_SET_BSSID, CMD_WAIT_TIMEOUT);
  3550. +   return 0;
  3551. +}
  3552. +
  3553. +int wlan_cmd_get_ip(unsigned char vif_id, u8 *ip)
  3554. +{
  3555. +   int dataLen;
  3556. +   struct wlan_cmd_get_ip *ptr;
  3557. +
  3558. +   dataLen = sizeof(struct wlan_cmd_get_ip);
  3559. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3560. +   memcpy(&(ptr->ip[0]),  ip,  4);
  3561. +   hex_dump("inetaddr ip", strlen("inetaddr ip"), ip, 4);
  3562. +
  3563. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_GET_IP, CMD_WAIT_TIMEOUT);
  3564. +   return 0;
  3565. +}
  3566. +
  3567. +int wlan_cmd_set_essid(unsigned char vif_id, const unsigned char *essid, int essid_len)
  3568. +{
  3569. +
  3570. +   int dataLen;
  3571. +   struct wlan_cmd_set_essid *ptr;
  3572. +
  3573. +   dataLen = sizeof(struct wlan_cmd_set_essid) + essid_len;
  3574. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3575. +   /*TODO essid_len is int, but ptr->len is __le16*/
  3576. +   ptr->len = (__le16)cpu_to_le32(essid_len);
  3577. +   memcpy(ptr->essid,  essid,  essid_len);
  3578. +  
  3579. +   return wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_SET_ESSID, CMD_WAIT_TIMEOUT);
  3580. +}
  3581. +
  3582. +int wlan_cmd_req_lte_concur(unsigned char vif_id, const unsigned char *val, int len)
  3583. +{
  3584. +   unsigned char *ptr;
  3585. +   ptr = kmalloc( len, GFP_KERNEL);
  3586. +   memcpy(ptr,  val,  len);
  3587. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, len, WIFI_CMD_REQ_LTE_CONCUR, CMD_WAIT_TIMEOUT);
  3588. +   return 0;
  3589. +}
  3590. +
  3591. +int wlan_cmd_pmksa(unsigned char vif_id, const unsigned char *bssid, const unsigned char *pmkid, unsigned char type)
  3592. +{
  3593. +   int dataLen;
  3594. +   struct wlan_cmd_pmkid *cmd;
  3595. +
  3596. +   dataLen = sizeof(struct wlan_cmd_pmkid);
  3597. +   cmd = kmalloc( dataLen, GFP_KERNEL);
  3598. +   memset((unsigned char *)cmd, 0, dataLen );
  3599. +   if(NULL != bssid)
  3600. +       memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
  3601. +   if (pmkid)
  3602. +       memcpy(cmd->pmkid, pmkid, sizeof(cmd->pmkid));
  3603. +
  3604. +   wlan_cmd_send_recv(vif_id, (unsigned char *)cmd, dataLen, type, CMD_WAIT_TIMEOUT);
  3605. +   return 0;
  3606. +}
  3607. +
  3608. +int wlan_cmd_disconnect(unsigned char vif_id, unsigned short reason_code)
  3609. +{
  3610. +
  3611. +   int dataLen;
  3612. +   struct wlan_cmd_disconnect *ptr;
  3613. +
  3614. +   dataLen = sizeof(struct wlan_cmd_disconnect);
  3615. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3616. +   ptr->reason_code = cpu_to_le16(reason_code);
  3617. +
  3618. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_SET_DISCONNECT, CMD_WAIT_TIMEOUT);
  3619. +   return 0;
  3620. +}
  3621. +
  3622. +int wlan_cmd_add_key(unsigned char vif_id, const unsigned char *key_data, unsigned char key_len,
  3623. +                          unsigned char pairwise, unsigned char key_index, const unsigned char *key_seq,
  3624. +                          unsigned char cypher_type, const unsigned char *pmac)
  3625. +{
  3626. +
  3627. +   int dataLen;
  3628. +   struct wlan_cmd_add_key *ptr;
  3629. +  
  3630. +   dataLen = sizeof(struct wlan_cmd_add_key)+key_len;
  3631. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3632. +   memset(ptr, 0, dataLen);
  3633. +
  3634. +   ptr->cypher_type = cypher_type;
  3635. +   if (key_seq != NULL)
  3636. +       memcpy(ptr->keyseq, key_seq, 8);
  3637. +   ptr->key_index = key_index;
  3638. +   ptr->key_len = key_len;
  3639. +   if (pmac != NULL)
  3640. +       memcpy(ptr->mac, pmac, 6);
  3641. +   ptr->pairwise = pairwise;
  3642. +   if(NULL != key_data)
  3643. +       memcpy(ptr->value, key_data, key_len);
  3644. +
  3645. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_KEY_ADD, CMD_WAIT_TIMEOUT);
  3646. +
  3647. +   return 0;
  3648. +}
  3649. +
  3650. +int wlan_cmd_del_key(unsigned char vif_id, unsigned short key_index, const unsigned char *mac_addr)
  3651. +{
  3652. +   int dataLen = 0;
  3653. +   struct wlan_cmd_del_key *ptr = NULL;
  3654. +
  3655. +   dataLen = sizeof(struct wlan_cmd_del_key);
  3656. +   ptr = kmalloc( dataLen, GFP_KERNEL);
  3657. +   memset(ptr, 0, dataLen);
  3658. +   ptr->key_index = key_index;
  3659. +   if(NULL != mac_addr)
  3660. +       memcpy(&(ptr->mac[0]),  mac_addr,  6);
  3661. +
  3662. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_KEY_DEL, CMD_WAIT_TIMEOUT);
  3663. +
  3664. +   return 0;
  3665. +}
  3666. +
  3667. +int wlan_cmd_set_key(unsigned char vif_id, unsigned char key_index)
  3668. +{
  3669. +
  3670. +   int dataLen;
  3671. +   struct wlan_cmd_set_key *ptr;
  3672. +
  3673. +   dataLen = sizeof(struct wlan_cmd_set_key);
  3674. +   ptr = kmalloc(dataLen,  GFP_KERNEL);
  3675. +   ptr->key_index = cpu_to_le32(key_index);
  3676. +
  3677. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_KEY_SET, CMD_WAIT_TIMEOUT);
  3678. +
  3679. +   return OK;
  3680. +}
  3681. +
  3682. +int wlan_cmd_set_rts(unsigned char vif_id, unsigned short rts_threshold)
  3683. +{
  3684. +   int dataLen;
  3685. +   struct wlan_cmd_set_rts *ptr;
  3686. +   dataLen = sizeof(struct wlan_cmd_set_rts);
  3687. +   ptr = kmalloc(dataLen, GFP_KERNEL);
  3688. +   ptr->threshold = cpu_to_le16(rts_threshold);
  3689. +
  3690. +   wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_SET_RTS_THRESHOLD, CMD_WAIT_TIMEOUT);
  3691. +
  3692. +   return OK;
  3693. +}
  3694. +
  3695. +int wlan_cmd_set_frag(unsigned char vif_id, unsigned short frag_threshold)
  3696. +{
  3697. +   struct wlan_cmd_set_frag *frag;
  3698. +
  3699. +   frag = kmalloc(sizeof(struct wlan_cmd_set_frag), GFP_KERNEL);
  3700. +   frag->frag = cpu_to_le16(frag_threshold);
  3701. +
  3702. +   wlan_cmd_send_recv(vif_id, (unsigned char *)frag, sizeof(struct wlan_cmd_set_frag), WIFI_CMD_SET_FRAG_THRESHOLD, CMD_WAIT_TIMEOUT);
  3703. +
  3704. +   return 0;
  3705. +}
  3706. +
  3707. +int wlan_cmd_set_wps_ie( unsigned char vif_id, unsigned char type, const unsigned char *ie, unsigned char len)
  3708. +{
  3709. +   struct wlan_cmd_wps_ie *wps_ptr = NULL;
  3710. +
  3711. +   wps_ptr = kmalloc(sizeof(struct wlan_cmd_wps_ie) + len,  GFP_KERNEL);
  3712. +   wps_ptr->type = type;
  3713. +   wps_ptr->len = len;
  3714. +   memcpy(wps_ptr->value, ie, len);
  3715. +
  3716. +   wlan_cmd_send_recv(vif_id, (unsigned char *)wps_ptr, sizeof(struct wlan_cmd_wps_ie) + len,   WIFI_CMD_SET_WPS_IE, CMD_WAIT_TIMEOUT);
  3717. +
  3718. +   return 0;
  3719. +}
  3720. +
  3721. +int wlan_cmd_update_ft_ies( unsigned char vif_id, struct cfg80211_update_ft_ies_params *ft_ies)
  3722. +{
  3723. +   int ret, dataLen;
  3724. +   struct wlan_cmd_ft_ies_params *ptr;
  3725. +   dataLen = sizeof(struct wlan_cmd_ft_ies_params) + ft_ies->ie_len;
  3726. +   ptr = kmalloc(dataLen,  GFP_KERNEL);
  3727. +   if(NULL == ptr)
  3728. +       return -1;
  3729. +   ptr->md = cpu_to_le16(ft_ies->md);
  3730. +   ptr->ie_len = cpu_to_le16(ft_ies->ie_len);
  3731. +   memcpy(&(ptr->ie[0]),  ft_ies->ie, ft_ies->ie_len);
  3732. +   hex_dump("update_ft_ie:", strlen("update_ft_ie:"), (unsigned char *)ptr, dataLen);
  3733. +   ret = wlan_cmd_send_recv(vif_id, (unsigned char *)ptr, dataLen, WIFI_CMD_UPDATE_FT_IE, CMD_WAIT_TIMEOUT);
  3734. +   return ret;
  3735. +}
  3736. +
  3737. +int wlan_cmd_mac_open(unsigned char vif_id,
  3738. +       unsigned short mode, unsigned char *mac_addr)
  3739. +{
  3740. +   int ret;
  3741. +   static int sync_flag = -1;
  3742. +   struct wlan_cmd_mac_open *open;
  3743. +   if(-1 == sync_flag)
  3744. +   {
  3745. +       g_wlan.hw.tx_cnt    = 0;
  3746. +       g_wlan.hw.rx_cnt    = 0;
  3747. +       g_wlan.hw.rx_record = 0;       
  3748. +       sync_flag = 0;
  3749. +   }
  3750. +   open = kmalloc(sizeof(struct wlan_cmd_mac_open),  GFP_KERNEL);
  3751. +   memset((unsigned char *)open, 0, sizeof(struct wlan_cmd_mac_open));
  3752. +   open->mode = cpu_to_le16(mode);
  3753. +  
  3754. +   if(NULL != mac_addr)
  3755. +       memcpy( (unsigned char *)(&(open->mac[0])),  mac_addr, 6);
  3756. +   ret = wlan_cmd_send_recv(vif_id, (unsigned char *)open, sizeof(struct wlan_cmd_mac_open), WIFI_CMD_SET_DEV_OPEN, 8000);
  3757. +   return ret;
  3758. +}
  3759. +
  3760. +int wlan_cmd_mac_close(unsigned char vif_id, unsigned char mode)
  3761. +{
  3762. +   struct wlan_cmd_mac_close *close;
  3763. +   close = kmalloc(sizeof(struct wlan_cmd_mac_close), GFP_KERNEL);
  3764. +   close->mode = mode;
  3765. +   wlan_cmd_send_recv(vif_id, (unsigned char *)(close), sizeof(struct wlan_cmd_mac_close), WIFI_CMD_SET_DEV_CLOSE,  CMD_WAIT_TIMEOUT);
  3766. +   return 0;
  3767. +}
  3768. +
  3769. +int wlan_cmd_assert(unsigned char vif_id, unsigned int reason_code)
  3770. +{
  3771. +   struct wlan_cmd_assert_t *assert_cmd = NULL;
  3772. +   unsigned int  dataLen = sizeof(struct wlan_cmd_assert_t);
  3773. +
  3774. +   assert_cmd = kmalloc(sizeof(struct wlan_cmd_assert_t), GFP_KERNEL);
  3775. +   assert_cmd->reason_code = cpu_to_le32(reason_code);
  3776. +   assert_cmd->tx_cnt = cpu_to_le32(g_wlan.hw.tx_cnt);
  3777. +   assert_cmd->rx_cnt = cpu_to_le32(g_wlan.hw.rx_cnt);
  3778. +   wlan_cmd_send_to_ic(vif_id, (unsigned char *)(assert_cmd), dataLen, WIFI_CMD_ASSERT);
  3779. +
  3780. +   return 0;
  3781. +}
  3782. +
  3783. +int wlan_cmd_sleep(int ops)
  3784. +{
  3785. +   unsigned char *ops_code;
  3786. +   ops_code = (unsigned char *)kmalloc(4, GFP_KERNEL);
  3787. +   memcpy( ops_code, (unsigned char *)(&ops), 4);
  3788. +   wlan_cmd_send_to_ic(0, ops_code, 4,  WIFI_CMD_SLEEP);
  3789. +   return 0;
  3790. +}
  3791. +
  3792. +int wlan_cmd_get_rssi(unsigned char vif_id, unsigned char *signal, unsigned char *noise)
  3793. +{
  3794. +   int             ret;
  3795. +   r_msg_hdr_t    *msg;
  3796. +   int            *rssi = NULL;
  3797. +   wlan_cmd_t     *cmd = &(g_wlan.cmd);
  3798. +   unsigned char   r_buf[sizeof(r_msg_hdr_t) + 8 ] = {0};
  3799. +   unsigned short  r_len = 8 ;
  3800. +   msg = (r_msg_hdr_t *)(&r_buf[0]);
  3801. +   if(1 == g_wlan.sync.exit )
  3802. +   {
  3803. +       printke("%s, exit flag\n", __func__);
  3804. +       return ERROR;
  3805. +   }
  3806. +   mutex_lock(&(cmd->cmd_lock));
  3807. +   ret = wlan_cmd_send_to_ic(vif_id, NULL, 0,  WIFI_CMD_GET_RSSI);
  3808. +   ret = wlan_timeout_recv_rsp(r_buf, &r_len, CMD_WAIT_TIMEOUT);
  3809. +   if(-1 == ret)
  3810. +   {
  3811. +       printke("[SEND_CMD %s %d ERROR][rsp timeout]\n", get_cmd_name(WIFI_CMD_GET_RSSI), vif_id);
  3812. +       goto err;
  3813. +   }
  3814. +   if( (SC2331_HOST_RSP != msg->type)  ||  (WIFI_CMD_GET_RSSI !=  msg->subtype) )
  3815. +   {
  3816. +       printke("[SEND_CMD %s %d ERROR][rsp match %s]\n", get_cmd_name(WIFI_CMD_GET_RSSI), vif_id, get_cmd_name(msg->subtype));
  3817. +       goto err;
  3818. +   }  
  3819. +   else
  3820. +   {
  3821. +       rssi = (int *)( &r_buf[sizeof(r_msg_hdr_t) + 4] );
  3822. +      *signal = (unsigned char) (le32_to_cpu(*rssi) | 0xffff0000);
  3823. +      *noise = (unsigned char) ((le32_to_cpu(*rssi) | 0x0000ffff) >> 16);
  3824. +   }
  3825. +   mutex_unlock(&(cmd->cmd_lock));
  3826. +   return OK;
  3827. +err:
  3828. +   wlan_cmd_assert(vif_id, 3);
  3829. +   mutex_unlock(&(cmd->cmd_lock));
  3830. +   return ERROR;
  3831. +}
  3832. +
  3833. +int wlan_cmd_get_txrate_txfailed(unsigned char vif_id, unsigned int *rate, unsigned int *failed)
  3834. +{
  3835. +   int             ret;
  3836. +   r_msg_hdr_t    *msg;
  3837. +   wlan_cmd_t     *cmd = &(g_wlan.cmd);
  3838. +   unsigned char   r_buf[sizeof(r_msg_hdr_t) + 12 ] = {0};
  3839. +   unsigned short  r_len = 12;
  3840. +   msg = (r_msg_hdr_t *)(&r_buf[0]);
  3841. +   if(1 == g_wlan.sync.exit )
  3842. +   {
  3843. +       printke("%s, exit flag\n", __func__);
  3844. +       return ERROR;
  3845. +   }
  3846. +   mutex_lock(&(cmd->cmd_lock));
  3847. +   ret = wlan_cmd_send_to_ic(vif_id, NULL, 0,  WIFI_CMD_GET_TXRATE_TXFAILED);
  3848. +   ret = wlan_timeout_recv_rsp(r_buf, &r_len, CMD_WAIT_TIMEOUT);
  3849. +   if(-1 == ret)
  3850. +   {
  3851. +       printke("[SEND_CMD %s %d ERROR][rsp timeout]\n", get_cmd_name(WIFI_CMD_GET_TXRATE_TXFAILED), vif_id);
  3852. +       goto err;
  3853. +   }
  3854. +   if( (SC2331_HOST_RSP != msg->type)  ||  (WIFI_CMD_GET_TXRATE_TXFAILED !=  msg->subtype) )
  3855. +   {
  3856. +       printke("[SEND_CMD %s %d ERROR][rsp match %s]\n", get_cmd_name(WIFI_CMD_GET_TXRATE_TXFAILED), vif_id, get_cmd_name(msg->subtype));
  3857. +       goto err;
  3858. +   }  
  3859. +   else
  3860. +   {
  3861. +       memcpy((unsigned char *)rate, &r_buf[sizeof(r_msg_hdr_t)+ 4], 4);
  3862. +       memcpy((unsigned char *)failed, &r_buf[sizeof(r_msg_hdr_t) + 8], 4);
  3863. +       *rate = le32_to_cpu(*rate);
  3864. +       *failed = le32_to_cpu(*failed);
  3865. +   }
  3866. +   mutex_unlock(&(cmd->cmd_lock));
  3867. +   return OK;
  3868. +err:
  3869. +   mutex_unlock(&(cmd->cmd_lock));
  3870. +   return ERROR;
  3871. +}
  3872. +
  3873. +int wlan_cmd_npi_send_recv(unsigned char *s_buf,unsigned short s_len, unsigned char *r_buf, unsigned short *r_len )
  3874. +{ 
  3875. +   r_msg_hdr_t *msg;
  3876. +   int ret;
  3877. +   wlan_cmd_t *cmd = &(g_wlan.cmd);
  3878. +   unsigned char *s_data = NULL;
  3879. +  
  3880. +   s_data = kmalloc(s_len, GFP_KERNEL);
  3881. +   memcpy(s_data, s_buf, s_len);
  3882. +  
  3883. +   mutex_lock(&(cmd->cmd_lock));
  3884. +   ret = wlan_cmd_send_to_ic(0, s_data, s_len,  WIFI_CMD_NPI_MSG);
  3885. +   if(1 == g_wlan.sync.exit)
  3886. +   {
  3887. +       printke("%s, exit flag\n", __func__);
  3888. +       goto err;
  3889. +   }
  3890. +   ret = wait_event_timeout( cmd->waitQ,  ((1 == cmd->wakeup)||(1 == g_wlan.sync.exit)), msecs_to_jiffies(5000) );
  3891. +   cmd->wakeup = 0;
  3892. +   if(0 == ret)
  3893. +   {
  3894. +       printke("%s(), wait timeout\n", __func__);
  3895. +       goto err;
  3896. +   }
  3897. +   msg = (r_msg_hdr_t *)cmd->mem;
  3898. +   if((SC2331_HOST_RSP == msg->type)  &&  (WIFI_CMD_NPI_MSG ==  msg->subtype))
  3899. +   {
  3900. +      
  3901. +       memcpy(r_buf,  (unsigned char *)(cmd->mem) + sizeof(r_msg_hdr_t), msg->len );
  3902. +       *r_len = msg->len;
  3903. +   }
  3904. +   else
  3905. +   {
  3906. +       printke("[%s] rsp not match, rsp:[%s]\n", get_cmd_name(WIFI_CMD_NPI_MSG), get_cmd_name(msg->subtype));
  3907. +       goto err;
  3908. +   }
  3909. +   mutex_unlock(&(cmd->cmd_lock));
  3910. +   printkd("%s cmd ok!\n",  get_cmd_name(WIFI_CMD_NPI_MSG) );
  3911. +   return OK;
  3912. +err:
  3913. +   mutex_unlock(&(cmd->cmd_lock));
  3914. +   printke(" ################### %s(), ERROR  ####################\n",  get_cmd_name(WIFI_CMD_NPI_MSG));
  3915. +   g_dbg= 0xffffffff;
  3916. +   return ERROR;  
  3917. +  
  3918. +}
  3919. +
  3920. +int wlan_rx_rsp_process(const unsigned char vif_id, r_msg_hdr_t *msg)
  3921. +{
  3922. +   wlan_cmd_t  *cmd = &(g_wlan.cmd);
  3923. +  
  3924. +   printkd("[RECV_RSP][%d][%s][%d]\n",vif_id, get_cmd_name(msg->subtype), msg->len);
  3925. +   memcpy(cmd->mem, (unsigned char *)msg,  msg->len + sizeof(r_msg_hdr_t) );
  3926. +   cmd->wakeup = 1;
  3927. +   wake_up(&(cmd->waitQ));
  3928. +   return OK;
  3929. +}
  3930. +
  3931. +int wlan_rx_event_process(const unsigned char vif_id, unsigned char event, unsigned char *pData, unsigned short len)
  3932. +{
  3933. +       if( (WIFI_EVENT_REPORT_SCAN_FRAME != event) && (WIFI_EVENT_SDIO_SEQ_NUM != event) )
  3934. +           printkd("[RECV_EVENT][%d][%s][%d]\n", vif_id, get_cmd_name(event), len);
  3935. +       switch(event)
  3936. +       {
  3937. +       case WIFI_EVENT_CONNECT:
  3938. +           cfg80211_report_connect_result(vif_id, pData, len);
  3939. +           break;
  3940. +       case WIFI_EVENT_DISCONNECT:
  3941. +           cfg80211_report_disconnect_done(vif_id, pData, len);
  3942. +           break;
  3943. +       case WIFI_EVENT_SCANDONE:
  3944. +           cfg80211_report_scan_done(vif_id, pData, len, false);
  3945. +           break;
  3946. +       case WIFI_EVENT_MGMT_DEAUTH:
  3947. +           cfg80211_report_mgmt_deauth(vif_id, pData, len);
  3948. +           break;
  3949. +       case WIFI_EVENT_MGMT_DISASSOC:
  3950. +           cfg80211_report_mgmt_disassoc(vif_id, pData, len);
  3951. +           break;
  3952. +       case WIFI_EVENT_REMAIN_ON_CHAN_EXPIRED:
  3953. +           cfg80211_report_remain_on_channel_expired(vif_id, pData, len);
  3954. +           break;
  3955. +       case WIFI_EVENT_NEW_STATION:
  3956. +           cfg80211_report_new_station(vif_id, pData, len);
  3957. +           break;
  3958. +       case WIFI_EVENT_REPORT_FRAME:
  3959. +           cfg80211_report_frame(vif_id, pData, len);
  3960. +           break;
  3961. +       case WIFI_EVENT_CONNECT_AP:
  3962. +           break;
  3963. +       case WIFI_EVENT_SDIO_SEQ_NUM:
  3964. +           break;
  3965. +       case WIFI_EVENT_REPORT_SCAN_FRAME:
  3966. +           cfg80211_report_scan_frame(vif_id, pData, len);
  3967. +           break;
  3968. +       case WIFI_EVENT_REPORT_MIC_FAIL:
  3969. +           cfg80211_report_mic_failure(vif_id, pData, len);
  3970. +           break;
  3971. +       default:
  3972. +           break;
  3973. +       }
  3974. +   return OK;
  3975. +}
  3976. +
  3977. +int hex_dump(unsigned char  *name, unsigned short nLen, unsigned char *pData,  unsigned short len)
  3978. +{
  3979. +   unsigned char *str;
  3980. +   int i, p, ret;
  3981. +   if(len > 1024)
  3982. +       len = 1024;
  3983. +   str = kmalloc( ( (len +1)*3 + nLen), GFP_KERNEL);
  3984. +   memset(str, 0,   (len +1)*3 + nLen );
  3985. +   memcpy(str, name, nLen);
  3986. +   if( (NULL == pData ) || (0 == len) )
  3987. +   {
  3988. +       printke("%s\n", str);
  3989. +       kfree(str);
  3990. +       return 0;
  3991. +   }
  3992. +   p = 0;
  3993. +   for(i=0; i< len; i++)
  3994. +   {
  3995. +       ret = sprintf( (str+ nLen + p),  "%02x ",  *(pData+i)  );
  3996. +       p = p+ret;
  3997. +   }
  3998. +   printke("%s\n", str);
  3999. +   kfree(str);
  4000. +   return 0;
  4001. +}
  4002. +
  4003. diff --git a/drivers/net/wireless/sprdwl/wlan_cmd.h b/drivers/net/wireless/sprdwl/wlan_cmd.h
  4004. new file mode 100644
  4005. index 0000000..ea3e8ec
  4006. --- /dev/null
  4007. +++ b/drivers/net/wireless/sprdwl/wlan_cmd.h
  4008. @@ -0,0 +1,352 @@
  4009. +#ifndef __ITM_CMD_H__
  4010. +#define __ITM_CMD_H__
  4011. +
  4012. +#include <linux/ieee80211.h>
  4013. +#include "wlan_common.h"
  4014. +#include "wlan_fifo.h"
  4015. +
  4016. +#define ITM_PMKID_LEN     16
  4017. +
  4018. +enum ITM_HOST_TROUT3_CMD_TYPE
  4019. +{
  4020. +   HOST_SC2331_CMD = 0,
  4021. +   SC2331_HOST_RSP,
  4022. +   HOST_SC2331_PKT,
  4023. +   HOST_SC2331_WAPI,
  4024. +};
  4025. +
  4026. +enum ITM_HOST_TROUT3_CMD_LIST
  4027. +{
  4028. +   WIFI_CMD_GET_MODE = 1,
  4029. +   WIFI_CMD_GET_RSSI,
  4030. +   WIFI_CMD_GET_TXRATE_TXFAILED,
  4031. +   WIFI_CMD_SET_SCAN,
  4032. +   WIFI_CMD_SET_AUTH_TYPE,
  4033. +   WIFI_CMD_SET_WPA_VERSION,
  4034. +   WIFI_CMD_SET_PAIRWISE_CIPHER,
  4035. +   WIFI_CMD_SET_GROUP_CIPHER,
  4036. +   WIFI_CMD_SET_AKM_SUITE,
  4037. +   WIFI_CMD_SET_CHANNEL,//10-0xA
  4038. +   WIFI_CMD_SET_BSSID,
  4039. +   WIFI_CMD_SET_ESSID,
  4040. +   WIFI_CMD_KEY_ADD,
  4041. +   WIFI_CMD_KEY_DEL,
  4042. +   WIFI_CMD_KEY_SET,
  4043. +   WIFI_CMD_SET_DISCONNECT,
  4044. +   WIFI_CMD_SET_RTS_THRESHOLD,
  4045. +   WIFI_CMD_SET_FRAG_THRESHOLD,
  4046. +   WIFI_CMD_SET_PMKSA,
  4047. +   WIFI_CMD_DEL_PMKSA,//20--0x14
  4048. +   WIFI_CMD_FLUSH_PMKSA,
  4049. +   WIFI_CMD_SET_DEV_OPEN,
  4050. +   WIFI_CMD_SET_DEV_CLOSE,
  4051. +   WIFI_CMD_SET_PSK,
  4052. +   WIFI_CMD_START_BEACON,
  4053. +   WIFI_CMD_SET_WPS_IE,
  4054. +   WIFI_CMD_TX_MGMT,
  4055. +   WIFI_CMD_REMAIN_CHAN,
  4056. +   WIFI_CMD_CANCEL_REMAIN_CHAN,
  4057. +   WIFI_CMD_P2P_IE,//30---0x1e
  4058. +   WIFI_CMD_CHANGE_BEACON,
  4059. +   WIFI_CMD_REGISTER_FRAME,
  4060. +   WIFI_CMD_NPI_MSG,
  4061. +   WIFI_CMD_NPI_GET,
  4062. +   WIFI_CMD_SET_FT_IE,
  4063. +   WIFI_CMD_UPDATE_FT_IE,
  4064. +   WIFI_CMD_ASSERT,
  4065. +   WIFI_CMD_SLEEP,
  4066. +   WIFI_CMD_ADD_SOFTAP_BLACKLIST,
  4067. +   WIFI_CMD_DEL_SOFTAP_BLACKLIST,
  4068. +   WIFI_CMD_SCAN_NOR_CHANNELS,
  4069. +   WIFI_CMD_GET_IP,
  4070. +   WIFI_CMD_REQ_LTE_CONCUR,
  4071. +   WIFI_CMD_MAX,
  4072. +  
  4073. +  
  4074. +   WIFI_EVENT_CONNECT = 128,
  4075. +   WIFI_EVENT_DISCONNECT,
  4076. +   WIFI_EVENT_SCANDONE,
  4077. +   WIFI_EVENT_MGMT_DEAUTH,
  4078. +   WIFI_EVENT_MGMT_DISASSOC,
  4079. +   WIFI_EVENT_REMAIN_ON_CHAN_EXPIRED,
  4080. +   WIFI_EVENT_NEW_STATION,
  4081. +   WIFI_EVENT_REPORT_FRAME,
  4082. +   WIFI_EVENT_CONNECT_AP,
  4083. +   WIFI_EVENT_SDIO_SEQ_NUM,
  4084. +   WIFI_EVENT_REPORT_SCAN_FRAME,
  4085. +   WIFI_EVENT_REPORT_MIC_FAIL,
  4086. +   WIFI_EVENT_MAX,
  4087. +};
  4088. +
  4089. +/* The reason code is defined by CP2 */
  4090. +enum wlan_cmd_disconnect_reason
  4091. +{
  4092. +   AP_LEAVING = 0xc1,
  4093. +   AP_DEAUTH = 0xc4,
  4094. +};
  4095. +
  4096. +struct wlan_cmd_add_key
  4097. +{
  4098. +   unsigned char mac[6];
  4099. +   unsigned char keyseq[8];
  4100. +   unsigned char pairwise;
  4101. +   unsigned char cypher_type;
  4102. +   unsigned char key_index;
  4103. +   unsigned char key_len;
  4104. +   unsigned char value[0];
  4105. +} __packed;
  4106. +
  4107. +struct wlan_cmd_del_key
  4108. +{
  4109. +   unsigned char key_index;
  4110. +   unsigned char pairwise;     /* unicase or group */
  4111. +   unsigned char mac[6];
  4112. +} __packed;
  4113. +
  4114. +struct wlan_cmd_pmkid
  4115. +{
  4116. +   unsigned char bssid[ETH_ALEN];
  4117. +   unsigned char pmkid[ITM_PMKID_LEN];
  4118. +} __packed;
  4119. +
  4120. +struct wlan_cmd_beacon
  4121. +{
  4122. +   unsigned char len;
  4123. +   unsigned char value[0];
  4124. +} __packed;
  4125. +
  4126. +struct wlan_cmd_mac_open
  4127. +{
  4128. +   __le16 mode;    /* AP or STATION mode */
  4129. +   unsigned char mac[6];
  4130. +} __packed;
  4131. +
  4132. +struct wlan_cmd_mac_close
  4133. +{
  4134. +   unsigned char mode; /* AP or STATION mode */
  4135. +} __packed;
  4136. +
  4137. +struct wlan_cmd_wps_ie
  4138. +{
  4139. +   unsigned char type; /* probe req ie or assoc req ie */
  4140. +   unsigned char len;      /* max ie len is 255 */
  4141. +   unsigned char value[0];
  4142. +} __packed;
  4143. +
  4144. +struct wlan_cmd_scan_ssid
  4145. +{
  4146. +   unsigned char len;
  4147. +   unsigned char ssid[0];
  4148. +} __packed;
  4149. +
  4150. +struct wlan_cmd_set_frag
  4151. +{
  4152. +   __le16 frag;
  4153. +} __packed;
  4154. +
  4155. +struct wlan_cmd_set_rts
  4156. +{
  4157. +   __le16 threshold;
  4158. +} __packed;
  4159. +
  4160. +struct wlan_cmd_set_key
  4161. +{
  4162. +   __le32 key_index;
  4163. +} __packed;
  4164. +
  4165. +struct wlan_cmd_disconnect
  4166. +{
  4167. +   __le16 reason_code;
  4168. +} __packed;
  4169. +
  4170. +struct wlan_cmd_set_essid
  4171. +{
  4172. +   __le16 len;
  4173. +   unsigned char essid[0];
  4174. +} __packed;
  4175. +
  4176. +struct wlan_cmd_set_bssid
  4177. +{
  4178. +   unsigned char addr[6];
  4179. +} __packed;
  4180. +
  4181. +struct wlan_cmd_get_ip
  4182. +{
  4183. +   unsigned char ip[4];
  4184. +} __packed;
  4185. +
  4186. +struct wlan_cmd_set_channel
  4187. +{
  4188. +   __le32 channel;
  4189. +} __packed;
  4190. +
  4191. +struct wlan_cmd_set_psk
  4192. +{
  4193. +   __le16 len;
  4194. +   unsigned char key[0];
  4195. +} __packed;
  4196. +
  4197. +struct wlan_cmd_set_key_management
  4198. +{
  4199. +   __le32 key_mgmt;
  4200. +
  4201. +} __packed;
  4202. +
  4203. +struct wlan_cmd_set_cipher
  4204. +{
  4205. +   __le32 cipher;
  4206. +} __packed;
  4207. +
  4208. +struct wlan_cmd_set_auth_type
  4209. +{
  4210. +   __le32 type;
  4211. +} __packed;
  4212. +
  4213. +struct wlan_cmd_set_wpa_version
  4214. +{
  4215. +   __le32 wpa_version;
  4216. +} __packed;
  4217. +
  4218. +struct wlan_cmd_assert_t
  4219. +{
  4220. +   __le32 reason_code;
  4221. +   __le32 tx_cnt;
  4222. +   __le32 rx_cnt;
  4223. +} __packed;
  4224. +
  4225. +struct wlan_cmd_scan
  4226. +{
  4227. +   /*
  4228. +   unsigned char channel_num;
  4229. +   unsigned char channel[15];
  4230. +   */
  4231. +   __le32 len;
  4232. +   unsigned char ssid[0];
  4233. +} __packed;
  4234. +
  4235. +struct wlan_cmd_get_txrate_txfailed
  4236. +{
  4237. +   __le32 rate;
  4238. +   __le32 failed;
  4239. +} __packed;
  4240. +
  4241. +struct wlan_cmd_get_device_mode
  4242. +{
  4243. +   __le32 mode;
  4244. +} __packed;
  4245. +
  4246. +struct wlan_cmd_rsp_state_code
  4247. +{
  4248. +   /* maybe fore it to int */
  4249. +   __le32 code;
  4250. +} __packed;
  4251. +
  4252. +struct wlan_cmd_remain_chan_t {
  4253. +   unsigned char chan;     /* send channel */
  4254. +   unsigned char chan_type;
  4255. +   __le32 duraion;
  4256. +   __le64 cookie;/* cookie */
  4257. +} __packed;
  4258. +
  4259. +struct wlan_cmd_cancel_remain_chan_t {
  4260. +   __le64 cookie;      /* cookie */
  4261. +} __packed;
  4262. +
  4263. +struct wlan_cmd_mgmt_tx_t {
  4264. +   unsigned char chan;     /* send channel */
  4265. +   __le32 wait;    /* wait time */
  4266. +   __le32 len;     /* mac length*/
  4267. +   unsigned char value[0];/* mac*/
  4268. +} __packed;
  4269. +
  4270. +/* wlan_sipc wps ie struct */
  4271. +struct wlan_cmd_p2p_ie_t {
  4272. +   unsigned char type; /*  assoc req ie */
  4273. +   __le16 len;     /* max ie len is 255 */
  4274. +   unsigned char value[0];
  4275. +} __packed;
  4276. +
  4277. +struct wlan_cmd_register_frame_t {
  4278. +   __le16 type;    /*  assoc req ie */
  4279. +   unsigned char reg;    /* max ie len is 255 */
  4280. +} __packed;
  4281. +
  4282. +struct wlan_cmd_beacon_t {
  4283. +   __le16 len;
  4284. +   unsigned char value[0];
  4285. +} __packed;
  4286. +
  4287. +struct wlan_cmd_ft_ies_params
  4288. +{
  4289. +   __le16 md;
  4290. +   __le16 ie_len;
  4291. +   unsigned char  ie[0];
  4292. +} __packed;
  4293. +
  4294. +struct wlan_event_report_frame_t {
  4295. +    unsigned char channel;
  4296. +    unsigned char frame_type;
  4297. +   __le16 frame_len;
  4298. +} __packed;
  4299. +
  4300. +struct wlan_event_scan_rsp
  4301. +{
  4302. +   __le16 ops;
  4303. +   __le16 channel;
  4304. +   /* maybe fore it to short */
  4305. +   __le16 signal;
  4306. +   __le16 frame_len;
  4307. +} __packed;
  4308. +
  4309. +struct wlan_event_mic_failure {
  4310. +   unsigned char key_id;
  4311. +   unsigned char is_mcast;
  4312. +} __packed;
  4313. +
  4314. +extern int wlan_cmd_send_recv(unsigned char vif_id, unsigned char *pData, int len, int type, int timeout);
  4315. +extern int wlan_cmd_start_ap(unsigned char vif_id, unsigned char *beacon, unsigned short len);
  4316. +extern int wlan_cmd_register_frame(unsigned char vif_id, struct  wlan_cmd_register_frame_t *data);
  4317. +extern int wlan_cmd_set_p2p_ie(unsigned char vif_id, u8 type, const u8 *ie, u16 len);
  4318. +extern int wlan_cmd_set_tx_mgmt(unsigned char vif_id, struct ieee80211_channel *channel, unsigned int wait, const u8 *mac, size_t mac_len);
  4319. +extern int wlan_cmd_remain_chan(unsigned char vif_id, struct ieee80211_channel *channel,  enum nl80211_channel_type channel_type, unsigned int duration, u64 *cookie);
  4320. +extern int wlan_cmd_cancel_remain_chan(unsigned char vif_id, u64 cookie);
  4321. +extern int wlan_cmd_scan(unsigned char vif_id, const unsigned char *ssid, const unsigned char *channels, int len);;
  4322. +extern int wlan_cmd_set_wpa_version(unsigned char vif_id,  unsigned int wpa_version);
  4323. +extern int wlan_cmd_set_auth_type(unsigned char vif_id, unsigned int type);
  4324. +extern int wlan_cmd_set_cipher(unsigned char vif_id, unsigned int cipher, unsigned char cmd_id);
  4325. +extern int wlan_cmd_set_key_management(unsigned char vif_id, unsigned char key_mgmt);
  4326. +extern int wlan_cmd_set_psk(unsigned char vif_id, const unsigned char *key, unsigned int key_len);
  4327. +extern int wlan_cmd_set_channel(unsigned char vif_id, unsigned int channel);
  4328. +extern int wlan_cmd_set_bssid(unsigned char vif_id, const unsigned char *addr);
  4329. +extern int wlan_cmd_get_ip(unsigned char vif_id, u8 *ip);
  4330. +extern int wlan_cmd_set_essid(unsigned char vif_id, const unsigned char *essid, int essid_len);
  4331. +extern int wlan_cmd_pmksa(unsigned char vif_id, const unsigned char *bssid, const unsigned char *pmkid, unsigned char type);
  4332. +extern int wlan_cmd_disconnect(unsigned char vif_id, unsigned short reason_code);
  4333. +extern int wlan_cmd_add_key(unsigned char vif_id, const unsigned char *key_data, unsigned char key_len, unsigned char pairwise, unsigned char key_index, const unsigned char *key_seq, unsigned char cypher_type, const unsigned char *pmac);
  4334. +extern int wlan_cmd_del_key(unsigned char vif_id, unsigned short key_index, const unsigned char *mac_addr);
  4335. +extern int wlan_cmd_set_key(unsigned char vif_id, unsigned char key_index);
  4336. +extern int wlan_cmd_set_rts(unsigned char vif_id, unsigned short rts_threshold);
  4337. +extern int wlan_cmd_set_frag(unsigned char vif_id, unsigned short frag_threshold);
  4338. +extern int wlan_cmd_set_wps_ie( unsigned char vif_id, unsigned char type, const unsigned char *ie, unsigned char len);
  4339. +extern int
  4340. +wlan_cmd_mac_open(unsigned char vif_id,
  4341. +                 unsigned short mode,
  4342. +                 unsigned char *mac_addr);
  4343. +extern int wlan_cmd_mac_close(unsigned char vif_id, unsigned char mode);
  4344. +extern int wlan_cmd_get_rssi(unsigned char vif_id, unsigned char *signal, unsigned char *noise);
  4345. +extern int wlan_cmd_get_txrate_txfailed(unsigned char vif_id, unsigned int *rate, unsigned int *failed);
  4346. +extern int wlan_cmd_get_txrate(unsigned char vif_id, unsigned int *rate);
  4347. +extern int wlan_rx_rsp_process(const unsigned char vif_id, r_msg_hdr_t *msg);
  4348. +extern int wlan_rx_event_process(const unsigned char vif_id, unsigned char event, unsigned char *pData, unsigned short len);
  4349. +extern int wlan_cmd_npi_send_recv(unsigned char *s_buf,unsigned short s_len, unsigned char *r_buf, unsigned short *r_len );
  4350. +extern int wlan_cmd_init(void );
  4351. +extern int wlan_cmd_deinit(void );
  4352. +extern int wlan_cmd_set_ft_ie(unsigned char vif_id, const unsigned char *ies, unsigned short len);
  4353. +extern int wlan_cmd_update_ft_ies( unsigned char vif_id, struct cfg80211_update_ft_ies_params *ft_ies);
  4354. +extern int wlan_cmd_assert(unsigned char vif_id, unsigned int reason_code);
  4355. +extern void cfg80211_report_scan_frame(unsigned char vif_id, unsigned char *pData, int len);
  4356. +extern void cfg80211_report_mic_failure(unsigned char vif_id, unsigned char *pdata, int len);
  4357. +extern int wlan_cmd_sleep(int ops);
  4358. +extern int wlan_cmd_req_lte_concur(unsigned char vif_id, const unsigned char *val, int len);
  4359. +#endif
  4360. +
  4361. diff --git a/drivers/net/wireless/sprdwl/wlan_common.h b/drivers/net/wireless/sprdwl/wlan_common.h
  4362. new file mode 100644
  4363. index 0000000..e35b48e
  4364. --- /dev/null
  4365. +++ b/drivers/net/wireless/sprdwl/wlan_common.h
  4366. @@ -0,0 +1,275 @@
  4367. +#ifndef SPRD_WLAN_COMMON_H_
  4368. +#define SPRD_WLAN_COMMON_H_
  4369. +
  4370. +#include <linux/proc_fs.h>
  4371. +#include <linux/sipc.h>
  4372. +#include <linux/mutex.h>
  4373. +#include <linux/spinlock.h>
  4374. +#include <linux/ieee80211.h>
  4375. +#include <linux/printk.h>
  4376. +#include <linux/inetdevice.h>
  4377. +#include <linux/spinlock.h>
  4378. +#include <net/cfg80211.h>
  4379. +#include <linux/kernel.h>
  4380. +#include <linux/errno.h>
  4381. +#include <linux/module.h>
  4382. +#include <linux/netdevice.h>
  4383. +#include <linux/skbuff.h>
  4384. +#include <net/ieee80211_radiotap.h>
  4385. +#include <linux/etherdevice.h>
  4386. +#include <linux/wireless.h>
  4387. +#include <net/iw_handler.h>
  4388. +#include <linux/string.h>
  4389. +#include <linux/delay.h>
  4390. +#include <linux/interrupt.h>
  4391. +#include <linux/init.h>
  4392. +#include <linux/wakelock.h>
  4393. +#include <linux/workqueue.h>
  4394. +#include <linux/ipv6.h>
  4395. +#include <linux/ip.h>
  4396. +#include <linux/inetdevice.h>
  4397. +#include <asm/byteorder.h>
  4398. +#include <linux/platform_device.h>
  4399. +#include <linux/atomic.h>
  4400. +#include <linux/wait.h>
  4401. +#include <linux/semaphore.h>
  4402. +#include <linux/vmalloc.h>
  4403. +#include <linux/kthread.h>
  4404. +#include <linux/time.h>
  4405. +#include <linux/delay.h>
  4406. +#include <linux/timer.h>
  4407. +#include <linux/completion.h>
  4408. +#include <asm/atomic.h>
  4409. +#include <linux/ieee80211.h>
  4410. +#include <linux/delay.h>
  4411. +#include <linux/wakelock.h>
  4412. +#include <linux/earlysuspend.h>
  4413. +#include <asm/gpio.h>
  4414. +#include "wlan_event_q.h"
  4415. +#include "wlan_fifo.h"
  4416. +#include "wlan_cmd.h"
  4417. +#include "wlan_cfg80211.h"
  4418. +
  4419. +//#define SDIO_CHN_CHECK                     (1)
  4420. +#define WIFI_DRV_WAPI
  4421. +#define KERNEL_VERSION(a, b, c)              (((a) << 16) + ((b) << 8) + (c))
  4422. +#define LINUX_VERSION_CODE                   KERNEL_VERSION(3, 10, 0)
  4423. +
  4424. +#define SDIO_ALIGN_SIZE                      (1024)
  4425. +#define ALIGN_4BYTE(a)                       (  (((a)+3)&(~3))  )
  4426. +#define INCR_RING_BUFF_INDX(indx,max_num)    ((((indx) + 1) < (max_num)) ?  ((indx) + 1) : (0) )
  4427. +#define MAX_TX_BUFFER_ID                     (12)
  4428. +#define TEST_BIT(a, k)                       ((a>>k)&1)
  4429. +#define CLEAR_BIT(a, k)                      ({a = ( a&(~(1<<k)) );0;})
  4430. +#define SET_BIT(a, k)                        ({a=( a | (1<<k) ); 0; })
  4431. +#define WLAN_SYSTEM_DBG                      TEST_BIT(g_dbg, 1)
  4432. +#define WLAN_PATH_DBG                        TEST_BIT(g_dbg, 2)
  4433. +#define WLAN_HEX_DBG                         TEST_BIT(g_dbg, 3)
  4434. +#define ETH_PCAP                             TEST_BIT(g_dbg, 4)
  4435. +#define MAC_PCAP                             TEST_BIT(g_dbg, 5)
  4436. +#define ETH_ALEN                            6
  4437. +#define SIOGETSSID                           0x89F2
  4438. +
  4439. +#define HW_TX_SIZE                          (11264)
  4440. +#define HW_RX_SIZE                          (15360)
  4441. +#define PKT_AGGR_NUM                        (10)
  4442. +#define SDIO_RX_GPIO                        (132)
  4443. +
  4444. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  4445. +#define KERNEL_DEBUG_LEVE     "\001" "0"
  4446. +#else
  4447. +#define KERNEL_DEBUG_LEVE       "<0>"
  4448. +#endif
  4449. +
  4450. +#define printkd(fmt, ...)     ({if(WLAN_SYSTEM_DBG)printk(KERNEL_DEBUG_LEVE "[SC2331]" fmt, ##__VA_ARGS__); 0; })
  4451. +#define printkp(fmt, ...)     ({if(WLAN_PATH_DBG)printk(KERNEL_DEBUG_LEVE "[SC2331]" fmt, ##__VA_ARGS__); 0; })
  4452. +#define printke(fmt, ...)     ({printk(KERNEL_DEBUG_LEVE "[SC2331]" fmt, ##__VA_ARGS__); 0; })
  4453. +#define ASSERT(fmt, ...)      ({printk(KERNEL_DEBUG_LEVE  "[SC2331-ASSERT][%s][%d]" fmt "\n", __func__, __LINE__,  ##__VA_ARGS__); 0; })
  4454. +
  4455. +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
  4456. +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
  4457. +
  4458. +typedef struct
  4459. +{
  4460. +   unsigned char  chn[16];
  4461. +   unsigned char  num;
  4462. +   unsigned short bit_map;
  4463. +   spinlock_t     lock;
  4464. +   int            gpio_high;
  4465. +   unsigned long  timeout;
  4466. +   unsigned long  timeout_time;
  4467. +   bool           timeout_flag;
  4468. +}sdio_chn_t;
  4469. +
  4470. +typedef enum
  4471. +{
  4472. +   EVENT_Q_ID_0   = 0,
  4473. +   EVENT_Q_ID_1   = 1,
  4474. +   EVENT_Q_ID_2   = 2,
  4475. +   EVENT_Q_ID_3   = 3,
  4476. +   EVENT_Q_ID_4   = 4,
  4477. +   EVENT_Q_MAX_ID = 5,
  4478. +}EVENT_Q_ID_T;
  4479. +
  4480. +typedef enum
  4481. +{
  4482. +   NETIF_0_ID   = 0,
  4483. +   NETIF_1_ID   = 1,
  4484. +   WLAN_MAX_ID  = 2,
  4485. +}NETIF_ID_T;
  4486. +
  4487. +typedef struct
  4488. +{
  4489. +   int              exit;
  4490. +   struct semaphore sem;
  4491. +}drv_sync_t;
  4492. +
  4493. +typedef struct
  4494. +{
  4495. +   sdio_chn_t            sdio_tx_chn;
  4496. +   sdio_chn_t            sdio_rx_chn;
  4497. +   unsigned int          tx_cnt;
  4498. +   unsigned int          rx_cnt;
  4499. +   unsigned int          rx_record;
  4500. +   struct wake_lock      wlan_lock;
  4501. +   struct early_suspend  early_suspend;
  4502. +   int                   wakeup;
  4503. +   struct timer_list     wakeup_timer;
  4504. +   unsigned long         wakeup_time;
  4505. +   int                   can_sleep;
  4506. +}hw_info_t;
  4507. +typedef struct
  4508. +{
  4509. +   m_event_t          tx_q;
  4510. +   txfifo_t           tx_fifo;
  4511. +   int                status;
  4512. +}tx_buf_t;
  4513. +
  4514. +typedef struct
  4515. +{
  4516. +   struct task_struct *task;
  4517. +   struct semaphore    sem;   
  4518. +}wlan_thread_t;
  4519. +
  4520. +typedef struct
  4521. +{
  4522. +   unsigned char      mac[ETH_ALEN];
  4523. +   unsigned char      netif_id;
  4524. +   unsigned char      prio;
  4525. +   unsigned char      wmm_supp;
  4526. +   unsigned char      status;
  4527. +}net_connect_dev_t;
  4528. +
  4529. +typedef struct
  4530. +{
  4531. +   wait_queue_head_t  waitQ;
  4532. +   int                wakeup;
  4533. +   struct mutex       cmd_lock;
  4534. +   unsigned char     *mem;
  4535. +}wlan_cmd_t;
  4536. +
  4537. +typedef struct
  4538. +{
  4539. +    struct work_struct       work;
  4540. +    unsigned short           frame_type;
  4541. +    bool                     reg;
  4542. +    void                    *vif;
  4543. +}register_frame_param_t;
  4544. +
  4545. +/* Best not to use the work to send deauth cmd
  4546. + * FIXME in the future
  4547. + */
  4548. +struct deauth_info {
  4549. +   struct work_struct work;
  4550. +   /* 60 length is enough, maybe FIXME */
  4551. +   unsigned char mac[60];
  4552. +   unsigned short len;
  4553. +};
  4554. +
  4555. +typedef struct
  4556. +{
  4557. +   struct wake_lock                  scan_done_lock;
  4558. +   atomic_t                          scan_status;
  4559. +   struct cfg80211_scan_request     *scan_request;
  4560. +   struct timer_list                 scan_timeout;
  4561. +   int                               connect_status;
  4562. +   int                               ssid_len;
  4563. +   unsigned char                     ssid[IEEE80211_MAX_SSID_LEN];
  4564. +   unsigned char                     bssid[ETH_ALEN];
  4565. +   unsigned char                     cipher_type;
  4566. +   unsigned char                     key_index[2];
  4567. +   unsigned char                     key[2][4][WLAN_MAX_KEY_LEN];
  4568. +   unsigned char                     key_len[2][4];
  4569. +   unsigned char                     key_txrsc[2][WLAN_MAX_KEY_LEN];
  4570. +   unsigned char                    *scan_frame_array;
  4571. +   int                               p2p_mode;
  4572. +   register_frame_param_t            register_frame;
  4573. +   struct deauth_info  deauth_info;
  4574. +}wlan_cfg80211_t;
  4575. +
  4576. +typedef struct
  4577. +{
  4578. +   struct net_device                *ndev;
  4579. +   struct wireless_dev               wdev;
  4580. +   unsigned short                    id;
  4581. +   unsigned char                     mac[ETH_ALEN];
  4582. +   int                               mode;
  4583. +   wlan_cfg80211_t                   cfg80211;
  4584. +   net_connect_dev_t                 connect_dev[8];
  4585. +   txfifo_t                          txfifo;
  4586. +   m_event_t                         event_q[EVENT_Q_MAX_ID];
  4587. +}wlan_vif_t;
  4588. +
  4589. +typedef struct
  4590. +{
  4591. +   struct wiphy       *wiphy;
  4592. +   struct device      *dev;
  4593. +   wlan_thread_t       wlan_core;
  4594. +   wlan_thread_t       wlan_trans;
  4595. +   hw_info_t           hw;
  4596. +   wlan_cmd_t          cmd;
  4597. +   drv_sync_t          sync;  
  4598. +   wlan_vif_t          netif[2];
  4599. +   rxfifo_t            rxfifo;
  4600. +}wlan_info_t;
  4601. +
  4602. +static inline wlan_vif_t *ndev_to_vif(struct net_device *ndev)
  4603. +{
  4604. +   return *(wlan_vif_t **)netdev_priv(ndev);
  4605. +}
  4606. +
  4607. +extern void core_down(void);
  4608. +extern void core_up(void);
  4609. +extern void trans_down(void );
  4610. +extern void trans_up(void );
  4611. +extern void up_wlan_rx_trans(void );
  4612. +extern int wlan_module_init(struct device *dev);
  4613. +extern int wlan_module_exit(struct device *dev);
  4614. +extern int hex_dump(unsigned char  *name, unsigned short nLen, unsigned char *pData,  unsigned short len);
  4615. +extern void init_register_frame_param(wlan_vif_t *vif );
  4616. +extern void init_send_deauth_work(wlan_vif_t *vif);
  4617. +extern wlan_vif_t *id_to_vif(unsigned char id);
  4618. +extern int hostap_conf_load(char *filename, unsigned char *key_val);
  4619. +extern int mac_addr_cfg(wlan_vif_t *vif, unsigned char vif_id);
  4620. +extern int wlan_vif_init(wlan_vif_t  *vif, int type, const char *name, void *ops);
  4621. +extern int wlan_wiphy_new(wlan_info_t *wlan);
  4622. +extern int wlan_vif_free(wlan_vif_t *vif);
  4623. +extern int wlan_wiphy_free(wlan_info_t *wlan);
  4624. +extern void wlan_nl_init(void );
  4625. +extern void wlan_nl_deinit(void );
  4626. +
  4627. +extern bool get_sdiohal_status(void);
  4628. +extern int  sdio_chn_status(unsigned short chn, unsigned short *status);
  4629. +extern int  sdio_dev_read(unsigned int chn,void* read_buf,unsigned int *count);
  4630. +extern int  sdio_dev_write(unsigned int chn,void* data_buf,unsigned int count);
  4631. +extern int  sdiodev_readchn_init(int chn, void *callback, bool with_para );
  4632. +extern int  sdio_read_wlan(unsigned int chn,void* read_buf,unsigned int *count);
  4633. +extern int sdiodev_readchn_uninit(unsigned int chn);
  4634. +extern void mdbg_sdio_read(void);
  4635. +extern void marlin_pa_enable(bool enable);
  4636. +extern int set_marlin_wakeup(unsigned int chn,unsigned int user_id);
  4637. +extern int set_marlin_sleep(unsigned int  chn,unsigned int user_id);
  4638. +extern char * get_cmd_name(int id);
  4639. +extern unsigned int g_dbg;
  4640. +extern wlan_info_t g_wlan;
  4641. +#endif
  4642. diff --git a/drivers/net/wireless/sprdwl/wlan_core.c b/drivers/net/wireless/sprdwl/wlan_core.c
  4643. new file mode 100644
  4644. index 0000000..5a3a61a
  4645. --- /dev/null
  4646. +++ b/drivers/net/wireless/sprdwl/wlan_core.c
  4647. @@ -0,0 +1,1228 @@
  4648. +/*
  4649. + * Copyright (C) 2014 Spreadtrum Communications Inc.
  4650. + *
  4651. + * Authors:<jinglong.chen@spreadtrum.com>
  4652. + * Owner:
  4653. + *      jinglong.chen
  4654. + *
  4655. + * This software is licensed under the terms of the GNU General Public
  4656. + * License version 2, as published by the Free Software Foundation, and
  4657. + * may be copied, distributed, and modified under those terms.
  4658. + *
  4659. + * This program is distributed in the hope that it will be useful,
  4660. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4661. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4662. + * GNU General Public License for more details.
  4663. + */
  4664. +
  4665. +#include "wlan_common.h"
  4666. +#include "wlan_event_q.h"
  4667. +#include "wlan_fifo.h"
  4668. +#include "wlan_cmd.h"
  4669. +#include "wlan_cfg80211.h"
  4670. +#include "wlan_wapi.h"
  4671. +
  4672. +wlan_info_t g_wlan = { 0 };
  4673. +unsigned int g_dbg = 0xFFFFFFFF;
  4674. +
  4675. +void core_up(void)
  4676. +{
  4677. +   up(&(g_wlan.wlan_core.sem));
  4678. +}
  4679. +void core_down(void)
  4680. +{
  4681. +   down(&(g_wlan.wlan_core.sem));
  4682. +}
  4683. +void trans_up(void )
  4684. +{
  4685. +   up(&(g_wlan.wlan_trans.sem));
  4686. +}
  4687. +void trans_down(void )
  4688. +{
  4689. +   down(&(g_wlan.wlan_trans.sem));
  4690. +}
  4691. +
  4692. +bool stop_net(unsigned char id )
  4693. +{
  4694. +   return false;
  4695. +   if(NULL == g_wlan.netif[id].ndev)
  4696. +       return false;  
  4697. +   if( ! netif_queue_stopped(g_wlan.netif[id].ndev) )
  4698. +   {
  4699. +       netif_stop_queue(g_wlan.netif[id].ndev);
  4700. +       return true;
  4701. +   }
  4702. +   return false;
  4703. +}
  4704. +
  4705. +bool wake_net(unsigned char id)
  4706. +{
  4707. +   return false;
  4708. +   if( (NULL == g_wlan.netif[id].ndev) || (1 == g_wlan.sync.exit) )
  4709. +       return false;
  4710. +   if(netif_queue_stopped(g_wlan.netif[id].ndev) )
  4711. +   {
  4712. +       netif_wake_queue(g_wlan.netif[id].ndev);
  4713. +       return true;
  4714. +   }
  4715. +   return false;
  4716. +}
  4717. +
  4718. +static int hw_rx(const unsigned short chn, unsigned char *buf, unsigned int *len)
  4719. +{
  4720. +   int ret;
  4721. +   unsigned int read_len = 0
  4722. +   static unsigned int cnt = 0;
  4723. +   if(NULL == buf)
  4724. +       return ERROR;
  4725. +#if 0
  4726. +   ret = sdio_read_wlan(chn, buf, HW_RX_SIZE);
  4727. +   *len = HW_RX_SIZE;
  4728. +#else
  4729. +   ret = sdio_dev_read(chn, buf, &read_len);
  4730. +   *len = read_len;
  4731. +#endif
  4732. +   if(0 != ret)
  4733. +   {
  4734. +       printke("[chn %d][sdio_read] err:%d\n", chn, ret);
  4735. +       return ERROR;
  4736. +   }
  4737. +   if(WLAN_HEX_DBG)
  4738. +   {
  4739. +       unsigned char str[64] = {0};
  4740. +       printkd("[sdio_read][%d][%d][%d]\n", chn, 1024, cnt);
  4741. +       sprintf(str, "[HEX-RX][%d]:", 1024);
  4742. +       hex_dump(str, strlen(str), buf, 1024);
  4743. +   }
  4744. +   printkp("[rx][%d]\n", chn );
  4745. +   cnt++;
  4746. +   *len = read_len;
  4747. +   g_wlan.hw.rx_cnt++;
  4748. +   return OK;
  4749. +}
  4750. +
  4751. +static int hw_tx(const unsigned short chn, unsigned char *buf, unsigned int len)
  4752. +{
  4753. +   int ret;
  4754. +   static unsigned int cnt = 0;
  4755. +   static unsigned int skb = 0;
  4756. +   tx_big_hdr_t *big_hdr;
  4757. +
  4758. +   big_hdr = (tx_big_hdr_t *)buf;
  4759. +   if( (14 < big_hdr->msg_num) || (0 == big_hdr->msg_num) )
  4760. +   {
  4761. +       ASSERT();
  4762. +       return ERROR;
  4763. +   }  
  4764. +   if(WLAN_HEX_DBG)
  4765. +   {
  4766. +       unsigned char str[64] = {0};
  4767. +       sprintf(str, "[HEX-TX][%d]:", len);
  4768. +       hex_dump(str, strlen(str), buf, 128);
  4769. +   }
  4770. +   big_hdr->tx_cnt = g_wlan.hw.tx_cnt;
  4771. +   printkp("[tx][%d][%d]\n",big_hdr->tx_cnt, chn);
  4772. +   len = (len+1023)&0xFC00;
  4773. +   ret = sdio_dev_write(chn, buf, len);
  4774. +   if(0 != ret)
  4775. +   {
  4776. +       ASSERT();
  4777. +       return ERROR;
  4778. +   }
  4779. +   skb = skb + big_hdr->msg_num;
  4780. +   cnt++;
  4781. +   if(100 == cnt)
  4782. +   {
  4783. +       printkd("w%d\n", skb);
  4784. +       cnt = 0;
  4785. +       skb = 0;
  4786. +   }
  4787. +   g_wlan.hw.tx_cnt++;
  4788. +   return OK;
  4789. +}
  4790. +
  4791. +static int wlan_rx_skb_process(const unsigned char vif_id, unsigned char *pData, unsigned short len)
  4792. +{
  4793. +   struct sk_buff *skb;
  4794. +   struct net_device *ndev = g_wlan.netif[vif_id].ndev;
  4795. +   if((NULL == pData) || (0 == len) || (NULL == ndev))
  4796. +   {
  4797. +       printkd("[%s][%d][err]\n", __func__, (int )vif_id);
  4798. +       return ERROR;
  4799. +   }
  4800. +   skb = dev_alloc_skb(len + NET_IP_ALIGN);
  4801. +   if(NULL == skb)
  4802. +       return ERROR;
  4803. +   skb_reserve(skb, NET_IP_ALIGN);
  4804. +   memcpy(skb->data,   pData,  len);
  4805. +
  4806. +   skb_put(skb, len);
  4807. +   skb->dev = ndev;
  4808. +   skb->protocol = eth_type_trans(skb, ndev);
  4809. +   ndev->stats.rx_packets++;
  4810. +   printkp("rx_skb:%d\n", (int)(ndev->stats.rx_packets) );
  4811. +   ndev->stats.rx_bytes += skb->len;
  4812. +   if ( in_interrupt() )
  4813. +       netif_rx(skb);
  4814. +   else
  4815. +       netif_rx_ni(skb);
  4816. +    return OK;
  4817. +}
  4818. +
  4819. +static int wlan_rx_wapi_process(const unsigned char vif_id, unsigned char *pData, unsigned short len)
  4820. +{
  4821. +   struct ieee80211_hdr_3addr *addr;
  4822. +   int decryp_data_len = 0;
  4823. +   struct sk_buff *skb;
  4824. +   u8 snap_header[6] = { 0xaa, 0xaa, 0x03,0x00, 0x00, 0x00};
  4825. +   wlan_vif_t   *vif;
  4826. +   struct net_device *ndev;
  4827. +
  4828. +   vif  = &(g_wlan.netif[vif_id]);
  4829. +   ndev = vif->ndev;
  4830. +   if((NULL == pData) || (0 == len) || (NULL == ndev))
  4831. +   {
  4832. +       printkd("[%s][%d][err]\n", __func__, (int )vif_id);
  4833. +       return ERROR;
  4834. +   }
  4835. +   addr = (struct ieee80211_hdr_3addr *)pData;
  4836. +   skb = dev_alloc_skb(len + NET_IP_ALIGN);
  4837. +   if(NULL == skb)
  4838. +       return ERROR;
  4839. +   skb_reserve(skb, NET_IP_ALIGN);
  4840. +
  4841. +   decryp_data_len = wlan_rx_wapi_decryption(vif, (unsigned char  *)addr, 24, (len -24),(skb->data + 12));
  4842. +   if (decryp_data_len == 0)
  4843. +   {
  4844. +       dev_kfree_skb(skb);
  4845. +       return ERROR;
  4846. +   }
  4847. +   if ( memcmp((skb->data + 12), snap_header, sizeof(snap_header)) == 0)
  4848. +   {
  4849. +       skb_reserve(skb, 6);
  4850. +       memcpy(skb->data,addr->addr1, 6);
  4851. +       memcpy(skb->data + 6,addr->addr2, 6);
  4852. +       skb_put(skb, (decryp_data_len + 6));
  4853. +   }
  4854. +   else
  4855. +   {
  4856. +       /* copy eth header */
  4857. +       memcpy(skb->data,addr->addr3, 6);
  4858. +       memcpy(skb->data + 6, addr->addr2, 6);
  4859. +       skb_put(skb, (decryp_data_len + 12) );
  4860. +   }
  4861. +   skb->dev = ndev;
  4862. +   skb->protocol = eth_type_trans(skb, ndev);
  4863. +   ndev->stats.rx_packets++;
  4864. +   printkp("rx_skb:%d\n", (int)(ndev->stats.rx_packets) );
  4865. +   ndev->stats.rx_bytes += skb->len;
  4866. +   if ( in_interrupt() )
  4867. +       netif_rx(skb);
  4868. +   else
  4869. +       netif_rx_ni(skb);
  4870. +   return OK;
  4871. +}
  4872. +
  4873. +void wlan_rx_chn_isr(int chn)
  4874. +{
  4875. +   static unsigned int cnt = 1;
  4876. +   printkp("[irq][%d]\n", cnt);
  4877. +   cnt++;
  4878. +   trans_up();
  4879. +}
  4880. +
  4881. +static unsigned char prio_to_q_id(unsigned char  *eth_hdr)
  4882. +{
  4883. +   unsigned short  eth_type;
  4884. +   int             priority;
  4885. +   unsigned char   q_id = EVENT_Q_ID_2;
  4886. +  
  4887. +   eth_type  = ( (eth_hdr[12]<<8) | eth_hdr[13] );
  4888. +   if(IP_TYPE != eth_type)
  4889. +       return q_id;
  4890. +   priority = eth_hdr[15]&0xE0;
  4891. +   switch(priority)
  4892. +   {
  4893. +       case 0x20:
  4894. +       case 0x40:
  4895. +           q_id = EVENT_Q_ID_1;
  4896. +           break;
  4897. +          
  4898. +       case 0x80:
  4899. +       case 0xA0:
  4900. +           q_id = EVENT_Q_ID_3;
  4901. +           break;
  4902. +          
  4903. +       case 0xc0:
  4904. +       case 0xe0:
  4905. +           q_id = EVENT_Q_ID_4;
  4906. +           break;
  4907. +
  4908. +       default:
  4909. +           q_id = EVENT_Q_ID_2;
  4910. +           break;
  4911. +   }
  4912. +   return q_id;
  4913. +}
  4914. +
  4915. +static int wlan_xmit(struct sk_buff *skb, struct net_device *dev)
  4916. +{
  4917. +   unsigned char q_id;
  4918. +   int addr_len = 0;
  4919. +   wlan_vif_t   *vif;
  4920. +   tx_msg_t     *event;
  4921. +   m_event_t    *event_q;
  4922. +   struct sk_buff *wapi_skb;
  4923. +
  4924. +   vif     = ndev_to_vif(dev);
  4925. +   q_id    = EVENT_Q_ID_1;//q_id    = prio_to_q_id(skb->data);
  4926. +   event_q = &(vif->event_q[q_id]);
  4927. +   if(event_q->event_cnt > event_q->highThres)
  4928. +   {
  4929. +       if( stop_net(vif->id) )
  4930. +           printke("[stop_net %d:%d][%d,%d]\n", vif->id, q_id, event_q->event_cnt, event_q->highThres);
  4931. +   }
  4932. +   event = alloc_event(event_q);
  4933. +   if(NULL == event)
  4934. +   {
  4935. +       printkd("L-PKT\n");
  4936. +       if( stop_net(vif->id) )
  4937. +           printke("[stop_net %d:%d][%d,%d]\n", vif->id, q_id, event_q->event_cnt, event_q->highThres);           
  4938. +       dev_kfree_skb(skb);
  4939. +       return NETDEV_TX_OK;
  4940. +   }
  4941. +#ifdef WIFI_DRV_WAPI
  4942. +   if (vif->cfg80211.cipher_type == WAPI && vif->cfg80211.connect_status == ITM_CONNECTED &&
  4943. +       vif->cfg80211.key_len[PAIRWISE][vif->cfg80211.key_index[PAIRWISE]] != 0 &&(*(u16 *)((u8 *)skb->data + ETH_PKT_TYPE_OFFSET) != 0xb488))
  4944. +   {
  4945. +       wapi_skb = dev_alloc_skb(skb->len+100+NET_IP_ALIGN);
  4946. +       skb_reserve(wapi_skb, NET_IP_ALIGN);
  4947. +       memcpy( wapi_skb->data, skb->data, ETHERNET_HDR_LEN );
  4948. +       addr_len = wlan_tx_wapi_encryption(vif, skb->data, (skb->len - ETHERNET_HDR_LEN),  ( (unsigned char *)(wapi_skb->data) + ETHERNET_HDR_LEN)  );
  4949. +       addr_len = addr_len + ETHERNET_HDR_LEN;
  4950. +       skb_put(wapi_skb, addr_len);
  4951. +       memset(event, 0, sizeof(tx_msg_t) );
  4952. +       event->p = (void *)wapi_skb;
  4953. +       event->slice[0].data = wapi_skb->data;
  4954. +       event->slice[0].len  = wapi_skb->len;
  4955. +       event->hdr.mode = vif->id;
  4956. +       event->hdr.type = HOST_SC2331_PKT;
  4957. +       event->hdr.subtype = 0;
  4958. +       event->hdr.len = event->slice[0].len;
  4959. +       vif->ndev->stats.tx_bytes += wapi_skb->len;
  4960. +       vif->ndev->stats.tx_packets++;
  4961. +       dev->trans_start = jiffies;
  4962. +       dev_kfree_skb(skb);
  4963. +   }
  4964. +   else
  4965. +#endif
  4966. +   {
  4967. +       event->p = (void *)skb;
  4968. +       event->slice[0].data = skb->data;
  4969. +       event->slice[0].len  = skb->len;
  4970. +       event->hdr.mode = vif->id;
  4971. +       event->hdr.type = HOST_SC2331_PKT;
  4972. +       event->hdr.subtype = 0;
  4973. +       event->hdr.len = skb->len;
  4974. +       vif->ndev->stats.tx_bytes += skb->len;
  4975. +       vif->ndev->stats.tx_packets++;
  4976. +       dev->trans_start = jiffies;
  4977. +   }
  4978. +
  4979. +   post_event( (unsigned char *)event, event_q );
  4980. +   core_up();
  4981. +   return NETDEV_TX_OK;
  4982. +}
  4983. +
  4984. +static int wlan_rx_process(unsigned char *buf, unsigned int max_len)
  4985. +{
  4986. +   static unsigned int cnt = 0;
  4987. +   static unsigned int skb = 0;
  4988. +   unsigned int     p = 0;
  4989. +   r_msg_hdr_t     *msg = NULL;
  4990. +   unsigned char    vif_id;   
  4991. +   unsigned char   *pData = NULL;
  4992. +   unsigned short   len;
  4993. +   unsigned char    event;
  4994. +   if((NULL == buf) || (0 == max_len))
  4995. +   {
  4996. +       printke("[%s][ERROR]\n", __func__);
  4997. +       return OK;
  4998. +   }
  4999. +   buf      = buf + 8;
  5000. +   msg      = (r_msg_hdr_t *)(buf);
  5001. +   max_len  = max_len - 8;
  5002. +   while(p < max_len)
  5003. +   {
  5004. +      
  5005. +       vif_id = msg->mode;
  5006. +       pData  = (unsigned char *)(msg+1);
  5007. +       len    = msg->len;
  5008. +      
  5009. +       if( (0xFF == msg->type) || (0xFF == msg->subtype) )
  5010. +           break;
  5011. +       if(HOST_SC2331_PKT == msg->type)
  5012. +       {
  5013. +           pData = pData + msg->subtype;
  5014. +           len   = len   - msg->subtype;
  5015. +           wlan_rx_skb_process(vif_id, pData, len);
  5016. +       }
  5017. +#ifdef WIFI_DRV_WAPI
  5018. +       else if(HOST_SC2331_WAPI == msg->type)
  5019. +       {
  5020. +           wlan_rx_wapi_process(vif_id, pData, len);
  5021. +       }
  5022. +#endif
  5023. +       else if(SC2331_HOST_RSP == msg->type)
  5024. +       {
  5025. +           wlan_rx_rsp_process(vif_id, msg);
  5026. +       }
  5027. +       else if(HOST_SC2331_CMD == msg->type)
  5028. +       {
  5029. +           event = msg->subtype;
  5030. +           wlan_rx_event_process(vif_id, event, pData, len);
  5031. +       }
  5032. +       else
  5033. +       {
  5034. +           printke("[%s][RX DATA ERR]\n", __func__);
  5035. +           break;
  5036. +       }
  5037. +       p = p + sizeof(t_msg_hdr_t) + ALIGN_4BYTE(msg->len);
  5038. +       msg = (r_msg_hdr_t *)(buf+p);
  5039. +       skb++;
  5040. +   }
  5041. +   cnt++;
  5042. +   if(100 == cnt)
  5043. +   {
  5044. +       printkd("r%d\n", skb);
  5045. +       cnt = 0;
  5046. +       skb = 0;
  5047. +   }
  5048. +   return OK;
  5049. +}
  5050. +
  5051. +static int wlan_open(struct net_device *dev)
  5052. +{
  5053. +   printkd("%s open\n", dev->name );
  5054. +   netif_start_queue(dev);
  5055. +   return 0;
  5056. +}
  5057. +static int wlan_close(struct net_device *dev)
  5058. +{
  5059. +   printkd("%s %s enter\n", __func__, dev->name );
  5060. +   netif_stop_queue(dev);
  5061. +   printkd("%s %s ok\n", __func__, dev->name );
  5062. +   return 0;
  5063. +}
  5064. +static struct net_device_stats *wlan_status(struct net_device *dev)
  5065. +{
  5066. +   return &(dev->stats);
  5067. +}
  5068. +
  5069. +static void wlan_tx_timeout(struct net_device *dev)
  5070. +{
  5071. +   wlan_vif_t   *vif;
  5072. +   printke("%s tx timeout\n", dev->name);
  5073. +   vif = ndev_to_vif(dev);
  5074. +  
  5075. +   if (!netif_carrier_ok(dev))
  5076. +       netif_carrier_on(dev);
  5077. +   dev->trans_start = jiffies;
  5078. +   wake_net(vif->id);
  5079. +   core_up();
  5080. +   return;
  5081. +}
  5082. +
  5083. +static int wlan_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
  5084. +{
  5085. +   return 0;
  5086. +}
  5087. +
  5088. +struct net_device_ops wlan_ops =
  5089. +{
  5090. +   .ndo_open                 = wlan_open,
  5091. +   .ndo_stop                 = wlan_close,
  5092. +   .ndo_start_xmit           = wlan_xmit,
  5093. +   .ndo_get_stats            = wlan_status,
  5094. +   .ndo_tx_timeout           = wlan_tx_timeout,
  5095. +   .ndo_do_ioctl             = wlan_ioctl,
  5096. +};
  5097. +
  5098. +static void wlan_early_suspend(struct early_suspend *es)
  5099. +{
  5100. +   printkd("[%s]\n", __func__);
  5101. +   wlan_cmd_sleep(1);
  5102. +}
  5103. +
  5104. +static void wlan_late_resume(struct early_suspend *es)
  5105. +{
  5106. +   printkd("[%s]\n", __func__);
  5107. +   wlan_cmd_sleep(2);
  5108. +}
  5109. +
  5110. +int wlan_wakeup(void )
  5111. +{
  5112. +   int ret;
  5113. +   if(0 != g_wlan.hw.wakeup)
  5114. +       return OK;
  5115. +   wake_lock(&g_wlan.hw.wlan_lock);
  5116. +   printkd("time[1]\n");
  5117. +   mod_timer(&(g_wlan.hw.wakeup_timer),  jiffies + msecs_to_jiffies(g_wlan.hw.wakeup_time) );
  5118. +   g_wlan.hw.wakeup    = 1;
  5119. +   g_wlan.hw.can_sleep = 0;
  5120. +   return ret;
  5121. +}
  5122. +
  5123. +void wlan_sleep(void )
  5124. +{
  5125. +   int     ret;
  5126. +   if( (1 != g_wlan.hw.wakeup) || (0 == g_wlan.hw.can_sleep) )
  5127. +       return;
  5128. +   g_wlan.hw.wakeup = 0;
  5129. +   printkd("time[4]\n");
  5130. +   wake_unlock(&g_wlan.hw.wlan_lock);
  5131. +   return;
  5132. +}
  5133. +
  5134. +void wakeup_timer_func(unsigned long data)
  5135. +{
  5136. +   if((g_wlan.wlan_trans.sem.count <= 0) && (0 == g_wlan.hw.can_sleep) )
  5137. +   {
  5138. +       printkd("timer[3]\n");
  5139. +       g_wlan.hw.can_sleep = 1;
  5140. +       trans_up();
  5141. +       return;
  5142. +   }
  5143. +   printkd("timer[2]\n");
  5144. +   mod_timer(&(g_wlan.hw.wakeup_timer),  jiffies + msecs_to_jiffies(g_wlan.hw.wakeup_time) );
  5145. +}
  5146. +
  5147. +int wlan_rx(rxfifo_t *rx_fifo, int cnt)
  5148. +{
  5149. +   int i,num,rx_cnt,ret;
  5150. +   rx_cnt = 0;
  5151. +   num = rx_fifo_used(rx_fifo);
  5152. +   if(num > cnt)
  5153. +       num = cnt;
  5154. +   for(i=0; i < num ; i++)
  5155. +   {
  5156. +       wlan_wakeup();
  5157. +       ret = rx_fifo_out(rx_fifo, wlan_rx_process);
  5158. +       if(ERROR == ret)
  5159. +           break;
  5160. +       rx_cnt++;
  5161. +   }
  5162. +   return rx_cnt;
  5163. +}
  5164. +
  5165. +int wlan_tx(txfifo_t *tx_fifo, m_event_t *event_q, int cnt)
  5166. +{
  5167. +   int tx_cnt,i,ret;
  5168. +   tx_msg_t  *event;
  5169. +   tx_cnt = 0;
  5170. +   for(i=0; i<cnt; i++)
  5171. +   {
  5172. +       event = (tx_msg_t *)get_event(event_q);
  5173. +       if(NULL == event)
  5174. +       {
  5175. +           break;
  5176. +       }
  5177. +       ret = tx_fifo_in(tx_fifo, event);
  5178. +       if(TX_FIFO_FULL == ret)
  5179. +       {
  5180. +           break;
  5181. +       }
  5182. +       trans_up();
  5183. +       if( HOST_SC2331_CMD == event->hdr.type)
  5184. +       {
  5185. +           if((event->slice[0].len > 0) &&(NULL != event->slice[0].data))
  5186. +               kfree(event->slice[0].data);
  5187. +       }
  5188. +       else if(HOST_SC2331_PKT == event->hdr.type)
  5189. +       {
  5190. +           if((NULL != event->p))
  5191. +               dev_kfree_skb((struct sk_buff  *)(event->p));
  5192. +       }
  5193. +       else
  5194. +       {}
  5195. +       memset((unsigned char *)event,  0,  sizeof(tx_msg_t));
  5196. +       free_event((void *)event, event_q );
  5197. +       tx_cnt++;
  5198. +   }
  5199. +   return tx_cnt;
  5200. +}
  5201. +
  5202. +int wmm_calc(wlan_vif_t *vif, unsigned short *q_event_num)
  5203. +{
  5204. +   int            i,weight;
  5205. +   unsigned short event_q_array[EVENT_Q_MAX_ID][2];
  5206. +   q_event_num[EVENT_Q_ID_0] = vif->event_q[EVENT_Q_ID_0].event_cnt;
  5207. +   for(i=EVENT_Q_ID_1, weight = 0; i<EVENT_Q_MAX_ID; i++)
  5208. +   {
  5209. +       event_q_array[i][0] = vif->event_q[i].event_cnt;
  5210. +       event_q_array[i][1] = vif->event_q[i].weight;
  5211. +       if(0 == event_q_array[i][0])
  5212. +           continue;
  5213. +       weight = weight + event_q_array[i][1];
  5214. +   }
  5215. +   for(i=EVENT_Q_ID_1; i<EVENT_Q_MAX_ID; i++)
  5216. +   {
  5217. +       if(0 == weight)
  5218. +       {
  5219. +           q_event_num[i] = 0;
  5220. +           continue;
  5221. +       }
  5222. +       q_event_num[i] = (event_q_array[i][0])*(event_q_array[i][1])/weight;
  5223. +   }
  5224. +   if( (0 == weight) &&  (0 == q_event_num[EVENT_Q_ID_0]) )
  5225. +       return ERROR;
  5226. +   return OK;
  5227. +}
  5228. +
  5229. +static int wlan_core_thread(void *data)
  5230. +{
  5231. +   wlan_vif_t    *vif;
  5232. +   rxfifo_t      *rx_fifo;
  5233. +   txfifo_t      *tx_fifo;
  5234. +   m_event_t     *event_q;
  5235. +   unsigned long  timeout;
  5236. +   unsigned int   i, ret, retry, vif_id, done;
  5237. +   unsigned int   sem_count, q_index, need_tx, tx_cnt, tmp;
  5238. +   short          q_event_num[EVENT_Q_MAX_ID] = {0};
  5239. +   rx_fifo = &(g_wlan.rxfifo);
  5240. +   sema_init(&g_wlan.wlan_core.sem, 0);
  5241. +   printke("%s enter\n", __func__);
  5242. +   up(&(g_wlan.sync.sem));
  5243. +   core_down();
  5244. +   do
  5245. +   {  
  5246. +       retry = done = 0;
  5247. +       sem_count = g_wlan.wlan_core.sem.count ;
  5248. +
  5249. +       ret    = wlan_rx(rx_fifo, 1);
  5250. +       done   = done + ret;
  5251. +      
  5252. +       for(vif_id = NETIF_0_ID, tx_cnt = 0; vif_id < WLAN_MAX_ID; vif_id++)
  5253. +       {
  5254. +           vif     = &(g_wlan.netif[vif_id]);
  5255. +           tx_fifo = &(vif->txfifo);
  5256. +           ret     = wmm_calc(vif, q_event_num);
  5257. +           if(OK  != ret)
  5258. +           {
  5259. +               continue;
  5260. +           }
  5261. +           for( q_index=EVENT_Q_ID_0;  q_index<EVENT_Q_MAX_ID;  q_index++ )
  5262. +           {
  5263. +               event_q      = &(vif->event_q[q_index]);
  5264. +               need_tx      = q_event_num[q_index];
  5265. +               timeout      = jiffies + msecs_to_jiffies(need_tx);
  5266. +               while(need_tx)
  5267. +               {
  5268. +                   tmp      = (need_tx > PKT_AGGR_NUM)?(PKT_AGGR_NUM):(need_tx);
  5269. +                   ret      = wlan_tx(tx_fifo, event_q, tmp);
  5270. +                   tmp      = done;
  5271. +                   if(ret  != tmp)
  5272. +                       retry++;
  5273. +                   done     = done    + ret;
  5274. +                   tx_cnt   = tx_cnt  + ret;
  5275. +                   need_tx  = need_tx - ret;
  5276. +                   if(tx_cnt > PKT_AGGR_NUM)
  5277. +                   {
  5278. +                       ret  = wlan_rx(rx_fifo, 1);
  5279. +                       done = done + ret;
  5280. +                       if(1 == ret)
  5281. +                           tx_cnt -= PKT_AGGR_NUM;
  5282. +                   }
  5283. +                   if ( time_after(jiffies, timeout) )
  5284. +                   {
  5285. +                       retry++;
  5286. +                       break;
  5287. +                   }
  5288. +               }
  5289. +           }
  5290. +       }
  5291. +      
  5292. +       if(g_wlan.sync.exit)
  5293. +           break;
  5294. +       if((0 == done) && (0 == retry) )
  5295. +           done = (  (0 == sem_count)?(1):(sem_count) );
  5296. +       for(i=0; i<done; i++)
  5297. +       {
  5298. +           core_down();
  5299. +       }
  5300. +   }while(!kthread_should_stop());
  5301. +  
  5302. +   printke("%s exit!\n", __func__);
  5303. +   up(&(g_wlan.sync.sem));
  5304. +   return 0;
  5305. +}
  5306. +
  5307. +static int check_valid_chn(int flag, unsigned short status, sdio_chn_t *chn_info)
  5308. +{
  5309. +   int i,index = -1;
  5310. +   if(1 == flag)
  5311. +       status = ( status & (chn_info->bit_map) )
  5312. +   else
  5313. +       status = ( (status & chn_info->bit_map) ^ (chn_info->bit_map) );
  5314. +   if(0 == status)
  5315. +       return -1;
  5316. +   for(i=0; i < chn_info->num; i++)
  5317. +   {
  5318. +       if( status & (0x1 << chn_info->chn[i]) )
  5319. +       {
  5320. +           index = chn_info->chn[i];      
  5321. +           break;
  5322. +       }
  5323. +   }
  5324. +   return index;
  5325. +}
  5326. +
  5327. +static int wlan_trans_thread(void *data)
  5328. +{
  5329. +   int i,vif_id,ret,done, retry,sem_count,send_pkt, index,pkt_num;
  5330. +   rxfifo_t       *rx_fifo;
  5331. +   txfifo_t       *tx_fifo;
  5332. +   wlan_vif_t     *vif;   
  5333. +   sdio_chn_t     *tx_chn;
  5334. +   sdio_chn_t     *rx_chn;
  5335. +   unsigned short  status;
  5336. +   int             tx_retry_cnt;
  5337. +   bool            tx_retry_flag = false;
  5338. +  
  5339. +   sema_init(&g_wlan.wlan_trans.sem, 0);
  5340. +   sdiodev_readchn_init(8, (void *)wlan_rx_chn_isr, 1);
  5341. +   sdiodev_readchn_init(9, (void *)wlan_rx_chn_isr, 1);   
  5342. +   rx_chn       = &(g_wlan.hw.sdio_rx_chn);
  5343. +   tx_chn       = &(g_wlan.hw.sdio_tx_chn);
  5344. +   rx_fifo      = &(g_wlan.rxfifo);
  5345. +   up(&(g_wlan.sync.sem));
  5346. +   printke("%s enter\n", __func__);
  5347. +   trans_down();
  5348. +  
  5349. +   do
  5350. +   {
  5351. +       send_pkt  = retry = done = 0;
  5352. +       sem_count = g_wlan.wlan_trans.sem.count;
  5353. +RX:
  5354. +       if(! gpio_get_value(SDIO_RX_GPIO) )
  5355. +       {
  5356. +#ifdef SDIO_CHN_CHECK 
  5357. +           if(true == rx_chn->gpio_high)
  5358. +           {
  5359. +               rx_chn->gpio_high    = false;
  5360. +               rx_chn->timeout_flag = false;
  5361. +           }
  5362. +#endif
  5363. +           goto TX;
  5364. +       }
  5365. +       else
  5366. +       {
  5367. +#ifdef SDIO_CHN_CHECK
  5368. +           if(false == rx_chn->gpio_high)
  5369. +           {
  5370. +               rx_chn->gpio_high    = true;
  5371. +           }
  5372. +#endif
  5373. +       }
  5374. +       wlan_wakeup();
  5375. +       set_marlin_wakeup(0, 1);
  5376. +       ret   = sdio_chn_status( rx_chn->bit_map, &status);
  5377. +       index = check_valid_chn(1, status, rx_chn);
  5378. +       if(index < 0)
  5379. +       {
  5380. +#ifdef SDIO_CHN_CHECK 
  5381. +           if(false == rx_chn->timeout_flag)
  5382. +           {
  5383. +               rx_chn->timeout_flag = true;
  5384. +               rx_chn->timeout      = jiffies + msecs_to_jiffies(rx_chn->timeout_time);
  5385. +           }
  5386. +           else
  5387. +           {
  5388. +               if ( time_after(jiffies, rx_chn->timeout) )
  5389. +               {
  5390. +                   rx_chn->timeout  = jiffies + msecs_to_jiffies(rx_chn->timeout_time);
  5391. +                   printke("[SDIO_RX_CHN][TIMEOUT][%d]\n", rx_chn->timeout_time);
  5392. +               }
  5393. +           }
  5394. +#endif    
  5395. +           goto TX;
  5396. +       }      
  5397. +#ifdef SDIO_CHN_CHECK
  5398. +       if(true == rx_chn->timeout_flag)
  5399. +       {
  5400. +           rx_chn->timeout_flag = false;
  5401. +       }
  5402. +#endif
  5403. +       if(14 == index)
  5404. +       {
  5405. +           mdbg_sdio_read();
  5406. +           goto TX;
  5407. +       }
  5408. +       ret = rx_fifo_in(index, rx_fifo, hw_rx);
  5409. +       if(OK != ret )
  5410. +       {
  5411. +           retry++;
  5412. +           goto TX;
  5413. +       }
  5414. +       core_up();
  5415. +
  5416. +TX:   
  5417. +       for(vif_id = NETIF_0_ID; vif_id < WLAN_MAX_ID; vif_id++ )
  5418. +       {
  5419. +           vif     = &(g_wlan.netif[vif_id]);
  5420. +           tx_fifo = &(vif->txfifo);
  5421. +           ret = tx_fifo_used(tx_fifo);
  5422. +           if(0 == ret)
  5423. +               continue;
  5424. +           wlan_wakeup();
  5425. +           set_marlin_wakeup(0, 1);
  5426. +           ret = sdio_chn_status(tx_chn->bit_map, &status);
  5427. +           index = check_valid_chn(0, status, tx_chn);
  5428. +           if(index < 0)
  5429. +           {
  5430. +#ifdef SDIO_CHN_CHECK
  5431. +               if(false == tx_chn->timeout_flag)
  5432. +               {
  5433. +                   tx_chn->timeout_flag = true;
  5434. +                   tx_chn->timeout      = jiffies + msecs_to_jiffies(tx_chn->timeout_time);
  5435. +               }
  5436. +               else
  5437. +               {
  5438. +                   if ( time_after(jiffies, tx_chn->timeout) )
  5439. +                   {
  5440. +                       tx_chn->timeout      = jiffies + msecs_to_jiffies(tx_chn->timeout_time);
  5441. +                       printke("[SDIO_TX_CHN][TIMEOUT][%d]\n", tx_chn->timeout_time);
  5442. +                   }
  5443. +               }
  5444. +#endif            
  5445. +               retry++;
  5446. +               continue;
  5447. +           }
  5448. +#ifdef SDIO_CHN_CHECK
  5449. +           if(true == tx_chn->timeout_flag)
  5450. +           {
  5451. +               tx_chn->timeout_flag = false;
  5452. +           }
  5453. +#endif
  5454. +           ret    = tx_fifo_out(vif_id, index, tx_fifo, hw_tx, &send_pkt);
  5455. +           if(OK != ret)
  5456. +           {
  5457. +               if(HW_WRITE_ERROR == ret)
  5458. +                   retry++;
  5459. +               continue;
  5460. +           }
  5461. +           done = done + send_pkt;
  5462. +       }
  5463. +      
  5464. +       if(g_wlan.sync.exit)
  5465. +           break;
  5466. +       wlan_sleep();
  5467. +      
  5468. +       if(gpio_get_value(SDIO_RX_GPIO))
  5469. +       {
  5470. +           if(g_wlan.wlan_trans.sem.count - done <= 1)
  5471. +           {
  5472. +               done = (g_wlan.wlan_trans.sem.count > 0)?(g_wlan.wlan_trans.sem.count-1):(0);
  5473. +           }
  5474. +       }
  5475. +       else
  5476. +       {
  5477. +           if( (0 == done) && (0 == retry) )
  5478. +               done = (  (0 == sem_count)?(1):(sem_count) );
  5479. +       }
  5480. +       for(i=0; i<done; i++)
  5481. +       {
  5482. +           trans_down();
  5483. +       }
  5484. +   }while(!kthread_should_stop());
  5485. +   sdiodev_readchn_uninit(8);
  5486. +   sdiodev_readchn_uninit(9);
  5487. +   mdbg_sdio_read();
  5488. +   del_timer_sync(&(g_wlan.hw.wakeup_timer));
  5489. +   printke("%s exit\n", __func__);
  5490. +   up(&(g_wlan.sync.sem));
  5491. +   return OK;
  5492. +}
  5493. +
  5494. +static int wlan_tx_buf_alloc(wlan_vif_t *vif)
  5495. +{
  5496. +   m_event_conf_t q_conf = {0};
  5497. +   txfifo_conf_t  fifo_conf  = {0};
  5498. +   int  ret,q_id;
  5499. +   q_conf.event_size  = sizeof(tx_msg_t);
  5500. +   q_conf.max_events  = 5;
  5501. +   q_conf.highThres   = 100;
  5502. +   q_conf.lowThres    = 0;
  5503. +   q_conf.weight      = 100;
  5504. +   ret = event_q_init(&(vif->event_q[EVENT_Q_ID_0]), &q_conf);
  5505. +   if(ERROR == ret)
  5506. +       return ERROR;
  5507. +
  5508. +   q_conf.max_events  = 150;
  5509. +   q_conf.highThres   = 130;
  5510. +   q_conf.lowThres    = 10;
  5511. +   for(q_id = EVENT_Q_ID_1; q_id < EVENT_Q_MAX_ID; q_id++)
  5512. +   {
  5513. +       ret = event_q_init(&(vif->event_q[q_id]), &q_conf);
  5514. +       if(ERROR == ret)
  5515. +           return ERROR;
  5516. +   }
  5517. +   vif->event_q[EVENT_Q_ID_1].weight = 40;
  5518. +   vif->event_q[EVENT_Q_ID_2].weight = 30;
  5519. +   vif->event_q[EVENT_Q_ID_3].weight = 20;
  5520. +   vif->event_q[EVENT_Q_ID_4].weight = 10;
  5521. +      
  5522. +   fifo_conf.cp2_txRam   = HW_TX_SIZE - 64;
  5523. +   fifo_conf.max_msg_num = PKT_AGGR_NUM;
  5524. +   fifo_conf.size        = 1024*256;
  5525. +   ret =  tx_fifo_alloc(&(vif->txfifo), &fifo_conf);
  5526. +   if(ERROR == ret)
  5527. +       return ERROR;
  5528. +   return OK;
  5529. +}
  5530. +
  5531. +static int wlan_tx_buf_free(wlan_vif_t *vif)
  5532. +{
  5533. +   int         q_id, num, i;
  5534. +   m_event_t  *event_q;
  5535. +   tx_msg_t   *event;
  5536. +   for(q_id=EVENT_Q_ID_0; q_id < EVENT_Q_MAX_ID; q_id++)
  5537. +   {
  5538. +       event_q = &(vif->event_q[q_id]);
  5539. +       num = event_q->event_cnt;
  5540. +       for(i=0; i < num; i++)
  5541. +       {
  5542. +           event = (tx_msg_t *)get_event(event_q);
  5543. +           if(NULL == event)
  5544. +               break;
  5545. +           if( HOST_SC2331_CMD == event->hdr.type)
  5546. +           {
  5547. +               if((event->slice[0].len > 0) &&(NULL != event->slice[0].data))
  5548. +                   kfree(event->slice[0].data);
  5549. +           }
  5550. +           else if(HOST_SC2331_PKT == event->hdr.type)
  5551. +           {
  5552. +               if((NULL != event->p))
  5553. +                   dev_kfree_skb((struct sk_buff  *)(event->p));
  5554. +           }
  5555. +           else
  5556. +           {}
  5557. +           memset((unsigned char *)event,  0,  sizeof(tx_msg_t) );
  5558. +           free_event((void *)event, event_q);
  5559. +       }
  5560. +       event_q_deinit(event_q);
  5561. +   }
  5562. +   tx_fifo_free(&(vif->txfifo));
  5563. +   return OK;
  5564. +}
  5565. +
  5566. +static int wlan_rx_buf_alloc(void)
  5567. +{
  5568. +   int ret;
  5569. +   rxfifo_t *rx_buf = &(g_wlan.rxfifo);
  5570. +   ret = rx_fifo_alloc(rx_buf);
  5571. +   return ret;
  5572. +}
  5573. +
  5574. +static int wlan_rx_buf_free(void )
  5575. +{
  5576. +   int ret;
  5577. +   rxfifo_t *rx_buf = &(g_wlan.rxfifo);
  5578. +   ret = rx_fifo_free(rx_buf);
  5579. +   return ret;
  5580. +}
  5581. +
  5582. +static int wlan_hw_init(hw_info_t *hw)
  5583. +{
  5584. +   memset(hw, 0, sizeof(hw_info_t) );
  5585. +  
  5586. +   hw->sdio_tx_chn.num          = 3;
  5587. +   hw->sdio_tx_chn.chn[0]       = 0;
  5588. +   hw->sdio_tx_chn.chn[1]       = 1;
  5589. +   hw->sdio_tx_chn.chn[2]       = 2;
  5590. +   hw->sdio_tx_chn.bit_map      = 0x0007;
  5591. +   hw->sdio_tx_chn.timeout_time = 3000;
  5592. +   hw->sdio_tx_chn.timeout_flag = false;
  5593. +
  5594. +   hw->sdio_rx_chn.num          = 3;
  5595. +   hw->sdio_rx_chn.chn[0]       = 8;
  5596. +   hw->sdio_rx_chn.chn[1]       = 9;
  5597. +   hw->sdio_rx_chn.chn[2]       = 14;
  5598. +   hw->sdio_rx_chn.bit_map      = 0x4300;
  5599. +   hw->sdio_rx_chn.gpio_high    = false;  
  5600. +   hw->sdio_rx_chn.timeout_time = 3000;
  5601. +   hw->sdio_rx_chn.timeout_flag = false;
  5602. +
  5603. +   printke("[SDIO_TX_CHN][0x%x][0x%x]\n", hw->sdio_tx_chn.bit_map, HW_TX_SIZE);
  5604. +   printke("[SDIO_RX_CHN][0x%x][0x%x]\n", hw->sdio_rx_chn.bit_map, HW_RX_SIZE);
  5605. +  
  5606. +   hw->wakeup = 0;
  5607. +   spin_lock_init(&(hw->sdio_rx_chn.lock));
  5608. +   wake_lock_init(&g_wlan.hw.wlan_lock, WAKE_LOCK_SUSPEND, "wlan_sc2331_lock");
  5609. +   init_timer(&g_wlan.hw.wakeup_timer);
  5610. +   g_wlan.hw.wakeup_timer.function = wakeup_timer_func;
  5611. +   g_wlan.hw.wakeup_time  = 2000;
  5612. +   return OK;
  5613. +}
  5614. +static int wlan_inetaddr_event(struct notifier_block *this,
  5615. +                 unsigned long event, void *ptr)
  5616. +{
  5617. +   unsigned  char      vif_id;
  5618. +   wlan_vif_t          *vif;
  5619. +   struct net_device   *dev;
  5620. +   struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
  5621. +
  5622. +   printkd("inetaddr callback is comming in !\n");
  5623. +
  5624. +   dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
  5625. +
  5626. +   if((dev != (id_to_vif(0)->ndev)) && (dev != (id_to_vif(1)->ndev)))
  5627. +   {
  5628. +       printkd("dev id not equal to 0 or 1!\n");
  5629. +       goto done;
  5630. +   }  
  5631. +
  5632. +   if (dev == NULL)
  5633. +       goto done;
  5634. +   printkd(" inetaddr dev not equal to null !\n");
  5635. +
  5636. +   vif = ndev_to_vif(dev);
  5637. +   vif_id = vif->id;
  5638. +
  5639. +   if (!vif)
  5640. +       goto done;
  5641. +   printkd("inetaddr vif not equal to null !\n");
  5642. +
  5643. +   switch (event) {
  5644. +   case NETDEV_UP:
  5645. +   printkd("inetaddr UP event is comming in !\n");
  5646. +       wlan_cmd_get_ip(vif_id, (u8 *) & ifa->ifa_address);
  5647. +       break;
  5648. +   case NETDEV_DOWN:
  5649. +   printkd("inetaddr DOWN event is comming in  !\n");
  5650. +       break;
  5651. +   default:
  5652. +   printkd("inetaddr defaut is comming in !\n");
  5653. +       break;
  5654. +   }
  5655. +
  5656. +done:
  5657. +   return NOTIFY_DONE;
  5658. +}
  5659. +
  5660. +static struct notifier_block itm_inetaddr_cb = {
  5661. +   .notifier_call = wlan_inetaddr_event,
  5662. +};
  5663. +
  5664. +static ssize_t wlan_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos)
  5665. +{
  5666. +   int cmd, value;
  5667. +   char kbuf[32] = {0};
  5668. +   if (copy_from_user(kbuf, buffer, ( (count <= 32)?(count):(32) ) )  )
  5669. +       return -EFAULT;
  5670. +   sscanf(kbuf, "%d %d\n", &cmd, &value);
  5671. +  
  5672. +   printkd("[%s][%d][%d]\n", __func__,cmd, value);
  5673. +   switch (cmd)
  5674. +   {
  5675. +   case 1:
  5676. +       SET_BIT(g_dbg, value);
  5677. +       break;
  5678. +   case 2:
  5679. +       CLEAR_BIT(g_dbg, value);
  5680. +       break;
  5681. +   case 3:
  5682. +       wlan_cmd_mac_open(NETIF_0_ID, value, &(g_wlan.netif[NETIF_0_ID].ndev->dev_addr[0] ) );
  5683. +       break;
  5684. +   case 4:
  5685. +       wlan_cmd_mac_open(NETIF_1_ID, value, &(g_wlan.netif[NETIF_1_ID].ndev->dev_addr[0] ) );
  5686. +       break;
  5687. +   default:
  5688. +       break;
  5689. +   }
  5690. +   return count;
  5691. +}
  5692. +
  5693. +static const struct file_operations wlan_proc_fops =
  5694. +{
  5695. +   .owner      = THIS_MODULE,
  5696. +   .write      = wlan_proc_write,
  5697. +};
  5698. +
  5699. +static const struct file_operations lte_concur_proc_fops =
  5700. +{
  5701. +   .owner      = THIS_MODULE,
  5702. +   .unlocked_ioctl  = lte_concur_proc_ioctl,
  5703. +#ifdef CONFIG_COMPAT
  5704. +   .compat_ioctl = compat_lte_concur_proc_ioctl,
  5705. +#endif
  5706. +   .open       = lte_concur_proc_open,
  5707. +   .release    = lte_concur_proc_release,
  5708. +};
  5709. +
  5710. +int wlan_module_init(struct device *dev)
  5711. +{
  5712. +   int ret;
  5713. +  
  5714. +   printke("[%s] [ version:0x21 ] [ time(%s %s) ]\n", __func__, __DATE__, __TIME__);
  5715. +   if(NULL == dev)
  5716. +       return -EPERM;
  5717. +   ret = get_sdiohal_status();
  5718. +   if(1 != ret)
  5719. +   {
  5720. +       printke("######## %s sdio is not ready  ##########\n", __func__);
  5721. +       return -EPERM;
  5722. +   }
  5723. +   else
  5724. +   {
  5725. +       printke("sdio is ready !!!\n");
  5726. +   }
  5727. +   //marlin_pa_enable(true);
  5728. +
  5729. +
  5730. +   memset((unsigned char *)(&g_wlan), 0, sizeof(wlan_info_t));
  5731. +   g_wlan.dev = dev;
  5732. +   g_wlan.netif[NETIF_0_ID].id= NETIF_0_ID;
  5733. +   g_wlan.netif[NETIF_1_ID].id= NETIF_1_ID;
  5734. +   g_wlan.sync.exit = 0;
  5735. +   sema_init(&g_wlan.sync.sem, 0);
  5736. +   wlan_hw_init(&(g_wlan.hw));
  5737. +
  5738. +   ret = wlan_tx_buf_alloc(&(g_wlan.netif[NETIF_0_ID]));
  5739. +   if(OK != ret)
  5740. +       return -EPERM;
  5741. +   ret = wlan_tx_buf_alloc(&(g_wlan.netif[NETIF_1_ID]));
  5742. +   if(OK != ret)
  5743. +       return -EPERM;
  5744. +   ret = wlan_rx_buf_alloc();
  5745. +   if(OK != ret)
  5746. +       return -EPERM;
  5747. +  
  5748. +   wlan_cmd_init();
  5749. +  
  5750. +   g_wlan.wlan_core.task  = kthread_create(wlan_core_thread, (void *)(dev), "wlan_core")
  5751. +   if(NULL != g_wlan.wlan_core.task)
  5752. +   {      
  5753. +       wake_up_process(g_wlan.wlan_core.task);
  5754. +   }
  5755. +   down(&(g_wlan.sync.sem));
  5756. +  
  5757. +   g_wlan.wlan_trans.task = kthread_create(wlan_trans_thread, (void *)(dev), "wlan_trans");   
  5758. +   if(NULL != g_wlan.wlan_trans.task)
  5759. +   {      
  5760. +       wake_up_process(g_wlan.wlan_trans.task);
  5761. +   }
  5762. +   down(&(g_wlan.sync.sem));
  5763. +  
  5764. +   ret = wlan_wiphy_new(&(g_wlan));
  5765. +   if(OK != ret)
  5766. +       return -EPERM;
  5767. +   ret = wlan_vif_init(&(g_wlan.netif[NETIF_0_ID]), NL80211_IFTYPE_ADHOC,       "wlan0",    (void *)(&wlan_ops) );
  5768. +   if(OK != ret)
  5769. +       return -EPERM;
  5770. +   ret = wlan_vif_init(&(g_wlan.netif[NETIF_1_ID]), NL80211_IFTYPE_P2P_DEVICE,  "p2p0",     (void *)(&wlan_ops) );
  5771. +   if(OK != ret)
  5772. +       return -EPERM;
  5773. +   wlan_nl_init();
  5774. +  
  5775. +   g_wlan.hw.early_suspend.suspend  = wlan_early_suspend;
  5776. +   g_wlan.hw.early_suspend.resume   = wlan_late_resume;
  5777. +   g_wlan.hw.early_suspend.level    = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1;   
  5778. +   register_early_suspend(&g_wlan.hw.early_suspend);
  5779. +  
  5780. +   ret = register_inetaddr_notifier(&itm_inetaddr_cb);
  5781. +   if (ret) {
  5782. +       printke("Couldn't register inetaddr notifier \n");
  5783. +   }
  5784. +   if (!proc_create("wlan", 0666, NULL, &wlan_proc_fops))
  5785. +   {
  5786. +       printke("Couldn't create the /proc/wlan \n");
  5787. +   }
  5788. +   if (!proc_create("lte_concur", 0666, NULL, &lte_concur_proc_fops))
  5789. +   {
  5790. +       printke("Couldn't create the /proc/lte_concur \n");
  5791. +   }  
  5792. +   g_dbg = 0x0;
  5793. +   SET_BIT(g_dbg,1);
  5794. +   printke("%s ok!\n", __func__);
  5795. +   return OK;
  5796. +}
  5797. +EXPORT_SYMBOL_GPL(wlan_module_init);
  5798. +
  5799. +int wlan_module_exit(struct device *dev)
  5800. +{
  5801. +   printke("%s enter\n", __func__);
  5802. +   unregister_inetaddr_notifier(&itm_inetaddr_cb);
  5803. +   //marlin_pa_enable(false);
  5804. +   if(ITM_NONE_MODE != g_wlan.netif[NETIF_0_ID].mode)
  5805. +       wlan_cmd_mac_close(NETIF_0_ID, g_wlan.netif[NETIF_0_ID].mode);
  5806. +   if(ITM_NONE_MODE != g_wlan.netif[NETIF_1_ID].mode)
  5807. +       wlan_cmd_mac_close(NETIF_1_ID, g_wlan.netif[NETIF_1_ID].mode);
  5808. +   g_wlan.sync.exit = 1;
  5809. +   core_up();
  5810. +   down(&(g_wlan.sync.sem));
  5811. +   trans_up();
  5812. +   down(&(g_wlan.sync.sem));
  5813. +
  5814. +   wlan_vif_free(&(g_wlan.netif[NETIF_0_ID]));
  5815. +   wlan_vif_free(&(g_wlan.netif[NETIF_1_ID]));
  5816. +   wlan_wiphy_free(&g_wlan);
  5817. +   wlan_cmd_deinit();
  5818. +   wlan_tx_buf_free(&(g_wlan.netif[NETIF_0_ID]));
  5819. +   wlan_tx_buf_free(&(g_wlan.netif[NETIF_1_ID]));
  5820. +   wlan_rx_buf_free();
  5821. +   wlan_nl_deinit();
  5822. +
  5823. +   remove_proc_entry("wlan", NULL);
  5824. +   unregister_early_suspend(&g_wlan.hw.early_suspend);
  5825. +   wake_lock_destroy(&g_wlan.hw.wlan_lock);
  5826. +   printke("%s ok!\n", __func__);
  5827. +   return OK;
  5828. +}
  5829. +EXPORT_SYMBOL_GPL(wlan_module_exit);
  5830. +
  5831. +static int  sprd_wlan_probe(struct platform_device *pdev)
  5832. +{
  5833. +   return wlan_module_init(&(pdev->dev));
  5834. +}
  5835. +
  5836. +static int  sprd_wlan_remove(struct platform_device *pdev)
  5837. +{
  5838. +   return wlan_module_exit(&(pdev->dev));
  5839. +}
  5840. +
  5841. +#define DEVICE_NAME "sc2331"
  5842. +static struct platform_device *sprd_wlan_device;
  5843. +static struct platform_driver  sprd_wlan_driver =
  5844. +{
  5845. +   .probe =   sprd_wlan_probe,
  5846. +   .remove =  sprd_wlan_remove,
  5847. +   .driver =
  5848. +   {
  5849. +       .owner = THIS_MODULE,
  5850. +       .name = DEVICE_NAME,
  5851. +   },
  5852. +};
  5853. +static int  sprd_wlan_init(void)
  5854. +{
  5855. +   sprd_wlan_device = platform_device_register_simple(DEVICE_NAME, 0, NULL, 0);
  5856. +   if (IS_ERR(sprd_wlan_device))
  5857. +       return PTR_ERR(sprd_wlan_device);
  5858. +   return platform_driver_register(&(sprd_wlan_driver));
  5859. +}
  5860. +
  5861. +static void  sprd_wlan_exit(void)
  5862. +{
  5863. +   platform_driver_unregister(&sprd_wlan_driver);
  5864. +   platform_device_unregister(sprd_wlan_device);
  5865. +   sprd_wlan_device = NULL;
  5866. +}
  5867. +
  5868. +module_init(sprd_wlan_init);
  5869. +module_exit(sprd_wlan_exit);
  5870. +MODULE_DESCRIPTION("SPRD sc2331 Wireless Network Adapter");
  5871. +MODULE_AUTHOR("jinglong.chen");
  5872. +MODULE_LICENSE("GPL");
  5873. +MODULE_VERSION("1.0");
  5874. +
  5875. +
  5876. diff --git a/drivers/net/wireless/sprdwl/wlan_event_q.c b/drivers/net/wireless/sprdwl/wlan_event_q.c
  5877. new file mode 100644
  5878. index 0000000..36baa47
  5879. --- /dev/null
  5880. +++ b/drivers/net/wireless/sprdwl/wlan_event_q.c
  5881. @@ -0,0 +1,123 @@
  5882. +/*
  5883. + * Copyright (C) 2014 Spreadtrum Communications Inc.
  5884. + *
  5885. + * Authors:<jinglong.chen@spreadtrum.com>
  5886. + * Owner:
  5887. + *      jinglong.chen
  5888. + *
  5889. + * This software is licensed under the terms of the GNU General Public
  5890. + * License version 2, as published by the Free Software Foundation, and
  5891. + * may be copied, distributed, and modified under those terms.
  5892. + *
  5893. + * This program is distributed in the hope that it will be useful,
  5894. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5895. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  5896. + * GNU General Public License for more details.
  5897. + */
  5898. +
  5899. +#include <linux/irqflags.h>
  5900. +#include <linux/spinlock.h>
  5901. +#include<linux/slab.h>
  5902. +#include "wlan_common.h"
  5903. +#include "wlan_event_q.h"
  5904. +
  5905. +static void update_buff_status(unsigned char *buff, unsigned short index, unsigned char status)
  5906. +{
  5907. +   unsigned char offset = 0;
  5908. +   offset = (index & 0x3) << 1;
  5909. +   buff  += (index >> 2);
  5910. +   *buff = (status << offset) | (*buff & (~(0x3 << offset)));
  5911. +}
  5912. +static unsigned char check_buff_status(unsigned char *buff, unsigned short index)
  5913. +{
  5914. +   unsigned char offset = 0;
  5915. +   unsigned char status = 0;
  5916. +   offset = (index & 0x3) << 1;
  5917. +   buff  += (index >> 2);
  5918. +   status = (*buff >> offset) & 0x3;
  5919. +   return status;
  5920. +}
  5921. +
  5922. +void  *alloc_event(m_event_t *mEventQ)
  5923. +{
  5924. +   unsigned short          index            = 0;
  5925. +   unsigned char          *free_event_buff = 0;
  5926. +   if(mEventQ->event_cnt == mEventQ->max_events)
  5927. +   {
  5928. +       return NULL;
  5929. +   }
  5930. +   spin_lock_bh( &(mEventQ->spinlock) );
  5931. +   index = INCR_RING_BUFF_INDX(mEventQ->tail_index, mEventQ->max_events);
  5932. +   if(check_buff_status(mEventQ->buf_status, index) == EVENT_BUFFER_FREE)
  5933. +   {
  5934. +       mEventQ->tail_index = index;
  5935. +       update_buff_status(mEventQ->buf_status, index, EVENT_BUFFER_ALLOC);
  5936. +       free_event_buff = (mEventQ->event_buf + (index * mEventQ->event_size));
  5937. +   }
  5938. +   spin_unlock_bh(&(mEventQ->spinlock));
  5939. +   return free_event_buff;
  5940. +}
  5941. +
  5942. +void post_event(unsigned char *event, m_event_t *mEventQ)
  5943. +{
  5944. +   unsigned short          index     = 0;
  5945. +   spin_lock_bh( &(mEventQ->spinlock) );
  5946. +   index = ((size_t)event - (size_t)mEventQ->event_buf) / mEventQ->event_size;
  5947. +   update_buff_status(mEventQ->buf_status, index, EVENT_BUFFER_VALID);
  5948. +   mEventQ->event_cnt++;
  5949. +   spin_unlock_bh(&(mEventQ->spinlock));
  5950. +}
  5951. +
  5952. +unsigned char *get_event(m_event_t *mEventQ)
  5953. +{
  5954. +   unsigned char status      = 0;
  5955. +   unsigned char *head_event = NULL;
  5956. +   if(mEventQ->event_cnt == 0)
  5957. +       return NULL;
  5958. +   status = check_buff_status(mEventQ->buf_status, mEventQ->head_index);
  5959. +   if(status == EVENT_BUFFER_VALID)
  5960. +   {
  5961. +       head_event = (mEventQ->event_buf) + (mEventQ->head_index * mEventQ->event_size);
  5962. +   }
  5963. +   return head_event;
  5964. +}
  5965. +
  5966. +void free_event(void *event, m_event_t *mEventQ)
  5967. +{
  5968. +   spin_lock_bh( &(mEventQ->spinlock) );
  5969. +   update_buff_status(mEventQ->buf_status, mEventQ->head_index, EVENT_BUFFER_FREE);
  5970. +   mEventQ->head_index = INCR_RING_BUFF_INDX(mEventQ->head_index, mEventQ->max_events);
  5971. +   mEventQ->event_cnt--;
  5972. +   spin_unlock_bh(&(mEventQ->spinlock));
  5973. +}
  5974. +
  5975. +int event_q_init(m_event_t *mEventQ, m_event_conf_t *conf)
  5976. +{
  5977. +   mEventQ->event_size = conf->event_size;
  5978. +   mEventQ->max_events = conf->max_events;
  5979. +   mEventQ->tail_index = conf->max_events - 1;
  5980. +   mEventQ->head_index = 0;
  5981. +   mEventQ->highThres  = conf->highThres;
  5982. +   mEventQ->lowThres   = conf->lowThres;
  5983. +   mEventQ->weight     = conf->weight;
  5984. +
  5985. +   mEventQ->buf_status = kmalloc(   EVENT_TOTAL_MEM_SIZE((mEventQ->max_events), (mEventQ->event_size)),   GFP_KERNEL   );
  5986. +   if(NULL == mEventQ->buf_status)
  5987. +   {
  5988. +       ASSERT();
  5989. +       return ERROR;
  5990. +   }
  5991. +   memset( mEventQ->buf_status,   0,   EVENT_TOTAL_MEM_SIZE((mEventQ->max_events), (mEventQ->event_size)) );
  5992. +   mEventQ->event_buf  = (unsigned char *)(WORD_ALIGN((size_t)(mEventQ->buf_status  +  EVENT_STATUS_SIZE(mEventQ->max_events) )));
  5993. +   spin_lock_init( &(mEventQ->spinlock) );
  5994. +   return OK;
  5995. +}
  5996. +
  5997. +int event_q_deinit(m_event_t *mEventQ)
  5998. +{
  5999. +   if(NULL != mEventQ->buf_status)
  6000. +       kfree(mEventQ->buf_status);
  6001. +   memset( (unsigned char *)mEventQ, 0, sizeof(m_event_t) );
  6002. +   return OK;
  6003. +}
  6004. +
  6005. diff --git a/drivers/net/wireless/sprdwl/wlan_event_q.h b/drivers/net/wireless/sprdwl/wlan_event_q.h
  6006. new file mode 100644
  6007. index 0000000..7202352
  6008. --- /dev/null
  6009. +++ b/drivers/net/wireless/sprdwl/wlan_event_q.h
  6010. @@ -0,0 +1,49 @@
  6011. +#ifndef __EVENT_MANAGER_H__
  6012. +#define __EVENT_MANAGER_H__
  6013. +#include <linux/spinlock.h>
  6014. +
  6015. +#define WORD_ALIGN(val) (((val) & 0x03) ? ((val) + 4 - ((val) & 0x03)) : (val))
  6016. +
  6017. +#define MAX_WORD_ALIGNMENT_BUFFER   (3)
  6018. +#define EVENT_TOTAL_MEM_SIZE( num, size  )     (  (WORD_ALIGN((num >> 2) + 1))  +   ( (num)*(size) )   +  (MAX_WORD_ALIGNMENT_BUFFER)  )
  6019. +#define EVENT_STATUS_SIZE(num)                           ( WORD_ALIGN((num >> 2) + 1)  )  
  6020. +
  6021. +typedef enum
  6022. +{
  6023. +   EVENT_BUFFER_FREE  = 0,
  6024. +   EVENT_BUFFER_ALLOC = 1,
  6025. +   EVENT_BUFFER_VALID = 2,
  6026. +} EVENT_BUFFER_STATUS_T;
  6027. +
  6028. +typedef struct
  6029. +{
  6030. +   unsigned char  *event_buf;   /* Base address of event buffer array               */
  6031. +   unsigned char  *buf_status;  /* Base address of buffer status array              */
  6032. +   unsigned short  event_size;  /* Size of the event message structure              */
  6033. +   unsigned short  max_events;  /* Number of events can be accomadated in the queue */
  6034. +   unsigned short  event_cnt;   /* Current number of valid events                   */
  6035. +   unsigned short  tail_index;  /* Last index inserted                              */
  6036. +   unsigned short  head_index;  /* Next index to be read                            */
  6037. +   unsigned short  highThres;
  6038. +   unsigned short  lowThres;
  6039. +   unsigned short  weight;
  6040. +   spinlock_t      spinlock;
  6041. +}m_event_t;
  6042. +
  6043. +typedef struct
  6044. +{
  6045. +   unsigned short  event_size;
  6046. +   unsigned short  max_events;
  6047. +   unsigned short  highThres;
  6048. +   unsigned short  lowThres;
  6049. +   unsigned short  weight;
  6050. +}m_event_conf_t;
  6051. +
  6052. +extern void  *alloc_event(m_event_t *mEventQ);
  6053. +extern void post_event(unsigned char *event, m_event_t *mEventQ);
  6054. +extern unsigned char *get_event(m_event_t *mEventQ);
  6055. +extern void free_event(void *event, m_event_t *mEventQ);
  6056. +extern int event_q_init(m_event_t *mEventQ, m_event_conf_t *conf);
  6057. +extern int event_q_deinit(m_event_t *mEventQ);
  6058. +#endif
  6059. +
  6060. diff --git a/drivers/net/wireless/sprdwl/wlan_fifo.c b/drivers/net/wireless/sprdwl/wlan_fifo.c
  6061. new file mode 100644
  6062. index 0000000..0b42f52
  6063. --- /dev/null
  6064. +++ b/drivers/net/wireless/sprdwl/wlan_fifo.c
  6065. @@ -0,0 +1,326 @@
  6066. +/*
  6067. + * Copyright (C) 2014 Spreadtrum Communications Inc.
  6068. + *
  6069. + * Authors:<jinglong.chen@spreadtrum.com>
  6070. + * Owner:
  6071. + *      jinglong.chen
  6072. + *
  6073. + * This software is licensed under the terms of the GNU General Public
  6074. + * License version 2, as published by the Free Software Foundation, and
  6075. + * may be copied, distributed, and modified under those terms.
  6076. + *
  6077. + * This program is distributed in the hope that it will be useful,
  6078. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6079. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  6080. + * GNU General Public License for more details.
  6081. + */
  6082. +
  6083. +#include<linux/slab.h>
  6084. +#include "wlan_common.h"
  6085. +#include "wlan_fifo.h"
  6086. +
  6087. +extern unsigned char *wifi_256k_alloc(void);
  6088. +extern int wifi_256k_free(unsigned char *mem);
  6089. +
  6090. +unsigned char *fifo_mem_alloc(unsigned int byte)
  6091. +{
  6092. +   unsigned char *mem = NULL;
  6093. +   if(byte > 16*1024)
  6094. +   {
  6095. +       mem = wifi_256k_alloc();
  6096. +   }
  6097. +   else
  6098. +   {
  6099. +       mem = kmalloc(byte, GFP_KERNEL);
  6100. +       printkd("kmalloc(%d):%p\n",  byte, mem);
  6101. +   }
  6102. +   if(NULL == mem)
  6103. +       printke("[%s][NULL]\n", __func__);
  6104. +   return mem;
  6105. +}
  6106. +
  6107. +int fifo_mem_free(unsigned char *mem, unsigned int byte)
  6108. +{
  6109. +   if(NULL == mem)
  6110. +       return ERROR;
  6111. +   if(byte > 16*1024)
  6112. +   {
  6113. +       wifi_256k_free(mem);
  6114. +   }
  6115. +   else
  6116. +   {
  6117. +       printkd("kfree:%p\n", mem);
  6118. +       kfree(mem);
  6119. +   }
  6120. +   return OK;
  6121. +}
  6122. +
  6123. +int tx_fifo_in(txfifo_t *fifo,  tx_msg_t *msg )
  6124. +{
  6125. +   int ret;
  6126. +   unsigned int unitLen;
  6127. +   unsigned char *p;
  6128. +   t_msg_hdr_t *hdr = &(msg->hdr);
  6129. +   unitLen = TX_MSG_UNIT_LEN(hdr);
  6130. +   if(fifo->WT >= fifo->RD)
  6131. +   {
  6132. +       if( unitLen > (fifo->size - fifo->WT) )
  6133. +       {
  6134. +           if( (unitLen+sizeof(tx_big_hdr_t)) > fifo->RD  )
  6135. +           {
  6136. +               ret = TX_FIFO_FULL;
  6137. +               goto out;
  6138. +           }
  6139. +           spin_lock( &(fifo->lock) );
  6140. +           fifo->LASTWT = fifo->WT;
  6141. +           spin_unlock( &(fifo->lock) );
  6142. +           fifo->WT = 0;
  6143. +       }
  6144. +   }
  6145. +   else
  6146. +   {
  6147. +       if( (unitLen + sizeof(tx_big_hdr_t) > (fifo->RD - fifo->WT) ))
  6148. +       {
  6149. +           ret = TX_FIFO_FULL;
  6150. +           goto out;
  6151. +       }
  6152. +   }  
  6153. +
  6154. +   hdr = (t_msg_hdr_t *)(fifo->mem + fifo->WT);
  6155. +   memcpy((unsigned char *)hdr,  (unsigned char *)(&(msg->hdr)),  sizeof(t_msg_hdr_t) );
  6156. +   p = (unsigned char *)hdr + TX_MSG_HEAD_FILED(hdr);
  6157. +   if(NULL != msg->slice[0].data)
  6158. +   {
  6159. +       memcpy(p, (unsigned char *)(msg->slice[0].data),  msg->hdr.len );
  6160. +   }
  6161. +   fifo->WT = fifo->WT + unitLen;
  6162. +   fifo->wt_cnt++;
  6163. +   if(HOST_SC2331_CMD == hdr->type)
  6164. +   {
  6165. +       printkp("[CMD_IN][%s]\n", get_cmd_name(hdr->subtype) );
  6166. +   }
  6167. +   ret = OK;
  6168. +out:
  6169. +   return ret;
  6170. +}
  6171. +
  6172. +int tx_fifo_out(const unsigned char netif_id,
  6173. +               const unsigned chn, txfifo_t *fifo,
  6174. +               P_FUNC_1 pfunc, unsigned int *count)
  6175. +{
  6176. +   unsigned int len,num;
  6177. +   unsigned char *readTo, *readFrom, *readMax;
  6178. +   t_msg_hdr_t *hdr;
  6179. +   tx_big_hdr_t  *big_hdr;
  6180. +   int ret = ERROR;
  6181. +  
  6182. +restart:
  6183. +   if(fifo->RD == fifo->WT )
  6184. +   {
  6185. +       readMax = fifo->mem + fifo->LASTWT;
  6186. +   }
  6187. +   else if(fifo->WT < fifo->RD)
  6188. +   {
  6189. +       if(fifo->RD == fifo->LASTWT)
  6190. +       {
  6191. +           fifo->RD = 0;
  6192. +           spin_lock( &(fifo->lock) );
  6193. +           fifo->LASTWT = -1;
  6194. +           spin_unlock( &(fifo->lock) );
  6195. +           goto restart;
  6196. +       }
  6197. +       else
  6198. +       {
  6199. +           readMax = fifo->mem + fifo->LASTWT;
  6200. +       }
  6201. +   }
  6202. +   else
  6203. +   {
  6204. +       readMax = fifo->mem + fifo->WT;
  6205. +   }
  6206. +
  6207. +   readTo = fifo->mem + fifo->RD;
  6208. +   readFrom = readTo - sizeof(tx_big_hdr_t);
  6209. +   big_hdr = (tx_big_hdr_t  *)(readFrom);
  6210. +  
  6211. +   memset((unsigned char *)big_hdr, 0, sizeof(tx_big_hdr_t) );
  6212. +   big_hdr->mode = netif_id;
  6213. +   len = sizeof(tx_big_hdr_t);
  6214. +  
  6215. +   for(num=0; num < fifo->max_msg_num; num++)
  6216. +   {  
  6217. +       hdr = (t_msg_hdr_t *)(readTo);
  6218. +       if((unsigned char *)hdr >= readMax )
  6219. +           break;     
  6220. +       len = len + TX_MSG_UNIT_LEN(hdr);
  6221. +       if( len >= fifo->cp2_txRam )
  6222. +           break;
  6223. +       if(HOST_SC2331_CMD == hdr->type)
  6224. +       {
  6225. +           printkp("[CMD_OUT][%s]\n", get_cmd_name(hdr->subtype) );
  6226. +       }
  6227. +       if( (hdr->type > 2) || (hdr->subtype > 47) )
  6228. +       {
  6229. +           ASSERT();
  6230. +       }
  6231. +       memcpy( (unsigned char *)(&(big_hdr->msg[num])), readTo, sizeof(t_msg_hdr_t));
  6232. +       big_hdr->msg_num++;
  6233. +       hdr = TX_MSG_NEXT_MSG(hdr);
  6234. +       readTo = (unsigned char *)hdr;
  6235. +   }
  6236. +   *count = num;
  6237. +   len = readTo - readFrom;
  6238. +   big_hdr->len = len;
  6239. +  
  6240. +   if(len >= (sizeof(tx_big_hdr_t) + sizeof(t_msg_hdr_t)))
  6241. +   {
  6242. +       ret = pfunc(chn, readFrom,  len);
  6243. +       if(OK != ret)
  6244. +       {
  6245. +           ret = HW_WRITE_ERROR;
  6246. +           goto out;
  6247. +       }
  6248. +       else
  6249. +           ret = OK;
  6250. +   }
  6251. +   else
  6252. +   {
  6253. +       ASSERT();
  6254. +       ret = -5;
  6255. +   }
  6256. +   if( (fifo->RD  >  fifo->WT) &&  ( (readMax - readTo) < sizeof(t_msg_hdr_t) )  )
  6257. +   {
  6258. +       fifo->RD = 0;
  6259. +       fifo->rd_cnt = fifo->rd_cnt + num;
  6260. +       spin_lock( &(fifo->lock) );
  6261. +       fifo->LASTWT = -1;
  6262. +       spin_unlock( &(fifo->lock) );
  6263. +   }
  6264. +   else
  6265. +   {
  6266. +       fifo->RD = readTo - fifo->mem;
  6267. +       fifo->rd_cnt = fifo->rd_cnt + num;
  6268. +   }  
  6269. +out:
  6270. +   return ret;
  6271. +}
  6272. +
  6273. +unsigned int tx_fifo_in_pkt(txfifo_t *tx_fifo)
  6274. +{
  6275. +   return tx_fifo->wt_cnt - tx_fifo->rd_cnt;
  6276. +}
  6277. +
  6278. +unsigned int tx_fifo_used(txfifo_t *tx_fifo)
  6279. +{
  6280. +   unsigned int used;
  6281. +   txfifo_t     fifo = {0};
  6282. +   memcpy((unsigned char *)(&fifo), (unsigned char *)(tx_fifo), 12 );
  6283. +   used = (  (-1 == fifo.LASTWT)?(fifo.WT - fifo.RD):((fifo.LASTWT - fifo.RD) + fifo.WT)  );
  6284. +   return used;
  6285. +}
  6286. +
  6287. +int tx_fifo_alloc(txfifo_t *tx_fifo,  txfifo_conf_t *conf)
  6288. +{
  6289. +   tx_fifo->size      = conf->size;
  6290. +   tx_fifo->cp2_txRam = conf->cp2_txRam;
  6291. +   tx_fifo->mem       = fifo_mem_alloc(tx_fifo->size);
  6292. +   if(NULL == tx_fifo->mem)
  6293. +   {
  6294. +       ASSERT();
  6295. +       return ERROR;
  6296. +   }
  6297. +   tx_fifo->mem         = tx_fifo->mem + sizeof(tx_big_hdr_t);
  6298. +   tx_fifo->size        = tx_fifo->size - (  sizeof(tx_big_hdr_t) + SDIO_ALIGN_SIZE  ) ;
  6299. +   tx_fifo->WT          = 0;
  6300. +   tx_fifo->RD          = 0;
  6301. +   tx_fifo->LASTWT      = -1;
  6302. +   tx_fifo->max_msg_num = conf->max_msg_num;
  6303. +   spin_lock_init(&(tx_fifo->lock));
  6304. +   return OK;
  6305. +}
  6306. +
  6307. +int tx_fifo_free(txfifo_t *tx_fifo)
  6308. +{
  6309. +   unsigned char *fifo_mem = tx_fifo->mem - sizeof(tx_big_hdr_t);
  6310. +   if(NULL != fifo_mem)
  6311. +       fifo_mem_free(fifo_mem,  (tx_fifo->size + sizeof(tx_big_hdr_t) + SDIO_ALIGN_SIZE ) );
  6312. +
  6313. +   memset((unsigned char *)tx_fifo, 0, sizeof(txfifo_t) );
  6314. +   return OK;
  6315. +}
  6316. +
  6317. +int rx_fifo_in(const unsigned char chn, rxfifo_t *fifo, P_FUNC_2 pfunc )
  6318. +{
  6319. +   int ret;
  6320. +   unsigned int rx_len = -1;
  6321. +   bool full = false;
  6322. +   if(fifo->WT  >= fifo->RD)
  6323. +   {
  6324. +       if( (fifo->WT - fifo->RD) >= ( fifo->block_num -1) )
  6325. +           full = true;
  6326. +   }
  6327. +   else
  6328. +   {
  6329. +       if( 1 == (fifo->RD - fifo->WT) )
  6330. +           full = true;   
  6331. +   }
  6332. +   if(true == full)
  6333. +       return ERROR;
  6334. +   ret = pfunc(chn, fifo->mem[fifo->WT], &rx_len);
  6335. +   if(ERROR != ret)
  6336. +       fifo->WT  = INCR_RING_BUFF_INDX(fifo->WT, fifo->block_num);
  6337. +   return ret;
  6338. +}
  6339. +
  6340. +int rx_fifo_out(rxfifo_t *fifo, P_FUNC_3 pfunc )
  6341. +{
  6342. +   int ret = OK;
  6343. +   if(fifo->WT == fifo->RD)
  6344. +       return ERROR;
  6345. +   ret = pfunc( fifo->mem[fifo->RD],  fifo->block_size );
  6346. +   fifo->RD = INCR_RING_BUFF_INDX(fifo->RD, fifo->block_num );
  6347. +   return ret;
  6348. +}
  6349. +
  6350. +int rx_fifo_used(rxfifo_t *fifo)
  6351. +{
  6352. +   int ret = 0;
  6353. +   if(fifo->WT  >= fifo->RD)
  6354. +       ret = fifo->WT  - fifo->RD;
  6355. +   else
  6356. +       ret = fifo->block_num  -  (fifo->RD - fifo->WT);
  6357. +   return ret;
  6358. +}
  6359. +
  6360. +int rx_fifo_alloc(rxfifo_t *fifo)
  6361. +{
  6362. +   int i;
  6363. +   memset(fifo, 0, sizeof(rxfifo_t) ) ;
  6364. +   fifo->block_size = RX_FIFO_BLOCK_SIZE;
  6365. +   fifo->block_num  = RX_FIFO_BLOCK_NUM;
  6366. +   for(i=0; i < fifo->block_num; i++)
  6367. +   {
  6368. +       fifo->mem[i] = kmalloc(fifo->block_size, GFP_KERNEL );
  6369. +       if(NULL  == fifo->mem[i])
  6370. +       {
  6371. +           ASSERT();
  6372. +           return ERROR;
  6373. +       }
  6374. +   }
  6375. +   return OK;
  6376. +}
  6377. +
  6378. +int rx_fifo_free(rxfifo_t *fifo )
  6379. +{
  6380. +   int i;
  6381. +   for(i=0; i < fifo->block_num; i++)
  6382. +   {
  6383. +       if(NULL != fifo->mem[i])
  6384. +           kfree(fifo->mem[i]);
  6385. +   }
  6386. +   memset(fifo, 0, sizeof(rxfifo_t)) ;
  6387. +   return OK;
  6388. +}
  6389. +
  6390. +
  6391. +
  6392. diff --git a/drivers/net/wireless/sprdwl/wlan_fifo.h b/drivers/net/wireless/sprdwl/wlan_fifo.h
  6393. new file mode 100644
  6394. index 0000000..d47b530
  6395. --- /dev/null
  6396. +++ b/drivers/net/wireless/sprdwl/wlan_fifo.h
  6397. @@ -0,0 +1,106 @@
  6398. +#ifndef __SPRD_WLAN_FIFO_H_
  6399. +#define __SPRD_WLAN_FIFO_H_
  6400. +
  6401. +#include "wlan_common.h"
  6402. +
  6403. +#define TX_MSG_HEAD_FILED(hdr)         (  ( sizeof(t_msg_hdr_t) + ( (2==((hdr)->type) )?34:0 )   ) )
  6404. +#define TX_MSG_UNIT_LEN(hdr)           (  ( ALIGN_4BYTE( TX_MSG_HEAD_FILED(hdr) + ((hdr)->len) ) )  )      
  6405. +#define TX_MSG_NEXT_MSG(hdr)           (  ( (t_msg_hdr_t *)( (unsigned char *)(hdr) + TX_MSG_UNIT_LEN(hdr) ) ) )
  6406. +
  6407. +#define OK                             ( 0)
  6408. +#define ERROR                          (-1)
  6409. +#define TX_FIFO_FULL                   (-2)
  6410. +#define TX_FIFO_EMPTY                  (-3)
  6411. +#define HW_WRITE_ERROR                 (-4)
  6412. +#define HW_READ_ERROR                  (-6)
  6413. +
  6414. +#define RX_FIFO_BLOCK_NUM              (8)
  6415. +#define RX_FIFO_BLOCK_SIZE             HW_RX_SIZE
  6416. +
  6417. +typedef  int (*P_FUNC_1)(unsigned short, unsigned char *,  unsigned int  );
  6418. +typedef  int (*P_FUNC_2)(unsigned short, unsigned char *,  unsigned int *);
  6419. +typedef  int (*P_FUNC_3)(unsigned char *,unsigned int);
  6420. +
  6421. +typedef struct
  6422. +{
  6423. +   unsigned char  *data;
  6424. +   unsigned short  len;
  6425. +} dataInfo;
  6426. +
  6427. +typedef struct
  6428. +{
  6429. +   unsigned char   type: 7; /* CMD/RSP/USER DATA */
  6430. +    unsigned char   mode: 1; /* message dest mode: 1 STA, 2 softAP, 3 P2P */
  6431. +    unsigned char   subtype; /* SEARCH/ ATTACH/DETACH */
  6432. +    unsigned short  len;     /* Length not include common header */
  6433. +}t_msg_hdr_t;
  6434. +
  6435. +typedef struct
  6436. +{
  6437. +   unsigned char   type: 7; /* CMD/RSP/USER DATA */
  6438. +    unsigned char   mode: 1; /* message dest mode: 1 STA, 2 softAP, 3 P2P */
  6439. +    unsigned char   subtype; /* SEARCH/ ATTACH/DETACH */
  6440. +    unsigned short  len;     /* Length not include common header */
  6441. +}r_msg_hdr_t;
  6442. +
  6443. +typedef struct
  6444. +{
  6445. +   unsigned char  mode;
  6446. +   unsigned char  msg_num;
  6447. +   unsigned short len;
  6448. +   t_msg_hdr_t    msg[14];
  6449. +   /* FIXME with CP if sizeof(int)==64 */
  6450. +   unsigned int   tx_cnt;
  6451. +}tx_big_hdr_t;
  6452. +
  6453. +typedef struct
  6454. +{
  6455. +   t_msg_hdr_t hdr;
  6456. +   dataInfo  slice[2];
  6457. +   void     *p;
  6458. +}tx_msg_t;
  6459. +
  6460. +typedef struct
  6461. +{
  6462. +   unsigned int   WT;
  6463. +   unsigned int   RD;
  6464. +   int            LASTWT;
  6465. +   unsigned char *mem;
  6466. +   unsigned int   size;
  6467. +   unsigned int   cp2_txRam;
  6468. +   unsigned short max_msg_num;
  6469. +   spinlock_t     lock;
  6470. +   unsigned int   wt_cnt;
  6471. +   unsigned int   rd_cnt;
  6472. +}txfifo_t;
  6473. +
  6474. +typedef struct
  6475. +{
  6476. +   unsigned int   size;
  6477. +   unsigned int   cp2_txRam;
  6478. +   unsigned short max_msg_num;
  6479. +}txfifo_conf_t;
  6480. +
  6481. +typedef struct
  6482. +{
  6483. +   unsigned int   WT;
  6484. +   unsigned int   RD;
  6485. +   unsigned int   block_size;
  6486. +   unsigned int   block_num;
  6487. +   unsigned char *mem[RX_FIFO_BLOCK_NUM];
  6488. +}rxfifo_t;
  6489. +extern int tx_fifo_alloc(txfifo_t *tx_fifo,  txfifo_conf_t *conf);
  6490. +extern int tx_fifo_free(txfifo_t *tx_fifo);
  6491. +extern int tx_fifo_in(txfifo_t *fifo,  tx_msg_t *msg );
  6492. +extern int tx_fifo_out(const unsigned char netif_id,
  6493. +                      const unsigned chn, txfifo_t *fifo,
  6494. +                      P_FUNC_1 pfunc, unsigned int *count);
  6495. +extern int rx_fifo_in(const unsigned char chn, rxfifo_t *fifo, P_FUNC_2 pfunc );
  6496. +extern int rx_fifo_out(rxfifo_t *fifo, P_FUNC_3 pfunc );
  6497. +extern int rx_fifo_used(rxfifo_t *fifo);
  6498. +extern unsigned int tx_fifo_used(txfifo_t *fifo);
  6499. +extern int rx_fifo_alloc(rxfifo_t *fifo);
  6500. +extern int rx_fifo_free(rxfifo_t *fifo);
  6501. +extern unsigned int tx_fifo_in_pkt(txfifo_t *tx_fifo);
  6502. +#endif
  6503. +
  6504. diff --git a/drivers/net/wireless/sprdwl/wlan_hostapd_conf.c b/drivers/net/wireless/sprdwl/wlan_hostapd_conf.c
  6505. new file mode 100644
  6506. index 0000000..2b96b4b
  6507. --- /dev/null
  6508. +++ b/drivers/net/wireless/sprdwl/wlan_hostapd_conf.c
  6509. @@ -0,0 +1,227 @@
  6510. +#include <linux/types.h>
  6511. +#include <linux/init.h>
  6512. +#include <linux/mm.h>
  6513. +#include <linux/fs.h>
  6514. +#include <linux/fs_struct.h>
  6515. +#include <linux/path.h>
  6516. +#include <linux/uaccess.h>
  6517. +#include <linux/slab.h>
  6518. +#include "wlan_common.h"
  6519. +
  6520. +static int hex2num(char c)
  6521. +{
  6522. +   if (c >= '0' && c <= '9')
  6523. +       return c - '0';
  6524. +
  6525. +   if (c >= 'a' && c <= 'f')
  6526. +       return c - 'a' + 10;
  6527. +
  6528. +   if (c >= 'A' && c <= 'F')
  6529. +       return c - 'A' + 10;
  6530. +
  6531. +   return -1;
  6532. +}
  6533. +
  6534. +static int hex2byte(const char *hex)
  6535. +{
  6536. +   int a, b;
  6537. +
  6538. +   a = hex2num(*hex++);
  6539. +   if (a < 0)
  6540. +       return -1;
  6541. +
  6542. +   b = hex2num(*hex++);
  6543. +   if (b < 0)
  6544. +       return -1;
  6545. +
  6546. +   return (a << 4) | b;
  6547. +}
  6548. +
  6549. +/**
  6550. + * hexstr2bin - Convert ASCII hex string into binary data
  6551. + * @hex: ASCII hex string (e.g., "01ab")
  6552. + * @buf: Buffer for the binary data
  6553. + * @len: Length of the text to convert in bytes (of buf); hex will be double
  6554. + * this size
  6555. + * Returns: 0 on success, -1 on failure (invalid hex string)
  6556. + */
  6557. +static int hexstr2bin(const char *hex, u8 *buf, size_t len)
  6558. +{
  6559. +   size_t i;
  6560. +   int a;
  6561. +   const char *ipos = hex;
  6562. +
  6563. +   u8 *opos = buf;
  6564. +   for (i = 0; i < len; i++)
  6565. +   {
  6566. +       a = hex2byte(ipos);
  6567. +       if (a < 0)
  6568. +           return -1;
  6569. +       *opos++ = a;
  6570. +       ipos += 2;
  6571. +   }
  6572. +
  6573. +   return 0;
  6574. +}
  6575. +
  6576. +static struct hostap_conf *hostap_conf_create(void)
  6577. +{
  6578. +   struct hostap_conf *conf = NULL;
  6579. +   conf = kmalloc(sizeof(struct hostap_conf), GFP_KERNEL);
  6580. +
  6581. +   return conf;
  6582. +}
  6583. +
  6584. +static int fp_size(struct file *f)
  6585. +{
  6586. +   int error = -EBADF;
  6587. +   struct kstat stat;
  6588. +
  6589. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
  6590. +   error = vfs_getattr(&f->f_path, &stat);
  6591. +#else
  6592. +   error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, &stat);
  6593. +#endif
  6594. +
  6595. +   if (error == 0)
  6596. +   {
  6597. +       return stat.size;
  6598. +   }
  6599. +   else
  6600. +   {
  6601. +       pr_err("get hostapd conf file stat error\n");
  6602. +       return error;
  6603. +   }
  6604. +}
  6605. +
  6606. +static int hostap_conf_read(char *filename, char **buf)
  6607. +{
  6608. +   struct file *fp;
  6609. +   mm_segment_t fs;
  6610. +   int size = 0;
  6611. +   loff_t pos = 0;
  6612. +
  6613. +   fp = filp_open(filename, O_RDONLY, 0);
  6614. +   if (IS_ERR(fp))
  6615. +   {
  6616. +       pr_err("open %s file error\n", filename);
  6617. +       goto end;
  6618. +   }
  6619. +
  6620. +   fs = get_fs();
  6621. +   set_fs(KERNEL_DS);
  6622. +   size = fp_size(fp);
  6623. +   if (size <= 0)
  6624. +   {
  6625. +       pr_err("load file:%s error\n", filename);
  6626. +       goto error;
  6627. +   }
  6628. +
  6629. +   *buf = kzalloc(size + 1, GFP_KERNEL);
  6630. +   vfs_read(fp, *buf, size, &pos);
  6631. +
  6632. +error:
  6633. +   filp_close(fp, NULL);
  6634. +   set_fs(fs);
  6635. +end:
  6636. +   return size;
  6637. +}
  6638. +
  6639. +static char *get_line(char *buf, char *end)
  6640. +{
  6641. +   if (buf == NULL || buf >= end)
  6642. +       return NULL;
  6643. +   while (buf != end && *buf != '\n')
  6644. +       buf++;
  6645. +
  6646. +   return buf;
  6647. +}
  6648. +
  6649. +static unsigned char hostap_conf_parse(char *buf, int size,
  6650. +                                       struct hostap_conf *conf)
  6651. +{
  6652. +   unsigned char ret = 0;
  6653. +   char *spos = buf, *epos = NULL, *pos = NULL;
  6654. +   int line = 0, errors = 0;
  6655. +
  6656. +   if (!buf || !conf)
  6657. +       return 0;
  6658. +
  6659. +   for (; (epos = get_line(spos, buf + size)); (spos = epos + 1))
  6660. +   {
  6661. +       line++;
  6662. +       if (spos[0] == '#')
  6663. +           continue;
  6664. +       pos = spos;
  6665. +       while (*pos != '\0' && pos <= epos)
  6666. +       {
  6667. +           if (*pos == '\n')
  6668. +           {
  6669. +               *pos = '\0';
  6670. +               break;
  6671. +           }
  6672. +           pos++;
  6673. +       }
  6674. +
  6675. +       if (spos[0] == '\0')
  6676. +           continue;
  6677. +
  6678. +       pos = strchr(spos, '=');
  6679. +       if (pos == NULL)
  6680. +       {
  6681. +           pr_err("Line %d: invalid line '%s'",
  6682. +                  line, spos);
  6683. +           errors++;
  6684. +           continue;
  6685. +       }
  6686. +
  6687. +       *pos = '\0';
  6688. +       pos++;
  6689. +
  6690. +       if (strcmp(spos, "wpa_psk") == 0)
  6691. +       {
  6692. +           strlcpy(conf->wpa_psk, pos, sizeof(conf->wpa_psk));
  6693. +           conf->len = strlen(pos);
  6694. +       }
  6695. +       else
  6696. +       {
  6697. +           continue;
  6698. +       }
  6699. +   }
  6700. +
  6701. +   return ret;
  6702. +}
  6703. +
  6704. +int hostap_conf_load(char *filename, unsigned char *key_val)
  6705. +{
  6706. +   struct hostap_conf *conf = NULL;
  6707. +   char *buf = NULL;
  6708. +   int size = 0;
  6709. +
  6710. +   if (filename == NULL)
  6711. +       filename = HOSTAP_CONF_FILE_NAME;
  6712. +
  6713. +   size = hostap_conf_read(filename, &buf);
  6714. +   if (size > 0)
  6715. +   {
  6716. +       conf = hostap_conf_create();
  6717. +       if (conf == NULL)
  6718. +       {
  6719. +           kfree(buf);
  6720. +           pr_err("create hostap_conf struct error.\n");
  6721. +           return -EINVAL;
  6722. +       }
  6723. +
  6724. +       hostap_conf_parse(buf, size, conf);
  6725. +       if (conf->len > 64)
  6726. +       {
  6727. +           pr_err("wpa_psk len is error.(%d)\n", conf->len);
  6728. +           return -EINVAL;
  6729. +       }
  6730. +       hexstr2bin(conf->wpa_psk, key_val, conf->len / 2);
  6731. +       kfree(buf);
  6732. +   }
  6733. +
  6734. +   return 0;
  6735. +}
  6736. +
  6737. diff --git a/drivers/net/wireless/sprdwl/wlan_npi.c b/drivers/net/wireless/sprdwl/wlan_npi.c
  6738. new file mode 100644
  6739. index 0000000..44da5f9
  6740. --- /dev/null
  6741. +++ b/drivers/net/wireless/sprdwl/wlan_npi.c
  6742. @@ -0,0 +1,173 @@
  6743. +/*
  6744. + * Copyright (C) 2014 Spreadtrum Communications Inc.
  6745. + *
  6746. + * Authors:<jinglong.chen@spreadtrum.com>
  6747. + * Owner:
  6748. + *      jinglong.chen
  6749. + *
  6750. + * This software is licensed under the terms of the GNU General Public
  6751. + * License version 2, as published by the Free Software Foundation, and
  6752. + * may be copied, distributed, and modified under those terms.
  6753. + *
  6754. + * This program is distributed in the hope that it will be useful,
  6755. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6756. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  6757. + * GNU General Public License for more details.
  6758. + */
  6759. +
  6760. +#include <linux/kernel.h>
  6761. +#include <linux/platform_device.h>
  6762. +#include <linux/module.h>
  6763. +#include <linux/uaccess.h>
  6764. +#include <net/genetlink.h>
  6765. +#include <linux/types.h>
  6766. +#include "wlan_common.h"
  6767. +#define WLAN_NL_GENERAL_SOCK_ID 1022
  6768. +enum wlan_nl_commands
  6769. +{
  6770. +   WLAN_NL_CMD_UNSPEC,
  6771. +   WLAN_NL_CMD_NPI,
  6772. +   WLAN_NL_CMD_GET_INFO,
  6773. +   WLAN_NL_CMD_MAX,
  6774. +};
  6775. +
  6776. +enum wlan_nl_attrs
  6777. +{
  6778. +   WLAN_NL_ATTR_UNSPEC,
  6779. +   WLAN_NL_ATTR_COMMON_USR_TO_DRV,
  6780. +   WLAN_NL_ATTR_COMMON_DRV_TO_USR,
  6781. +   WLAN_NL_ATTR_MAX,
  6782. +};
  6783. +extern unsigned int g_dbg;
  6784. +extern wlan_info_t g_wlan;
  6785. +static int wlan_nl_send_generic(struct genl_info *info, u8 attr, u8 cmd, u32 len, u8 *data);
  6786. +extern int wlan_cmd_npi_send_recv(unsigned char *s_buf,unsigned short s_len, unsigned char *r_buf, unsigned short *r_len );
  6787. +static int wlan_nl_npi_handler(struct sk_buff *skb_2,   struct genl_info *info)
  6788. +{
  6789. +   int ret = -EINVAL;
  6790. +   unsigned short s_len = 0;
  6791. +   unsigned char *s_buf = NULL;
  6792. +   /* -Werror=frame-larger-than, so kmalloc 1024 bytes*/
  6793. +   unsigned char  *r_buf = NULL;
  6794. +   unsigned short r_len = 0;
  6795. +   unsigned char  dbgStr[64] = {0};
  6796. +
  6797. +   printkd("[%s][enter]\n", __func__);
  6798. +   if (info == NULL)
  6799. +   {
  6800. +       printkd("[%s][%d][ERROR]\n", __func__, __LINE__);
  6801. +       goto out;
  6802. +   }
  6803. +   if (info->attrs[WLAN_NL_ATTR_COMMON_USR_TO_DRV])
  6804. +   {
  6805. +       s_buf  = nla_data(info->attrs[WLAN_NL_ATTR_COMMON_USR_TO_DRV]);
  6806. +       s_len  = nla_len(info->attrs[WLAN_NL_ATTR_COMMON_USR_TO_DRV]);
  6807. +       sprintf(dbgStr, "[iwnpi][SEND][%d]:", s_len );
  6808. +       hex_dump(dbgStr, strlen(dbgStr), s_buf, s_len);
  6809. +       r_buf = kmalloc(1024, GFP_KERNEL);
  6810. +       if (!r_buf)
  6811. +           goto out;
  6812. +       wlan_cmd_npi_send_recv(s_buf, s_len, r_buf, &r_len);
  6813. +       sprintf(dbgStr, "[iwnpi][RECV][%d]:", r_len );
  6814. +       hex_dump(dbgStr, strlen(dbgStr), r_buf, r_len);
  6815. +   }
  6816. +out:
  6817. +   ret = wlan_nl_send_generic(info,
  6818. +                   WLAN_NL_ATTR_COMMON_DRV_TO_USR,
  6819. +                   WLAN_NL_CMD_NPI, r_len, r_buf);
  6820. +   if (r_buf)
  6821. +       kfree(r_buf);
  6822. +   return ret;
  6823. +}
  6824. +
  6825. +static int wlan_nl_get_info_handler(struct sk_buff *skb_2,  struct genl_info *info)
  6826. +{
  6827. +   int ret;
  6828. +   unsigned char  r_buf[64] = {0};
  6829. +   unsigned short r_len = 0;
  6830. +   memcpy(r_buf, &( g_wlan.netif[0].ndev->dev_addr[0] ), 6 );
  6831. +   r_len = 6;
  6832. +   printkd("[%s][enter]\n", __func__ );
  6833. +   ret = wlan_nl_send_generic(info, WLAN_NL_ATTR_COMMON_DRV_TO_USR, WLAN_NL_CMD_GET_INFO, r_len, r_buf );
  6834. +   return ret;
  6835. +}
  6836. +
  6837. +static struct nla_policy wlan_genl_policy[WLAN_NL_ATTR_MAX + 1] =
  6838. +{
  6839. +   [WLAN_NL_ATTR_COMMON_USR_TO_DRV] = {.type = NLA_BINARY, .len = 1024},
  6840. +   [WLAN_NL_ATTR_COMMON_DRV_TO_USR] = {.type = NLA_BINARY, .len = 1024},
  6841. +};
  6842. +
  6843. +static struct genl_ops wlan_nl_ops[] =
  6844. +{
  6845. +   {
  6846. +       .cmd = WLAN_NL_CMD_NPI,
  6847. +       .policy = wlan_genl_policy,
  6848. +       .doit = wlan_nl_npi_handler,
  6849. +   },
  6850. +   {
  6851. +       .cmd = WLAN_NL_CMD_GET_INFO,
  6852. +       .policy = wlan_genl_policy,
  6853. +       .doit = wlan_nl_get_info_handler,
  6854. +   }
  6855. +};
  6856. +
  6857. +static struct genl_family wlan_nl_genl_family =
  6858. +{
  6859. +   .id = WLAN_NL_GENERAL_SOCK_ID,
  6860. +   .hdrsize = 0,
  6861. +   .name = "WLAN_NL",
  6862. +   .version = 1,
  6863. +   .maxattr = WLAN_NL_ATTR_MAX,
  6864. +};
  6865. +
  6866. +static int wlan_nl_send_generic(struct genl_info *info, u8 attr, u8 cmd, u32 len, u8 *data)
  6867. +{
  6868. +   struct sk_buff *skb;
  6869. +   void *hdr;
  6870. +   int ret;
  6871. +   skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  6872. +   if (!skb)
  6873. +       return -ENOMEM;
  6874. +   hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, &wlan_nl_genl_family, 0, cmd);
  6875. +   if (IS_ERR(hdr))
  6876. +   {
  6877. +       ret = PTR_ERR(hdr);
  6878. +       goto err_put;
  6879. +   }
  6880. +   nla_put(skb, attr, len, data);
  6881. +   genlmsg_end(skb, hdr);
  6882. +   return genlmsg_reply(skb, info);
  6883. +
  6884. +err_put:
  6885. +   nlmsg_free(skb);
  6886. +   return ret;
  6887. +}
  6888. +
  6889. +void wlan_nl_init(void )
  6890. +{
  6891. +   int ret;
  6892. +   ret = genl_register_family_with_ops(&wlan_nl_genl_family,  wlan_nl_ops, ARRAY_SIZE(wlan_nl_ops));
  6893. +   if (ret)
  6894. +   {
  6895. +       printkd("genl_register_family_with_ops error ret:%d\n", ret);
  6896. +       return;
  6897. +   }
  6898. +   printkd("%s\n", __func__);
  6899. +   return;
  6900. +}
  6901. +
  6902. +void wlan_nl_deinit(void )
  6903. +{
  6904. +   int ret;
  6905. +   ret = genl_unregister_family(&wlan_nl_genl_family);
  6906. +   if (ret)
  6907. +   {
  6908. +       printkd("genl_unregister_family error ret:%d\n", ret);
  6909. +       return;
  6910. +   }
  6911. +   printkd("%s\n", __func__);
  6912. +   return;
  6913. +}
  6914. +
  6915. +
  6916. diff --git a/drivers/net/wireless/sprdwl/wlan_wapi.c b/drivers/net/wireless/sprdwl/wlan_wapi.c
  6917. new file mode 100644
  6918. index 0000000..048d1cd
  6919. --- /dev/null
  6920. +++ b/drivers/net/wireless/sprdwl/wlan_wapi.c
  6921. @@ -0,0 +1,666 @@
  6922. +/*
  6923. + * Copyright (C) 2013 Spreadtrum Communications Inc.
  6924. + *
  6925. + * Filename : wapi.c
  6926. + * Abstract : This file is a implementation of WAPI decryption
  6927. + *            and encryption
  6928. + *
  6929. + * Authors      :
  6930. + * Wenjie.Zhang <Wenjie.Zhang@spreadtrum.com>
  6931. + *
  6932. + * This software is licensed under the terms of the GNU General Public
  6933. + * License version 2, as published by the Free Software Foundation, and
  6934. + * may be copied, distributed, and modified under those terms.
  6935. + *
  6936. + * This program is distributed in the hope that it will be useful,
  6937. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6938. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  6939. + * GNU General Public License for more details.
  6940. + */
  6941. +#include "wlan_wapi.h"
  6942. +
  6943. +#define KEYID_LEN 1
  6944. +#define RESERVD_LEN 1
  6945. +#define PN_LEN 16
  6946. +#define MIC_LEN 16
  6947. +
  6948. +/* little order,4, 5, 6, 11, 12, 13 should be set 0 */
  6949. +const unsigned short frame_cntl_mask = 0x8FC7;
  6950. +/* little order,bit 4~15 should be set 0 */
  6951. +const unsigned short seq_cntl_mask = 0x0F00;
  6952. +
  6953. +#define SHA256_BLOCK_SIZE 64
  6954. +#define SHA256_DIGEST_SIZE 32
  6955. +
  6956. +#define BYTES_PER_WORD  4
  6957. +#define BYTE_LEN        8
  6958. +#define WORD_LEN        (BYTE_LEN * BYTES_PER_WORD)
  6959. +#define TEXT_LEN        128
  6960. +#define MK_LEN          (TEXT_LEN / WORD_LEN)
  6961. +#define RK_LEN          32
  6962. +#define TEXT_BYTES      (TEXT_LEN / BYTE_LEN)
  6963. +
  6964. +#define CK_INCREMENT    7
  6965. +#define KEY_MULTIPLIER  0x80040100
  6966. +#define TEXT_MULTIPLIER 0xa0202080
  6967. +#define FK_PARAMETER_0  0xa3b1bac6
  6968. +#define FK_PARAMETER_1  0x56aa3350
  6969. +#define FK_PARAMETER_2  0x677d9197
  6970. +#define FK_PARAMETER_3  0xb27022dc
  6971. +
  6972. +static const unsigned char s_box[] = {
  6973. +   0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
  6974. +   0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
  6975. +   0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
  6976. +   0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
  6977. +   0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
  6978. +   0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
  6979. +   0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
  6980. +   0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
  6981. +   0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
  6982. +   0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
  6983. +   0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
  6984. +   0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
  6985. +   0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
  6986. +   0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
  6987. +   0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
  6988. +   0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
  6989. +   0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
  6990. +   0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
  6991. +   0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
  6992. +   0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
  6993. +   0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
  6994. +   0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
  6995. +   0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
  6996. +   0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
  6997. +   0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
  6998. +   0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
  6999. +   0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
  7000. +   0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
  7001. +   0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
  7002. +   0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
  7003. +   0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
  7004. +   0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
  7005. +};
  7006. +
  7007. +static const unsigned int fk_parameter[] = { FK_PARAMETER_0, FK_PARAMETER_1,
  7008. +   FK_PARAMETER_2, FK_PARAMETER_3
  7009. +};
  7010. +
  7011. +static const unsigned char s_xstate[] = {
  7012. +   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 0x00-0x0F */
  7013. +   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 0x10-0x1F */
  7014. +   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 0x20-0x2F */
  7015. +   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 0x30-0x3F */
  7016. +   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 0x40-0x4F */
  7017. +   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 0x50-0x5F */
  7018. +   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 0x60-0x6F */
  7019. +   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 0x70-0x7F */
  7020. +   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 0x80-0x8F */
  7021. +   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 0x90-0x9F */
  7022. +   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 0xA0-0xAF */
  7023. +   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 0xB0-0xBF */
  7024. +   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 0xC0-0xCF */
  7025. +   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 0xD0-0xDF */
  7026. +   1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 0xE0-0xEF */
  7027. +   0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0  /* 0xF0-0xFF */
  7028. +};
  7029. +
  7030. +static const unsigned int g_nextinputtable[RK_LEN] = {
  7031. +   0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
  7032. +   0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
  7033. +   0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
  7034. +   0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
  7035. +   0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
  7036. +   0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
  7037. +   0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
  7038. +   0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
  7039. +};
  7040. +
  7041. +static const unsigned int cipherdataidx[MK_LEN][MK_LEN] = {
  7042. +   {3, 2, 1, 0},
  7043. +   {0, 3, 2, 1},
  7044. +   {1, 0, 3, 2},
  7045. +   {2, 1, 0, 3}
  7046. +};
  7047. +
  7048. +#define PARITY_MACRO(value) (s_xstate[(value) >> 24]           \
  7049. +               ^ s_xstate[((value) >> 16) & 0xFF]  \
  7050. +               ^ s_xstate[((value) >> 8) & 0xFF]   \
  7051. +               ^ s_xstate[(value) & 0xFF])
  7052. +#define XOR_MACRO(A, B) ((A) ^ (B))
  7053. +#define L_TRANSFORM_MACRO(word, key) multiplycircular(word,        \
  7054. +               key ? KEY_MULTIPLIER : TEXT_MULTIPLIER)
  7055. +
  7056. +static unsigned int t_transform(unsigned int word)
  7057. +{
  7058. +   unsigned int j;
  7059. +   unsigned int new_word;
  7060. +   int offset = 0;
  7061. +
  7062. +   new_word = 0;
  7063. +   for (j = 0; j < MK_LEN; j++) {
  7064. +       new_word = (new_word << BYTE_LEN);
  7065. +       offset =
  7066. +           ((unsigned int)(word >> (WORD_LEN - BYTE_LEN))) &
  7067. +           ((unsigned int)((1 << BYTE_LEN) - 1));
  7068. +       new_word = new_word | (unsigned int)s_box[offset];
  7069. +       word = (word << BYTE_LEN);
  7070. +   }
  7071. +   return new_word;
  7072. +}
  7073. +
  7074. +static unsigned int multiplycircular(unsigned int word, unsigned int basis)
  7075. +{
  7076. +   unsigned int new_word;
  7077. +   unsigned int i;
  7078. +
  7079. +   new_word = 0;
  7080. +
  7081. +   for (i = 0; i < WORD_LEN; i++) {
  7082. +       new_word = (new_word << 1) | PARITY_MACRO(word & basis);
  7083. +
  7084. +       basis = (basis >> 1) | ((basis & 1) << (WORD_LEN - 1));
  7085. +   }
  7086. +   return new_word;
  7087. +}
  7088. +
  7089. +static unsigned int iterate(bool key, unsigned int next_input,
  7090. +               unsigned int *cipher_text, unsigned int curidx)
  7091. +{
  7092. +   unsigned int new_state;
  7093. +
  7094. +   new_state = next_input;
  7095. +   new_state = XOR_MACRO(new_state, cipher_text[cipherdataidx[curidx][0]]);
  7096. +   new_state = XOR_MACRO(new_state, cipher_text[cipherdataidx[curidx][1]]);
  7097. +   new_state = XOR_MACRO(new_state, cipher_text[cipherdataidx[curidx][2]]);
  7098. +   new_state = L_TRANSFORM_MACRO(t_transform(new_state), key);
  7099. +   new_state = XOR_MACRO(new_state, cipher_text[cipherdataidx[curidx][3]]);
  7100. +
  7101. +   cipher_text[curidx] = new_state;
  7102. +
  7103. +   return new_state;
  7104. +}
  7105. +
  7106. +static void calculateenkey(unsigned char *key, unsigned int *key_store)
  7107. +{
  7108. +   unsigned int cipher_text[MK_LEN];
  7109. +
  7110. +   unsigned int next, i, j, next_input;
  7111. +
  7112. +   for (j = 0; j < MK_LEN; j++) {
  7113. +       next = 0;
  7114. +       for (i = 0; i < BYTES_PER_WORD; i++) {
  7115. +           next = (next << BYTE_LEN);
  7116. +           next = next | key[(j << 2) + i];
  7117. +       }
  7118. +
  7119. +       cipher_text[j] = XOR_MACRO(next, fk_parameter[j]);
  7120. +   }
  7121. +
  7122. +   for (i = 0; i < RK_LEN; i++) {
  7123. +       next_input = g_nextinputtable[i];
  7124. +
  7125. +       key_store[i] =
  7126. +           iterate(true, next_input, cipher_text, i & (MK_LEN - 1));
  7127. +   }
  7128. +}
  7129. +
  7130. +static void SMS4_Run(unsigned int *key_store, unsigned char *plaintext,
  7131. +            unsigned char *ciphertext)
  7132. +{
  7133. +   unsigned int i, j;
  7134. +   unsigned int next;
  7135. +   unsigned int next_input;
  7136. +   unsigned int plain_text[MK_LEN];
  7137. +
  7138. +   for (j = 0; j < MK_LEN; j++) {
  7139. +       next = 0;
  7140. +       for (i = 0; i < BYTES_PER_WORD; i++) {
  7141. +           next = (next << BYTE_LEN);
  7142. +           next = next | plaintext[(j << 2) + i];
  7143. +       }
  7144. +       plain_text[j] = next;
  7145. +   }
  7146. +
  7147. +   for (i = 0; i < RK_LEN; i++) {
  7148. +       next_input = key_store[i];
  7149. +       (void)iterate(false, next_input, plain_text, i & (MK_LEN - 1));
  7150. +   }
  7151. +
  7152. +   for (j = 0; j < MK_LEN; j++) {
  7153. +       next = plain_text[(MK_LEN - 1) - j];
  7154. +       for (i = 0; i < BYTES_PER_WORD; i++) {
  7155. +           ciphertext[(j << 2) + i] =
  7156. +               (unsigned char)((next >> (WORD_LEN - BYTE_LEN)) &
  7157. +                       ((1 << BYTE_LEN) - 1));
  7158. +           next = (next << BYTE_LEN);
  7159. +       }
  7160. +   }
  7161. +}
  7162. +
  7163. +void WapiCryptoSms4(unsigned char *iv, unsigned char *key, unsigned char *input,
  7164. +           unsigned int length,
  7165. +           unsigned char *mic, unsigned char *output)
  7166. +{
  7167. +   unsigned int i;
  7168. +   unsigned char sms4Output[TEXT_BYTES];
  7169. +   unsigned char tmp_data[TEXT_BYTES];
  7170. +
  7171. +   unsigned int key_store[RK_LEN];
  7172. +
  7173. +   unsigned int j = 0;
  7174. +   unsigned char *p[2];
  7175. +
  7176. +   p[0] = sms4Output;
  7177. +   p[1] = tmp_data;
  7178. +
  7179. +   memcpy(tmp_data, iv, TEXT_BYTES);
  7180. +
  7181. +   calculateenkey(key, key_store);
  7182. +
  7183. +   for (i = 0; i < length; i++) {
  7184. +       if ((i & (TEXT_BYTES - 1)) == 0) {
  7185. +           SMS4_Run(key_store, p[1 - j], p[j]);
  7186. +
  7187. +           j = 1 - j;
  7188. +       }
  7189. +
  7190. +       if (i < (length - 16))
  7191. +           output[i] = input[i] ^ p[1 - j][i & (TEXT_BYTES - 1)];
  7192. +       else
  7193. +           output[i] =
  7194. +               mic[i - length + 16] ^ p[1 -
  7195. +                            j][i & (TEXT_BYTES - 1)];
  7196. +   }
  7197. +}
  7198. +
  7199. +void WapiCryptoSms4Mic(unsigned char *iv, unsigned char *key,
  7200. +              unsigned char *header,
  7201. +              unsigned int headerlength, unsigned char *input,
  7202. +              unsigned int datalength, unsigned char *mic)
  7203. +{
  7204. +   unsigned int i, j = 0, totallength;
  7205. +   unsigned char sms4Output[TEXT_BYTES], sms4Input[TEXT_BYTES];
  7206. +   unsigned int tmp_headerlength = 0;
  7207. +   unsigned int tmp_datalenth = 0;
  7208. +
  7209. +   unsigned int header_cnt = 0;
  7210. +   unsigned int header0_cnt = 0;
  7211. +   unsigned int data_cnt = 0;
  7212. +   unsigned int data0_cnt = 0;
  7213. +
  7214. +   unsigned int key_store[RK_LEN];
  7215. +
  7216. +   memcpy(sms4Input, iv, TEXT_BYTES);
  7217. +
  7218. +   totallength = headerlength + datalength;
  7219. +   tmp_headerlength =
  7220. +       ((headerlength & (TEXT_BYTES - 1)) ==
  7221. +        0) ? 0 : (TEXT_BYTES - (headerlength & (TEXT_BYTES - 1)));
  7222. +   tmp_datalenth =
  7223. +       ((datalength & (TEXT_BYTES - 1)) ==
  7224. +        0) ? 0 : (TEXT_BYTES - (datalength & (TEXT_BYTES - 1)));
  7225. +
  7226. +   totallength += tmp_headerlength;
  7227. +   totallength += tmp_datalenth;
  7228. +
  7229. +   calculateenkey(key, key_store);
  7230. +
  7231. +   for (i = 0; i < totallength; i++) {
  7232. +       if ((i & (TEXT_BYTES - 1)) == 0)
  7233. +           SMS4_Run(key_store, sms4Input, sms4Output);
  7234. +
  7235. +       if ((datalength == 0) && (headerlength == 0)) {
  7236. +           sms4Input[i & (TEXT_BYTES - 1)] =
  7237. +               0 ^ sms4Output[i & (TEXT_BYTES - 1)];
  7238. +           data0_cnt++;
  7239. +       } else if ((headerlength == 0) && (tmp_headerlength == 0)) {
  7240. +           sms4Input[i & (TEXT_BYTES - 1)] =
  7241. +               input[j] ^ sms4Output[i & (TEXT_BYTES - 1)];
  7242. +           j++;
  7243. +           datalength--;
  7244. +           data_cnt++;
  7245. +       } else if (headerlength == 0) {
  7246. +           sms4Input[i & (TEXT_BYTES - 1)] =
  7247. +               0 ^ sms4Output[i & (TEXT_BYTES - 1)];
  7248. +           tmp_headerlength--;
  7249. +           header0_cnt++;
  7250. +       } else {
  7251. +           sms4Input[i & (TEXT_BYTES - 1)] =
  7252. +               header[i] ^ sms4Output[i & (TEXT_BYTES - 1)];
  7253. +           headerlength--;
  7254. +           header_cnt++;
  7255. +       }
  7256. +   }
  7257. +
  7258. +   SMS4_Run(key_store, sms4Input, mic);
  7259. +}
  7260. +
  7261. +unsigned short wlan_tx_wapi_encryption(wlan_vif_t *vif,
  7262. +                      unsigned char *data,
  7263. +                      unsigned short len,
  7264. +                      unsigned char *ouput_buf)
  7265. +{
  7266. +   unsigned short offset = 0;
  7267. +   bool qos_in = false;
  7268. +   bool valid_addr4 = true;
  7269. +
  7270. +   unsigned short eth_type = 0;
  7271. +   unsigned char snap_hdr[8] = { 0 };
  7272. +   unsigned char *data_pos = data + 14;
  7273. +   unsigned short data_len = len;
  7274. +   unsigned char snap_backup[8] = { 0 };
  7275. +   unsigned char arp_backup[6] = { 0 };
  7276. +   unsigned char snap_flag = 0;
  7277. +   unsigned char arp_flag = 0;
  7278. +
  7279. +   unsigned char ptk_header[36] = { 0 };
  7280. +   unsigned short ptk_headr_len = 32;
  7281. +   unsigned char *p_ptk_header = ptk_header;
  7282. +   unsigned char *p_outputdata = ouput_buf;
  7283. +   unsigned char data_mic[16] = { 0 };
  7284. +
  7285. +   unsigned char *iv = inc_wapi_pairwise_key_txrsc(vif);
  7286. +   unsigned char keyid = vif->cfg80211.key_index[PAIRWISE];
  7287. +
  7288. +   int i = 0;
  7289. +
  7290. +   /* save frame cntl */
  7291. +   *p_ptk_header = 8;
  7292. +   *(p_ptk_header + 1) = 65;
  7293. +
  7294. +   if (*p_ptk_header & 0x80) {
  7295. +       qos_in = true;
  7296. +       /* add qos len 2 byte */
  7297. +       ptk_headr_len += 2;
  7298. +   }
  7299. +
  7300. +   /* valid addr4 in case:ToDS==1 && FromDS==1 */
  7301. +   if ((*(p_ptk_header + 1) & 0x03) != 0x03)
  7302. +       valid_addr4 = false;
  7303. +
  7304. +   p_ptk_header += 2;
  7305. +   offset += 2;
  7306. +
  7307. +   /* jump over duration id */
  7308. +   offset += 2;
  7309. +   /* save addr1 addr2 */
  7310. +   memcpy(p_ptk_header, vif->cfg80211.bssid, 6);
  7311. +   memcpy(p_ptk_header + 6, data + 6, 6);
  7312. +   p_ptk_header += 12;
  7313. +   offset += 12;
  7314. +
  7315. +   /* save seq cntl */
  7316. +   *p_ptk_header = 0;
  7317. +   *(p_ptk_header + 1) = 0;
  7318. +   p_ptk_header += 2;
  7319. +
  7320. +   /* save addr3 */
  7321. +   memcpy(p_ptk_header, data, 6);
  7322. +   p_ptk_header += 6;
  7323. +   offset += 6;
  7324. +
  7325. +   /* save addr4 */
  7326. +   memset(p_ptk_header, 0x00, 6);
  7327. +   p_ptk_header += 6;
  7328. +
  7329. +   /* jump seq cntl */
  7330. +   offset += 2;
  7331. +
  7332. +   /* save qos */
  7333. +   /*if(qos_in)
  7334. +   {
  7335. +       memcpy(p_ptk_header,&header[offset],2);
  7336. +       p_ptk_header += 2;
  7337. +       offset       += 2;
  7338. +   }
  7339. +   */
  7340. +
  7341. +   /* save keyid */
  7342. +   *p_ptk_header = keyid;
  7343. +   p_ptk_header++;
  7344. +
  7345. +   /* reserved */
  7346. +   *p_ptk_header = 0x00;
  7347. +   p_ptk_header++;
  7348. +
  7349. +   eth_type =
  7350. +       ((*(data + ETH_PKT_TYPE_OFFSET) << 8) |
  7351. +        *(data + ETH_PKT_TYPE_OFFSET + 1));
  7352. +   if ((eth_type == ARP_TYPE) || (eth_type == IP_TYPE) ||
  7353. +       (eth_type == ONE_X_TYPE) || (eth_type == VLAN_TYPE) ||
  7354. +       (eth_type == WAPI_TYPE) || (eth_type == IPV6_TYPE) ||
  7355. +       (eth_type == LLTD_TYPE)) {
  7356. +       snap_hdr[0] = 0xAA;
  7357. +       snap_hdr[1] = 0xAA;
  7358. +       snap_hdr[2] = 0x03;
  7359. +       snap_hdr[3] = 0x00;
  7360. +       snap_hdr[4] = 0x00;
  7361. +       snap_hdr[5] = 0x00;
  7362. +       snap_hdr[6] = *(data + 12);
  7363. +       snap_hdr[7] = *(data + 13);
  7364. +       /* An ARP request/response frame has to be dissected to modify*/
  7365. +       /* MAC address, for the host interface. MAC layer acts as an  */
  7366. +       /* interface to the packets from Etherent and WLAN and takes  */
  7367. +       /* responsibility of ensuring proper interfacing.             */
  7368. +       /* The source MAC address is modified only if the packet is an*/
  7369. +       /* ARP Request or a Response. The appropriate bytes are checke*/
  7370. +       /* Type field (2 bytes): ARP Request (1) or an ARP Response(2)*/
  7371. +       if (eth_type == ARP_TYPE) {
  7372. +           if ((*(data + 20) == 0x00) &&
  7373. +               (*(data + 21) == 0x02 || *(data + 21) == 0x01)) {
  7374. +               /* Set Address2 field with source address */
  7375. +               memcpy(arp_backup, data + 22, 6);
  7376. +               arp_flag = 1;
  7377. +               memcpy((data + 22), data + 6, 6);
  7378. +           }
  7379. +       }
  7380. +
  7381. +       /* Set the data length parameter to the MAC data length only */
  7382. +       /* not include headers)                                      */
  7383. +       data_pos = data + 6;
  7384. +       data_len = len + 8;
  7385. +       memcpy(snap_backup, data_pos, sizeof(snap_hdr));
  7386. +       snap_flag = 1;
  7387. +       memcpy(data_pos, snap_hdr, sizeof(snap_hdr));
  7388. +   } else {
  7389. +       data_len = len;
  7390. +       data_pos = data + 14;
  7391. +   }
  7392. +
  7393. +   /* save data len */
  7394. +   *p_ptk_header = (data_len >> 8);
  7395. +   *(p_ptk_header + 1) = data_len & 0xFF;
  7396. +
  7397. +   /* calc mic */
  7398. +   WapiCryptoSms4Mic(iv,
  7399. +             mget_wapi_pairwise_mic_key(vif, keyid),
  7400. +             ptk_header, ptk_headr_len, data_pos, data_len,
  7401. +             data_mic);
  7402. +
  7403. +   /* add mic to data */
  7404. +   data_len += 16;
  7405. +
  7406. +   /* encryption data(inclue mic) & save keyid & iv */
  7407. +   WapiCryptoSms4(iv,
  7408. +              mget_wapi_pairwise_pkt_key(vif, keyid),
  7409. +              data_pos, data_len, data_mic, p_outputdata + 1 + 1 + 16);
  7410. +   if (snap_flag)
  7411. +       memcpy(data_pos, snap_backup, sizeof(snap_hdr));
  7412. +
  7413. +   if (arp_flag)
  7414. +       memcpy(data + 22, arp_backup, 6);
  7415. +
  7416. +   *p_outputdata = keyid;
  7417. +   *(p_outputdata + 1) = 0x00;
  7418. +   p_outputdata += 2;
  7419. +
  7420. +   for (i = 15; i >= 0; i--) {
  7421. +       *p_outputdata = iv[i];
  7422. +       p_outputdata++;
  7423. +   }
  7424. +   return data_len + 1 + 1 + 16;
  7425. +}
  7426. +
  7427. +unsigned short wlan_rx_wapi_decryption(wlan_vif_t *vif,
  7428. +                      unsigned char *input_ptk,
  7429. +                      unsigned short header_len,
  7430. +                      unsigned short data_len,
  7431. +                      unsigned char *output_buf)
  7432. +{
  7433. +   unsigned short offset = 0;
  7434. +   bool qos_in = false;
  7435. +   bool valid_addr4 = true;
  7436. +   bool is_group_ptk = false;
  7437. +
  7438. +   unsigned char ptk_header[36] = { 0 };
  7439. +   unsigned short ptk_headr_len = 32;
  7440. +   unsigned char *p_ptk_header = ptk_header;
  7441. +   unsigned char data_mic[16] = { 0 };
  7442. +   unsigned char calc_data_mic[16] = { 0 };
  7443. +   unsigned char iv[16] = { 0 };
  7444. +   unsigned char keyid = { 0 };
  7445. +
  7446. +   unsigned short ral_data_len = 0;
  7447. +   unsigned short encryp_data_len = 0;
  7448. +
  7449. +   int i = 0;
  7450. +
  7451. +   /* save calc mic header */
  7452. +
  7453. +   /* save frame cntl */
  7454. +   *p_ptk_header = input_ptk[offset] & (frame_cntl_mask >> 8);
  7455. +   *(p_ptk_header + 1) = input_ptk[offset + 1] & (frame_cntl_mask & 0xFF);
  7456. +
  7457. +   if (*p_ptk_header & 0x80) {
  7458. +       qos_in = true;
  7459. +       /* add qos len 2 byte */
  7460. +       ptk_headr_len += 2;
  7461. +   }
  7462. +        
  7463. +   /* valid addr4 in case:ToDS==1 && FromDS==1 */
  7464. +   if ((*(p_ptk_header + 1) & 0x03) != 0x03)
  7465. +       valid_addr4 = false;
  7466. +
  7467. +   p_ptk_header += 2;
  7468. +   offset += 2;
  7469. +
  7470. +   /* jump over duration id */
  7471. +   offset += 2;
  7472. +
  7473. +   /* save addr1 addr2 */
  7474. +       memcpy(p_ptk_header, &input_ptk[offset], 6);
  7475. +       memcpy(p_ptk_header + 6, vif->cfg80211.bssid, 6);
  7476. +   is_group_ptk = is_group(p_ptk_header);
  7477. +   p_ptk_header += 12;
  7478. +   offset += 12;
  7479. +
  7480. +   /* save seq cntl */
  7481. +   *p_ptk_header = input_ptk[offset + 6] & (seq_cntl_mask >> 8);
  7482. +   *(p_ptk_header + 1) =
  7483. +       input_ptk[offset + 6 + 1] & (seq_cntl_mask & 0xFF);
  7484. +   p_ptk_header += 2;
  7485. +
  7486. +   /* save addr3 */
  7487. +   memcpy(p_ptk_header, &input_ptk[offset], 6);
  7488. +   p_ptk_header += 6;
  7489. +   offset += 6;
  7490. +
  7491. +   /* save addr4 */
  7492. +   if (valid_addr4) {
  7493. +       memcpy(p_ptk_header, &input_ptk[offset], 6);
  7494. +       p_ptk_header += 6;
  7495. +       offset += 6;
  7496. +   } else {
  7497. +       memset(p_ptk_header, 0x00, 6);
  7498. +       p_ptk_header += 6;
  7499. +   }
  7500. +
  7501. +   /* jump seq cntl */
  7502. +   offset += 2;
  7503. +
  7504. +   /* save qos */
  7505. +   if (qos_in) {
  7506. +       memcpy(p_ptk_header, &input_ptk[offset], 2);
  7507. +       p_ptk_header += 2;
  7508. +       offset += 2;
  7509. +
  7510. +       /* mac h/w offset 2 byte to multiple of 4 */
  7511. +       offset += 2;
  7512. +   }
  7513. +
  7514. +   /* save keyid */
  7515. +   *p_ptk_header = input_ptk[offset];
  7516. +   keyid = input_ptk[offset];
  7517. +   p_ptk_header++;
  7518. +   offset++;
  7519. +
  7520. +   /* reserved */
  7521. +   *p_ptk_header = input_ptk[offset];
  7522. +   p_ptk_header++;
  7523. +   offset++;
  7524. +
  7525. +   /* save data len */
  7526. +   encryp_data_len = data_len - KEYID_LEN - RESERVD_LEN - PN_LEN;
  7527. +   ral_data_len = data_len - KEYID_LEN - RESERVD_LEN - PN_LEN - MIC_LEN;
  7528. +   *p_ptk_header = (ral_data_len >> 8);
  7529. +   *(p_ptk_header + 1) = ral_data_len & 0xFF;
  7530. +
  7531. +   /* save calc mic header over */
  7532. +
  7533. +   /* save iv */
  7534. +   for (i = 15; i >= 0; i--) {
  7535. +       iv[i] = input_ptk[offset];
  7536. +       offset++;
  7537. +   }
  7538. +
  7539. +   /* add adjust here,later... */
  7540. +   if (is_group_ptk) {
  7541. +       /*if( (iv[15] & 0x01) == 0x00 )
  7542. +       {
  7543. +           return 0;
  7544. +       }
  7545. +       */
  7546. +   } else {
  7547. +       if ((iv[15] & 0x01) != 0x01)
  7548. +           return 0;
  7549. +   }
  7550. +   /* decryption */
  7551. +   if (is_group_ptk) {
  7552. +       WapiCryptoSms4(iv,
  7553. +                  mget_wapi_group_pkt_key(vif, keyid),
  7554. +                  (input_ptk + header_len + KEYID_LEN +
  7555. +               RESERVD_LEN + PN_LEN), encryp_data_len,
  7556. +                  (input_ptk + header_len + KEYID_LEN +
  7557. +               RESERVD_LEN + PN_LEN + encryp_data_len - 16),
  7558. +                  output_buf);
  7559. +   } else {
  7560. +       WapiCryptoSms4(iv,
  7561. +                  mget_wapi_pairwise_pkt_key(vif, keyid),
  7562. +                  (input_ptk + header_len + KEYID_LEN +
  7563. +               RESERVD_LEN + PN_LEN), encryp_data_len,
  7564. +                  (input_ptk + header_len + KEYID_LEN +
  7565. +               RESERVD_LEN + PN_LEN + encryp_data_len - 16),
  7566. +                  output_buf);
  7567. +   }
  7568. +   memcpy(data_mic, output_buf + ral_data_len, MIC_LEN);    
  7569. +
  7570. +   /* calc mic */
  7571. +   if (is_group_ptk) {
  7572. +       WapiCryptoSms4Mic(iv,
  7573. +                 mget_wapi_group_mic_key(vif, keyid),
  7574. +                 ptk_header, ptk_headr_len,
  7575. +                 (output_buf), ral_data_len, calc_data_mic);
  7576. +   } else {
  7577. +       WapiCryptoSms4Mic(iv,
  7578. +                 mget_wapi_pairwise_mic_key(vif, keyid),
  7579. +                 ptk_header, ptk_headr_len,
  7580. +                 (output_buf), ral_data_len, calc_data_mic);
  7581. +   }
  7582. +
  7583. +   if (memcmp(calc_data_mic, data_mic, MIC_LEN) != 0)
  7584. +       return 0;
  7585. +   else
  7586. +       return ral_data_len;
  7587. +}
  7588. \ No newline at end of file
  7589. diff --git a/drivers/net/wireless/sprdwl/wlan_wapi.h b/drivers/net/wireless/sprdwl/wlan_wapi.h
  7590. new file mode 100644
  7591. index 0000000..a25d94b
  7592. --- /dev/null
  7593. +++ b/drivers/net/wireless/sprdwl/wlan_wapi.h
  7594. @@ -0,0 +1,158 @@
  7595. +/*
  7596. + * Copyright (C) 2013 Spreadtrum Communications Inc.
  7597. + *
  7598. + * Filename : wapi.h
  7599. + *
  7600. + * Authors      :
  7601. + * Wenjie.Zhang <Wenjie.Zhang@spreadtrum.com>
  7602. + *
  7603. + * This software is licensed under the terms of the GNU General Public
  7604. + * License version 2, as published by the Free Software Foundation, and
  7605. + * may be copied, distributed, and modified under those terms.
  7606. + *
  7607. + * This program is distributed in the hope that it will be useful,
  7608. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7609. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  7610. + * GNU General Public License for more details.
  7611. + */
  7612. +
  7613. +#ifndef __WAPI_H__
  7614. +#define __WAPI_H__
  7615. +
  7616. +#include "wlan_common.h"
  7617. +
  7618. +#ifndef false
  7619. +#define false 0
  7620. +#endif
  7621. +#ifndef true
  7622. +#define true 1
  7623. +#endif
  7624. +#ifndef NULL
  7625. +#define NULL 0
  7626. +#endif
  7627. +
  7628. +/* Bit Values */
  7629. +#define BIT31                   ((unsigned int)(1 << 31))
  7630. +#define BIT30                   ((unsigned int)(1 << 30))
  7631. +#define BIT29                   ((unsigned int)(1 << 29))
  7632. +#define BIT28                   ((unsigned int)(1 << 28))
  7633. +#define BIT27                   ((unsigned int)(1 << 27))
  7634. +#define BIT26                   ((unsigned int)(1 << 26))
  7635. +#define BIT25                   ((unsigned int)(1 << 25))
  7636. +#define BIT24                   ((unsigned int)(1 << 24))
  7637. +#define BIT23                   ((unsigned int)(1 << 23))
  7638. +#define BIT22                   ((unsigned int)(1 << 22))
  7639. +#define BIT21                   ((unsigned int)(1 << 21))
  7640. +#define BIT20                   ((unsigned int)(1 << 20))
  7641. +#define BIT19                   ((unsigned int)(1 << 19))
  7642. +#define BIT18                   ((unsigned int)(1 << 18))
  7643. +#define BIT17                   ((unsigned int)(1 << 17))
  7644. +#define BIT16                   ((unsigned int)(1 << 16))
  7645. +#define BIT15                   ((unsigned int)(1 << 15))
  7646. +#define BIT14                   ((unsigned int)(1 << 14))
  7647. +#define BIT13                   ((unsigned int)(1 << 13))
  7648. +#define BIT12                   ((unsigned int)(1 << 12))
  7649. +#define BIT11                   ((unsigned int)(1 << 11))
  7650. +#define BIT10                   ((unsigned int)(1 << 10))
  7651. +#define BIT9                    ((unsigned int)(1 << 9))
  7652. +#define BIT8                    ((unsigned int)(1 << 8))
  7653. +#define BIT7                    ((unsigned int)(1 << 7))
  7654. +#define BIT6                    ((unsigned int)(1 << 6))
  7655. +#define BIT5                    ((unsigned int)(1 << 5))
  7656. +#define BIT4                    ((unsigned int)(1 << 4))
  7657. +#define BIT3                    ((unsigned int)(1 << 3))
  7658. +#define BIT2                    ((unsigned int)(1 << 2))
  7659. +#define BIT1                    ((unsigned int)(1 << 1))
  7660. +#define BIT0                    ((unsigned int)(1 << 0))
  7661. +#define ALL                     0xFFFF
  7662. +
  7663. +#define ETH_PKT_TYPE_OFFSET       12
  7664. +#define WAPI_TYPE                 0x88B4
  7665. +#define IPV6_TYPE                 0x86DD
  7666. +#define IP_TYPE                   0x0800
  7667. +#define ARP_TYPE                  0x0806
  7668. +#define ONE_X_TYPE                0x888E
  7669. +#define VLAN_TYPE                 0x8100
  7670. +#define LLTD_TYPE                 0x88D9
  7671. +#define UDP_TYPE                  0x11
  7672. +#define TCP_TYPE                  0x06
  7673. +#define SNAP_HDR_LEN         8
  7674. +#define ETHERNET_HDR_LEN          14
  7675. +#define IP_HDR_OFFSET             ETHERNET_HDR_LEN
  7676. +#define IP_HDR_LEN                20
  7677. +#define IP_PROT_OFFSET            23
  7678. +#define UDP_HDR_OFFSET            (IP_HDR_LEN + IP_HDR_OFFSET)
  7679. +#define UDP_HDR_LEN               8
  7680. +#define UDP_DATA_OFFSET           (UDP_HDR_OFFSET + UDP_HDR_LEN)
  7681. +#define UDP_SRC_PORT_OFFSET       UDP_HDR_OFFSET
  7682. +#define UDP_DST_PORT_OFFSET       (UDP_HDR_OFFSET + 2)
  7683. +#define VLAN_HDR_LEN              18
  7684. +#define TOS_FIELD_OFFSET          15
  7685. +#define VLAN_TID_FIELD_OFFSET     14
  7686. +#define MAC_UDP_DATA_LEN          1472
  7687. +#define MAX_UDP_IP_PKT_LEN        (MAC_UDP_DATA_LEN + UDP_DATA_OFFSET)
  7688. +
  7689. +extern unsigned short wlan_tx_wapi_encryption(wlan_vif_t *vif,
  7690. +                         unsigned char *data,
  7691. +                         unsigned short data_len,
  7692. +                         unsigned char *ouput_buf);
  7693. +
  7694. +extern unsigned short wlan_rx_wapi_decryption(wlan_vif_t *vif,
  7695. +                         unsigned char *input_ptk,
  7696. +                         unsigned short header_len,
  7697. +                         unsigned short data_len,
  7698. +                         unsigned char *output_buf);
  7699. +
  7700. +/* This function compares the address with the (last bit on air) BIT24 to    */
  7701. +/* determine if the address is a group address.                              */
  7702. +/* Returns true if the input address has the group bit set.                  */
  7703. +static inline bool is_group(unsigned char *addr)
  7704. +{
  7705. +   if ((addr[0] & BIT0) != 0)
  7706. +       return true;
  7707. +
  7708. +   return false;
  7709. +}
  7710. +
  7711. +static inline unsigned char *inc_wapi_pairwise_key_txrsc(wlan_vif_t *vif)
  7712. +{
  7713. +   int i;
  7714. +
  7715. +    vif->cfg80211.key_txrsc[1][15] += 2;
  7716. +
  7717. +   if (vif->cfg80211.key_txrsc[1][15] == 0x00) {
  7718. +       for (i = 14; i >= 0; i--) {
  7719. +           vif->cfg80211.key_txrsc[1][i] += 1;
  7720. +           if ((vif->cfg80211.key_txrsc[1][i]) != 0x00)
  7721. +               break;
  7722. +       }
  7723. +   }
  7724. +
  7725. +   return vif->cfg80211.key_txrsc[1];
  7726. +}
  7727. +
  7728. +static inline unsigned char *mget_wapi_group_pkt_key(wlan_vif_t *vif,
  7729. +                            int index)
  7730. +{
  7731. +   return (index >= 3) ? NULL : vif->cfg80211.key[0][index];
  7732. +}
  7733. +
  7734. +static inline unsigned char *mget_wapi_pairwise_pkt_key(wlan_vif_t
  7735. +                           *vif, int index)
  7736. +{
  7737. +   return (index >= 3) ? NULL : vif->cfg80211.key[1][index];
  7738. +}
  7739. +
  7740. +static inline unsigned char *mget_wapi_group_mic_key(wlan_vif_t *vif,
  7741. +                            int index)
  7742. +{
  7743. +   return (index >= 3) ? NULL : ((u8 *)vif->cfg80211.key[0][index] + 16);
  7744. +}
  7745. +
  7746. +static inline unsigned char *mget_wapi_pairwise_mic_key(wlan_vif_t
  7747. +                           *vif, int index)
  7748. +{
  7749. +   return (index >= 3) ? NULL : ((u8 *)vif->cfg80211.key[1][index] + 16);
  7750. +}
  7751. +
  7752. +#endif /* __WAPI_H__ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement