1 #include "wilc_wfi_cfgoperations.h"
2 #include "linux_wlan_common.h"
3 #include "wilc_wlan_if.h"
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>
12 #include <linux/gpio.h>
14 #include <linux/kthread.h>
15 #include <linux/firmware.h>
16 #include <linux/delay.h>
18 #include <linux/init.h>
19 #include <linux/netdevice.h>
20 #include <linux/inetdevice.h>
21 #include <linux/etherdevice.h>
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/skbuff.h>
26 #include <linux/version.h>
27 #include <linux/semaphore.h>
30 #include "linux_wlan_sdio.h"
32 #include "linux_wlan_spi.h"
35 #if defined(CUSTOMER_PLATFORM)
37 TODO : Write power control functions as customer platform.
41 #define _linux_wlan_device_power_on() {}
42 #define _linux_wlan_device_power_off() {}
44 #define _linux_wlan_device_detection() {}
45 #define _linux_wlan_device_removal() {}
48 extern bool g_obtainingIP;
49 extern u16 Set_machw_change_vir_if(bool bValue);
50 extern void resolve_disconnect_aberration(void *drvHandler);
51 extern u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
52 void wilc1000_wlan_deinit(linux_wlan_t *nic);
53 extern struct timer_list hDuringIpTimer;
55 static int linux_wlan_device_power(int on_off)
57 PRINT_D(INIT_DBG, "linux_wlan_device_power.. (%d)\n", on_off);
60 _linux_wlan_device_power_on();
62 _linux_wlan_device_power_off();
68 static int linux_wlan_device_detection(int on_off)
70 PRINT_D(INIT_DBG, "linux_wlan_device_detection.. (%d)\n", on_off);
74 _linux_wlan_device_detection();
76 _linux_wlan_device_removal();
83 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr);
85 static struct notifier_block g_dev_notifier = {
86 .notifier_call = dev_state_ev_handler
89 #define wilc_wlan_deinit(nic) { if (&g_linux_wlan->oup != NULL) \
90 if (g_linux_wlan->oup.wlan_cleanup != NULL) \
91 g_linux_wlan->oup.wlan_cleanup(); }
96 * to sync between mac_close and module exit.
97 * don't initialize or de-initialize from init/deinitlocks
98 * to be initialized from module wilc_netdev_init and
99 * deinitialized from mdoule_exit
101 static struct semaphore close_exit_sync;
103 static int wlan_deinit_locks(linux_wlan_t *nic);
104 static void wlan_deinitialize_threads(linux_wlan_t *nic);
105 extern void WILC_WFI_monitor_rx(u8 *buff, u32 size);
106 extern void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size);
108 static void linux_wlan_tx_complete(void *priv, int status);
109 static int mac_init_fn(struct net_device *ndev);
110 int mac_xmit(struct sk_buff *skb, struct net_device *dev);
111 int mac_open(struct net_device *ndev);
112 int mac_close(struct net_device *ndev);
113 static struct net_device_stats *mac_stats(struct net_device *dev);
114 static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd);
115 static void wilc_set_multicast_list(struct net_device *dev);
118 * for now - in frmw_to_linux there should be private data to be passed to it
119 * and this data should be pointer to net device
121 linux_wlan_t *g_linux_wlan;
122 wilc_wlan_oup_t *gpstrWlanOps;
123 bool bEnablePS = true;
125 static const struct net_device_ops wilc_netdev_ops = {
126 .ndo_init = mac_init_fn,
127 .ndo_open = mac_open,
128 .ndo_stop = mac_close,
129 .ndo_start_xmit = mac_xmit,
130 .ndo_do_ioctl = mac_ioctl,
131 .ndo_get_stats = mac_stats,
132 .ndo_set_rx_mode = wilc_set_multicast_list,
138 extern volatile int timeNo;
140 #define DEGUG_BUFFER_LENGTH 1000
141 volatile int WatchDogdebuggerCounter;
142 char DebugBuffer[DEGUG_BUFFER_LENGTH + 20] = {0};
143 static char *ps8current = DebugBuffer;
145 void printk_later(const char *format, ...)
149 va_start(args, format);
150 ps8current += vsprintf(ps8current, format, args);
152 if ((ps8current - DebugBuffer) > DEGUG_BUFFER_LENGTH)
153 ps8current = DebugBuffer;
159 if (DebugBuffer[0]) {
160 DebugBuffer[DEGUG_BUFFER_LENGTH] = 0;
161 PRINT_INFO(GENERIC_DBG, "early printed\n");
162 PRINT_D(GENERIC_DBG, ps8current + 1);
164 PRINT_INFO(GENERIC_DBG, "latest printed\n");
165 PRINT_D(GENERIC_DBG, DebugBuffer);
167 ps8current = DebugBuffer;
171 void Reset_WatchDogdebugger(void)
173 WatchDogdebuggerCounter = 0;
176 static int DebuggingThreadTask(void *vp)
179 while (!WatchDogdebuggerCounter) {
180 PRINT_D(GENERIC_DBG, "Debug Thread Running %d\n", timeNo);
181 WatchDogdebuggerCounter = 1;
185 WatchDogdebuggerCounter = 0;
190 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr)
192 struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr;
193 struct wilc_priv *priv;
194 tstrWILC_WFIDrv *pstrWFIDrv;
195 struct net_device *dev;
197 perInterface_wlan_t *nic;
199 char wlan_dev_name[5] = "wlan0";
201 if (dev_iface == NULL || dev_iface->ifa_dev == NULL || dev_iface->ifa_dev->dev == NULL) {
202 PRINT_D(GENERIC_DBG, "dev_iface = NULL\n");
206 if ((memcmp(dev_iface->ifa_label, "wlan0", 5)) && (memcmp(dev_iface->ifa_label, "p2p0", 4))) {
207 PRINT_D(GENERIC_DBG, "Interface is neither WLAN0 nor P2P0\n");
211 dev = (struct net_device *)dev_iface->ifa_dev->dev;
212 if (dev->ieee80211_ptr == NULL || dev->ieee80211_ptr->wiphy == NULL) {
213 PRINT_D(GENERIC_DBG, "No Wireless registerd\n");
216 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
218 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
221 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
222 nic = netdev_priv(dev);
223 if (nic == NULL || pstrWFIDrv == NULL) {
224 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
228 PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler +++\n"); /* tony */
232 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_UP %p\n", dev); /* tony */
234 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n");
236 /*If we are in station mode or client mode*/
237 if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) {
238 pstrWFIDrv->IFC_UP = 1;
239 g_obtainingIP = false;
240 del_timer(&hDuringIpTimer);
241 PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n");
245 host_int_set_power_mgmt(pstrWFIDrv, 1, 0);
247 PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label);
249 pIP_Add_buff = (char *) (&(dev_iface->ifa_address));
250 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]);
251 host_int_setup_ipaddress(pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx);
256 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev); /* tony */
258 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n");
259 if (nic->iftype == STATION_MODE || nic->iftype == CLIENT_MODE) {
260 pstrWFIDrv->IFC_UP = 0;
261 g_obtainingIP = false;
264 if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0)
265 host_int_set_power_mgmt(pstrWFIDrv, 0, 0);
267 resolve_disconnect_aberration(pstrWFIDrv);
269 PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label);
271 pIP_Add_buff = null_ip;
272 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]);
274 host_int_setup_ipaddress(pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx);
279 PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler event=default\n"); /* tony */
280 PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event);
289 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
290 static irqreturn_t isr_uh_routine(int irq, void *user_data)
292 PRINT_D(INT_DBG, "Interrupt received UH\n");
294 /*While mac is closing cacncel the handling of any interrupts received*/
295 if (g_linux_wlan->close) {
296 PRINT_ER("Driver is CLOSING: Can't handle UH interrupt\n");
299 return IRQ_WAKE_THREAD;
303 irqreturn_t isr_bh_routine(int irq, void *userdata)
307 nic = (linux_wlan_t *)userdata;
309 /*While mac is closing cacncel the handling of any interrupts received*/
310 if (g_linux_wlan->close) {
311 PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n");
315 PRINT_D(INT_DBG, "Interrupt received BH\n");
316 if (g_linux_wlan->oup.wlan_handle_rx_isr != 0)
317 g_linux_wlan->oup.wlan_handle_rx_isr();
319 PRINT_ER("wlan_handle_rx_isr() hasn't been initialized\n");
324 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
325 static int init_irq(linux_wlan_t *p_nic)
328 linux_wlan_t *nic = p_nic;
330 /*initialize GPIO and register IRQ num*/
332 if ((gpio_request(GPIO_NUM, "WILC_INTR") == 0) &&
333 (gpio_direction_input(GPIO_NUM) == 0)) {
334 #if defined(CUSTOMER_PLATFORM)
336 TODO : save the registerd irq number to the private wilc context in kernel.
338 * ex) nic->dev_irq_num = gpio_to_irq(GPIO_NUM);
341 nic->dev_irq_num = gpio_to_irq(GPIO_NUM);
345 PRINT_ER("could not obtain gpio for WILC_INTR\n");
348 if ((ret != -1) && (request_threaded_irq(nic->dev_irq_num, isr_uh_routine, isr_bh_routine,
349 IRQF_TRIGGER_LOW | IRQF_ONESHOT, /*Without IRQF_ONESHOT the uh will remain kicked in and dont gave a chance to bh*/
350 "WILC_IRQ", nic)) < 0) {
352 PRINT_ER("Failed to request IRQ for GPIO: %d\n", GPIO_NUM);
356 PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n",
357 nic->dev_irq_num, GPIO_NUM);
364 static void deinit_irq(linux_wlan_t *nic)
366 #if (defined WILC_SPI) || (defined WILC_SDIO_IRQ_GPIO)
367 /* Deintialize IRQ */
368 if (&nic->dev_irq_num != 0) {
369 free_irq(nic->dev_irq_num, g_linux_wlan);
379 void linux_wlan_dbg(u8 *buff)
381 PRINT_D(INIT_DBG, "%d\n", *buff);
384 int linux_wlan_lock_timeout(void *vp, u32 timeout)
388 PRINT_D(LOCK_DBG, "Locking %p\n", vp);
390 error = down_timeout((struct semaphore *)vp, msecs_to_jiffies(timeout));
392 PRINT_ER("Failed, mutex is NULL\n");
396 void linux_wlan_mac_indicate(int flag)
398 /*I have to do it that way becuase there is no mean to encapsulate device pointer
401 linux_wlan_t *pd = g_linux_wlan;
404 if (flag == WILC_MAC_INDICATE_STATUS) {
405 pd->oup.wlan_cfg_get_value(WID_STATUS, (unsigned char *)&status, 4);
406 if (pd->mac_status == WILC_MAC_STATUS_INIT) {
407 pd->mac_status = status;
410 pd->mac_status = status;
413 if (pd->mac_status == WILC_MAC_STATUS_CONNECT) { /* Connect */
416 } else if (flag == WILC_MAC_INDICATE_SCAN) {
417 PRINT_D(GENERIC_DBG, "Scanning ...\n");
423 struct net_device *GetIfHandler(u8 *pMacHeader)
428 Bssid = pMacHeader + 10;
429 Bssid1 = pMacHeader + 4;
431 for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
432 if (!memcmp(Bssid1, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN) ||
433 !memcmp(Bssid, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN)) {
434 return g_linux_wlan->strInterfaceInfo[i].wilc_netdev;
437 PRINT_INFO(INIT_DBG, "Invalide handle\n");
438 for (i = 0; i < 25; i++)
439 PRINT_D(INIT_DBG, "%02x ", pMacHeader[i]);
440 Bssid = pMacHeader + 18;
441 Bssid1 = pMacHeader + 12;
442 for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
443 if (!memcmp(Bssid1, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN) ||
444 !memcmp(Bssid, g_linux_wlan->strInterfaceInfo[i].aBSSID, ETH_ALEN)) {
445 PRINT_D(INIT_DBG, "Ctx [%p]\n", g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
446 return g_linux_wlan->strInterfaceInfo[i].wilc_netdev;
449 PRINT_INFO(INIT_DBG, "\n");
453 int linux_wlan_set_bssid(struct net_device *wilc_netdev, u8 *pBSSID)
458 PRINT_D(INIT_DBG, "set bssid on[%p]\n", wilc_netdev);
459 for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
460 if (g_linux_wlan->strInterfaceInfo[i].wilc_netdev == wilc_netdev) {
461 PRINT_D(INIT_DBG, "set bssid [%x][%x][%x]\n", pBSSID[0], pBSSID[1], pBSSID[2]);
462 memcpy(g_linux_wlan->strInterfaceInfo[i].aBSSID, pBSSID, 6);
470 /*Function to get number of connected interfaces*/
471 int linux_wlan_get_num_conn_ifcs(void)
474 u8 null_bssid[6] = {0};
477 for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
478 if (memcmp(g_linux_wlan->strInterfaceInfo[i].aBSSID, null_bssid, 6))
484 #define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
486 static int linux_wlan_txq_task(void *vp)
490 #if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
491 #define TX_BACKOFF_WEIGHT_INCR_STEP (1)
492 #define TX_BACKOFF_WEIGHT_DECR_STEP (1)
493 #define TX_BACKOFF_WEIGHT_MAX (7)
494 #define TX_BACKOFF_WEIGHT_MIN (0)
495 #define TX_BACKOFF_WEIGHT_UNIT_MS (10)
496 int backoff_weight = TX_BACKOFF_WEIGHT_MIN;
499 /* inform wilc1000_wlan_init that TXQ task is started. */
500 up(&g_linux_wlan->txq_thread_started);
503 PRINT_D(TX_DBG, "txq_task Taking a nap :)\n");
504 down(&g_linux_wlan->txq_event);
505 /* wait_for_completion(&pd->txq_event); */
506 PRINT_D(TX_DBG, "txq_task Who waked me up :$\n");
508 if (g_linux_wlan->close) {
509 /*Unlock the mutex in the mac_close function to indicate the exiting of the TX thread */
510 up(&g_linux_wlan->txq_thread_started);
512 while (!kthread_should_stop())
515 PRINT_D(TX_DBG, "TX thread stopped\n");
518 PRINT_D(TX_DBG, "txq_task handle the sending packet and let me go to sleep.\n");
519 #if !defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
520 ret = wilc_wlan_handle_txq(&txq_count);
523 ret = wilc_wlan_handle_txq(&txq_count);
524 if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD /* && netif_queue_stopped(pd->wilc_netdev)*/) {
525 PRINT_D(TX_DBG, "Waking up queue\n");
526 /* netif_wake_queue(pd->wilc_netdev); */
527 if (netif_queue_stopped(g_linux_wlan->strInterfaceInfo[0].wilc_netdev))
528 netif_wake_queue(g_linux_wlan->strInterfaceInfo[0].wilc_netdev);
529 if (netif_queue_stopped(g_linux_wlan->strInterfaceInfo[1].wilc_netdev))
530 netif_wake_queue(g_linux_wlan->strInterfaceInfo[1].wilc_netdev);
533 if (ret == WILC_TX_ERR_NO_BUF) { /* failed to allocate buffers in chip. */
535 /* Back off from sending packets for some time. */
536 /* schedule_timeout will allow RX task to run and free buffers.*/
537 /* set_current_state(TASK_UNINTERRUPTIBLE); */
538 /* timeout = schedule_timeout(timeout); */
539 msleep(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight);
540 } while (/*timeout*/ 0);
541 backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP;
542 if (backoff_weight > TX_BACKOFF_WEIGHT_MAX)
543 backoff_weight = TX_BACKOFF_WEIGHT_MAX;
545 if (backoff_weight > TX_BACKOFF_WEIGHT_MIN) {
546 backoff_weight -= TX_BACKOFF_WEIGHT_DECR_STEP;
547 if (backoff_weight < TX_BACKOFF_WEIGHT_MIN)
548 backoff_weight = TX_BACKOFF_WEIGHT_MIN;
551 /*TODO: drop packets after a certain time/number of retry count. */
552 } while (ret == WILC_TX_ERR_NO_BUF && !g_linux_wlan->close); /* retry sending packets if no more buffers in chip. */
558 void linux_wlan_rx_complete(void)
560 PRINT_D(RX_DBG, "RX completed\n");
563 int linux_wlan_get_firmware(perInterface_wlan_t *p_nic)
566 perInterface_wlan_t *nic = p_nic;
568 const struct firmware *wilc_firmware;
571 if (nic->iftype == AP_MODE)
572 firmware = AP_FIRMWARE;
573 else if (nic->iftype == STATION_MODE)
574 firmware = STA_FIRMWARE;
577 PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n");
578 firmware = P2P_CONCURRENCY_FIRMWARE;
582 PRINT_ER("NIC is NULL\n");
586 if (&nic->wilc_netdev->dev == NULL) {
587 PRINT_ER("&nic->wilc_netdev->dev is NULL\n");
591 /* the firmare should be located in /lib/firmware in
592 * root file system with the name specified above */
595 if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_sdio_func->dev) != 0) {
596 PRINT_ER("%s - firmare not available\n", firmware);
601 if (request_firmware(&wilc_firmware, firmware, &g_linux_wlan->wilc_spidev->dev) != 0) {
602 PRINT_ER("%s - firmare not available\n", firmware);
607 g_linux_wlan->wilc_firmware = wilc_firmware;
615 #ifdef COMPLEMENT_BOOT
616 int repeat_power_cycle(perInterface_wlan_t *nic);
619 static int linux_wlan_start_firmware(perInterface_wlan_t *nic)
624 PRINT_D(INIT_DBG, "Starting Firmware ...\n");
625 ret = wilc_wlan_start();
627 PRINT_ER("Failed to start Firmware\n");
631 /* wait for mac ready */
632 PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n");
633 ret = linux_wlan_lock_timeout(&g_linux_wlan->sync_event, 5000);
635 #ifdef COMPLEMENT_BOOT
636 static int timeout = 5;
639 PRINT_D(INIT_DBG, "repeat power cycle[%d]", timeout);
640 ret = repeat_power_cycle(nic);
647 PRINT_D(INIT_DBG, "Firmware start timed out");
651 * TODO: Driver shouoldn't wait forever for firmware to get started -
652 * in case of timeout this should be handled properly
654 PRINT_D(INIT_DBG, "Firmware successfully started\n");
659 static int linux_wlan_firmware_download(linux_wlan_t *p_nic)
664 if (g_linux_wlan->wilc_firmware == NULL) {
665 PRINT_ER("Firmware buffer is NULL\n");
670 * do the firmware download
672 PRINT_D(INIT_DBG, "Downloading Firmware ...\n");
673 ret = wilc_wlan_firmware_download(g_linux_wlan->wilc_firmware->data,
674 g_linux_wlan->wilc_firmware->size);
678 /* Freeing FW buffer */
679 PRINT_D(INIT_DBG, "Freeing FW buffer ...\n");
680 PRINT_D(INIT_DBG, "Releasing firmware\n");
681 release_firmware(g_linux_wlan->wilc_firmware);
682 g_linux_wlan->wilc_firmware = NULL;
684 PRINT_D(INIT_DBG, "Download Succeeded\n");
690 /* startup configuration - could be changed later using iconfig*/
691 static int linux_wlan_init_test_config(struct net_device *dev, linux_wlan_t *p_nic)
694 unsigned char c_val[64];
695 unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff};
697 struct wilc_priv *priv;
698 tstrWILC_WFIDrv *pstrWFIDrv;
700 PRINT_D(TX_DBG, "Start configuring Firmware\n");
701 get_random_bytes(&mac_add[5], 1);
702 get_random_bytes(&mac_add[4], 1);
703 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
704 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
705 PRINT_D(INIT_DBG, "Host = %p\n", pstrWFIDrv);
707 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]);
710 if (g_linux_wlan->oup.wlan_cfg_set == NULL) {
711 PRINT_D(INIT_DBG, "Null p[ointer\n");
717 if (!g_linux_wlan->oup.wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0))
720 /*to tell fw that we are going to use PC test - WILC specific*/
722 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_PC_TEST_MODE, c_val, 1, 0, 0))
725 c_val[0] = INFRASTRUCTURE;
726 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0, 0))
729 /* c_val[0] = RATE_AUTO; */
730 c_val[0] = RATE_AUTO;
731 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0))
734 c_val[0] = G_MIXED_11B_2_MODE;
735 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11G_OPERATING_MODE, c_val, 1, 0, 0))
739 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0))
742 c_val[0] = G_SHORT_PREAMBLE;
743 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_PREAMBLE, c_val, 1, 0, 0))
746 c_val[0] = AUTO_PROT;
747 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0, 0))
750 c_val[0] = ACTIVE_SCAN;
751 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0, 0))
754 c_val[0] = SITE_SURVEY_OFF;
755 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0, 0))
758 *((int *)c_val) = 0xffff; /* Never use RTS-CTS */
759 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0, 0))
762 *((int *)c_val) = 2346;
763 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0))
767 /* -------------------------------------------------------------- */
768 /* Configuration : String with length less than 32 bytes */
769 /* Values to set : Any string with length less than 32 bytes */
770 /* ( In BSS Station Set SSID to "" (null string) */
771 /* to enable Broadcast SSID suppport ) */
772 /* -------------------------------------------------------------- */
774 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0, 0))
778 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_QOS_ENABLE, c_val, 1, 0, 0))
781 c_val[0] = NO_POWERSAVE;
782 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0))
785 c_val[0] = NO_ENCRYPT; /* NO_ENCRYPT, 0x79 */
786 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0, 0))
789 c_val[0] = OPEN_SYSTEM;
790 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 0, 0))
793 /* WEP/802 11I Configuration */
794 /* ------------------------------------------------------------------ */
795 /* Configuration : WEP Key */
796 /* Values (0x) : 5 byte for WEP40 and 13 bytes for WEP104 */
797 /* In case more than 5 bytes are passed on for WEP 40 */
798 /* only first 5 bytes will be used as the key */
799 /* ------------------------------------------------------------------ */
801 strcpy(c_val, "123456790abcdef1234567890");
802 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val) + 1), 0, 0))
805 /* WEP/802 11I Configuration */
806 /* ------------------------------------------------------------------ */
807 /* Configuration : AES/TKIP WPA/RSNA Pre-Shared Key */
808 /* Values to set : Any string with length greater than equal to 8 bytes */
809 /* and less than 64 bytes */
810 /* ------------------------------------------------------------------ */
811 strcpy(c_val, "12345678");
812 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 0, 0))
815 /* IEEE802.1X Key Configuration */
816 /* ------------------------------------------------------------------ */
817 /* Configuration : Radius Server Access Secret Key */
818 /* Values to set : Any string with length greater than equal to 8 bytes */
819 /* and less than 65 bytes */
820 /* ------------------------------------------------------------------ */
821 strcpy(c_val, "password");
822 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val) + 1), 0, 0))
825 /* IEEE802.1X Server Address Configuration */
826 /* ------------------------------------------------------------------ */
827 /* Configuration : Radius Server IP Address */
828 /* Values to set : Any valid IP Address */
829 /* ------------------------------------------------------------------ */
834 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_1X_SERV_ADDR, c_val, 4, 0, 0))
838 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0))
842 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_DTIM_PERIOD, c_val, 1, 0, 0))
845 c_val[0] = NORMAL_ACK;
846 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_ACK_POLICY, c_val, 1, 0, 0))
850 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, 0, 0))
854 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0, 0))
858 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0, 0))
861 /* Beacon Interval */
862 /* -------------------------------------------------------------------- */
863 /* Configuration : Sets the beacon interval value */
864 /* Values to set : Any 16-bit value */
865 /* -------------------------------------------------------------------- */
867 *((int *)c_val) = 100;
868 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0, 0))
871 c_val[0] = REKEY_DISABLE;
872 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 0, 0))
875 /* Rekey Time (s) (Used only when the Rekey policy is 2 or 4) */
876 /* -------------------------------------------------------------------- */
877 /* Configuration : Sets the Rekey Time (s) */
878 /* Values to set : 32-bit value */
879 /* -------------------------------------------------------------------- */
880 *((int *)c_val) = 84600;
881 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 0, 0))
884 /* Rekey Packet Count (in 1000s; used when Rekey Policy is 3) */
885 /* -------------------------------------------------------------------- */
886 /* Configuration : Sets Rekey Group Packet count */
887 /* Values to set : 32-bit Value */
888 /* -------------------------------------------------------------------- */
889 *((int *)c_val) = 500;
890 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0, 0))
894 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0, 0))
897 c_val[0] = G_SELF_CTS_PROT;
898 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0))
901 c_val[0] = 1; /* Enable N */
902 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0, 0))
905 c_val[0] = HT_MIXED_MODE;
906 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 0, 0))
909 c_val[0] = 1; /* TXOP Prot disable in N mode: No RTS-CTS on TX A-MPDUs to save air-time. */
910 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0, 0))
913 memcpy(c_val, mac_add, 6);
915 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0, 0))
921 c_val[0] = DETECT_PROTECT_REPORT;
922 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0, 0))
925 c_val[0] = RTS_CTS_NONHT_PROT;
926 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0))
930 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0, 0))
933 c_val[0] = MIMO_MODE;
934 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_SMPS_MODE, c_val, 1, 0, 0))
938 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0, 0))
941 c_val[0] = 1; /* Enable N with immediate block ack. */
942 if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 1, 1))
951 /**************************/
952 void wilc1000_wlan_deinit(linux_wlan_t *nic)
955 if (g_linux_wlan->wilc1000_initialized) {
957 printk("Deinitializing wilc1000 ...\n");
960 PRINT_ER("nic is NULL\n");
964 #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
965 /* johnny : remove */
966 PRINT_D(INIT_DBG, "skip wilc_bus_set_default_speed\n");
968 wilc_bus_set_default_speed();
971 PRINT_D(INIT_DBG, "Disabling IRQ\n");
973 mutex_lock(&g_linux_wlan->hif_cs);
974 disable_sdio_interrupt();
975 mutex_unlock(&g_linux_wlan->hif_cs);
977 if (&g_linux_wlan->txq_event != NULL)
978 up(&g_linux_wlan->txq_event);
980 PRINT_D(INIT_DBG, "Deinitializing Threads\n");
981 wlan_deinitialize_threads(nic);
983 PRINT_D(INIT_DBG, "Deinitializing IRQ\n");
984 deinit_irq(g_linux_wlan);
988 PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n");
989 wilc_wlan_deinit(nic);
990 #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
991 #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
992 PRINT_D(INIT_DBG, "Disabling IRQ 2\n");
994 mutex_lock(&g_linux_wlan->hif_cs);
995 disable_sdio_interrupt();
996 mutex_unlock(&g_linux_wlan->hif_cs);
1000 /*De-Initialize locks*/
1001 PRINT_D(INIT_DBG, "Deinitializing Locks\n");
1002 wlan_deinit_locks(g_linux_wlan);
1004 /* announce that wilc1000 is not initialized */
1005 g_linux_wlan->wilc1000_initialized = 0;
1007 PRINT_D(INIT_DBG, "wilc1000 deinitialization Done\n");
1010 PRINT_D(INIT_DBG, "wilc1000 is not initialized\n");
1014 int wlan_init_locks(linux_wlan_t *p_nic)
1017 PRINT_D(INIT_DBG, "Initializing Locks ...\n");
1019 mutex_init(&g_linux_wlan->hif_cs);
1020 mutex_init(&g_linux_wlan->rxq_cs);
1022 spin_lock_init(&g_linux_wlan->txq_spinlock);
1023 sema_init(&g_linux_wlan->txq_add_to_head_cs, 1);
1025 sema_init(&g_linux_wlan->txq_event, 0);
1027 sema_init(&g_linux_wlan->cfg_event, 0);
1028 sema_init(&g_linux_wlan->sync_event, 0);
1030 sema_init(&g_linux_wlan->txq_thread_started, 0);
1035 static int wlan_deinit_locks(linux_wlan_t *nic)
1037 PRINT_D(INIT_DBG, "De-Initializing Locks\n");
1039 if (&g_linux_wlan->hif_cs != NULL)
1040 mutex_destroy(&g_linux_wlan->hif_cs);
1042 if (&g_linux_wlan->rxq_cs != NULL)
1043 mutex_destroy(&g_linux_wlan->rxq_cs);
1047 void linux_to_wlan(wilc_wlan_inp_t *nwi, linux_wlan_t *nic)
1050 PRINT_D(INIT_DBG, "Linux to Wlan services ...\n");
1052 nwi->os_context.os_private = (void *)nic;
1055 nwi->io_func.io_type = HIF_SDIO;
1056 nwi->io_func.io_init = linux_sdio_init;
1057 nwi->io_func.io_deinit = linux_sdio_deinit;
1058 nwi->io_func.u.sdio.sdio_cmd52 = linux_sdio_cmd52;
1059 nwi->io_func.u.sdio.sdio_cmd53 = linux_sdio_cmd53;
1060 nwi->io_func.u.sdio.sdio_set_max_speed = linux_sdio_set_max_speed;
1061 nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed;
1063 nwi->io_func.io_type = HIF_SPI;
1064 nwi->io_func.io_init = linux_spi_init;
1065 nwi->io_func.io_deinit = linux_spi_deinit;
1066 nwi->io_func.u.spi.spi_tx = linux_spi_write;
1067 nwi->io_func.u.spi.spi_rx = linux_spi_read;
1068 nwi->io_func.u.spi.spi_trx = linux_spi_write_read;
1069 nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed;
1073 int wlan_initialize_threads(perInterface_wlan_t *nic)
1078 PRINT_D(INIT_DBG, "Initializing Threads ...\n");
1080 /* create tx task */
1081 PRINT_D(INIT_DBG, "Creating kthread for transmission\n");
1082 g_linux_wlan->txq_thread = kthread_run(linux_wlan_txq_task, (void *)g_linux_wlan, "K_TXQ_TASK");
1083 if (g_linux_wlan->txq_thread == NULL) {
1084 PRINT_ER("couldn't create TXQ thread\n");
1089 PRINT_D(INIT_DBG, "Creating kthread for Debugging\n");
1090 g_linux_wlan->txq_thread = kthread_run(DebuggingThreadTask, (void *)g_linux_wlan, "DebugThread");
1091 if (g_linux_wlan->txq_thread == 0) {
1092 PRINT_ER("couldn't create TXQ thread\n");
1097 /* wait for TXQ task to start. */
1098 down(&g_linux_wlan->txq_thread_started);
1103 /*De-Initialize 2nd thread*/
1104 g_linux_wlan->close = 1;
1106 g_linux_wlan->close = 0;
1110 static void wlan_deinitialize_threads(linux_wlan_t *nic)
1113 g_linux_wlan->close = 1;
1114 PRINT_D(INIT_DBG, "Deinitializing Threads\n");
1116 if (&g_linux_wlan->txq_event != NULL)
1117 up(&g_linux_wlan->txq_event);
1119 if (g_linux_wlan->txq_thread != NULL) {
1120 kthread_stop(g_linux_wlan->txq_thread);
1121 g_linux_wlan->txq_thread = NULL;
1125 #ifdef COMPLEMENT_BOOT
1127 extern volatile int probe;
1128 extern u8 core_11b_ready(void);
1130 #define READY_CHECK_THRESHOLD 30
1131 extern void wilc_wlan_global_reset(void);
1132 u8 wilc1000_prepare_11b_core(wilc_wlan_inp_t *nwi, wilc_wlan_oup_t *nwo, linux_wlan_t *nic)
1136 while ((core_11b_ready() && (READY_CHECK_THRESHOLD > (trials++)))) {
1137 PRINT_D(INIT_DBG, "11b core not ready yet: %u\n", trials);
1138 wilc_wlan_deinit(nic);
1139 wilc_wlan_global_reset();
1140 sdio_unregister_driver(&wilc_bus);
1142 linux_wlan_device_detection(0);
1146 linux_wlan_device_detection(1);
1148 sdio_register_driver(&wilc_bus);
1153 g_linux_wlan->wilc_sdio_func = local_sdio_func;
1154 linux_to_wlan(nwi, nic);
1155 wilc_wlan_init(nwi, nwo);
1158 if (READY_CHECK_THRESHOLD <= trials)
1165 int repeat_power_cycle(perInterface_wlan_t *nic)
1168 wilc_wlan_inp_t nwi;
1169 wilc_wlan_oup_t nwo;
1171 sdio_unregister_driver(&wilc_bus);
1173 linux_wlan_device_detection(0);
1174 linux_wlan_device_power(0);
1176 linux_wlan_device_power(1);
1178 linux_wlan_device_detection(1);
1181 sdio_register_driver(&wilc_bus);
1187 g_linux_wlan->wilc_sdio_func = local_sdio_func;
1188 linux_to_wlan(&nwi, g_linux_wlan);
1189 ret = wilc_wlan_init(&nwi, &nwo);
1191 g_linux_wlan->mac_status = WILC_MAC_STATUS_INIT;
1192 #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1193 enable_sdio_interrupt();
1196 if (linux_wlan_get_firmware(nic)) {
1197 PRINT_ER("Can't get firmware\n");
1202 /*Download firmware*/
1203 ret = linux_wlan_firmware_download(g_linux_wlan);
1205 PRINT_ER("Failed to download firmware\n");
1209 ret = linux_wlan_start_firmware(nic);
1211 PRINT_ER("Failed to start firmware\n");
1217 int wilc1000_wlan_init(struct net_device *dev, perInterface_wlan_t *p_nic)
1219 wilc_wlan_inp_t nwi;
1220 wilc_wlan_oup_t nwo;
1221 perInterface_wlan_t *nic = p_nic;
1224 if (!g_linux_wlan->wilc1000_initialized) {
1225 g_linux_wlan->mac_status = WILC_MAC_STATUS_INIT;
1226 g_linux_wlan->close = 0;
1227 g_linux_wlan->wilc1000_initialized = 0;
1229 wlan_init_locks(g_linux_wlan);
1231 linux_to_wlan(&nwi, g_linux_wlan);
1233 ret = wilc_wlan_init(&nwi, &nwo);
1235 PRINT_ER("Initializing WILC_Wlan FAILED\n");
1239 memcpy(&g_linux_wlan->oup, &nwo, sizeof(wilc_wlan_oup_t));
1241 /*Save the oup structre into global pointer*/
1242 gpstrWlanOps = &g_linux_wlan->oup;
1244 ret = wlan_initialize_threads(nic);
1246 PRINT_ER("Initializing Threads FAILED\n");
1248 goto _fail_wilc_wlan_;
1251 #if (defined WILC_SDIO) && (defined COMPLEMENT_BOOT)
1252 if (wilc1000_prepare_11b_core(&nwi, &nwo, g_linux_wlan)) {
1253 PRINT_ER("11b Core is not ready\n");
1255 goto _fail_threads_;
1259 #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
1260 if (init_irq(g_linux_wlan)) {
1261 PRINT_ER("couldn't initialize IRQ\n");
1263 goto _fail_threads_;
1267 #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1268 if (enable_sdio_interrupt()) {
1269 PRINT_ER("couldn't initialize IRQ\n");
1271 goto _fail_irq_init_;
1275 if (linux_wlan_get_firmware(nic)) {
1276 PRINT_ER("Can't get firmware\n");
1278 goto _fail_irq_enable_;
1281 /*Download firmware*/
1282 ret = linux_wlan_firmware_download(g_linux_wlan);
1284 PRINT_ER("Failed to download firmware\n");
1286 goto _fail_irq_enable_;
1290 ret = linux_wlan_start_firmware(nic);
1292 PRINT_ER("Failed to start firmware\n");
1294 goto _fail_irq_enable_;
1297 wilc_bus_set_max_speed();
1299 if (g_linux_wlan->oup.wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1, 0)) {
1301 char Firmware_ver[20];
1303 size = g_linux_wlan->oup.wlan_cfg_get_value(
1304 WID_FIRMWARE_VERSION,
1305 Firmware_ver, sizeof(Firmware_ver));
1306 Firmware_ver[size] = '\0';
1307 PRINT_D(INIT_DBG, "***** Firmware Ver = %s *******\n", Firmware_ver);
1309 /* Initialize firmware with default configuration */
1310 ret = linux_wlan_init_test_config(dev, g_linux_wlan);
1313 PRINT_ER("Failed to configure firmware\n");
1315 goto _fail_fw_start_;
1318 g_linux_wlan->wilc1000_initialized = 1;
1319 return 0; /*success*/
1325 #if (defined WILC_SDIO) && (!defined WILC_SDIO_IRQ_GPIO)
1326 disable_sdio_interrupt();
1329 #if (!defined WILC_SDIO) || (defined WILC_SDIO_IRQ_GPIO)
1330 deinit_irq(g_linux_wlan);
1334 wlan_deinitialize_threads(g_linux_wlan);
1336 wilc_wlan_deinit(g_linux_wlan);
1338 wlan_deinit_locks(g_linux_wlan);
1339 PRINT_ER("WLAN Iinitialization FAILED\n");
1341 PRINT_D(INIT_DBG, "wilc1000 already initialized\n");
1347 * - this function will be called automatically by OS when module inserted.
1350 int mac_init_fn(struct net_device *ndev)
1353 /*Why we do this !!!*/
1354 netif_start_queue(ndev); /* ma */
1355 netif_stop_queue(ndev); /* ma */
1360 /* This fn is called, when this device is setup using ifconfig */
1361 int mac_open(struct net_device *ndev)
1363 perInterface_wlan_t *nic;
1365 /*No need for setting mac address here anymore,*/
1366 /*Just set it in init_test_config()*/
1367 unsigned char mac_add[ETH_ALEN] = {0};
1370 struct wilc_priv *priv;
1373 if (!g_linux_wlan || !g_linux_wlan->wilc_spidev) {
1374 netdev_err(ndev, "wilc1000: SPI device not ready\n");
1378 nic = netdev_priv(ndev);
1379 priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
1380 PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev);
1382 ret = wilc_init_host_int(ndev);
1384 PRINT_ER("Failed to initialize host interface\n");
1389 /*initialize platform*/
1390 PRINT_D(INIT_DBG, "*** re-init ***\n");
1391 ret = wilc1000_wlan_init(ndev, nic);
1393 PRINT_ER("Failed to initialize wilc1000\n");
1394 wilc_deinit_host_int(ndev);
1398 Set_machw_change_vir_if(false);
1400 host_int_get_MacAddress(priv->hWILCWFIDrv, mac_add);
1401 PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add);
1403 /* loop through the NUM of supported devices and set the MAC address */
1404 for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
1405 if (ndev == g_linux_wlan->strInterfaceInfo[i].wilc_netdev) {
1406 memcpy(g_linux_wlan->strInterfaceInfo[i].aSrcAddress, mac_add, ETH_ALEN);
1407 g_linux_wlan->strInterfaceInfo[i].drvHandler = priv->hWILCWFIDrv;
1412 /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/
1413 memcpy(ndev->dev_addr, g_linux_wlan->strInterfaceInfo[i].aSrcAddress, ETH_ALEN);
1415 if (!is_valid_ether_addr(ndev->dev_addr)) {
1416 PRINT_ER("Error: Wrong MAC address\n");
1421 wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev->ieee80211_ptr,
1422 nic->g_struct_frame_reg[0].frame_type, nic->g_struct_frame_reg[0].reg);
1423 wilc_mgmt_frame_register(nic->wilc_netdev->ieee80211_ptr->wiphy, nic->wilc_netdev->ieee80211_ptr,
1424 nic->g_struct_frame_reg[1].frame_type, nic->g_struct_frame_reg[1].reg);
1425 netif_wake_queue(ndev);
1426 g_linux_wlan->open_ifcs++;
1427 nic->mac_opened = 1;
1431 wilc_deinit_host_int(ndev);
1432 wilc1000_wlan_deinit(g_linux_wlan);
1436 struct net_device_stats *mac_stats(struct net_device *dev)
1438 perInterface_wlan_t *nic = netdev_priv(dev);
1440 return &nic->netstats;
1443 /* Setup the multicast filter */
1444 static void wilc_set_multicast_list(struct net_device *dev)
1447 struct netdev_hw_addr *ha;
1448 struct wilc_priv *priv;
1449 tstrWILC_WFIDrv *pstrWFIDrv;
1452 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1453 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
1458 PRINT_D(INIT_DBG, "Setting Multicast List with count = %d.\n", dev->mc.count);
1460 if (dev->flags & IFF_PROMISC) {
1461 /* Normally, we should configure the chip to retrive all packets
1462 * but we don't wanna support this right now */
1463 /* TODO: add promiscuous mode support */
1464 PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets\n");
1468 /* If there's more addresses than we handle, get all multicast
1469 * packets and sort them out in software. */
1470 if ((dev->flags & IFF_ALLMULTI) || (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) {
1471 PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n");
1472 /* get all multicast packets */
1473 host_int_setup_multicast_filter(pstrWFIDrv, false, 0);
1477 /* No multicast? Just get our own stuff */
1478 if ((dev->mc.count) == 0) {
1479 PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n");
1480 host_int_setup_multicast_filter(pstrWFIDrv, true, 0);
1484 /* Store all of the multicast addresses in the hardware filter */
1485 netdev_for_each_mc_addr(ha, dev)
1487 memcpy(gau8MulticastMacAddrList[i], ha->addr, ETH_ALEN);
1488 PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i,
1489 gau8MulticastMacAddrList[i][0], gau8MulticastMacAddrList[i][1], gau8MulticastMacAddrList[i][2], gau8MulticastMacAddrList[i][3], gau8MulticastMacAddrList[i][4], gau8MulticastMacAddrList[i][5]);
1493 host_int_setup_multicast_filter(pstrWFIDrv, true, (dev->mc.count));
1499 static void linux_wlan_tx_complete(void *priv, int status)
1502 struct tx_complete_data *pv_data = (struct tx_complete_data *)priv;
1505 PRINT_D(TX_DBG, "Packet sent successfully - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
1507 PRINT_D(TX_DBG, "Couldn't send packet - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
1508 /* Free the SK Buffer, its work is done */
1509 dev_kfree_skb(pv_data->skb);
1513 int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
1515 perInterface_wlan_t *nic;
1516 struct tx_complete_data *tx_data = NULL;
1520 struct ethhdr *eth_h;
1522 nic = netdev_priv(ndev);
1524 PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n");
1526 /* Stop the network interface queue */
1527 if (skb->dev != ndev) {
1528 PRINT_ER("Packet not destined to this device\n");
1532 tx_data = kmalloc(sizeof(struct tx_complete_data), GFP_ATOMIC);
1533 if (tx_data == NULL) {
1534 PRINT_ER("Failed to allocate memory for tx_data structure\n");
1536 netif_wake_queue(ndev);
1540 tx_data->buff = skb->data;
1541 tx_data->size = skb->len;
1544 eth_h = (struct ethhdr *)(skb->data);
1545 if (eth_h->h_proto == 0x8e88)
1546 PRINT_D(INIT_DBG, "EAPOL transmitted\n");
1548 /*get source and dest ip addresses*/
1549 ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
1551 pu8UdpBuffer = (char *)ih + sizeof(struct iphdr);
1552 if ((pu8UdpBuffer[1] == 68 && pu8UdpBuffer[3] == 67) || (pu8UdpBuffer[1] == 67 && pu8UdpBuffer[3] == 68))
1553 PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n", pu8UdpBuffer[248], pu8UdpBuffer[249], pu8UdpBuffer[250]);
1555 PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb);
1557 /* Send packet to MAC HW - for now the tx_complete function will be just status
1558 * indicator. still not sure if I need to suspend host transmission till the tx_complete
1559 * function called or not?
1560 * allocated buffer will be freed in tx_complete function.
1562 PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n");
1563 nic->netstats.tx_packets++;
1564 nic->netstats.tx_bytes += tx_data->size;
1565 tx_data->pBssid = g_linux_wlan->strInterfaceInfo[nic->u8IfIdx].aBSSID;
1566 QueueCount = wilc_wlan_txq_add_net_pkt((void *)tx_data, tx_data->buff,
1568 linux_wlan_tx_complete);
1570 if (QueueCount > FLOW_CONTROL_UPPER_THRESHOLD) {
1571 netif_stop_queue(g_linux_wlan->strInterfaceInfo[0].wilc_netdev);
1572 netif_stop_queue(g_linux_wlan->strInterfaceInfo[1].wilc_netdev);
1578 int mac_close(struct net_device *ndev)
1580 struct wilc_priv *priv;
1581 perInterface_wlan_t *nic;
1582 tstrWILC_WFIDrv *pstrWFIDrv;
1584 nic = netdev_priv(ndev);
1586 if ((nic == NULL) || (nic->wilc_netdev == NULL) || (nic->wilc_netdev->ieee80211_ptr == NULL) || (nic->wilc_netdev->ieee80211_ptr->wiphy == NULL)) {
1587 PRINT_ER("nic = NULL\n");
1591 priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
1594 PRINT_ER("priv = NULL\n");
1598 pstrWFIDrv = (tstrWILC_WFIDrv *)priv->hWILCWFIDrv;
1600 PRINT_D(GENERIC_DBG, "Mac close\n");
1602 if (g_linux_wlan == NULL) {
1603 PRINT_ER("g_linux_wlan = NULL\n");
1607 if (pstrWFIDrv == NULL) {
1608 PRINT_ER("pstrWFIDrv = NULL\n");
1612 if ((g_linux_wlan->open_ifcs) > 0) {
1613 g_linux_wlan->open_ifcs--;
1615 PRINT_ER("ERROR: MAC close called while number of opened interfaces is zero\n");
1619 if (nic->wilc_netdev != NULL) {
1620 /* Stop the network interface queue */
1621 netif_stop_queue(nic->wilc_netdev);
1623 wilc_deinit_host_int(nic->wilc_netdev);
1626 if (g_linux_wlan->open_ifcs == 0) {
1627 PRINT_D(GENERIC_DBG, "Deinitializing wilc1000\n");
1628 g_linux_wlan->close = 1;
1629 wilc1000_wlan_deinit(g_linux_wlan);
1630 WILC_WFI_deinit_mon_interface();
1633 up(&close_exit_sync);
1634 nic->mac_opened = 0;
1639 int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
1644 u32 size = 0, length = 0;
1645 perInterface_wlan_t *nic;
1646 struct wilc_priv *priv;
1649 /* struct iwreq *wrq = (struct iwreq *) req; // tony moved to case SIOCSIWPRIV */
1650 nic = netdev_priv(ndev);
1652 if (!g_linux_wlan->wilc1000_initialized)
1660 struct iwreq *wrq = (struct iwreq *) req; /* added by tony */
1662 size = wrq->u.data.length;
1664 if (size && wrq->u.data.pointer) {
1666 buff = memdup_user(wrq->u.data.pointer, wrq->u.data.length);
1668 return PTR_ERR(buff);
1670 if (strncasecmp(buff, "RSSI", length) == 0) {
1671 priv = wiphy_priv(nic->wilc_netdev->ieee80211_ptr->wiphy);
1672 s32Error = host_int_get_rssi(priv->hWILCWFIDrv, &(rssi));
1674 PRINT_ER("Failed to send get rssi param's message queue ");
1675 PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi);
1677 /*Rounding up the rssi negative value*/
1680 snprintf(buff, size, "rssi %d", rssi);
1682 if (copy_to_user(wrq->u.data.pointer, buff, size)) {
1683 PRINT_ER("%s: failed to copy data to user buffer\n", __func__);
1694 PRINT_INFO(GENERIC_DBG, "Command - %d - has been received\n", cmd);
1695 s32Error = -EOPNOTSUPP;
1707 void frmw_to_linux(u8 *buff, u32 size, u32 pkt_offset)
1710 unsigned int frame_len = 0;
1712 unsigned char *buff_to_send = NULL;
1713 struct sk_buff *skb;
1714 struct net_device *wilc_netdev;
1715 perInterface_wlan_t *nic;
1717 wilc_netdev = GetIfHandler(buff);
1718 if (wilc_netdev == NULL)
1722 nic = netdev_priv(wilc_netdev);
1727 buff_to_send = buff;
1729 /* Need to send the packet up to the host, allocate a skb buffer */
1730 skb = dev_alloc_skb(frame_len);
1732 PRINT_ER("Low memory - packet droped\n");
1736 if (g_linux_wlan == NULL || wilc_netdev == NULL)
1737 PRINT_ER("wilc_netdev in g_linux_wlan is NULL");
1738 skb->dev = wilc_netdev;
1740 if (skb->dev == NULL)
1741 PRINT_ER("skb->dev is NULL\n");
1747 * WILC_PRINTF("buff_to_send[%d]=%2x\n",i,buff_to_send[i]);
1751 /* skb_put(skb, frame_len); */
1752 memcpy(skb_put(skb, frame_len), buff_to_send, frame_len);
1754 /* WILC_PRINTF("After MEM_CPY\n"); */
1756 /* nic = netdev_priv(wilc_netdev); */
1758 skb->protocol = eth_type_trans(skb, wilc_netdev);
1759 /* Send the packet to the stack by giving it to the bridge */
1760 nic->netstats.rx_packets++;
1761 nic->netstats.rx_bytes += frame_len;
1762 skb->ip_summed = CHECKSUM_UNNECESSARY;
1763 stats = netif_rx(skb);
1764 PRINT_D(RX_DBG, "netif_rx ret value is: %d\n", stats);
1768 void WILC_WFI_mgmt_rx(u8 *buff, u32 size)
1771 perInterface_wlan_t *nic;
1773 /*Pass the frame on the monitor interface, if any.*/
1774 /*Otherwise, pass it on p2p0 netdev, if registered on it*/
1775 for (i = 0; i < g_linux_wlan->u8NoIfcs; i++) {
1776 nic = netdev_priv(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
1777 if (nic->monitor_flag) {
1778 WILC_WFI_monitor_rx(buff, size);
1783 nic = netdev_priv(g_linux_wlan->strInterfaceInfo[1].wilc_netdev); /* p2p0 */
1784 if ((buff[0] == nic->g_struct_frame_reg[0].frame_type && nic->g_struct_frame_reg[0].reg) ||
1785 (buff[0] == nic->g_struct_frame_reg[1].frame_type && nic->g_struct_frame_reg[1].reg))
1786 WILC_WFI_p2p_rx(g_linux_wlan->strInterfaceInfo[1].wilc_netdev, buff, size);
1789 int wilc_netdev_init(void)
1793 perInterface_wlan_t *nic;
1794 struct net_device *ndev;
1796 sema_init(&close_exit_sync, 0);
1798 /*create the common structure*/
1799 g_linux_wlan = kzalloc(sizeof(linux_wlan_t), GFP_KERNEL);
1803 register_inetaddr_notifier(&g_dev_notifier);
1805 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1806 /*allocate first ethernet device with perinterface_wlan_t as its private data*/
1807 ndev = alloc_etherdev(sizeof(perInterface_wlan_t));
1809 PRINT_ER("Failed to allocate ethernet dev\n");
1813 nic = netdev_priv(ndev);
1814 memset(nic, 0, sizeof(perInterface_wlan_t));
1816 /*Name the Devices*/
1818 #if defined(NM73131) /* tony, 2012-09-20 */
1819 strcpy(ndev->name, "wilc_eth%d");
1820 #elif defined(PLAT_CLM9722) /* rachel */
1821 strcpy(ndev->name, "eth%d");
1822 #else /* PANDA_BOARD, PLAT_ALLWINNER_A10, PLAT_ALLWINNER_A20, PLAT_ALLWINNER_A31, PLAT_AML8726_M3 or PLAT_WMS8304 */
1823 strcpy(ndev->name, "wlan%d");
1826 strcpy(ndev->name, "p2p%d");
1828 nic->u8IfIdx = g_linux_wlan->u8NoIfcs;
1829 nic->wilc_netdev = ndev;
1830 g_linux_wlan->strInterfaceInfo[g_linux_wlan->u8NoIfcs].wilc_netdev = ndev;
1831 g_linux_wlan->u8NoIfcs++;
1832 ndev->netdev_ops = &wilc_netdev_ops;
1835 struct wireless_dev *wdev;
1837 wdev = wilc_create_wiphy(ndev);
1840 /* set netdev, tony */
1841 SET_NETDEV_DEV(ndev, &local_sdio_func->dev);
1845 PRINT_ER("Can't register WILC Wiphy\n");
1849 /*linking the wireless_dev structure with the netdevice*/
1850 nic->wilc_netdev->ieee80211_ptr = wdev;
1851 nic->wilc_netdev->ml_priv = nic;
1852 wdev->netdev = nic->wilc_netdev;
1853 nic->netstats.rx_packets = 0;
1854 nic->netstats.tx_packets = 0;
1855 nic->netstats.rx_bytes = 0;
1856 nic->netstats.tx_bytes = 0;
1860 if (register_netdev(ndev)) {
1861 PRINT_ER("Device couldn't be registered - %s\n", ndev->name);
1862 return -1; /* ERROR */
1865 nic->iftype = STATION_MODE;
1866 nic->mac_opened = 0;
1871 if (!linux_spi_init(&g_linux_wlan->wilc_spidev)) {
1872 PRINT_ER("Can't initialize SPI\n");
1873 return -1; /* ERROR */
1875 g_linux_wlan->wilc_spidev = wilc_spi_dev;
1877 g_linux_wlan->wilc_sdio_func = local_sdio_func;
1883 /*The 1st function called after module inserted*/
1884 static int __init init_wilc_driver(void)
1886 #if defined(WILC_DEBUGFS)
1887 if (wilc_debugfs_init() < 0) {
1888 PRINT_D(GENERIC_DBG, "fail to create debugfs for wilc driver\n");
1893 printk("IN INIT FUNCTION\n");
1894 printk("*** WILC1000 driver VERSION=[10.2] FW_VER=[10.2] ***\n");
1896 linux_wlan_device_power(1);
1898 linux_wlan_device_detection(1);
1904 ret = sdio_register_driver(&wilc_bus);
1906 PRINT_D(INIT_DBG, "init_wilc_driver: Failed register sdio driver\n");
1911 PRINT_D(INIT_DBG, "Initializing netdev\n");
1912 if (wilc_netdev_init())
1913 PRINT_ER("Couldn't initialize netdev\n");
1917 late_initcall(init_wilc_driver);
1919 static void __exit exit_wilc_driver(void)
1922 perInterface_wlan_t *nic[NUM_CONCURRENT_IFC] = {NULL,};
1923 #define CLOSE_TIMEOUT (12 * 1000)
1925 if ((g_linux_wlan != NULL) && (((g_linux_wlan->strInterfaceInfo[0].wilc_netdev) != NULL)
1926 || ((g_linux_wlan->strInterfaceInfo[1].wilc_netdev) != NULL))) {
1927 unregister_inetaddr_notifier(&g_dev_notifier);
1929 for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1930 nic[i] = netdev_priv(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
1933 if ((g_linux_wlan != NULL) && g_linux_wlan->wilc_firmware != NULL) {
1934 release_firmware(g_linux_wlan->wilc_firmware);
1935 g_linux_wlan->wilc_firmware = NULL;
1938 if ((g_linux_wlan != NULL) && (((g_linux_wlan->strInterfaceInfo[0].wilc_netdev) != NULL)
1939 || ((g_linux_wlan->strInterfaceInfo[1].wilc_netdev) != NULL))) {
1940 PRINT_D(INIT_DBG, "Waiting for mac_close ....\n");
1942 if (linux_wlan_lock_timeout(&close_exit_sync, CLOSE_TIMEOUT) < 0)
1943 PRINT_D(INIT_DBG, "Closed TimedOUT\n");
1945 PRINT_D(INIT_DBG, "mac_closed\n");
1947 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1948 /* close all opened interfaces */
1949 if (g_linux_wlan->strInterfaceInfo[i].wilc_netdev != NULL) {
1950 if (nic[i]->mac_opened)
1951 mac_close(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
1954 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1955 PRINT_D(INIT_DBG, "Unregistering netdev %p\n", g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
1956 unregister_netdev(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
1957 PRINT_D(INIT_DBG, "Freeing Wiphy...\n");
1958 wilc_free_wiphy(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
1959 PRINT_D(INIT_DBG, "Freeing netdev...\n");
1960 free_netdev(g_linux_wlan->strInterfaceInfo[i].wilc_netdev);
1964 /* WILC_WFI_deinit_mon_interface(); */
1966 /* if(g_linux_wlan->open_ifcs==0) */
1969 PRINT_D(INIT_DBG, "SPI unregsiter...\n");
1970 spi_unregister_driver(&wilc_bus);
1972 PRINT_D(INIT_DBG, "SDIO unregsiter...\n");
1973 sdio_unregister_driver(&wilc_bus);
1976 if (g_linux_wlan != NULL) {
1977 kfree(g_linux_wlan);
1978 g_linux_wlan = NULL;
1980 printk("Module_exit Done.\n");
1982 #if defined(WILC_DEBUGFS)
1983 wilc_debugfs_remove();
1986 linux_wlan_device_detection(0);
1987 linux_wlan_device_power(0);
1990 module_exit(exit_wilc_driver);
1992 MODULE_LICENSE("GPL");