staging: wilc1000: frmw_to_linux: add argument struct wilc
[deliverable/linux.git] / drivers / staging / wilc1000 / linux_wlan.c
CommitLineData
c5c77ba1
JK
1#include "wilc_wfi_cfgoperations.h"
2#include "linux_wlan_common.h"
3#include "wilc_wlan_if.h"
4#include "wilc_wlan.h"
c5c77ba1
JK
5
6#include <linux/slab.h>
7#include <linux/sched.h>
8#include <linux/delay.h>
9#include <linux/workqueue.h>
10#include <linux/interrupt.h>
11#include <linux/irq.h>
f1a99830 12#include <linux/gpio.h>
c5c77ba1
JK
13
14#include <linux/kthread.h>
15#include <linux/firmware.h>
16#include <linux/delay.h>
17
18#include <linux/init.h>
19#include <linux/netdevice.h>
c5c77ba1 20#include <linux/inetdevice.h>
c5c77ba1
JK
21#include <linux/etherdevice.h>
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/skbuff.h>
25
26#include <linux/version.h>
27#include <linux/semaphore.h>
28
29#ifdef WILC_SDIO
30#include "linux_wlan_sdio.h"
31#else
32#include "linux_wlan_spi.h"
33#endif
34
c5c77ba1
JK
35#if defined(CUSTOMER_PLATFORM)
36/*
37 TODO : Write power control functions as customer platform.
38 */
39#else
40
41 #define _linux_wlan_device_power_on() {}
42 #define _linux_wlan_device_power_off() {}
43
44 #define _linux_wlan_device_detection() {}
45 #define _linux_wlan_device_removal() {}
46#endif
47
72ed4dc7 48extern bool g_obtainingIP;
72ed4dc7 49extern u16 Set_machw_change_vir_if(bool bValue);
c5c77ba1 50extern void resolve_disconnect_aberration(void *drvHandler);
63d03e47 51extern u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
da711eb6 52extern struct timer_list hDuringIpTimer;
c5c77ba1
JK
53
54static int linux_wlan_device_power(int on_off)
55{
56 PRINT_D(INIT_DBG, "linux_wlan_device_power.. (%d)\n", on_off);
57
58 if (on_off) {
59 _linux_wlan_device_power_on();
60 } else {
61 _linux_wlan_device_power_off();
62 }
63
64 return 0;
65}
66
67static int linux_wlan_device_detection(int on_off)
68{
69 PRINT_D(INIT_DBG, "linux_wlan_device_detection.. (%d)\n", on_off);
70
71#ifdef WILC_SDIO
72 if (on_off) {
73 _linux_wlan_device_detection();
74 } else {
75 _linux_wlan_device_removal();
76 }
77#endif
78
79 return 0;
80}
81
c5c77ba1
JK
82static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr);
83
84static struct notifier_block g_dev_notifier = {
85 .notifier_call = dev_state_ev_handler
86};
c5c77ba1 87
c5c77ba1
JK
88#define IRQ_WAIT 1
89#define IRQ_NO_WAIT 0
90/*
91 * to sync between mac_close and module exit.
92 * don't initialize or de-initialize from init/deinitlocks
93 * to be initialized from module wilc_netdev_init and
94 * deinitialized from mdoule_exit
95 */
96static struct semaphore close_exit_sync;
c5c77ba1 97
7c67c053 98static int wlan_deinit_locks(struct net_device *dev);
32dd51bc 99static void wlan_deinitialize_threads(struct net_device *dev);
fbc2fe16
CL
100extern void WILC_WFI_monitor_rx(u8 *buff, u32 size);
101extern void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size);
c5c77ba1 102
c5c77ba1 103static void linux_wlan_tx_complete(void *priv, int status);
c5c77ba1
JK
104static int mac_init_fn(struct net_device *ndev);
105int mac_xmit(struct sk_buff *skb, struct net_device *dev);
106int mac_open(struct net_device *ndev);
107int mac_close(struct net_device *ndev);
108static struct net_device_stats *mac_stats(struct net_device *dev);
109static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd);
110static void wilc_set_multicast_list(struct net_device *dev);
111
c5c77ba1
JK
112/*
113 * for now - in frmw_to_linux there should be private data to be passed to it
114 * and this data should be pointer to net device
115 */
f61c5aff 116struct wilc *g_linux_wlan;
72ed4dc7 117bool bEnablePS = true;
c5c77ba1 118
c5c77ba1
JK
119static const struct net_device_ops wilc_netdev_ops = {
120 .ndo_init = mac_init_fn,
121 .ndo_open = mac_open,
122 .ndo_stop = mac_close,
123 .ndo_start_xmit = mac_xmit,
124 .ndo_do_ioctl = mac_ioctl,
125 .ndo_get_stats = mac_stats,
126 .ndo_set_rx_mode = wilc_set_multicast_list,
127
128};
c5c77ba1 129
c5c77ba1
JK
130static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr)
131{
132 struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr;
2726887c 133 struct wilc_priv *priv;
441dc609 134 struct host_if_drv *pstrWFIDrv;
c5c77ba1 135 struct net_device *dev;
63d03e47 136 u8 *pIP_Add_buff;
c5c77ba1 137 perInterface_wlan_t *nic;
63d03e47 138 u8 null_ip[4] = {0};
c5c77ba1
JK
139 char wlan_dev_name[5] = "wlan0";
140
141 if (dev_iface == NULL || dev_iface->ifa_dev == NULL || dev_iface->ifa_dev->dev == NULL) {
142 PRINT_D(GENERIC_DBG, "dev_iface = NULL\n");
143 return NOTIFY_DONE;
144 }
145
146 if ((memcmp(dev_iface->ifa_label, "wlan0", 5)) && (memcmp(dev_iface->ifa_label, "p2p0", 4))) {
147 PRINT_D(GENERIC_DBG, "Interface is neither WLAN0 nor P2P0\n");
148 return NOTIFY_DONE;
149 }
150
151 dev = (struct net_device *)dev_iface->ifa_dev->dev;
152 if (dev->ieee80211_ptr == NULL || dev->ieee80211_ptr->wiphy == NULL) {
153 PRINT_D(GENERIC_DBG, "No Wireless registerd\n");
154 return NOTIFY_DONE;
155 }
156 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
157 if (priv == NULL) {
158 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
159 return NOTIFY_DONE;
160 }
441dc609 161 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
c5c77ba1
JK
162 nic = netdev_priv(dev);
163 if (nic == NULL || pstrWFIDrv == NULL) {
164 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
165 return NOTIFY_DONE;
166 }
167
168 PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler +++\n"); /* tony */
169
170 switch (event) {
171 case NETDEV_UP:
172 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_UP %p\n", dev); /* tony */
173
174 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n");
175
c5c77ba1
JK
176 /*If we are in station mode or client mode*/
177 if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) {
178 pstrWFIDrv->IFC_UP = 1;
72ed4dc7 179 g_obtainingIP = false;
8972d0fe 180 del_timer(&hDuringIpTimer);
c5c77ba1
JK
181 PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n");
182 }
183
5a66bf20 184 if (bEnablePS)
218dc407 185 host_int_set_power_mgmt(pstrWFIDrv, 1, 0);
c5c77ba1
JK
186
187 PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label);
188
189 pIP_Add_buff = (char *) (&(dev_iface->ifa_address));
17aacd43 190 PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]);
218dc407 191 host_int_setup_ipaddress(pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx);
c5c77ba1
JK
192
193 break;
194
195 case NETDEV_DOWN:
196 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev); /* tony */
197
198 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n");
199 if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) {
200 pstrWFIDrv->IFC_UP = 0;
72ed4dc7 201 g_obtainingIP = false;
c5c77ba1
JK
202 }
203
204 if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0)
218dc407 205 host_int_set_power_mgmt(pstrWFIDrv, 0, 0);
c5c77ba1
JK
206
207 resolve_disconnect_aberration(pstrWFIDrv);
208
c5c77ba1
JK
209 PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label);
210
211 pIP_Add_buff = null_ip;
17aacd43 212 PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n", pIP_Add_buff[0], pIP_Add_buff[1], pIP_Add_buff[2], pIP_Add_buff[3]);
c5c77ba1 213
218dc407 214 host_int_setup_ipaddress(pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx);
c5c77ba1
JK
215
216 break;
217
218 default:
219 PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler event=default\n"); /* tony */
220 PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event);
221
222 break;
223 }
224
225 return NOTIFY_DONE;
226
227}
c5c77ba1 228
c5c77ba1
JK
229#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
230static irqreturn_t isr_uh_routine(int irq, void *user_data)
231{
3948362d
GL
232 perInterface_wlan_t *nic;
233 struct wilc *wilc;
234 struct net_device *dev = (struct net_device *)user_data;
235
236 nic = netdev_priv(dev);
237 wilc = nic->wilc;
c5c77ba1
JK
238 PRINT_D(INT_DBG, "Interrupt received UH\n");
239
240 /*While mac is closing cacncel the handling of any interrupts received*/
3948362d 241 if (wilc->close) {
c5c77ba1 242 PRINT_ER("Driver is CLOSING: Can't handle UH interrupt\n");
c5c77ba1 243 return IRQ_HANDLED;
c5c77ba1 244 }
c5c77ba1 245 return IRQ_WAKE_THREAD;
c5c77ba1
JK
246}
247#endif
248
c5c77ba1
JK
249irqreturn_t isr_bh_routine(int irq, void *userdata)
250{
2e7933d0
GL
251 perInterface_wlan_t *nic;
252 struct wilc *wilc;
253
254 nic = netdev_priv(userdata);
255 wilc = nic->wilc;
256
c5c77ba1 257 /*While mac is closing cacncel the handling of any interrupts received*/
2e7933d0 258 if (wilc->close) {
c5c77ba1 259 PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n");
c5c77ba1 260 return IRQ_HANDLED;
c5c77ba1
JK
261 }
262
c5c77ba1 263 PRINT_D(INT_DBG, "Interrupt received BH\n");
50b929e0 264 wilc_handle_isr(wilc);
c5c77ba1 265
c5c77ba1 266 return IRQ_HANDLED;
c5c77ba1 267}
c5c77ba1 268
c5c77ba1 269#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
2c1d05d1 270static int init_irq(struct net_device *dev)
c5c77ba1
JK
271{
272 int ret = 0;
2c1d05d1
GL
273 perInterface_wlan_t *nic;
274 struct wilc *wl;
275
276 nic = netdev_priv(dev);
277 wl = nic->wilc;
c5c77ba1
JK
278
279 /*initialize GPIO and register IRQ num*/
280 /*GPIO request*/
281 if ((gpio_request(GPIO_NUM, "WILC_INTR") == 0) &&
282 (gpio_direction_input(GPIO_NUM) == 0)) {
283#if defined(CUSTOMER_PLATFORM)
284/*
285 TODO : save the registerd irq number to the private wilc context in kernel.
286 *
287 * ex) nic->dev_irq_num = gpio_to_irq(GPIO_NUM);
288 */
c5c77ba1 289#else
2c1d05d1 290 wl->dev_irq_num = gpio_to_irq(GPIO_NUM);
c5c77ba1
JK
291#endif
292 } else {
293 ret = -1;
294 PRINT_ER("could not obtain gpio for WILC_INTR\n");
295 }
296
2c1d05d1 297 if ((ret != -1) && (request_threaded_irq(wl->dev_irq_num, isr_uh_routine, isr_bh_routine,
c5c77ba1 298 IRQF_TRIGGER_LOW | IRQF_ONESHOT, /*Without IRQF_ONESHOT the uh will remain kicked in and dont gave a chance to bh*/
3948362d 299 "WILC_IRQ", dev)) < 0) {
c5c77ba1 300
c5c77ba1
JK
301 PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM);
302 ret = -1;
303 } else {
304
305 PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n",
2c1d05d1 306 wl->dev_irq_num, GPIO_NUM);
c5c77ba1
JK
307 }
308
309 return ret;
310}
311#endif
312
ec5cc750 313static void deinit_irq(struct net_device *dev)
c5c77ba1 314{
ec5cc750
GL
315 perInterface_wlan_t *nic;
316 struct wilc *wilc;
317
318 nic = netdev_priv(dev);
319 wilc = nic->wilc;
320
c5c77ba1
JK
321#if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
322 /* Deintialize IRQ */
ec5cc750
GL
323 if (&wilc->dev_irq_num != 0) {
324 free_irq(wilc->dev_irq_num, wilc);
c5c77ba1
JK
325
326 gpio_free(GPIO_NUM);
327 }
328#endif
329}
330
c5c77ba1
JK
331/*
332 * OS functions
333 */
ef2b784c 334void linux_wlan_dbg(u8 *buff)
c5c77ba1
JK
335{
336 PRINT_D(INIT_DBG, "%d\n", *buff);
337}
338
b002e20d 339int linux_wlan_lock_timeout(void *vp, u32 timeout)
c5c77ba1
JK
340{
341 int error = -1;
8dfaafd6 342
c5c77ba1 343 PRINT_D(LOCK_DBG, "Locking %p\n", vp);
78174ada 344 if (vp != NULL)
c5c77ba1 345 error = down_timeout((struct semaphore *)vp, msecs_to_jiffies(timeout));
78174ada 346 else
c5c77ba1 347 PRINT_ER("Failed, mutex is NULL\n");
c5c77ba1
JK
348 return error;
349}
350
64f2b71b 351void linux_wlan_mac_indicate(struct wilc *wilc, int flag)
c5c77ba1
JK
352{
353 /*I have to do it that way becuase there is no mean to encapsulate device pointer
354 * as a parameter
355 */
c5c77ba1
JK
356 int status;
357
358 if (flag == WILC_MAC_INDICATE_STATUS) {
894de36b 359 wilc_wlan_cfg_get_val(WID_STATUS, (unsigned char *)&status, 4);
64f2b71b
GL
360 if (wilc->mac_status == WILC_MAC_STATUS_INIT) {
361 wilc->mac_status = status;
362 up(&wilc->sync_event);
c5c77ba1 363 } else {
64f2b71b 364 wilc->mac_status = status;
c5c77ba1
JK
365 }
366
64f2b71b 367 if (wilc->mac_status == WILC_MAC_STATUS_CONNECT) { /* Connect */
c5c77ba1
JK
368 }
369
370 } else if (flag == WILC_MAC_INDICATE_SCAN) {
371 PRINT_D(GENERIC_DBG, "Scanning ...\n");
372
373 }
374
375}
376
51e825f7 377struct net_device *GetIfHandler(u8 *pMacHeader)
c5c77ba1 378{
51e825f7 379 u8 *Bssid, *Bssid1;
c5c77ba1
JK
380 int i = 0;
381
382 Bssid = pMacHeader + 10;
383 Bssid1 = pMacHeader + 4;
384
8259a53e 385 for (i = 0; i < g_linux_wlan->vif_num; i++)
7201cd2c
TC
386 if (!memcmp(Bssid1, g_linux_wlan->vif[i].bssid, ETH_ALEN) ||
387 !memcmp(Bssid, g_linux_wlan->vif[i].bssid, ETH_ALEN))
817f3fb9 388 return g_linux_wlan->vif[i].ndev;
8259a53e 389
c5c77ba1 390 PRINT_INFO(INIT_DBG, "Invalide handle\n");
fc4b95d6 391 for (i = 0; i < 25; i++)
c5c77ba1 392 PRINT_D(INIT_DBG, "%02x ", pMacHeader[i]);
c5c77ba1
JK
393 Bssid = pMacHeader + 18;
394 Bssid1 = pMacHeader + 12;
8259a53e 395 for (i = 0; i < g_linux_wlan->vif_num; i++)
7201cd2c
TC
396 if (!memcmp(Bssid1, g_linux_wlan->vif[i].bssid, ETH_ALEN) ||
397 !memcmp(Bssid, g_linux_wlan->vif[i].bssid, ETH_ALEN))
817f3fb9 398 return g_linux_wlan->vif[i].ndev;
8259a53e 399
c5c77ba1
JK
400 PRINT_INFO(INIT_DBG, "\n");
401 return NULL;
402}
403
51e825f7 404int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *pBSSID)
c5c77ba1
JK
405{
406 int i = 0;
407 int ret = -1;
472791a9
GL
408 perInterface_wlan_t *nic;
409 struct wilc *wilc;
c5c77ba1 410
472791a9
GL
411 nic = netdev_priv(wilc_netdev);
412 wilc = nic->wilc;
413
414 for (i = 0; i < wilc->vif_num; i++)
415 if (wilc->vif[i].ndev == wilc_netdev) {
416 memcpy(wilc->vif[i].bssid, pBSSID, 6);
c5c77ba1
JK
417 ret = 0;
418 break;
419 }
8259a53e 420
c5c77ba1
JK
421 return ret;
422}
423
c5c77ba1
JK
424/*Function to get number of connected interfaces*/
425int linux_wlan_get_num_conn_ifcs(void)
426{
51e825f7
CL
427 u8 i = 0;
428 u8 null_bssid[6] = {0};
429 u8 ret_val = 0;
c5c77ba1 430
8259a53e 431 for (i = 0; i < g_linux_wlan->vif_num; i++)
7201cd2c 432 if (memcmp(g_linux_wlan->vif[i].bssid, null_bssid, 6))
c5c77ba1 433 ret_val++;
8259a53e 434
c5c77ba1
JK
435 return ret_val;
436}
437
c5c77ba1
JK
438#define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
439
440static int linux_wlan_txq_task(void *vp)
441{
442 int ret, txq_count;
88687584
GL
443 perInterface_wlan_t *nic;
444 struct wilc *wl;
445 struct net_device *dev = vp;
c5c77ba1
JK
446#if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
447#define TX_BACKOFF_WEIGHT_INCR_STEP (1)
448#define TX_BACKOFF_WEIGHT_DECR_STEP (1)
449#define TX_BACKOFF_WEIGHT_MAX (7)
450#define TX_BACKOFF_WEIGHT_MIN (0)
451#define TX_BACKOFF_WEIGHT_UNIT_MS (10)
452 int backoff_weight = TX_BACKOFF_WEIGHT_MIN;
c5c77ba1
JK
453#endif
454
88687584
GL
455 nic = netdev_priv(dev);
456 wl = nic->wilc;
457
c5c77ba1 458 /* inform wilc1000_wlan_init that TXQ task is started. */
88687584 459 up(&wl->txq_thread_started);
c5c77ba1
JK
460 while (1) {
461
462 PRINT_D(TX_DBG, "txq_task Taking a nap :)\n");
88687584 463 down(&wl->txq_event);
c5c77ba1
JK
464 /* wait_for_completion(&pd->txq_event); */
465 PRINT_D(TX_DBG, "txq_task Who waked me up :$\n");
466
88687584 467 if (wl->close) {
c5c77ba1 468 /*Unlock the mutex in the mac_close function to indicate the exiting of the TX thread */
88687584 469 up(&wl->txq_thread_started);
c5c77ba1
JK
470
471 while (!kthread_should_stop())
472 schedule();
473
474 PRINT_D(TX_DBG, "TX thread stopped\n");
475 break;
476 }
477 PRINT_D(TX_DBG, "txq_task handle the sending packet and let me go to sleep.\n");
478#if !defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
a1332cad 479 ret = wilc_wlan_handle_txq(dev, &txq_count);
c5c77ba1
JK
480#else
481 do {
a1332cad 482 ret = wilc_wlan_handle_txq(dev, &txq_count);
c5c77ba1
JK
483 if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD /* && netif_queue_stopped(pd->wilc_netdev)*/) {
484 PRINT_D(TX_DBG, "Waking up queue\n");
485 /* netif_wake_queue(pd->wilc_netdev); */
88687584
GL
486 if (netif_queue_stopped(wl->vif[0].ndev))
487 netif_wake_queue(wl->vif[0].ndev);
488 if (netif_queue_stopped(wl->vif[1].ndev))
489 netif_wake_queue(wl->vif[1].ndev);
c5c77ba1
JK
490 }
491
492 if (ret == WILC_TX_ERR_NO_BUF) { /* failed to allocate buffers in chip. */
c5c77ba1
JK
493 do {
494 /* Back off from sending packets for some time. */
495 /* schedule_timeout will allow RX task to run and free buffers.*/
496 /* set_current_state(TASK_UNINTERRUPTIBLE); */
497 /* timeout = schedule_timeout(timeout); */
498 msleep(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight);
499 } while (/*timeout*/ 0);
500 backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP;
fc4b95d6 501 if (backoff_weight > TX_BACKOFF_WEIGHT_MAX)
c5c77ba1 502 backoff_weight = TX_BACKOFF_WEIGHT_MAX;
c5c77ba1
JK
503 } else {
504 if (backoff_weight > TX_BACKOFF_WEIGHT_MIN) {
505 backoff_weight -= TX_BACKOFF_WEIGHT_DECR_STEP;
fc4b95d6 506 if (backoff_weight < TX_BACKOFF_WEIGHT_MIN)
c5c77ba1 507 backoff_weight = TX_BACKOFF_WEIGHT_MIN;
c5c77ba1
JK
508 }
509 }
510 /*TODO: drop packets after a certain time/number of retry count. */
88687584 511 } while (ret == WILC_TX_ERR_NO_BUF && !wl->close); /* retry sending packets if no more buffers in chip. */
c5c77ba1
JK
512#endif
513 }
514 return 0;
515}
516
c0cadaa4 517void linux_wlan_rx_complete(void)
c5c77ba1
JK
518{
519 PRINT_D(RX_DBG, "RX completed\n");
520}
521
522int linux_wlan_get_firmware(perInterface_wlan_t *p_nic)
523{
524
525 perInterface_wlan_t *nic = p_nic;
526 int ret = 0;
527 const struct firmware *wilc_firmware;
528 char *firmware;
529
c5c77ba1
JK
530 if (nic->iftype == AP_MODE)
531 firmware = AP_FIRMWARE;
532 else if (nic->iftype == STATION_MODE)
533 firmware = STA_FIRMWARE;
534
c5c77ba1
JK
535 else {
536 PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n");
537 firmware = P2P_CONCURRENCY_FIRMWARE;
538 }
539
c5c77ba1
JK
540 if (nic == NULL) {
541 PRINT_ER("NIC is NULL\n");
542 goto _fail_;
543 }
544
545 if (&nic->wilc_netdev->dev == NULL) {
546 PRINT_ER("&nic->wilc_netdev->dev is NULL\n");
547 goto _fail_;
548 }
549
c5c77ba1
JK
550 /* the firmare should be located in /lib/firmware in
551 * root file system with the name specified above */
552
553#ifdef WILC_SDIO
554 if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_sdio_func->dev) != 0) {
555 PRINT_ER("%s - firmare not available\n", firmware);
556 ret = -1;
557 goto _fail_;
558 }
559#else
560 if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_spidev->dev) != 0) {
561 PRINT_ER("%s - firmare not available\n", firmware);
562 ret = -1;
563 goto _fail_;
564 }
565#endif
8b8ad7bc 566 g_linux_wlan->firmware = wilc_firmware;
c5c77ba1
JK
567
568_fail_:
569
570 return ret;
571
572}
573
c5c77ba1
JK
574static int linux_wlan_start_firmware(perInterface_wlan_t *nic)
575{
576
c5c77ba1
JK
577 int ret = 0;
578 /* start firmware */
579 PRINT_D(INIT_DBG, "Starting Firmware ...\n");
e42563bb 580 ret = wilc_wlan_start();
c5c77ba1
JK
581 if (ret < 0) {
582 PRINT_ER("Failed to start Firmware\n");
583 goto _fail_;
584 }
585
586 /* wait for mac ready */
587 PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n");
588 ret = linux_wlan_lock_timeout(&g_linux_wlan->sync_event, 5000);
589 if (ret) {
c5c77ba1
JK
590 PRINT_D(INIT_DBG, "Firmware start timed out");
591 goto _fail_;
592 }
593 /*
594 * TODO: Driver shouoldn't wait forever for firmware to get started -
595 * in case of timeout this should be handled properly
596 */
597 PRINT_D(INIT_DBG, "Firmware successfully started\n");
598
599_fail_:
600 return ret;
601}
f61c5aff 602static int linux_wlan_firmware_download(struct wilc *p_nic)
c5c77ba1
JK
603{
604
605 int ret = 0;
606
8b8ad7bc 607 if (!g_linux_wlan->firmware) {
c5c77ba1
JK
608 PRINT_ER("Firmware buffer is NULL\n");
609 ret = -ENOBUFS;
610 goto _FAIL_;
611 }
612 /**
613 * do the firmware download
614 **/
615 PRINT_D(INIT_DBG, "Downloading Firmware ...\n");
8b8ad7bc
TC
616 ret = wilc_wlan_firmware_download(g_linux_wlan->firmware->data,
617 g_linux_wlan->firmware->size);
fc4b95d6 618 if (ret < 0)
c5c77ba1 619 goto _FAIL_;
c5c77ba1
JK
620
621 /* Freeing FW buffer */
622 PRINT_D(INIT_DBG, "Freeing FW buffer ...\n");
623 PRINT_D(INIT_DBG, "Releasing firmware\n");
8b8ad7bc 624 release_firmware(g_linux_wlan->firmware);
c5c77ba1 625
17aacd43 626 PRINT_D(INIT_DBG, "Download Succeeded\n");
c5c77ba1
JK
627
628_FAIL_:
629 return ret;
630}
631
c5c77ba1 632/* startup configuration - could be changed later using iconfig*/
f61c5aff 633static int linux_wlan_init_test_config(struct net_device *dev, struct wilc *p_nic)
c5c77ba1
JK
634{
635
636 unsigned char c_val[64];
c5c77ba1 637 unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff};
c5c77ba1 638
2726887c 639 struct wilc_priv *priv;
441dc609 640 struct host_if_drv *pstrWFIDrv;
c5c77ba1
JK
641
642 PRINT_D(TX_DBG, "Start configuring Firmware\n");
c5c77ba1
JK
643 get_random_bytes(&mac_add[5], 1);
644 get_random_bytes(&mac_add[4], 1);
c5c77ba1 645 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
441dc609 646 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
8a14330f 647 PRINT_D(INIT_DBG, "Host = %p\n", pstrWFIDrv);
c5c77ba1
JK
648
649 PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n", mac_add[0], mac_add[1], mac_add[2], mac_add[3], mac_add[4], mac_add[5]);
21175ef7 650 wilc_get_chipid(0);
c5c77ba1 651
e5d57e91 652 *(int *)c_val = 1;
c5c77ba1 653
1028e5a4 654 if (!wilc_wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0))
c5c77ba1
JK
655 goto _fail_;
656
657 /*to tell fw that we are going to use PC test - WILC specific*/
658 c_val[0] = 0;
1028e5a4 659 if (!wilc_wlan_cfg_set(0, WID_PC_TEST_MODE, c_val, 1, 0, 0))
c5c77ba1
JK
660 goto _fail_;
661
662 c_val[0] = INFRASTRUCTURE;
1028e5a4 663 if (!wilc_wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0, 0))
c5c77ba1
JK
664 goto _fail_;
665
c3ca6372 666 /* c_val[0] = RATE_AUTO; */
c5c77ba1 667 c_val[0] = RATE_AUTO;
1028e5a4 668 if (!wilc_wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0))
c5c77ba1
JK
669 goto _fail_;
670
671 c_val[0] = G_MIXED_11B_2_MODE;
1028e5a4 672 if (!wilc_wlan_cfg_set(0, WID_11G_OPERATING_MODE, c_val, 1, 0, 0))
c5c77ba1
JK
673 goto _fail_;
674
675 c_val[0] = 1;
1028e5a4 676 if (!wilc_wlan_cfg_set(0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0))
c5c77ba1
JK
677 goto _fail_;
678
679 c_val[0] = G_SHORT_PREAMBLE;
1028e5a4 680 if (!wilc_wlan_cfg_set(0, WID_PREAMBLE, c_val, 1, 0, 0))
c5c77ba1
JK
681 goto _fail_;
682
683 c_val[0] = AUTO_PROT;
1028e5a4 684 if (!wilc_wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0, 0))
c5c77ba1
JK
685 goto _fail_;
686
c5c77ba1 687 c_val[0] = ACTIVE_SCAN;
1028e5a4 688 if (!wilc_wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0, 0))
c5c77ba1
JK
689 goto _fail_;
690
691 c_val[0] = SITE_SURVEY_OFF;
1028e5a4 692 if (!wilc_wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0, 0))
c5c77ba1
JK
693 goto _fail_;
694
695 *((int *)c_val) = 0xffff; /* Never use RTS-CTS */
1028e5a4 696 if (!wilc_wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0, 0))
c5c77ba1
JK
697 goto _fail_;
698
699 *((int *)c_val) = 2346;
1028e5a4 700 if (!wilc_wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0))
c5c77ba1
JK
701 goto _fail_;
702
703 /* SSID */
704 /* -------------------------------------------------------------- */
705 /* Configuration : String with length less than 32 bytes */
706 /* Values to set : Any string with length less than 32 bytes */
707 /* ( In BSS Station Set SSID to "" (null string) */
708 /* to enable Broadcast SSID suppport ) */
709 /* -------------------------------------------------------------- */
c5c77ba1 710 c_val[0] = 0;
1028e5a4 711 if (!wilc_wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0, 0))
c5c77ba1
JK
712 goto _fail_;
713
714 c_val[0] = 1;
1028e5a4 715 if (!wilc_wlan_cfg_set(0, WID_QOS_ENABLE, c_val, 1, 0, 0))
c5c77ba1
JK
716 goto _fail_;
717
718 c_val[0] = NO_POWERSAVE;
1028e5a4 719 if (!wilc_wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0))
c5c77ba1
JK
720 goto _fail_;
721
722 c_val[0] = NO_ENCRYPT; /* NO_ENCRYPT, 0x79 */
1028e5a4 723 if (!wilc_wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0, 0))
c5c77ba1
JK
724 goto _fail_;
725
726 c_val[0] = OPEN_SYSTEM;
1028e5a4 727 if (!wilc_wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 0, 0))
c5c77ba1
JK
728 goto _fail_;
729
730 /* WEP/802 11I Configuration */
731 /* ------------------------------------------------------------------ */
732 /* Configuration : WEP Key */
733 /* Values (0x) : 5 byte for WEP40 and 13 bytes for WEP104 */
734 /* In case more than 5 bytes are passed on for WEP 40 */
735 /* only first 5 bytes will be used as the key */
736 /* ------------------------------------------------------------------ */
737
738 strcpy(c_val, "123456790abcdef1234567890");
1028e5a4 739 if (!wilc_wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val) + 1), 0, 0))
c5c77ba1
JK
740 goto _fail_;
741
742 /* WEP/802 11I Configuration */
743 /* ------------------------------------------------------------------ */
744 /* Configuration : AES/TKIP WPA/RSNA Pre-Shared Key */
745 /* Values to set : Any string with length greater than equal to 8 bytes */
746 /* and less than 64 bytes */
747 /* ------------------------------------------------------------------ */
748 strcpy(c_val, "12345678");
1028e5a4 749 if (!wilc_wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 0, 0))
c5c77ba1
JK
750 goto _fail_;
751
752 /* IEEE802.1X Key Configuration */
753 /* ------------------------------------------------------------------ */
754 /* Configuration : Radius Server Access Secret Key */
755 /* Values to set : Any string with length greater than equal to 8 bytes */
756 /* and less than 65 bytes */
757 /* ------------------------------------------------------------------ */
758 strcpy(c_val, "password");
1028e5a4 759 if (!wilc_wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val) + 1), 0, 0))
c5c77ba1
JK
760 goto _fail_;
761
762 /* IEEE802.1X Server Address Configuration */
763 /* ------------------------------------------------------------------ */
764 /* Configuration : Radius Server IP Address */
765 /* Values to set : Any valid IP Address */
766 /* ------------------------------------------------------------------ */
767 c_val[0] = 192;
768 c_val[1] = 168;
769 c_val[2] = 1;
770 c_val[3] = 112;
1028e5a4 771 if (!wilc_wlan_cfg_set(0, WID_1X_SERV_ADDR, c_val, 4, 0, 0))
c5c77ba1
JK
772 goto _fail_;
773
774 c_val[0] = 3;
1028e5a4 775 if (!wilc_wlan_cfg_set(0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0))
c5c77ba1
JK
776 goto _fail_;
777
778 c_val[0] = 3;
1028e5a4 779 if (!wilc_wlan_cfg_set(0, WID_DTIM_PERIOD, c_val, 1, 0, 0))
c5c77ba1
JK
780 goto _fail_;
781
782 c_val[0] = NORMAL_ACK;
1028e5a4 783 if (!wilc_wlan_cfg_set(0, WID_ACK_POLICY, c_val, 1, 0, 0))
c5c77ba1
JK
784 goto _fail_;
785
786 c_val[0] = 0;
1028e5a4 787 if (!wilc_wlan_cfg_set(0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, 0, 0))
c5c77ba1
JK
788 goto _fail_;
789
790 c_val[0] = 48;
1028e5a4 791 if (!wilc_wlan_cfg_set(0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, 0))
c5c77ba1
JK
792 goto _fail_;
793
794 c_val[0] = 28;
1028e5a4 795 if (!wilc_wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, 0))
c5c77ba1
JK
796 goto _fail_;
797
798 /* Beacon Interval */
799 /* -------------------------------------------------------------------- */
800 /* Configuration : Sets the beacon interval value */
801 /* Values to set : Any 16-bit value */
802 /* -------------------------------------------------------------------- */
803
804 *((int *)c_val) = 100;
1028e5a4 805 if (!wilc_wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0, 0))
c5c77ba1
JK
806 goto _fail_;
807
808 c_val[0] = REKEY_DISABLE;
1028e5a4 809 if (!wilc_wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 0, 0))
c5c77ba1
JK
810 goto _fail_;
811
812 /* Rekey Time (s) (Used only when the Rekey policy is 2 or 4) */
813 /* -------------------------------------------------------------------- */
814 /* Configuration : Sets the Rekey Time (s) */
815 /* Values to set : 32-bit value */
816 /* -------------------------------------------------------------------- */
817 *((int *)c_val) = 84600;
1028e5a4 818 if (!wilc_wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 0, 0))
c5c77ba1
JK
819 goto _fail_;
820
821 /* Rekey Packet Count (in 1000s; used when Rekey Policy is 3) */
822 /* -------------------------------------------------------------------- */
823 /* Configuration : Sets Rekey Group Packet count */
824 /* Values to set : 32-bit Value */
825 /* -------------------------------------------------------------------- */
826 *((int *)c_val) = 500;
1028e5a4 827 if (!wilc_wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, 0))
c5c77ba1
JK
828 goto _fail_;
829
830 c_val[0] = 1;
1028e5a4 831 if (!wilc_wlan_cfg_set(0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, 0))
c5c77ba1
JK
832 goto _fail_;
833
834 c_val[0] = G_SELF_CTS_PROT;
1028e5a4 835 if (!wilc_wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0))
c5c77ba1
JK
836 goto _fail_;
837
838 c_val[0] = 1; /* Enable N */
1028e5a4 839 if (!wilc_wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0, 0))
c5c77ba1
JK
840 goto _fail_;
841
842 c_val[0] = HT_MIXED_MODE;
1028e5a4 843 if (!wilc_wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 0, 0))
c5c77ba1
JK
844 goto _fail_;
845
846 c_val[0] = 1; /* TXOP Prot disable in N mode: No RTS-CTS on TX A-MPDUs to save air-time. */
1028e5a4 847 if (!wilc_wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, 0))
c5c77ba1
JK
848 goto _fail_;
849
850 memcpy(c_val, mac_add, 6);
851
1028e5a4 852 if (!wilc_wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0, 0))
c5c77ba1
JK
853 goto _fail_;
854
855 /**
856 * AP only
857 **/
858 c_val[0] = DETECT_PROTECT_REPORT;
1028e5a4 859 if (!wilc_wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0, 0))
c5c77ba1
JK
860 goto _fail_;
861
862 c_val[0] = RTS_CTS_NONHT_PROT;
1028e5a4 863 if (!wilc_wlan_cfg_set(0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0))
c5c77ba1
JK
864 goto _fail_;
865
866 c_val[0] = 0;
1028e5a4 867 if (!wilc_wlan_cfg_set(0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, 0))
c5c77ba1
JK
868 goto _fail_;
869
870 c_val[0] = MIMO_MODE;
1028e5a4 871 if (!wilc_wlan_cfg_set(0, WID_11N_SMPS_MODE, c_val, 1, 0, 0))
c5c77ba1
JK
872 goto _fail_;
873
874 c_val[0] = 7;
1028e5a4 875 if (!wilc_wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, 0))
c5c77ba1
JK
876 goto _fail_;
877
878 c_val[0] = 1; /* Enable N with immediate block ack. */
1028e5a4 879 if (!wilc_wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, 1))
c5c77ba1
JK
880 goto _fail_;
881
882 return 0;
883
884_fail_:
885 return -1;
886}
887
c5c77ba1 888/**************************/
53dc0cfe 889void wilc1000_wlan_deinit(struct net_device *dev)
c5c77ba1 890{
53dc0cfe
GL
891 perInterface_wlan_t *nic;
892 struct wilc *wl;
c5c77ba1 893
53dc0cfe
GL
894 nic = netdev_priv(dev);
895 wl = nic->wilc;
896
897 if (!wl) {
898 netdev_err(dev, "wl is NULL\n");
899 return;
900 }
901
902 if (wl->initialized) {
903 netdev_info(dev, "Deinitializing wilc1000...\n");
c5c77ba1
JK
904
905#if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
906 /* johnny : remove */
907 PRINT_D(INIT_DBG, "skip wilc_bus_set_default_speed\n");
908#else
909 wilc_bus_set_default_speed();
910#endif
911
912 PRINT_D(INIT_DBG, "Disabling IRQ\n");
d59177cb 913#ifdef WILC_SDIO
53dc0cfe 914 mutex_lock(&wl->hif_cs);
c5c77ba1 915 disable_sdio_interrupt();
53dc0cfe 916 mutex_unlock(&wl->hif_cs);
d59177cb 917#endif
53dc0cfe
GL
918 if (&wl->txq_event != NULL)
919 up(&wl->txq_event);
c5c77ba1 920
c5c77ba1 921 PRINT_D(INIT_DBG, "Deinitializing Threads\n");
32dd51bc 922 wlan_deinitialize_threads(dev);
c5c77ba1
JK
923
924 PRINT_D(INIT_DBG, "Deinitializing IRQ\n");
ec5cc750 925 deinit_irq(dev);
c5c77ba1 926
8cec741e 927 wilc_wlan_stop();
c5c77ba1
JK
928
929 PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n");
2de7cbec 930 wilc_wlan_cleanup(dev);
c5c77ba1
JK
931#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
932 #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
933 PRINT_D(INIT_DBG, "Disabling IRQ 2\n");
934
53dc0cfe 935 mutex_lock(&wl->hif_cs);
c5c77ba1 936 disable_sdio_interrupt();
53dc0cfe 937 mutex_unlock(&wl->hif_cs);
c5c77ba1
JK
938 #endif
939#endif
940
941 /*De-Initialize locks*/
942 PRINT_D(INIT_DBG, "Deinitializing Locks\n");
7c67c053 943 wlan_deinit_locks(dev);
c5c77ba1
JK
944
945 /* announce that wilc1000 is not initialized */
53dc0cfe 946 wl->initialized = false;
c5c77ba1
JK
947
948 PRINT_D(INIT_DBG, "wilc1000 deinitialization Done\n");
949
950 } else {
951 PRINT_D(INIT_DBG, "wilc1000 is not initialized\n");
952 }
c5c77ba1
JK
953}
954
38afb390 955int wlan_init_locks(struct net_device *dev)
c5c77ba1 956{
38afb390
GL
957 perInterface_wlan_t *nic;
958 struct wilc *wl;
959
960 nic = netdev_priv(dev);
961 wl = nic->wilc;
c5c77ba1
JK
962
963 PRINT_D(INIT_DBG, "Initializing Locks ...\n");
964
38afb390
GL
965 mutex_init(&wl->hif_cs);
966 mutex_init(&wl->rxq_cs);
c5c77ba1 967
38afb390
GL
968 spin_lock_init(&wl->txq_spinlock);
969 sema_init(&wl->txq_add_to_head_cs, 1);
c5c77ba1 970
38afb390 971 sema_init(&wl->txq_event, 0);
c5c77ba1 972
38afb390
GL
973 sema_init(&wl->cfg_event, 0);
974 sema_init(&wl->sync_event, 0);
c5c77ba1 975
38afb390 976 sema_init(&wl->txq_thread_started, 0);
c5c77ba1 977
c5c77ba1
JK
978 return 0;
979}
980
7c67c053 981static int wlan_deinit_locks(struct net_device *dev)
c5c77ba1 982{
7c67c053
GL
983 perInterface_wlan_t *nic;
984 struct wilc *wilc;
985
986 nic = netdev_priv(dev);
987 wilc = nic->wilc;
988
c5c77ba1
JK
989 PRINT_D(INIT_DBG, "De-Initializing Locks\n");
990
7c67c053
GL
991 if (&wilc->hif_cs != NULL)
992 mutex_destroy(&wilc->hif_cs);
c5c77ba1 993
7c67c053
GL
994 if (&wilc->rxq_cs != NULL)
995 mutex_destroy(&wilc->rxq_cs);
c5c77ba1 996
c5c77ba1
JK
997 return 0;
998}
f61c5aff 999void linux_to_wlan(wilc_wlan_inp_t *nwi, struct wilc *nic)
c5c77ba1
JK
1000{
1001
1002 PRINT_D(INIT_DBG, "Linux to Wlan services ...\n");
1003
c5c77ba1 1004 nwi->os_context.os_private = (void *)nic;
c5c77ba1 1005
c5c77ba1
JK
1006#ifdef WILC_SDIO
1007 nwi->io_func.io_type = HIF_SDIO;
1008 nwi->io_func.io_init = linux_sdio_init;
1009 nwi->io_func.io_deinit = linux_sdio_deinit;
1010 nwi->io_func.u.sdio.sdio_cmd52 = linux_sdio_cmd52;
1011 nwi->io_func.u.sdio.sdio_cmd53 = linux_sdio_cmd53;
1012 nwi->io_func.u.sdio.sdio_set_max_speed = linux_sdio_set_max_speed;
1013 nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed;
1014#else
1015 nwi->io_func.io_type = HIF_SPI;
1016 nwi->io_func.io_init = linux_spi_init;
1017 nwi->io_func.io_deinit = linux_spi_deinit;
1018 nwi->io_func.u.spi.spi_tx = linux_spi_write;
1019 nwi->io_func.u.spi.spi_rx = linux_spi_read;
1020 nwi->io_func.u.spi.spi_trx = linux_spi_write_read;
1021 nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed;
1022#endif
c5c77ba1
JK
1023}
1024
75a94665 1025int wlan_initialize_threads(struct net_device *dev)
c5c77ba1 1026{
75a94665
GL
1027 perInterface_wlan_t *nic;
1028 struct wilc *wilc;
c5c77ba1 1029 int ret = 0;
8dfaafd6 1030
75a94665
GL
1031 nic = netdev_priv(dev);
1032 wilc = nic->wilc;
1033
c5c77ba1
JK
1034 PRINT_D(INIT_DBG, "Initializing Threads ...\n");
1035
c5c77ba1
JK
1036 /* create tx task */
1037 PRINT_D(INIT_DBG, "Creating kthread for transmission\n");
88687584 1038 wilc->txq_thread = kthread_run(linux_wlan_txq_task, (void *)dev,
75a94665
GL
1039 "K_TXQ_TASK");
1040 if (!wilc->txq_thread) {
c5c77ba1
JK
1041 PRINT_ER("couldn't create TXQ thread\n");
1042 ret = -ENOBUFS;
1043 goto _fail_2;
1044 }
c5c77ba1 1045 /* wait for TXQ task to start. */
75a94665 1046 down(&wilc->txq_thread_started);
c5c77ba1
JK
1047
1048 return 0;
1049
1050_fail_2:
1051 /*De-Initialize 2nd thread*/
75a94665 1052 wilc->close = 0;
c5c77ba1
JK
1053 return ret;
1054}
1055
32dd51bc 1056static void wlan_deinitialize_threads(struct net_device *dev)
c5c77ba1 1057{
32dd51bc
GL
1058 perInterface_wlan_t *nic;
1059 struct wilc *wl;
1060
1061 nic = netdev_priv(dev);
1062 wl = nic->wilc;
c5c77ba1 1063
32dd51bc 1064 wl->close = 1;
c5c77ba1 1065 PRINT_D(INIT_DBG, "Deinitializing Threads\n");
c5c77ba1 1066
32dd51bc
GL
1067 if (&wl->txq_event != NULL)
1068 up(&wl->txq_event);
c5c77ba1 1069
32dd51bc
GL
1070 if (wl->txq_thread != NULL) {
1071 kthread_stop(wl->txq_thread);
1072 wl->txq_thread = NULL;
c5c77ba1 1073 }
c5c77ba1
JK
1074}
1075
c5c77ba1
JK
1076int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
1077{
1078 wilc_wlan_inp_t nwi;
c5c77ba1
JK
1079 perInterface_wlan_t *nic = p_nic;
1080 int ret = 0;
0fa683b6 1081 struct wilc *wl = nic->wilc;
c5c77ba1 1082
0fa683b6
GL
1083 if (!wl->initialized) {
1084 wl->mac_status = WILC_MAC_STATUS_INIT;
1085 wl->close = 0;
c5c77ba1 1086
38afb390 1087 wlan_init_locks(dev);
c5c77ba1 1088
0fa683b6 1089 linux_to_wlan(&nwi, wl);
c5c77ba1 1090
c9d4834d 1091 ret = wilc_wlan_init(&nwi);
c5c77ba1
JK
1092 if (ret < 0) {
1093 PRINT_ER("Initializing WILC_Wlan FAILED\n");
1094 ret = -EIO;
1095 goto _fail_locks_;
1096 }
c5c77ba1 1097
c5c77ba1 1098#if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
2c1d05d1 1099 if (init_irq(dev)) {
c5c77ba1
JK
1100 PRINT_ER("couldn't initialize IRQ\n");
1101 ret = -EIO;
b46d6882 1102 goto _fail_locks_;
c5c77ba1
JK
1103 }
1104#endif
1105
75a94665 1106 ret = wlan_initialize_threads(dev);
b46d6882
TC
1107 if (ret < 0) {
1108 PRINT_ER("Initializing Threads FAILED\n");
1109 ret = -EIO;
1110 goto _fail_wilc_wlan_;
1111 }
1112
c5c77ba1
JK
1113#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1114 if (enable_sdio_interrupt()) {
1115 PRINT_ER("couldn't initialize IRQ\n");
1116 ret = -EIO;
1117 goto _fail_irq_init_;
1118 }
1119#endif
1120
1121 if (linux_wlan_get_firmware(nic)) {
17aacd43 1122 PRINT_ER("Can't get firmware\n");
c5c77ba1
JK
1123 ret = -EIO;
1124 goto _fail_irq_enable_;
1125 }
1126
c5c77ba1 1127 /*Download firmware*/
0fa683b6 1128 ret = linux_wlan_firmware_download(wl);
c5c77ba1
JK
1129 if (ret < 0) {
1130 PRINT_ER("Failed to download firmware\n");
1131 ret = -EIO;
1132 goto _fail_irq_enable_;
1133 }
1134
1135 /* Start firmware*/
1136 ret = linux_wlan_start_firmware(nic);
1137 if (ret < 0) {
1138 PRINT_ER("Failed to start firmware\n");
1139 ret = -EIO;
1140 goto _fail_irq_enable_;
1141 }
1142
1143 wilc_bus_set_max_speed();
1144
07056a85 1145 if (wilc_wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1, 0)) {
c5c77ba1
JK
1146 int size;
1147 char Firmware_ver[20];
8dfaafd6 1148
894de36b 1149 size = wilc_wlan_cfg_get_val(
c5c77ba1
JK
1150 WID_FIRMWARE_VERSION,
1151 Firmware_ver, sizeof(Firmware_ver));
1152 Firmware_ver[size] = '\0';
1153 PRINT_D(INIT_DBG, "***** Firmware Ver = %s *******\n", Firmware_ver);
1154 }
1155 /* Initialize firmware with default configuration */
0fa683b6 1156 ret = linux_wlan_init_test_config(dev, wl);
c5c77ba1
JK
1157
1158 if (ret < 0) {
1159 PRINT_ER("Failed to configure firmware\n");
1160 ret = -EIO;
1161 goto _fail_fw_start_;
1162 }
1163
0fa683b6 1164 wl->initialized = true;
c5c77ba1
JK
1165 return 0; /*success*/
1166
c5c77ba1 1167_fail_fw_start_:
8cec741e 1168 wilc_wlan_stop();
c5c77ba1
JK
1169
1170_fail_irq_enable_:
1171#if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1172 disable_sdio_interrupt();
c5c77ba1 1173_fail_irq_init_:
7a8fd841 1174#endif
c5c77ba1 1175#if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
ec5cc750 1176 deinit_irq(dev);
c5c77ba1
JK
1177
1178#endif
32dd51bc 1179 wlan_deinitialize_threads(dev);
c5c77ba1 1180_fail_wilc_wlan_:
2de7cbec 1181 wilc_wlan_cleanup(dev);
c5c77ba1 1182_fail_locks_:
7c67c053 1183 wlan_deinit_locks(dev);
c5c77ba1
JK
1184 PRINT_ER("WLAN Iinitialization FAILED\n");
1185 } else {
1186 PRINT_D(INIT_DBG, "wilc1000 already initialized\n");
1187 }
1188 return ret;
1189}
1190
c5c77ba1
JK
1191/*
1192 * - this function will be called automatically by OS when module inserted.
1193 */
1194
c5c77ba1
JK
1195int mac_init_fn(struct net_device *ndev)
1196{
1197
1198 /*Why we do this !!!*/
1199 netif_start_queue(ndev); /* ma */
1200 netif_stop_queue(ndev); /* ma */
1201
1202 return 0;
1203}
c5c77ba1 1204
c5c77ba1 1205/* This fn is called, when this device is setup using ifconfig */
c5c77ba1
JK
1206int mac_open(struct net_device *ndev)
1207{
1208 perInterface_wlan_t *nic;
1209
c5c77ba1
JK
1210 /*No need for setting mac address here anymore,*/
1211 /*Just set it in init_test_config()*/
1212 unsigned char mac_add[ETH_ALEN] = {0};
c5c77ba1
JK
1213 int ret = 0;
1214 int i = 0;
2726887c 1215 struct wilc_priv *priv;
f3c1366e
GL
1216 struct wilc *wl;
1217
1218 nic = netdev_priv(ndev);
1219 wl = nic->wilc;
c5c77ba1 1220
7d05652c 1221#ifdef WILC_SPI
f3c1366e 1222 if (!wl|| !wl->wilc_spidev) {
7d05652c
CG
1223 netdev_err(ndev, "wilc1000: SPI device not ready\n");
1224 return -ENODEV;
1225 }
1226#endif
c5c77ba1
JK
1227 nic = netdev_priv(ndev);
1228 priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
1229 PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev);
1230
dd4b6a83 1231 ret = wilc_init_host_int(ndev);
c5c77ba1
JK
1232 if (ret < 0) {
1233 PRINT_ER("Failed to initialize host interface\n");
1234
1235 return ret;
1236 }
c5c77ba1
JK
1237
1238 /*initialize platform*/
1239 PRINT_D(INIT_DBG, "*** re-init ***\n");
1240 ret = wilc1000_wlan_init(ndev, nic);
1241 if (ret < 0) {
1242 PRINT_ER("Failed to initialize wilc1000\n");
a9a16823 1243 wilc_deinit_host_int(ndev);
c5c77ba1
JK
1244 return ret;
1245 }
1246
72ed4dc7 1247 Set_machw_change_vir_if(false);
c5c77ba1 1248
21175ef7 1249 host_int_get_MacAddress(priv->hWILCWFIDrv, mac_add);
310a28fd 1250 PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add);
c5c77ba1
JK
1251
1252 /* loop through the NUM of supported devices and set the MAC address */
f3c1366e
GL
1253 for (i = 0; i < wl->vif_num; i++) {
1254 if (ndev == wl->vif[i].ndev) {
1255 memcpy(wl->vif[i].src_addr, mac_add, ETH_ALEN);
1256 wl->vif[i].hif_drv = priv->hWILCWFIDrv;
c5c77ba1
JK
1257 break;
1258 }
1259 }
1260
1261 /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/
f3c1366e 1262 memcpy(ndev->dev_addr, wl->vif[i].src_addr, ETH_ALEN);
c5c77ba1
JK
1263
1264 if (!is_valid_ether_addr(ndev->dev_addr)) {
1265 PRINT_ER("Error: Wrong MAC address\n");
1266 ret = -EINVAL;
1267 goto _err_;
1268 }
1269
8e0735c5
CL
1270 wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev->ieee80211_ptr,
1271 nic->g_struct_frame_reg[0].frame_type, nic->g_struct_frame_reg[0].reg);
1272 wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev->ieee80211_ptr,
1273 nic->g_struct_frame_reg[1].frame_type, nic->g_struct_frame_reg[1].reg);
c5c77ba1 1274 netif_wake_queue(ndev);
f3c1366e 1275 wl->open_ifcs++;
c5c77ba1
JK
1276 nic->mac_opened = 1;
1277 return 0;
1278
1279_err_:
a9a16823 1280 wilc_deinit_host_int(ndev);
53dc0cfe 1281 wilc1000_wlan_deinit(ndev);
c5c77ba1
JK
1282 return ret;
1283}
c5c77ba1
JK
1284
1285struct net_device_stats *mac_stats(struct net_device *dev)
1286{
1287 perInterface_wlan_t *nic = netdev_priv(dev);
1288
c5c77ba1
JK
1289 return &nic->netstats;
1290}
1291
1292/* Setup the multicast filter */
c5c77ba1
JK
1293static void wilc_set_multicast_list(struct net_device *dev)
1294{
1295
1296 struct netdev_hw_addr *ha;
2726887c 1297 struct wilc_priv *priv;
441dc609 1298 struct host_if_drv *pstrWFIDrv;
c5c77ba1 1299 int i = 0;
8dfaafd6 1300
c5c77ba1 1301 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
441dc609 1302 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
c5c77ba1 1303
c5c77ba1
JK
1304 if (!dev)
1305 return;
1306
17aacd43 1307 PRINT_D(INIT_DBG, "Setting Multicast List with count = %d.\n", dev->mc.count);
c5c77ba1
JK
1308
1309 if (dev->flags & IFF_PROMISC) {
1310 /* Normally, we should configure the chip to retrive all packets
1311 * but we don't wanna support this right now */
1312 /* TODO: add promiscuous mode support */
17aacd43 1313 PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets\n");
c5c77ba1
JK
1314 return;
1315 }
1316
1317 /* If there's more addresses than we handle, get all multicast
1318 * packets and sort them out in software. */
1319 if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) {
1320 PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n");
1321 /* get all multicast packets */
218dc407 1322 host_int_setup_multicast_filter(pstrWFIDrv, false, 0);
c5c77ba1
JK
1323 return;
1324 }
1325
1326 /* No multicast? Just get our own stuff */
1327 if ((dev->mc.count) == 0) {
1328 PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n");
218dc407 1329 host_int_setup_multicast_filter(pstrWFIDrv, true, 0);
c5c77ba1
JK
1330 return;
1331 }
1332
1333 /* Store all of the multicast addresses in the hardware filter */
1334 netdev_for_each_mc_addr(ha, dev)
1335 {
d00d2ba3 1336 memcpy(gau8MulticastMacAddrList[i], ha->addr, ETH_ALEN);
c5c77ba1
JK
1337 PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i,
1338 gau8MulticastMacAddrList[i][0], gau8MulticastMacAddrList[i][1], gau8MulticastMacAddrList[i][2], gau8MulticastMacAddrList[i][3], gau8MulticastMacAddrList[i][4], gau8MulticastMacAddrList[i][5]);
1339 i++;
1340 }
1341
218dc407 1342 host_int_setup_multicast_filter(pstrWFIDrv, true, (dev->mc.count));
c5c77ba1
JK
1343
1344 return;
1345
1346}
1347
c5c77ba1
JK
1348static void linux_wlan_tx_complete(void *priv, int status)
1349{
1350
1351 struct tx_complete_data *pv_data = (struct tx_complete_data *)priv;
8dfaafd6 1352
78174ada 1353 if (status == 1)
c5c77ba1 1354 PRINT_D(TX_DBG, "Packet sent successfully - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
78174ada 1355 else
c5c77ba1 1356 PRINT_D(TX_DBG, "Couldn't send packet - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
c5c77ba1
JK
1357 /* Free the SK Buffer, its work is done */
1358 dev_kfree_skb(pv_data->skb);
a18dd630 1359 kfree(pv_data);
c5c77ba1
JK
1360}
1361
1362int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
1363{
1364 perInterface_wlan_t *nic;
1365 struct tx_complete_data *tx_data = NULL;
1366 int QueueCount;
1367 char *pu8UdpBuffer;
1368 struct iphdr *ih;
1369 struct ethhdr *eth_h;
8dfaafd6 1370
c5c77ba1
JK
1371 nic = netdev_priv(ndev);
1372
c5c77ba1
JK
1373 PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n");
1374
1375 /* Stop the network interface queue */
1376 if (skb->dev != ndev) {
1377 PRINT_ER("Packet not destined to this device\n");
1378 return 0;
1379 }
1380
d5df3797 1381 tx_data = kmalloc(sizeof(struct tx_complete_data), GFP_ATOMIC);
c5c77ba1
JK
1382 if (tx_data == NULL) {
1383 PRINT_ER("Failed to allocate memory for tx_data structure\n");
1384 dev_kfree_skb(skb);
1385 netif_wake_queue(ndev);
1386 return 0;
1387 }
1388
1389 tx_data->buff = skb->data;
1390 tx_data->size = skb->len;
1391 tx_data->skb = skb;
1392
1393 eth_h = (struct ethhdr *)(skb->data);
fc4b95d6 1394 if (eth_h->h_proto == 0x8e88)
c5c77ba1 1395 PRINT_D(INIT_DBG, "EAPOL transmitted\n");
c5c77ba1
JK
1396
1397 /*get source and dest ip addresses*/
1398 ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
1399
1400 pu8UdpBuffer = (char *)ih + sizeof(struct iphdr);
fc4b95d6 1401 if ((pu8UdpBuffer[1] == 68 && pu8UdpBuffer[3] == 67) || (pu8UdpBuffer[1] == 67 && pu8UdpBuffer[3] == 68))
c5c77ba1
JK
1402 PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n", pu8UdpBuffer[248], pu8UdpBuffer[249], pu8UdpBuffer[250]);
1403
c5c77ba1
JK
1404 PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb);
1405
1406 /* Send packet to MAC HW - for now the tx_complete function will be just status
1407 * indicator. still not sure if I need to suspend host transmission till the tx_complete
1408 * function called or not?
1409 * allocated buffer will be freed in tx_complete function.
1410 */
1411 PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n");
1412 nic->netstats.tx_packets++;
1413 nic->netstats.tx_bytes += tx_data->size;
7201cd2c 1414 tx_data->pBssid = g_linux_wlan->vif[nic->u8IfIdx].bssid;
8fc84a6f
GL
1415 QueueCount = wilc_wlan_txq_add_net_pkt((void *)tx_data, tx_data->buff,
1416 tx_data->size,
1417 linux_wlan_tx_complete);
c5c77ba1 1418
c5c77ba1 1419 if (QueueCount > FLOW_CONTROL_UPPER_THRESHOLD) {
817f3fb9
TC
1420 netif_stop_queue(g_linux_wlan->vif[0].ndev);
1421 netif_stop_queue(g_linux_wlan->vif[1].ndev);
c5c77ba1
JK
1422 }
1423
1424 return 0;
1425}
1426
c5c77ba1
JK
1427int mac_close(struct net_device *ndev)
1428{
2726887c 1429 struct wilc_priv *priv;
c5c77ba1 1430 perInterface_wlan_t *nic;
441dc609 1431 struct host_if_drv *pstrWFIDrv;
ca64ad6e 1432 struct wilc *wl;
c5c77ba1
JK
1433
1434 nic = netdev_priv(ndev);
1435
1436 if ((nic == NULL) || (nic->wilc_netdev == NULL) || (nic->wilc_netdev->ieee80211_ptr == NULL) || (nic->wilc_netdev->ieee80211_ptr->wiphy == NULL)) {
1437 PRINT_ER("nic = NULL\n");
1438 return 0;
1439 }
1440
1441 priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
ca64ad6e 1442 wl = nic->wilc;
c5c77ba1
JK
1443
1444 if (priv == NULL) {
1445 PRINT_ER("priv = NULL\n");
1446 return 0;
1447 }
1448
441dc609 1449 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
c5c77ba1 1450
c5c77ba1
JK
1451 PRINT_D(GENERIC_DBG, "Mac close\n");
1452
ca64ad6e
GL
1453 if (!wl) {
1454 PRINT_ER("wl = NULL\n");
c5c77ba1
JK
1455 return 0;
1456 }
1457
1458 if (pstrWFIDrv == NULL) {
1459 PRINT_ER("pstrWFIDrv = NULL\n");
1460 return 0;
1461 }
1462
ca64ad6e
GL
1463 if ((wl->open_ifcs) > 0) {
1464 wl->open_ifcs--;
c5c77ba1
JK
1465 } else {
1466 PRINT_ER("ERROR: MAC close called while number of opened interfaces is zero\n");
1467 return 0;
1468 }
1469
1470 if (nic->wilc_netdev != NULL) {
1471 /* Stop the network interface queue */
1472 netif_stop_queue(nic->wilc_netdev);
1473
a9a16823 1474 wilc_deinit_host_int(nic->wilc_netdev);
c5c77ba1
JK
1475 }
1476
ca64ad6e 1477 if (wl->open_ifcs == 0) {
c5c77ba1 1478 PRINT_D(GENERIC_DBG, "Deinitializing wilc1000\n");
ca64ad6e 1479 wl->close = 1;
53dc0cfe 1480 wilc1000_wlan_deinit(ndev);
c5c77ba1 1481 WILC_WFI_deinit_mon_interface();
c5c77ba1
JK
1482 }
1483
8990d856 1484 up(&close_exit_sync);
c5c77ba1
JK
1485 nic->mac_opened = 0;
1486
1487 return 0;
1488}
1489
c5c77ba1
JK
1490int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
1491{
1492
63d03e47 1493 u8 *buff = NULL;
ca356ada 1494 s8 rssi;
4e4467fd 1495 u32 size = 0, length = 0;
c5c77ba1 1496 perInterface_wlan_t *nic;
2726887c 1497 struct wilc_priv *priv;
e6e12661 1498 s32 s32Error = 0;
07320b6b 1499 struct wilc *wilc;
c5c77ba1 1500
c5c77ba1 1501 /* struct iwreq *wrq = (struct iwreq *) req; // tony moved to case SIOCSIWPRIV */
c5c77ba1 1502 nic = netdev_priv(ndev);
07320b6b 1503 wilc = nic->wilc;
c5c77ba1 1504
07320b6b 1505 if (!wilc->initialized)
c5c77ba1
JK
1506 return 0;
1507
c5c77ba1 1508 switch (cmd) {
c5c77ba1
JK
1509
1510 /* ]] 2013-06-24 */
1511 case SIOCSIWPRIV:
1512 {
1513 struct iwreq *wrq = (struct iwreq *) req; /* added by tony */
1514
1515 size = wrq->u.data.length;
1516
1517 if (size && wrq->u.data.pointer) {
c5c77ba1 1518
4a01f1c3 1519 buff = memdup_user(wrq->u.data.pointer, wrq->u.data.length);
360e27a9
SM
1520 if (IS_ERR(buff))
1521 return PTR_ERR(buff);
c5c77ba1
JK
1522
1523 if (strncasecmp(buff, "RSSI", length) == 0) {
c5c77ba1
JK
1524 priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
1525 s32Error = host_int_get_rssi(priv->hWILCWFIDrv, &(rssi));
1526 if (s32Error)
1527 PRINT_ER("Failed to send get rssi param's message queue ");
c5c77ba1
JK
1528 PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi);
1529
1530 /*Rounding up the rssi negative value*/
1531 rssi += 5;
1532
1533 snprintf(buff, size, "rssi %d", rssi);
1534
1535 if (copy_to_user(wrq->u.data.pointer, buff, size)) {
60cb1e20 1536 PRINT_ER("%s: failed to copy data to user buffer\n", __func__);
c5c77ba1
JK
1537 s32Error = -EFAULT;
1538 goto done;
1539 }
1540 }
1541 }
1542 }
1543 break;
1544
1545 default:
1546 {
1547 PRINT_INFO(GENERIC_DBG, "Command - %d - has been received\n", cmd);
1548 s32Error = -EOPNOTSUPP;
1549 goto done;
1550 }
1551 }
1552
1553done:
1554
642ac6c0 1555 kfree(buff);
c5c77ba1
JK
1556
1557 return s32Error;
1558}
1559
cb1991ac 1560void frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset)
c5c77ba1
JK
1561{
1562
1563 unsigned int frame_len = 0;
1564 int stats;
1565 unsigned char *buff_to_send = NULL;
1566 struct sk_buff *skb;
c5c77ba1
JK
1567 struct net_device *wilc_netdev;
1568 perInterface_wlan_t *nic;
1569
1570 wilc_netdev = GetIfHandler(buff);
1571 if (wilc_netdev == NULL)
1572 return;
1573
1574 buff += pkt_offset;
1575 nic = netdev_priv(wilc_netdev);
1576
1577 if (size > 0) {
1578
1579 frame_len = size;
1580 buff_to_send = buff;
1581
c5c77ba1
JK
1582 /* Need to send the packet up to the host, allocate a skb buffer */
1583 skb = dev_alloc_skb(frame_len);
1584 if (skb == NULL) {
1585 PRINT_ER("Low memory - packet droped\n");
1586 return;
1587 }
1588
cb1991ac
GL
1589 if (wilc == NULL || wilc_netdev == NULL)
1590 PRINT_ER("wilc_netdev in wilc is NULL");
c5c77ba1
JK
1591 skb->dev = wilc_netdev;
1592
fc4b95d6 1593 if (skb->dev == NULL)
c5c77ba1 1594 PRINT_ER("skb->dev is NULL\n");
c5c77ba1
JK
1595
1596 /*
1597 * for(i=0;i<40;i++)
1598 * {
1599 * if(i<frame_len)
1600 * WILC_PRINTF("buff_to_send[%d]=%2x\n",i,buff_to_send[i]);
1601 *
1602 * }*/
1603
1604 /* skb_put(skb, frame_len); */
1605 memcpy(skb_put(skb, frame_len), buff_to_send, frame_len);
1606
1607 /* WILC_PRINTF("After MEM_CPY\n"); */
1608
1609 /* nic = netdev_priv(wilc_netdev); */
1610
c5c77ba1 1611 skb->protocol = eth_type_trans(skb, wilc_netdev);
c5c77ba1
JK
1612 /* Send the packet to the stack by giving it to the bridge */
1613 nic->netstats.rx_packets++;
1614 nic->netstats.rx_bytes += frame_len;
1615 skb->ip_summed = CHECKSUM_UNNECESSARY;
1616 stats = netif_rx(skb);
1617 PRINT_D(RX_DBG, "netif_rx ret value is: %d\n", stats);
1618 }
c5c77ba1
JK
1619}
1620
11f4b2ee 1621void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
c5c77ba1
JK
1622{
1623 int i = 0;
1624 perInterface_wlan_t *nic;
1625
c5c77ba1
JK
1626 /*Pass the frame on the monitor interface, if any.*/
1627 /*Otherwise, pass it on p2p0 netdev, if registered on it*/
11f4b2ee
GL
1628 for (i = 0; i < wilc->vif_num; i++) {
1629 nic = netdev_priv(wilc->vif[i].ndev);
c5c77ba1
JK
1630 if (nic->monitor_flag) {
1631 WILC_WFI_monitor_rx(buff, size);
1632 return;
1633 }
1634 }
1635
11f4b2ee 1636 nic = netdev_priv(wilc->vif[1].ndev); /* p2p0 */
c5c77ba1 1637 if ((buff[0] == nic->g_struct_frame_reg[0].frame_type && nic->g_struct_frame_reg[0].reg) ||
fc4b95d6 1638 (buff[0] == nic->g_struct_frame_reg[1].frame_type && nic->g_struct_frame_reg[1].reg))
11f4b2ee 1639 WILC_WFI_p2p_rx(wilc->vif[1].ndev, buff, size);
c5c77ba1
JK
1640}
1641
4875c499
TC
1642void wl_wlan_cleanup(void)
1643{
1644 int i = 0;
1645 perInterface_wlan_t *nic[NUM_CONCURRENT_IFC];
1646
1647 if (g_linux_wlan &&
1648 (g_linux_wlan->vif[0].ndev || g_linux_wlan->vif[1].ndev)) {
1649 unregister_inetaddr_notifier(&g_dev_notifier);
1650
1651 for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1652 nic[i] = netdev_priv(g_linux_wlan->vif[i].ndev);
1653 }
1654
8b8ad7bc
TC
1655 if (g_linux_wlan && g_linux_wlan->firmware)
1656 release_firmware(g_linux_wlan->firmware);
4875c499
TC
1657
1658 if (g_linux_wlan &&
1659 (g_linux_wlan->vif[0].ndev || g_linux_wlan->vif[1].ndev)) {
1660 linux_wlan_lock_timeout(&close_exit_sync, 12 * 1000);
1661
1662 for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1663 if (g_linux_wlan->vif[i].ndev)
1664 if (nic[i]->mac_opened)
1665 mac_close(g_linux_wlan->vif[i].ndev);
1666
1667 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1668 unregister_netdev(g_linux_wlan->vif[i].ndev);
1669 wilc_free_wiphy(g_linux_wlan->vif[i].ndev);
1670 free_netdev(g_linux_wlan->vif[i].ndev);
1671 }
1672 }
1673
1674 kfree(g_linux_wlan);
1675
1676#if defined(WILC_DEBUGFS)
1677 wilc_debugfs_remove();
1678#endif
1679 linux_wlan_device_detection(0);
1680 linux_wlan_device_power(0);
1681}
1682
12ba5416 1683int wilc_netdev_init(struct wilc **wilc)
c5c77ba1 1684{
c5c77ba1
JK
1685 int i;
1686 perInterface_wlan_t *nic;
1687 struct net_device *ndev;
1688
642768ee 1689 sema_init(&close_exit_sync, 0);
c5c77ba1
JK
1690
1691 /*create the common structure*/
f61c5aff 1692 g_linux_wlan = kzalloc(sizeof(*g_linux_wlan), GFP_KERNEL);
ac61ef86
CL
1693 if (!g_linux_wlan)
1694 return -ENOMEM;
c5c77ba1 1695
12ba5416
TC
1696 *wilc = g_linux_wlan;
1697
c5c77ba1 1698 register_inetaddr_notifier(&g_dev_notifier);
c5c77ba1
JK
1699
1700 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1701 /*allocate first ethernet device with perinterface_wlan_t as its private data*/
1702 ndev = alloc_etherdev(sizeof(perInterface_wlan_t));
1703 if (!ndev) {
1704 PRINT_ER("Failed to allocate ethernet dev\n");
1705 return -1;
1706 }
1707
1708 nic = netdev_priv(ndev);
1709 memset(nic, 0, sizeof(perInterface_wlan_t));
1710
1711 /*Name the Devices*/
1712 if (i == 0) {
1713 #if defined(NM73131) /* tony, 2012-09-20 */
1714 strcpy(ndev->name, "wilc_eth%d");
1715 #elif defined(PLAT_CLM9722) /* rachel */
1716 strcpy(ndev->name, "eth%d");
1717 #else /* PANDA_BOARD, PLAT_ALLWINNER_A10, PLAT_ALLWINNER_A20, PLAT_ALLWINNER_A31, PLAT_AML8726_M3 or PLAT_WMS8304 */
1718 strcpy(ndev->name, "wlan%d");
1719 #endif
1720 } else
1721 strcpy(ndev->name, "p2p%d");
1722
c1b30f6a 1723 nic->u8IfIdx = g_linux_wlan->vif_num;
c5c77ba1 1724 nic->wilc_netdev = ndev;
38b3001d 1725 nic->wilc = *wilc;
817f3fb9 1726 g_linux_wlan->vif[g_linux_wlan->vif_num].ndev = ndev;
c1b30f6a 1727 g_linux_wlan->vif_num++;
e5af0561 1728 ndev->netdev_ops = &wilc_netdev_ops;
c5c77ba1 1729
c5c77ba1
JK
1730 {
1731 struct wireless_dev *wdev;
1732 /*Register WiFi*/
8459fd54 1733 wdev = wilc_create_wiphy(ndev);
c5c77ba1
JK
1734
1735 #ifdef WILC_SDIO
1736 /* set netdev, tony */
1737 SET_NETDEV_DEV(ndev, &local_sdio_func->dev);
1738 #endif
1739
1740 if (wdev == NULL) {
1741 PRINT_ER("Can't register WILC Wiphy\n");
1742 return -1;
1743 }
1744
1745 /*linking the wireless_dev structure with the netdevice*/
1746 nic->wilc_netdev->ieee80211_ptr = wdev;
1747 nic->wilc_netdev->ml_priv = nic;
1748 wdev->netdev = nic->wilc_netdev;
1749 nic->netstats.rx_packets = 0;
1750 nic->netstats.tx_packets = 0;
1751 nic->netstats.rx_bytes = 0;
1752 nic->netstats.tx_bytes = 0;
1753
1754 }
c5c77ba1 1755
c5c77ba1
JK
1756 if (register_netdev(ndev)) {
1757 PRINT_ER("Device couldn't be registered - %s\n", ndev->name);
1758 return -1; /* ERROR */
1759 }
1760
1761 nic->iftype = STATION_MODE;
1762 nic->mac_opened = 0;
1763
1764 }
1765
1766 #ifndef WILC_SDIO
1767 if (!linux_spi_init(&g_linux_wlan->wilc_spidev)) {
17aacd43 1768 PRINT_ER("Can't initialize SPI\n");
c5c77ba1
JK
1769 return -1; /* ERROR */
1770 }
1771 g_linux_wlan->wilc_spidev = wilc_spi_dev;
1772 #else
1773 g_linux_wlan->wilc_sdio_func = local_sdio_func;
1774 #endif
1775
1776 return 0;
1777}
1778
c5c77ba1
JK
1779/*The 1st function called after module inserted*/
1780static int __init init_wilc_driver(void)
1781{
702c0e50
GL
1782#ifdef WILC_SPI
1783 struct wilc *wilc;
1784#endif
1785
33694632 1786#if defined(WILC_DEBUGFS)
c5c77ba1
JK
1787 if (wilc_debugfs_init() < 0) {
1788 PRINT_D(GENERIC_DBG, "fail to create debugfs for wilc driver\n");
1789 return -1;
1790 }
1791#endif
1792
1793 printk("IN INIT FUNCTION\n");
691f1a2f 1794 printk("*** WILC1000 driver VERSION=[10.2] FW_VER=[10.2] ***\n");
c5c77ba1
JK
1795
1796 linux_wlan_device_power(1);
1797 msleep(100);
1798 linux_wlan_device_detection(1);
1799
1800#ifdef WILC_SDIO
1801 {
1802 int ret;
1803
1804 ret = sdio_register_driver(&wilc_bus);
fc4b95d6 1805 if (ret < 0)
c5c77ba1 1806 PRINT_D(INIT_DBG, "init_wilc_driver: Failed register sdio driver\n");
c5c77ba1
JK
1807
1808 return ret;
1809 }
1810#else
1811 PRINT_D(INIT_DBG, "Initializing netdev\n");
702c0e50 1812 if (wilc_netdev_init(&wilc))
c5c77ba1 1813 PRINT_ER("Couldn't initialize netdev\n");
c5c77ba1
JK
1814 return 0;
1815#endif
1816}
1817late_initcall(init_wilc_driver);
1818
1819static void __exit exit_wilc_driver(void)
1820{
c2eda352 1821#ifndef WILC_SDIO
0c07f8c7 1822 PRINT_D(INIT_DBG, "SPI unregister...\n");
c2eda352
CL
1823 spi_unregister_driver(&wilc_bus);
1824#else
0c07f8c7 1825 PRINT_D(INIT_DBG, "SDIO unregister...\n");
c2eda352
CL
1826 sdio_unregister_driver(&wilc_bus);
1827#endif
c5c77ba1
JK
1828}
1829module_exit(exit_wilc_driver);
1830
1831MODULE_LICENSE("GPL");
This page took 0.276014 seconds and 5 git commands to generate.