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/semaphore.h>
28 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr);
30 static struct notifier_block g_dev_notifier = {
31 .notifier_call = dev_state_ev_handler
36 static struct semaphore close_exit_sync;
38 static int wlan_deinit_locks(struct net_device *dev);
39 static void wlan_deinitialize_threads(struct net_device *dev);
41 static void linux_wlan_tx_complete(void *priv, int status);
42 static int mac_init_fn(struct net_device *ndev);
43 static struct net_device_stats *mac_stats(struct net_device *dev);
44 static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd);
45 static void wilc_set_multicast_list(struct net_device *dev);
47 bool wilc_enable_ps = true;
49 static const struct net_device_ops wilc_netdev_ops = {
50 .ndo_init = mac_init_fn,
51 .ndo_open = wilc_mac_open,
52 .ndo_stop = wilc_mac_close,
53 .ndo_start_xmit = wilc_mac_xmit,
54 .ndo_do_ioctl = mac_ioctl,
55 .ndo_get_stats = mac_stats,
56 .ndo_set_rx_mode = wilc_set_multicast_list,
60 static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr)
62 struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr;
63 struct wilc_priv *priv;
64 struct host_if_drv *hif_drv;
65 struct net_device *dev;
69 char wlan_dev_name[5] = "wlan0";
71 if (!dev_iface || !dev_iface->ifa_dev || !dev_iface->ifa_dev->dev) {
72 PRINT_D(GENERIC_DBG, "dev_iface = NULL\n");
76 if (memcmp(dev_iface->ifa_label, "wlan0", 5) &&
77 memcmp(dev_iface->ifa_label, "p2p0", 4)) {
78 PRINT_D(GENERIC_DBG, "Interface is neither WLAN0 nor P2P0\n");
82 dev = (struct net_device *)dev_iface->ifa_dev->dev;
83 if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) {
84 PRINT_D(GENERIC_DBG, "No Wireless registerd\n");
87 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
89 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
92 hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv;
93 vif = netdev_priv(dev);
94 if (!vif || !hif_drv) {
95 PRINT_D(GENERIC_DBG, "No Wireless Priv\n");
99 PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler +++\n");
103 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_UP %p\n", dev);
105 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Obtained ===============\n\n");
107 if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
109 wilc_optaining_ip = false;
110 del_timer(&wilc_during_ip_timer);
111 PRINT_D(GENERIC_DBG, "IP obtained , enable scan\n");
115 wilc_set_power_mgmt(vif, 1, 0);
117 PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label);
119 ip_addr_buf = (char *)&dev_iface->ifa_address;
120 PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n",
121 ip_addr_buf[0], ip_addr_buf[1],
122 ip_addr_buf[2], ip_addr_buf[3]);
123 wilc_setup_ipaddress(vif, ip_addr_buf, vif->u8IfIdx);
128 PRINT_D(GENERIC_DBG, "dev_state_ev_handler event=NETDEV_DOWN %p\n", dev);
130 PRINT_INFO(GENERIC_DBG, "\n ============== IP Address Released ===============\n\n");
131 if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
133 wilc_optaining_ip = false;
136 if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0)
137 wilc_set_power_mgmt(vif, 0, 0);
139 wilc_resolve_disconnect_aberration(vif);
141 PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label);
143 ip_addr_buf = null_ip;
144 PRINT_D(GENERIC_DBG, "IP add=%d:%d:%d:%d\n",
145 ip_addr_buf[0], ip_addr_buf[1],
146 ip_addr_buf[2], ip_addr_buf[3]);
148 wilc_setup_ipaddress(vif, ip_addr_buf, vif->u8IfIdx);
153 PRINT_INFO(GENERIC_DBG, "dev_state_ev_handler event=default\n");
154 PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event);
162 static irqreturn_t isr_uh_routine(int irq, void *user_data)
164 struct wilc_vif *vif;
166 struct net_device *dev = (struct net_device *)user_data;
168 vif = netdev_priv(dev);
170 PRINT_D(INT_DBG, "Interrupt received UH\n");
173 PRINT_ER("Driver is CLOSING: Can't handle UH interrupt\n");
176 return IRQ_WAKE_THREAD;
179 static irqreturn_t isr_bh_routine(int irq, void *userdata)
181 struct wilc_vif *vif;
184 vif = netdev_priv(userdata);
188 PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n");
192 PRINT_D(INT_DBG, "Interrupt received BH\n");
193 wilc_handle_isr(wilc);
198 static int init_irq(struct net_device *dev)
201 struct wilc_vif *vif;
204 vif = netdev_priv(dev);
207 if ((gpio_request(wl->gpio, "WILC_INTR") == 0) &&
208 (gpio_direction_input(wl->gpio) == 0)) {
209 wl->dev_irq_num = gpio_to_irq(wl->gpio);
212 PRINT_ER("could not obtain gpio for WILC_INTR\n");
215 if (ret != -1 && request_threaded_irq(wl->dev_irq_num,
218 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
219 "WILC_IRQ", dev) < 0) {
220 PRINT_ER("Failed to request IRQ for GPIO: %d\n", wl->gpio);
224 PRINT_D(INIT_DBG, "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n",
225 wl->dev_irq_num, wl->gpio);
231 static void deinit_irq(struct net_device *dev)
233 struct wilc_vif *vif;
236 vif = netdev_priv(dev);
239 /* Deintialize IRQ */
240 if (wilc->dev_irq_num) {
241 free_irq(wilc->dev_irq_num, wilc);
242 gpio_free(wilc->gpio);
246 void wilc_dbg(u8 *buff)
248 PRINT_D(INIT_DBG, "%d\n", *buff);
251 int wilc_lock_timeout(struct wilc *nic, void *vp, u32 timeout)
253 /* FIXME: replace with mutex_lock or wait_for_completion */
256 PRINT_D(LOCK_DBG, "Locking %p\n", vp);
258 error = down_timeout((struct semaphore *)vp,
259 msecs_to_jiffies(timeout));
261 PRINT_ER("Failed, mutex is NULL\n");
265 void wilc_mac_indicate(struct wilc *wilc, int flag)
269 if (flag == WILC_MAC_INDICATE_STATUS) {
270 wilc_wlan_cfg_get_val(WID_STATUS,
271 (unsigned char *)&status, 4);
272 if (wilc->mac_status == WILC_MAC_STATUS_INIT) {
273 wilc->mac_status = status;
274 up(&wilc->sync_event);
276 wilc->mac_status = status;
278 } else if (flag == WILC_MAC_INDICATE_SCAN) {
279 PRINT_D(GENERIC_DBG, "Scanning ...\n");
283 static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
288 bssid = mac_header + 10;
289 bssid1 = mac_header + 4;
291 for (i = 0; i < wilc->vif_num; i++)
292 if (!memcmp(bssid1, wilc->vif[i]->bssid, ETH_ALEN) ||
293 !memcmp(bssid, wilc->vif[i]->bssid, ETH_ALEN))
294 return wilc->vif[i]->ndev;
296 PRINT_INFO(INIT_DBG, "Invalide handle\n");
297 for (i = 0; i < 25; i++)
298 PRINT_D(INIT_DBG, "%02x ", mac_header[i]);
299 bssid = mac_header + 18;
300 bssid1 = mac_header + 12;
301 for (i = 0; i < wilc->vif_num; i++)
302 if (!memcmp(bssid1, wilc->vif[i]->bssid, ETH_ALEN) ||
303 !memcmp(bssid, wilc->vif[i]->bssid, ETH_ALEN))
304 return wilc->vif[i]->ndev;
306 PRINT_INFO(INIT_DBG, "\n");
310 int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid)
314 struct wilc_vif *vif;
317 vif = netdev_priv(wilc_netdev);
320 for (i = 0; i < wilc->vif_num; i++)
321 if (wilc->vif[i]->ndev == wilc_netdev) {
322 memcpy(wilc->vif[i]->bssid, bssid, 6);
330 int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc)
333 u8 null_bssid[6] = {0};
336 for (i = 0; i < wilc->vif_num; i++)
337 if (memcmp(wilc->vif[i]->bssid, null_bssid, 6))
343 #define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
345 static int linux_wlan_txq_task(void *vp)
348 struct wilc_vif *vif;
350 struct net_device *dev = vp;
351 #if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
352 #define TX_BACKOFF_WEIGHT_INCR_STEP (1)
353 #define TX_BACKOFF_WEIGHT_DECR_STEP (1)
354 #define TX_BACKOFF_WEIGHT_MAX (7)
355 #define TX_BACKOFF_WEIGHT_MIN (0)
356 #define TX_BACKOFF_WEIGHT_UNIT_MS (10)
357 int backoff_weight = TX_BACKOFF_WEIGHT_MIN;
360 vif = netdev_priv(dev);
363 up(&wl->txq_thread_started);
365 PRINT_D(TX_DBG, "txq_task Taking a nap :)\n");
366 down(&wl->txq_event);
367 PRINT_D(TX_DBG, "txq_task Who waked me up :$\n");
370 up(&wl->txq_thread_started);
372 while (!kthread_should_stop())
375 PRINT_D(TX_DBG, "TX thread stopped\n");
378 PRINT_D(TX_DBG, "txq_task handle the sending packet and let me go to sleep.\n");
379 #if !defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
380 ret = wilc_wlan_handle_txq(dev, &txq_count);
383 ret = wilc_wlan_handle_txq(dev, &txq_count);
384 if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) {
385 PRINT_D(TX_DBG, "Waking up queue\n");
387 if (netif_queue_stopped(wl->vif[0]->ndev))
388 netif_wake_queue(wl->vif[0]->ndev);
389 if (netif_queue_stopped(wl->vif[1]->ndev))
390 netif_wake_queue(wl->vif[1]->ndev);
393 if (ret == WILC_TX_ERR_NO_BUF) {
395 msleep(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight);
397 backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP;
398 if (backoff_weight > TX_BACKOFF_WEIGHT_MAX)
399 backoff_weight = TX_BACKOFF_WEIGHT_MAX;
401 if (backoff_weight > TX_BACKOFF_WEIGHT_MIN) {
402 backoff_weight -= TX_BACKOFF_WEIGHT_DECR_STEP;
403 if (backoff_weight < TX_BACKOFF_WEIGHT_MIN)
404 backoff_weight = TX_BACKOFF_WEIGHT_MIN;
407 } while (ret == WILC_TX_ERR_NO_BUF && !wl->close);
413 void wilc_rx_complete(struct wilc *nic)
415 PRINT_D(RX_DBG, "RX completed\n");
418 int wilc_wlan_get_firmware(struct net_device *dev)
420 struct wilc_vif *vif;
423 const struct firmware *wilc_firmware;
426 vif = netdev_priv(dev);
429 if (vif->iftype == AP_MODE) {
430 firmware = AP_FIRMWARE;
431 } else if (vif->iftype == STATION_MODE) {
432 firmware = STA_FIRMWARE;
434 PRINT_D(INIT_DBG, "Get P2P_CONCURRENCY_FIRMWARE\n");
435 firmware = P2P_CONCURRENCY_FIRMWARE;
439 PRINT_ER("vif is NULL\n");
443 if (!(&vif->ndev->dev)) {
444 PRINT_ER("&vif->ndev->dev is NULL\n");
448 if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) {
449 PRINT_ER("%s - firmare not available\n", firmware);
453 wilc->firmware = wilc_firmware;
460 static int linux_wlan_start_firmware(struct net_device *dev)
462 struct wilc_vif *vif;
466 vif = netdev_priv(dev);
469 PRINT_D(INIT_DBG, "Starting Firmware ...\n");
470 ret = wilc_wlan_start(wilc);
472 PRINT_ER("Failed to start Firmware\n");
476 PRINT_D(INIT_DBG, "Waiting for Firmware to get ready ...\n");
477 ret = wilc_lock_timeout(wilc, &wilc->sync_event, 5000);
479 PRINT_D(INIT_DBG, "Firmware start timed out");
482 PRINT_D(INIT_DBG, "Firmware successfully started\n");
487 static int wilc1000_firmware_download(struct net_device *dev)
489 struct wilc_vif *vif;
493 vif = netdev_priv(dev);
496 if (!wilc->firmware) {
497 PRINT_ER("Firmware buffer is NULL\n");
500 PRINT_D(INIT_DBG, "Downloading Firmware ...\n");
501 ret = wilc_wlan_firmware_download(wilc, wilc->firmware->data,
502 wilc->firmware->size);
506 PRINT_D(INIT_DBG, "Freeing FW buffer ...\n");
507 PRINT_D(INIT_DBG, "Releasing firmware\n");
508 release_firmware(wilc->firmware);
509 wilc->firmware = NULL;
511 PRINT_D(INIT_DBG, "Download Succeeded\n");
516 static int linux_wlan_init_test_config(struct net_device *dev,
519 unsigned char c_val[64];
520 unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff};
522 struct wilc_priv *priv;
523 struct host_if_drv *hif_drv;
525 PRINT_D(TX_DBG, "Start configuring Firmware\n");
526 get_random_bytes(&mac_add[5], 1);
527 get_random_bytes(&mac_add[4], 1);
528 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
529 hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv;
530 PRINT_D(INIT_DBG, "Host = %p\n", hif_drv);
532 PRINT_D(INIT_DBG, "MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n",
533 mac_add[0], mac_add[1], mac_add[2],
534 mac_add[3], mac_add[4], mac_add[5]);
535 wilc_get_chipid(wilc, 0);
539 if (!wilc_wlan_cfg_set(wilc, 1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0))
543 if (!wilc_wlan_cfg_set(wilc, 0, WID_PC_TEST_MODE, c_val, 1, 0, 0))
546 c_val[0] = INFRASTRUCTURE;
547 if (!wilc_wlan_cfg_set(wilc, 0, WID_BSS_TYPE, c_val, 1, 0, 0))
550 c_val[0] = RATE_AUTO;
551 if (!wilc_wlan_cfg_set(wilc, 0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0))
554 c_val[0] = G_MIXED_11B_2_MODE;
555 if (!wilc_wlan_cfg_set(wilc, 0, WID_11G_OPERATING_MODE, c_val, 1, 0,
560 if (!wilc_wlan_cfg_set(wilc, 0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0))
563 c_val[0] = G_SHORT_PREAMBLE;
564 if (!wilc_wlan_cfg_set(wilc, 0, WID_PREAMBLE, c_val, 1, 0, 0))
567 c_val[0] = AUTO_PROT;
568 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_PROT_MECH, c_val, 1, 0, 0))
571 c_val[0] = ACTIVE_SCAN;
572 if (!wilc_wlan_cfg_set(wilc, 0, WID_SCAN_TYPE, c_val, 1, 0, 0))
575 c_val[0] = SITE_SURVEY_OFF;
576 if (!wilc_wlan_cfg_set(wilc, 0, WID_SITE_SURVEY, c_val, 1, 0, 0))
579 *((int *)c_val) = 0xffff;
580 if (!wilc_wlan_cfg_set(wilc, 0, WID_RTS_THRESHOLD, c_val, 2, 0, 0))
583 *((int *)c_val) = 2346;
584 if (!wilc_wlan_cfg_set(wilc, 0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0))
588 if (!wilc_wlan_cfg_set(wilc, 0, WID_BCAST_SSID, c_val, 1, 0, 0))
592 if (!wilc_wlan_cfg_set(wilc, 0, WID_QOS_ENABLE, c_val, 1, 0, 0))
595 c_val[0] = NO_POWERSAVE;
596 if (!wilc_wlan_cfg_set(wilc, 0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0))
599 c_val[0] = NO_SECURITY; /* NO_ENCRYPT, 0x79 */
600 if (!wilc_wlan_cfg_set(wilc, 0, WID_11I_MODE, c_val, 1, 0, 0))
603 c_val[0] = OPEN_SYSTEM;
604 if (!wilc_wlan_cfg_set(wilc, 0, WID_AUTH_TYPE, c_val, 1, 0, 0))
607 strcpy(c_val, "123456790abcdef1234567890");
608 if (!wilc_wlan_cfg_set(wilc, 0, WID_WEP_KEY_VALUE, c_val,
609 (strlen(c_val) + 1), 0, 0))
612 strcpy(c_val, "12345678");
613 if (!wilc_wlan_cfg_set(wilc, 0, WID_11I_PSK, c_val, (strlen(c_val)), 0,
617 strcpy(c_val, "password");
618 if (!wilc_wlan_cfg_set(wilc, 0, WID_1X_KEY, c_val, (strlen(c_val) + 1),
626 if (!wilc_wlan_cfg_set(wilc, 0, WID_1X_SERV_ADDR, c_val, 4, 0, 0))
630 if (!wilc_wlan_cfg_set(wilc, 0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0))
634 if (!wilc_wlan_cfg_set(wilc, 0, WID_DTIM_PERIOD, c_val, 1, 0, 0))
637 c_val[0] = NORMAL_ACK;
638 if (!wilc_wlan_cfg_set(wilc, 0, WID_ACK_POLICY, c_val, 1, 0, 0))
642 if (!wilc_wlan_cfg_set(wilc, 0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1,
647 if (!wilc_wlan_cfg_set(wilc, 0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0,
652 if (!wilc_wlan_cfg_set(wilc, 0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0,
656 *((int *)c_val) = 100;
657 if (!wilc_wlan_cfg_set(wilc, 0, WID_BEACON_INTERVAL, c_val, 2, 0, 0))
660 c_val[0] = REKEY_DISABLE;
661 if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_POLICY, c_val, 1, 0, 0))
664 *((int *)c_val) = 84600;
665 if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_PERIOD, c_val, 4, 0, 0))
668 *((int *)c_val) = 500;
669 if (!wilc_wlan_cfg_set(wilc, 0, WID_REKEY_PACKET_COUNT, c_val, 4, 0,
674 if (!wilc_wlan_cfg_set(wilc, 0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0,
678 c_val[0] = G_SELF_CTS_PROT;
679 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0))
683 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_ENABLE, c_val, 1, 0, 0))
686 c_val[0] = HT_MIXED_MODE;
687 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_OPERATING_MODE, c_val, 1, 0,
692 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0,
696 memcpy(c_val, mac_add, 6);
698 if (!wilc_wlan_cfg_set(wilc, 0, WID_MAC_ADDR, c_val, 6, 0, 0))
701 c_val[0] = DETECT_PROTECT_REPORT;
702 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1,
706 c_val[0] = RTS_CTS_NONHT_PROT;
707 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0))
711 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0,
715 c_val[0] = MIMO_MODE;
716 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_SMPS_MODE, c_val, 1, 0, 0))
720 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0,
725 if (!wilc_wlan_cfg_set(wilc, 0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1,
735 void wilc1000_wlan_deinit(struct net_device *dev)
737 struct wilc_vif *vif;
740 vif = netdev_priv(dev);
744 netdev_err(dev, "wl is NULL\n");
748 if (wl->initialized) {
749 netdev_info(dev, "Deinitializing wilc1000...\n");
751 PRINT_D(INIT_DBG, "Disabling IRQ\n");
752 if (!wl->dev_irq_num &&
753 wl->hif_func->disable_interrupt) {
754 mutex_lock(&wl->hif_cs);
755 wl->hif_func->disable_interrupt(wl);
756 mutex_unlock(&wl->hif_cs);
761 PRINT_D(INIT_DBG, "Deinitializing Threads\n");
762 wlan_deinitialize_threads(dev);
764 PRINT_D(INIT_DBG, "Deinitializing IRQ\n");
769 PRINT_D(INIT_DBG, "Deinitializing WILC Wlan\n");
770 wilc_wlan_cleanup(dev);
771 #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
772 if (!wl->dev_irq_num &&
773 wl->hif_func->disable_interrupt) {
775 PRINT_D(INIT_DBG, "Disabling IRQ 2\n");
777 mutex_lock(&wl->hif_cs);
778 wl->hif_func->disable_interrupt(wl);
779 mutex_unlock(&wl->hif_cs);
783 PRINT_D(INIT_DBG, "Deinitializing Locks\n");
784 wlan_deinit_locks(dev);
786 wl->initialized = false;
788 PRINT_D(INIT_DBG, "wilc1000 deinitialization Done\n");
791 PRINT_D(INIT_DBG, "wilc1000 is not initialized\n");
795 static int wlan_init_locks(struct net_device *dev)
797 struct wilc_vif *vif;
800 vif = netdev_priv(dev);
803 PRINT_D(INIT_DBG, "Initializing Locks ...\n");
805 mutex_init(&wl->hif_cs);
806 mutex_init(&wl->rxq_cs);
808 spin_lock_init(&wl->txq_spinlock);
809 sema_init(&wl->txq_add_to_head_cs, 1);
811 sema_init(&wl->txq_event, 0);
813 sema_init(&wl->cfg_event, 0);
814 sema_init(&wl->sync_event, 0);
816 sema_init(&wl->txq_thread_started, 0);
821 static int wlan_deinit_locks(struct net_device *dev)
823 struct wilc_vif *vif;
826 vif = netdev_priv(dev);
829 PRINT_D(INIT_DBG, "De-Initializing Locks\n");
832 mutex_destroy(&wilc->hif_cs);
835 mutex_destroy(&wilc->rxq_cs);
840 static int wlan_initialize_threads(struct net_device *dev)
842 struct wilc_vif *vif;
845 vif = netdev_priv(dev);
848 PRINT_D(INIT_DBG, "Initializing Threads ...\n");
849 PRINT_D(INIT_DBG, "Creating kthread for transmission\n");
850 wilc->txq_thread = kthread_run(linux_wlan_txq_task, (void *)dev,
852 if (!wilc->txq_thread) {
853 PRINT_ER("couldn't create TXQ thread\n");
857 down(&wilc->txq_thread_started);
862 static void wlan_deinitialize_threads(struct net_device *dev)
864 struct wilc_vif *vif;
866 vif = netdev_priv(dev);
870 PRINT_D(INIT_DBG, "Deinitializing Threads\n");
875 if (wl->txq_thread) {
876 kthread_stop(wl->txq_thread);
877 wl->txq_thread = NULL;
881 int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif)
884 struct wilc *wl = vif->wilc;
886 if (!wl->initialized) {
887 wl->mac_status = WILC_MAC_STATUS_INIT;
890 wlan_init_locks(dev);
892 ret = wilc_wlan_init(dev);
894 PRINT_ER("Initializing WILC_Wlan FAILED\n");
899 if (wl->gpio >= 0 && init_irq(dev)) {
900 PRINT_ER("couldn't initialize IRQ\n");
905 ret = wlan_initialize_threads(dev);
907 PRINT_ER("Initializing Threads FAILED\n");
909 goto _fail_wilc_wlan_;
912 if (!wl->dev_irq_num &&
913 wl->hif_func->enable_interrupt &&
914 wl->hif_func->enable_interrupt(wl)) {
915 PRINT_ER("couldn't initialize IRQ\n");
917 goto _fail_irq_init_;
920 if (wilc_wlan_get_firmware(dev)) {
921 PRINT_ER("Can't get firmware\n");
923 goto _fail_irq_enable_;
926 ret = wilc1000_firmware_download(dev);
928 PRINT_ER("Failed to download firmware\n");
930 goto _fail_irq_enable_;
933 ret = linux_wlan_start_firmware(dev);
935 PRINT_ER("Failed to start firmware\n");
937 goto _fail_irq_enable_;
940 if (wilc_wlan_cfg_get(wl, 1, WID_FIRMWARE_VERSION, 1, 0)) {
942 char Firmware_ver[20];
944 size = wilc_wlan_cfg_get_val(
945 WID_FIRMWARE_VERSION,
946 Firmware_ver, sizeof(Firmware_ver));
947 Firmware_ver[size] = '\0';
948 PRINT_D(INIT_DBG, "***** Firmware Ver = %s *******\n", Firmware_ver);
950 ret = linux_wlan_init_test_config(dev, wl);
953 PRINT_ER("Failed to configure firmware\n");
955 goto _fail_fw_start_;
958 wl->initialized = true;
965 if (!wl->dev_irq_num &&
966 wl->hif_func->disable_interrupt)
967 wl->hif_func->disable_interrupt(wl);
972 wlan_deinitialize_threads(dev);
974 wilc_wlan_cleanup(dev);
976 wlan_deinit_locks(dev);
977 PRINT_ER("WLAN Iinitialization FAILED\n");
979 PRINT_D(INIT_DBG, "wilc1000 already initialized\n");
984 static int mac_init_fn(struct net_device *ndev)
986 netif_start_queue(ndev);
987 netif_stop_queue(ndev);
992 int wilc_mac_open(struct net_device *ndev)
994 struct wilc_vif *vif;
997 unsigned char mac_add[ETH_ALEN] = {0};
1000 struct wilc_priv *priv;
1003 vif = netdev_priv(ndev);
1006 if (!wl|| !wl->dev) {
1007 netdev_err(ndev, "wilc1000: SPI device not ready\n");
1011 vif = netdev_priv(ndev);
1013 priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy);
1014 PRINT_D(INIT_DBG, "MAC OPEN[%p]\n", ndev);
1016 ret = wilc_init_host_int(ndev);
1018 PRINT_ER("Failed to initialize host interface\n");
1023 PRINT_D(INIT_DBG, "*** re-init ***\n");
1024 ret = wilc1000_wlan_init(ndev, vif);
1026 PRINT_ER("Failed to initialize wilc1000\n");
1027 wilc_deinit_host_int(ndev);
1031 wilc_set_machw_change_vir_if(ndev, false);
1033 wilc_get_mac_address(vif, mac_add);
1034 PRINT_D(INIT_DBG, "Mac address: %pM\n", mac_add);
1036 for (i = 0; i < wl->vif_num; i++) {
1037 if (ndev == wl->vif[i]->ndev) {
1038 memcpy(wl->vif[i]->src_addr, mac_add, ETH_ALEN);
1043 memcpy(ndev->dev_addr, wl->vif[i]->src_addr, ETH_ALEN);
1045 if (!is_valid_ether_addr(ndev->dev_addr)) {
1046 PRINT_ER("Error: Wrong MAC address\n");
1047 wilc_deinit_host_int(ndev);
1048 wilc1000_wlan_deinit(ndev);
1052 wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy,
1053 vif->ndev->ieee80211_ptr,
1054 vif->g_struct_frame_reg[0].frame_type,
1055 vif->g_struct_frame_reg[0].reg);
1056 wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy,
1057 vif->ndev->ieee80211_ptr,
1058 vif->g_struct_frame_reg[1].frame_type,
1059 vif->g_struct_frame_reg[1].reg);
1060 netif_wake_queue(ndev);
1062 vif->mac_opened = 1;
1066 static struct net_device_stats *mac_stats(struct net_device *dev)
1068 struct wilc_vif *vif= netdev_priv(dev);
1070 return &vif->netstats;
1073 static void wilc_set_multicast_list(struct net_device *dev)
1075 struct netdev_hw_addr *ha;
1076 struct wilc_priv *priv;
1077 struct host_if_drv *hif_drv;
1078 struct wilc_vif *vif;
1081 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1082 vif = netdev_priv(dev);
1083 hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv;
1088 PRINT_D(INIT_DBG, "Setting Multicast List with count = %d.\n",
1091 if (dev->flags & IFF_PROMISC) {
1092 PRINT_D(INIT_DBG, "Set promiscuous mode ON, retrive all packets\n");
1096 if ((dev->flags & IFF_ALLMULTI) ||
1097 (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) {
1098 PRINT_D(INIT_DBG, "Disable multicast filter, retrive all multicast packets\n");
1099 wilc_setup_multicast_filter(vif, false, 0);
1103 if ((dev->mc.count) == 0) {
1104 PRINT_D(INIT_DBG, "Enable multicast filter, retrive directed packets only.\n");
1105 wilc_setup_multicast_filter(vif, true, 0);
1109 netdev_for_each_mc_addr(ha, dev) {
1110 memcpy(wilc_multicast_mac_addr_list[i], ha->addr, ETH_ALEN);
1111 PRINT_D(INIT_DBG, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i,
1112 wilc_multicast_mac_addr_list[i][0],
1113 wilc_multicast_mac_addr_list[i][1],
1114 wilc_multicast_mac_addr_list[i][2],
1115 wilc_multicast_mac_addr_list[i][3],
1116 wilc_multicast_mac_addr_list[i][4],
1117 wilc_multicast_mac_addr_list[i][5]);
1121 wilc_setup_multicast_filter(vif, true, (dev->mc.count));
1126 static void linux_wlan_tx_complete(void *priv, int status)
1128 struct tx_complete_data *pv_data = (struct tx_complete_data *)priv;
1131 PRINT_D(TX_DBG, "Packet sent successfully - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
1133 PRINT_D(TX_DBG, "Couldn't send packet - Size = %d - Address = %p - SKB = %p\n", pv_data->size, pv_data->buff, pv_data->skb);
1134 dev_kfree_skb(pv_data->skb);
1138 int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
1140 struct wilc_vif *vif;
1141 struct tx_complete_data *tx_data = NULL;
1145 struct ethhdr *eth_h;
1148 vif = netdev_priv(ndev);
1151 PRINT_D(TX_DBG, "Sending packet just received from TCP/IP\n");
1153 if (skb->dev != ndev) {
1154 PRINT_ER("Packet not destined to this device\n");
1158 tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC);
1160 PRINT_ER("Failed to allocate memory for tx_data structure\n");
1162 netif_wake_queue(ndev);
1166 tx_data->buff = skb->data;
1167 tx_data->size = skb->len;
1170 eth_h = (struct ethhdr *)(skb->data);
1171 if (eth_h->h_proto == 0x8e88)
1172 PRINT_D(INIT_DBG, "EAPOL transmitted\n");
1174 ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
1176 udp_buf = (char *)ih + sizeof(struct iphdr);
1177 if ((udp_buf[1] == 68 && udp_buf[3] == 67) ||
1178 (udp_buf[1] == 67 && udp_buf[3] == 68))
1179 PRINT_D(GENERIC_DBG, "DHCP Message transmitted, type:%x %x %x\n",
1180 udp_buf[248], udp_buf[249], udp_buf[250]);
1182 PRINT_D(TX_DBG, "Sending packet - Size = %d - Address = %p - SKB = %p\n", tx_data->size, tx_data->buff, tx_data->skb);
1183 PRINT_D(TX_DBG, "Adding tx packet to TX Queue\n");
1184 vif->netstats.tx_packets++;
1185 vif->netstats.tx_bytes += tx_data->size;
1186 tx_data->pBssid = wilc->vif[vif->u8IfIdx]->bssid;
1187 queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data,
1188 tx_data->buff, tx_data->size,
1189 linux_wlan_tx_complete);
1191 if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
1192 netif_stop_queue(wilc->vif[0]->ndev);
1193 netif_stop_queue(wilc->vif[1]->ndev);
1199 int wilc_mac_close(struct net_device *ndev)
1201 struct wilc_priv *priv;
1202 struct wilc_vif *vif;
1203 struct host_if_drv *hif_drv;
1206 vif = netdev_priv(ndev);
1208 if (!vif || !vif->ndev || !vif->ndev->ieee80211_ptr ||
1209 !vif->ndev->ieee80211_ptr->wiphy) {
1210 PRINT_ER("vif = NULL\n");
1214 priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy);
1218 PRINT_ER("priv = NULL\n");
1222 hif_drv = (struct host_if_drv *)priv->hWILCWFIDrv;
1224 PRINT_D(GENERIC_DBG, "Mac close\n");
1227 PRINT_ER("wl = NULL\n");
1232 PRINT_ER("hif_drv = NULL\n");
1236 if ((wl->open_ifcs) > 0) {
1239 PRINT_ER("ERROR: MAC close called while number of opened interfaces is zero\n");
1244 netif_stop_queue(vif->ndev);
1246 wilc_deinit_host_int(vif->ndev);
1249 if (wl->open_ifcs == 0) {
1250 PRINT_D(GENERIC_DBG, "Deinitializing wilc1000\n");
1252 wilc1000_wlan_deinit(ndev);
1253 WILC_WFI_deinit_mon_interface();
1256 up(&close_exit_sync);
1257 vif->mac_opened = 0;
1262 static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
1266 u32 size = 0, length = 0;
1267 struct wilc_vif *vif;
1268 struct wilc_priv *priv;
1272 vif = netdev_priv(ndev);
1275 if (!wilc->initialized)
1281 struct iwreq *wrq = (struct iwreq *) req;
1283 size = wrq->u.data.length;
1285 if (size && wrq->u.data.pointer) {
1286 buff = memdup_user(wrq->u.data.pointer,
1287 wrq->u.data.length);
1289 return PTR_ERR(buff);
1291 if (strncasecmp(buff, "RSSI", length) == 0) {
1292 priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy);
1293 ret = wilc_get_rssi(vif, &rssi);
1295 PRINT_ER("Failed to send get rssi param's message queue ");
1296 PRINT_INFO(GENERIC_DBG, "RSSI :%d\n", rssi);
1300 snprintf(buff, size, "rssi %d", rssi);
1302 if (copy_to_user(wrq->u.data.pointer, buff, size)) {
1303 PRINT_ER("%s: failed to copy data to user buffer\n", __func__);
1314 PRINT_INFO(GENERIC_DBG, "Command - %d - has been received\n", cmd);
1327 void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset)
1329 unsigned int frame_len = 0;
1331 unsigned char *buff_to_send = NULL;
1332 struct sk_buff *skb;
1333 struct net_device *wilc_netdev;
1334 struct wilc_vif *vif;
1336 wilc_netdev = get_if_handler(wilc, buff);
1341 vif = netdev_priv(wilc_netdev);
1345 buff_to_send = buff;
1347 skb = dev_alloc_skb(frame_len);
1349 PRINT_ER("Low memory - packet droped\n");
1353 if (!wilc || !wilc_netdev)
1354 PRINT_ER("wilc_netdev in wilc is NULL");
1355 skb->dev = wilc_netdev;
1358 PRINT_ER("skb->dev is NULL\n");
1360 memcpy(skb_put(skb, frame_len), buff_to_send, frame_len);
1362 skb->protocol = eth_type_trans(skb, wilc_netdev);
1363 vif->netstats.rx_packets++;
1364 vif->netstats.rx_bytes += frame_len;
1365 skb->ip_summed = CHECKSUM_UNNECESSARY;
1366 stats = netif_rx(skb);
1367 PRINT_D(RX_DBG, "netif_rx ret value is: %d\n", stats);
1371 void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
1374 struct wilc_vif *vif;
1376 for (i = 0; i < wilc->vif_num; i++) {
1377 vif = netdev_priv(wilc->vif[i]->ndev);
1378 if (vif->monitor_flag) {
1379 WILC_WFI_monitor_rx(buff, size);
1384 vif = netdev_priv(wilc->vif[1]->ndev);
1385 if ((buff[0] == vif->g_struct_frame_reg[0].frame_type && vif->g_struct_frame_reg[0].reg) ||
1386 (buff[0] == vif->g_struct_frame_reg[1].frame_type && vif->g_struct_frame_reg[1].reg))
1387 WILC_WFI_p2p_rx(wilc->vif[1]->ndev, buff, size);
1390 void wilc_netdev_cleanup(struct wilc *wilc)
1393 struct wilc_vif *vif[NUM_CONCURRENT_IFC];
1395 if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
1396 unregister_inetaddr_notifier(&g_dev_notifier);
1398 for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1399 vif[i] = netdev_priv(wilc->vif[i]->ndev);
1402 if (wilc && wilc->firmware)
1403 release_firmware(wilc->firmware);
1405 if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
1406 wilc_lock_timeout(wilc, &close_exit_sync, 12 * 1000);
1408 for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1409 if (wilc->vif[i]->ndev)
1410 if (vif[i]->mac_opened)
1411 wilc_mac_close(wilc->vif[i]->ndev);
1413 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1414 unregister_netdev(wilc->vif[i]->ndev);
1415 wilc_free_wiphy(wilc->vif[i]->ndev);
1416 free_netdev(wilc->vif[i]->ndev);
1422 EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
1424 int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
1425 int gpio, const struct wilc_hif_func *ops)
1428 struct wilc_vif *vif;
1429 struct net_device *ndev;
1432 sema_init(&close_exit_sync, 0);
1434 wl = kzalloc(sizeof(*wl), GFP_KERNEL);
1439 wl->io_type = io_type;
1443 register_inetaddr_notifier(&g_dev_notifier);
1445 for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1446 ndev = alloc_etherdev(sizeof(struct wilc_vif));
1448 PRINT_ER("Failed to allocate ethernet dev\n");
1452 vif = netdev_priv(ndev);
1453 memset(vif, 0, sizeof(struct wilc_vif));
1456 strcpy(ndev->name, "wlan%d");
1458 strcpy(ndev->name, "p2p%d");
1460 vif->u8IfIdx = wl->vif_num;
1463 wl->vif[wl->vif_num]->ndev = ndev;
1465 ndev->netdev_ops = &wilc_netdev_ops;
1468 struct wireless_dev *wdev;
1469 wdev = wilc_create_wiphy(ndev, dev);
1472 SET_NETDEV_DEV(ndev, dev);
1475 PRINT_ER("Can't register WILC Wiphy\n");
1479 vif->ndev->ieee80211_ptr = wdev;
1480 vif->ndev->ml_priv = vif;
1481 wdev->netdev = vif->ndev;
1482 vif->netstats.rx_packets = 0;
1483 vif->netstats.tx_packets = 0;
1484 vif->netstats.rx_bytes = 0;
1485 vif->netstats.tx_bytes = 0;
1488 if (register_netdev(ndev)) {
1489 PRINT_ER("Device couldn't be registered - %s\n",
1494 vif->iftype = STATION_MODE;
1495 vif->mac_opened = 0;
1500 EXPORT_SYMBOL_GPL(wilc_netdev_init);
1502 MODULE_LICENSE("GPL");