linux/drivers/staging/wilc1000/linux_wlan.c
<<
>>
Prefs
   1#include "wilc_wfi_cfgoperations.h"
   2#include "wilc_wlan_if.h"
   3#include "wilc_wlan.h"
   4
   5#include <linux/slab.h>
   6#include <linux/sched.h>
   7#include <linux/delay.h>
   8#include <linux/workqueue.h>
   9#include <linux/interrupt.h>
  10#include <linux/irq.h>
  11#include <linux/gpio.h>
  12
  13#include <linux/kthread.h>
  14#include <linux/firmware.h>
  15
  16#include <linux/init.h>
  17#include <linux/netdevice.h>
  18#include <linux/inetdevice.h>
  19#include <linux/etherdevice.h>
  20#include <linux/module.h>
  21#include <linux/kernel.h>
  22#include <linux/skbuff.h>
  23#include <linux/mutex.h>
  24#include <linux/semaphore.h>
  25#include <linux/completion.h>
  26
  27static int dev_state_ev_handler(struct notifier_block *this,
  28                                unsigned long event, void *ptr);
  29
  30static struct notifier_block g_dev_notifier = {
  31        .notifier_call = dev_state_ev_handler
  32};
  33
  34static int wlan_deinit_locks(struct net_device *dev);
  35static void wlan_deinitialize_threads(struct net_device *dev);
  36
  37static void linux_wlan_tx_complete(void *priv, int status);
  38static int  mac_init_fn(struct net_device *ndev);
  39static struct net_device_stats *mac_stats(struct net_device *dev);
  40static int  mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd);
  41static void wilc_set_multicast_list(struct net_device *dev);
  42
  43bool wilc_enable_ps = true;
  44
  45static const struct net_device_ops wilc_netdev_ops = {
  46        .ndo_init = mac_init_fn,
  47        .ndo_open = wilc_mac_open,
  48        .ndo_stop = wilc_mac_close,
  49        .ndo_start_xmit = wilc_mac_xmit,
  50        .ndo_do_ioctl = mac_ioctl,
  51        .ndo_get_stats = mac_stats,
  52        .ndo_set_rx_mode  = wilc_set_multicast_list,
  53
  54};
  55
  56static int dev_state_ev_handler(struct notifier_block *this,
  57                                unsigned long event, void *ptr)
  58{
  59        struct in_ifaddr *dev_iface = ptr;
  60        struct wilc_priv *priv;
  61        struct host_if_drv *hif_drv;
  62        struct net_device *dev;
  63        u8 *ip_addr_buf;
  64        struct wilc_vif *vif;
  65        u8 null_ip[4] = {0};
  66        char wlan_dev_name[5] = "wlan0";
  67
  68        if (!dev_iface || !dev_iface->ifa_dev || !dev_iface->ifa_dev->dev)
  69                return NOTIFY_DONE;
  70
  71        if (memcmp(dev_iface->ifa_label, "wlan0", 5) &&
  72            memcmp(dev_iface->ifa_label, "p2p0", 4))
  73                return NOTIFY_DONE;
  74
  75        dev  = (struct net_device *)dev_iface->ifa_dev->dev;
  76        if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
  77                return NOTIFY_DONE;
  78
  79        priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
  80        if (!priv)
  81                return NOTIFY_DONE;
  82
  83        hif_drv = (struct host_if_drv *)priv->hif_drv;
  84        vif = netdev_priv(dev);
  85        if (!vif || !hif_drv)
  86                return NOTIFY_DONE;
  87
  88        switch (event) {
  89        case NETDEV_UP:
  90                if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
  91                        hif_drv->IFC_UP = 1;
  92                        wilc_optaining_ip = false;
  93                        del_timer(&wilc_during_ip_timer);
  94                }
  95
  96                if (wilc_enable_ps)
  97                        wilc_set_power_mgmt(vif, 1, 0);
  98
  99                netdev_dbg(dev, "[%s] Up IP\n", dev_iface->ifa_label);
 100
 101                ip_addr_buf = (char *)&dev_iface->ifa_address;
 102                netdev_dbg(dev, "IP add=%d:%d:%d:%d\n",
 103                           ip_addr_buf[0], ip_addr_buf[1],
 104                           ip_addr_buf[2], ip_addr_buf[3]);
 105                wilc_setup_ipaddress(vif, ip_addr_buf, vif->idx);
 106
 107                break;
 108
 109        case NETDEV_DOWN:
 110                if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
 111                        hif_drv->IFC_UP = 0;
 112                        wilc_optaining_ip = false;
 113                }
 114
 115                if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0)
 116                        wilc_set_power_mgmt(vif, 0, 0);
 117
 118                wilc_resolve_disconnect_aberration(vif);
 119
 120                netdev_dbg(dev, "[%s] Down IP\n", dev_iface->ifa_label);
 121
 122                ip_addr_buf = null_ip;
 123                netdev_dbg(dev, "IP add=%d:%d:%d:%d\n",
 124                           ip_addr_buf[0], ip_addr_buf[1],
 125                           ip_addr_buf[2], ip_addr_buf[3]);
 126
 127                wilc_setup_ipaddress(vif, ip_addr_buf, vif->idx);
 128
 129                break;
 130
 131        default:
 132                break;
 133        }
 134
 135        return NOTIFY_DONE;
 136}
 137
 138static irqreturn_t isr_uh_routine(int irq, void *user_data)
 139{
 140        struct wilc_vif *vif;
 141        struct wilc *wilc;
 142        struct net_device *dev = user_data;
 143
 144        vif = netdev_priv(dev);
 145        wilc = vif->wilc;
 146
 147        if (wilc->close) {
 148                netdev_err(dev, "Can't handle UH interrupt\n");
 149                return IRQ_HANDLED;
 150        }
 151        return IRQ_WAKE_THREAD;
 152}
 153
 154static irqreturn_t isr_bh_routine(int irq, void *userdata)
 155{
 156        struct wilc_vif *vif;
 157        struct wilc *wilc;
 158        struct net_device *dev = userdata;
 159
 160        vif = netdev_priv(userdata);
 161        wilc = vif->wilc;
 162
 163        if (wilc->close) {
 164                netdev_err(dev, "Can't handle BH interrupt\n");
 165                return IRQ_HANDLED;
 166        }
 167
 168        wilc_handle_isr(wilc);
 169
 170        return IRQ_HANDLED;
 171}
 172
 173static int init_irq(struct net_device *dev)
 174{
 175        int ret = 0;
 176        struct wilc_vif *vif;
 177        struct wilc *wl;
 178
 179        vif = netdev_priv(dev);
 180        wl = vif->wilc;
 181
 182        if ((gpio_request(wl->gpio, "WILC_INTR") == 0) &&
 183            (gpio_direction_input(wl->gpio) == 0)) {
 184                wl->dev_irq_num = gpio_to_irq(wl->gpio);
 185        } else {
 186                ret = -1;
 187                netdev_err(dev, "could not obtain gpio for WILC_INTR\n");
 188        }
 189
 190        if (ret != -1 && request_threaded_irq(wl->dev_irq_num,
 191                                              isr_uh_routine,
 192                                              isr_bh_routine,
 193                                              IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 194                                              "WILC_IRQ", dev) < 0) {
 195                netdev_err(dev, "Failed to request IRQ GPIO: %d\n", wl->gpio);
 196                gpio_free(wl->gpio);
 197                ret = -1;
 198        } else {
 199                netdev_dbg(dev,
 200                           "IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n",
 201                           wl->dev_irq_num, wl->gpio);
 202        }
 203
 204        return ret;
 205}
 206
 207static void deinit_irq(struct net_device *dev)
 208{
 209        struct wilc_vif *vif;
 210        struct wilc *wilc;
 211
 212        vif = netdev_priv(dev);
 213        wilc = vif->wilc;
 214
 215        /* Deintialize IRQ */
 216        if (wilc->dev_irq_num) {
 217                free_irq(wilc->dev_irq_num, wilc);
 218                gpio_free(wilc->gpio);
 219        }
 220}
 221
 222int wilc_lock_timeout(struct wilc *nic, void *vp, u32 timeout)
 223{
 224        /* FIXME: replace with mutex_lock or wait_for_completion */
 225        int error = -1;
 226
 227        if (vp)
 228                error = down_timeout(vp,
 229                                     msecs_to_jiffies(timeout));
 230        return error;
 231}
 232
 233void wilc_mac_indicate(struct wilc *wilc, int flag)
 234{
 235        int status;
 236
 237        if (flag == WILC_MAC_INDICATE_STATUS) {
 238                wilc_wlan_cfg_get_val(WID_STATUS,
 239                                      (unsigned char *)&status, 4);
 240                if (wilc->mac_status == WILC_MAC_STATUS_INIT) {
 241                        wilc->mac_status = status;
 242                        complete(&wilc->sync_event);
 243                } else {
 244                        wilc->mac_status = status;
 245                }
 246        }
 247}
 248
 249static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
 250{
 251        u8 *bssid, *bssid1;
 252        int i = 0;
 253
 254        bssid = mac_header + 10;
 255        bssid1 = mac_header + 4;
 256
 257        for (i = 0; i < wilc->vif_num; i++) {
 258                if (wilc->vif[i]->mode == STATION_MODE)
 259                        if (ether_addr_equal_unaligned(bssid,
 260                                                       wilc->vif[i]->bssid))
 261                                return wilc->vif[i]->ndev;
 262                if (wilc->vif[i]->mode == AP_MODE)
 263                        if (ether_addr_equal_unaligned(bssid1,
 264                                                       wilc->vif[i]->bssid))
 265                                return wilc->vif[i]->ndev;
 266        }
 267
 268        return NULL;
 269}
 270
 271int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode)
 272{
 273        int i = 0;
 274        int ret = -1;
 275        struct wilc_vif *vif;
 276        struct wilc *wilc;
 277
 278        vif = netdev_priv(wilc_netdev);
 279        wilc = vif->wilc;
 280
 281        for (i = 0; i < wilc->vif_num; i++)
 282                if (wilc->vif[i]->ndev == wilc_netdev) {
 283                        memcpy(wilc->vif[i]->bssid, bssid, 6);
 284                        wilc->vif[i]->mode = mode;
 285                        ret = 0;
 286                        break;
 287                }
 288
 289        return ret;
 290}
 291
 292int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc)
 293{
 294        u8 i = 0;
 295        u8 null_bssid[6] = {0};
 296        u8 ret_val = 0;
 297
 298        for (i = 0; i < wilc->vif_num; i++)
 299                if (memcmp(wilc->vif[i]->bssid, null_bssid, 6))
 300                        ret_val++;
 301
 302        return ret_val;
 303}
 304
 305static int linux_wlan_txq_task(void *vp)
 306{
 307        int ret, txq_count;
 308        struct wilc_vif *vif;
 309        struct wilc *wl;
 310        struct net_device *dev = vp;
 311
 312        vif = netdev_priv(dev);
 313        wl = vif->wilc;
 314
 315        complete(&wl->txq_thread_started);
 316        while (1) {
 317                wait_for_completion(&wl->txq_event);
 318
 319                if (wl->close) {
 320                        complete(&wl->txq_thread_started);
 321
 322                        while (!kthread_should_stop())
 323                                schedule();
 324                        break;
 325                }
 326                do {
 327                        ret = wilc_wlan_handle_txq(dev, &txq_count);
 328                        if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) {
 329                                if (netif_queue_stopped(wl->vif[0]->ndev))
 330                                        netif_wake_queue(wl->vif[0]->ndev);
 331                                if (netif_queue_stopped(wl->vif[1]->ndev))
 332                                        netif_wake_queue(wl->vif[1]->ndev);
 333                        }
 334                } while (ret == WILC_TX_ERR_NO_BUF && !wl->close);
 335        }
 336        return 0;
 337}
 338
 339int wilc_wlan_get_firmware(struct net_device *dev)
 340{
 341        struct wilc_vif *vif;
 342        struct wilc *wilc;
 343        int chip_id, ret = 0;
 344        const struct firmware *wilc_firmware;
 345        char *firmware;
 346
 347        vif = netdev_priv(dev);
 348        wilc = vif->wilc;
 349
 350        chip_id = wilc_get_chipid(wilc, false);
 351
 352        if (chip_id < 0x1003a0)
 353                firmware = FIRMWARE_1002;
 354        else
 355                firmware = FIRMWARE_1003;
 356
 357        netdev_info(dev, "loading firmware %s\n", firmware);
 358
 359        if (!(&vif->ndev->dev))
 360                goto _fail_;
 361
 362        if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) {
 363                netdev_err(dev, "%s - firmware not available\n", firmware);
 364                ret = -1;
 365                goto _fail_;
 366        }
 367        wilc->firmware = wilc_firmware;
 368
 369_fail_:
 370
 371        return ret;
 372}
 373
 374static int linux_wlan_start_firmware(struct net_device *dev)
 375{
 376        struct wilc_vif *vif;
 377        struct wilc *wilc;
 378        int ret = 0;
 379
 380        vif = netdev_priv(dev);
 381        wilc = vif->wilc;
 382
 383        ret = wilc_wlan_start(wilc);
 384        if (ret < 0)
 385                return ret;
 386
 387        if (!wait_for_completion_timeout(&wilc->sync_event,
 388                                        msecs_to_jiffies(5000)))
 389                return -ETIME;
 390
 391        return 0;
 392}
 393
 394static int wilc1000_firmware_download(struct net_device *dev)
 395{
 396        struct wilc_vif *vif;
 397        struct wilc *wilc;
 398        int ret = 0;
 399
 400        vif = netdev_priv(dev);
 401        wilc = vif->wilc;
 402
 403        if (!wilc->firmware) {
 404                netdev_err(dev, "Firmware buffer is NULL\n");
 405                return -ENOBUFS;
 406        }
 407
 408        ret = wilc_wlan_firmware_download(wilc, wilc->firmware->data,
 409                                          wilc->firmware->size);
 410        if (ret < 0)
 411                return ret;
 412
 413        release_firmware(wilc->firmware);
 414        wilc->firmware = NULL;
 415
 416        netdev_dbg(dev, "Download Succeeded\n");
 417
 418        return 0;
 419}
 420
 421static int linux_wlan_init_test_config(struct net_device *dev,
 422                                       struct wilc_vif *vif)
 423{
 424        unsigned char c_val[64];
 425        struct wilc *wilc = vif->wilc;
 426        struct wilc_priv *priv;
 427        struct host_if_drv *hif_drv;
 428
 429        netdev_dbg(dev, "Start configuring Firmware\n");
 430        priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
 431        hif_drv = (struct host_if_drv *)priv->hif_drv;
 432        netdev_dbg(dev, "Host = %p\n", hif_drv);
 433        wilc_get_chipid(wilc, false);
 434
 435        *(int *)c_val = 1;
 436
 437        if (!wilc_wlan_cfg_set(vif, 1, WID_SET_DRV_HANDLER, c_val, 4, 0, 0))
 438                goto _fail_;
 439
 440        c_val[0] = 0;
 441        if (!wilc_wlan_cfg_set(vif, 0, WID_PC_TEST_MODE, c_val, 1, 0, 0))
 442                goto _fail_;
 443
 444        c_val[0] = INFRASTRUCTURE;
 445        if (!wilc_wlan_cfg_set(vif, 0, WID_BSS_TYPE, c_val, 1, 0, 0))
 446                goto _fail_;
 447
 448        c_val[0] = RATE_AUTO;
 449        if (!wilc_wlan_cfg_set(vif, 0, WID_CURRENT_TX_RATE, c_val, 1, 0, 0))
 450                goto _fail_;
 451
 452        c_val[0] = G_MIXED_11B_2_MODE;
 453        if (!wilc_wlan_cfg_set(vif, 0, WID_11G_OPERATING_MODE, c_val, 1, 0,
 454                               0))
 455                goto _fail_;
 456
 457        c_val[0] = 1;
 458        if (!wilc_wlan_cfg_set(vif, 0, WID_CURRENT_CHANNEL, c_val, 1, 0, 0))
 459                goto _fail_;
 460
 461        c_val[0] = G_SHORT_PREAMBLE;
 462        if (!wilc_wlan_cfg_set(vif, 0, WID_PREAMBLE, c_val, 1, 0, 0))
 463                goto _fail_;
 464
 465        c_val[0] = AUTO_PROT;
 466        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_PROT_MECH, c_val, 1, 0, 0))
 467                goto _fail_;
 468
 469        c_val[0] = ACTIVE_SCAN;
 470        if (!wilc_wlan_cfg_set(vif, 0, WID_SCAN_TYPE, c_val, 1, 0, 0))
 471                goto _fail_;
 472
 473        c_val[0] = SITE_SURVEY_OFF;
 474        if (!wilc_wlan_cfg_set(vif, 0, WID_SITE_SURVEY, c_val, 1, 0, 0))
 475                goto _fail_;
 476
 477        *((int *)c_val) = 0xffff;
 478        if (!wilc_wlan_cfg_set(vif, 0, WID_RTS_THRESHOLD, c_val, 2, 0, 0))
 479                goto _fail_;
 480
 481        *((int *)c_val) = 2346;
 482        if (!wilc_wlan_cfg_set(vif, 0, WID_FRAG_THRESHOLD, c_val, 2, 0, 0))
 483                goto _fail_;
 484
 485        c_val[0] = 0;
 486        if (!wilc_wlan_cfg_set(vif, 0, WID_BCAST_SSID, c_val, 1, 0, 0))
 487                goto _fail_;
 488
 489        c_val[0] = 1;
 490        if (!wilc_wlan_cfg_set(vif, 0, WID_QOS_ENABLE, c_val, 1, 0, 0))
 491                goto _fail_;
 492
 493        c_val[0] = NO_POWERSAVE;
 494        if (!wilc_wlan_cfg_set(vif, 0, WID_POWER_MANAGEMENT, c_val, 1, 0, 0))
 495                goto _fail_;
 496
 497        c_val[0] = NO_SECURITY; /* NO_ENCRYPT, 0x79 */
 498        if (!wilc_wlan_cfg_set(vif, 0, WID_11I_MODE, c_val, 1, 0, 0))
 499                goto _fail_;
 500
 501        c_val[0] = OPEN_SYSTEM;
 502        if (!wilc_wlan_cfg_set(vif, 0, WID_AUTH_TYPE, c_val, 1, 0, 0))
 503                goto _fail_;
 504
 505        strcpy(c_val, "123456790abcdef1234567890");
 506        if (!wilc_wlan_cfg_set(vif, 0, WID_WEP_KEY_VALUE, c_val,
 507                               (strlen(c_val) + 1), 0, 0))
 508                goto _fail_;
 509
 510        strcpy(c_val, "12345678");
 511        if (!wilc_wlan_cfg_set(vif, 0, WID_11I_PSK, c_val, (strlen(c_val)), 0,
 512                               0))
 513                goto _fail_;
 514
 515        strcpy(c_val, "password");
 516        if (!wilc_wlan_cfg_set(vif, 0, WID_1X_KEY, c_val, (strlen(c_val) + 1),
 517                               0, 0))
 518                goto _fail_;
 519
 520        c_val[0] = 192;
 521        c_val[1] = 168;
 522        c_val[2] = 1;
 523        c_val[3] = 112;
 524        if (!wilc_wlan_cfg_set(vif, 0, WID_1X_SERV_ADDR, c_val, 4, 0, 0))
 525                goto _fail_;
 526
 527        c_val[0] = 3;
 528        if (!wilc_wlan_cfg_set(vif, 0, WID_LISTEN_INTERVAL, c_val, 1, 0, 0))
 529                goto _fail_;
 530
 531        c_val[0] = 3;
 532        if (!wilc_wlan_cfg_set(vif, 0, WID_DTIM_PERIOD, c_val, 1, 0, 0))
 533                goto _fail_;
 534
 535        c_val[0] = NORMAL_ACK;
 536        if (!wilc_wlan_cfg_set(vif, 0, WID_ACK_POLICY, c_val, 1, 0, 0))
 537                goto _fail_;
 538
 539        c_val[0] = 0;
 540        if (!wilc_wlan_cfg_set(vif, 0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1,
 541                               0, 0))
 542                goto _fail_;
 543
 544        c_val[0] = 48;
 545        if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0,
 546                               0))
 547                goto _fail_;
 548
 549        c_val[0] = 28;
 550        if (!wilc_wlan_cfg_set(vif, 0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0,
 551                               0))
 552                goto _fail_;
 553
 554        *((int *)c_val) = 100;
 555        if (!wilc_wlan_cfg_set(vif, 0, WID_BEACON_INTERVAL, c_val, 2, 0, 0))
 556                goto _fail_;
 557
 558        c_val[0] = REKEY_DISABLE;
 559        if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_POLICY, c_val, 1, 0, 0))
 560                goto _fail_;
 561
 562        *((int *)c_val) = 84600;
 563        if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PERIOD, c_val, 4, 0, 0))
 564                goto _fail_;
 565
 566        *((int *)c_val) = 500;
 567        if (!wilc_wlan_cfg_set(vif, 0, WID_REKEY_PACKET_COUNT, c_val, 4, 0,
 568                               0))
 569                goto _fail_;
 570
 571        c_val[0] = 1;
 572        if (!wilc_wlan_cfg_set(vif, 0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0,
 573                               0))
 574                goto _fail_;
 575
 576        c_val[0] = G_SELF_CTS_PROT;
 577        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0, 0))
 578                goto _fail_;
 579
 580        c_val[0] = 1;
 581        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_ENABLE, c_val, 1, 0, 0))
 582                goto _fail_;
 583
 584        c_val[0] = HT_MIXED_MODE;
 585        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OPERATING_MODE, c_val, 1, 0,
 586                               0))
 587                goto _fail_;
 588
 589        c_val[0] = 1;
 590        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0,
 591                               0))
 592                goto _fail_;
 593
 594        c_val[0] = DETECT_PROTECT_REPORT;
 595        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1,
 596                               0, 0))
 597                goto _fail_;
 598
 599        c_val[0] = RTS_CTS_NONHT_PROT;
 600        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_HT_PROT_TYPE, c_val, 1, 0, 0))
 601                goto _fail_;
 602
 603        c_val[0] = 0;
 604        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0,
 605                               0))
 606                goto _fail_;
 607
 608        c_val[0] = MIMO_MODE;
 609        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_SMPS_MODE, c_val, 1, 0, 0))
 610                goto _fail_;
 611
 612        c_val[0] = 7;
 613        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0,
 614                               0))
 615                goto _fail_;
 616
 617        c_val[0] = 1;
 618        if (!wilc_wlan_cfg_set(vif, 0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1,
 619                               1, 1))
 620                goto _fail_;
 621
 622        return 0;
 623
 624_fail_:
 625        return -1;
 626}
 627
 628void wilc1000_wlan_deinit(struct net_device *dev)
 629{
 630        struct wilc_vif *vif;
 631        struct wilc *wl;
 632
 633        vif = netdev_priv(dev);
 634        wl = vif->wilc;
 635
 636        if (!wl) {
 637                netdev_err(dev, "wl is NULL\n");
 638                return;
 639        }
 640
 641        if (wl->initialized)    {
 642                netdev_info(dev, "Deinitializing wilc1000...\n");
 643
 644                if (!wl->dev_irq_num &&
 645                    wl->hif_func->disable_interrupt) {
 646                        mutex_lock(&wl->hif_cs);
 647                        wl->hif_func->disable_interrupt(wl);
 648                        mutex_unlock(&wl->hif_cs);
 649                }
 650                if (&wl->txq_event)
 651                        complete(&wl->txq_event);
 652
 653                wlan_deinitialize_threads(dev);
 654                deinit_irq(dev);
 655
 656                wilc_wlan_stop(wl);
 657                wilc_wlan_cleanup(dev);
 658                wlan_deinit_locks(dev);
 659
 660                wl->initialized = false;
 661
 662                netdev_dbg(dev, "wilc1000 deinitialization Done\n");
 663        } else {
 664                netdev_dbg(dev, "wilc1000 is not initialized\n");
 665        }
 666}
 667
 668static int wlan_init_locks(struct net_device *dev)
 669{
 670        struct wilc_vif *vif;
 671        struct wilc *wl;
 672
 673        vif = netdev_priv(dev);
 674        wl = vif->wilc;
 675
 676        mutex_init(&wl->hif_cs);
 677        mutex_init(&wl->rxq_cs);
 678
 679        spin_lock_init(&wl->txq_spinlock);
 680        mutex_init(&wl->txq_add_to_head_cs);
 681
 682        init_completion(&wl->txq_event);
 683
 684        init_completion(&wl->cfg_event);
 685        init_completion(&wl->sync_event);
 686        init_completion(&wl->txq_thread_started);
 687
 688        return 0;
 689}
 690
 691static int wlan_deinit_locks(struct net_device *dev)
 692{
 693        struct wilc_vif *vif;
 694        struct wilc *wilc;
 695
 696        vif = netdev_priv(dev);
 697        wilc = vif->wilc;
 698
 699        if (&wilc->hif_cs)
 700                mutex_destroy(&wilc->hif_cs);
 701
 702        if (&wilc->rxq_cs)
 703                mutex_destroy(&wilc->rxq_cs);
 704
 705        return 0;
 706}
 707
 708static int wlan_initialize_threads(struct net_device *dev)
 709{
 710        struct wilc_vif *vif;
 711        struct wilc *wilc;
 712
 713        vif = netdev_priv(dev);
 714        wilc = vif->wilc;
 715
 716        wilc->txq_thread = kthread_run(linux_wlan_txq_task, (void *)dev,
 717                                     "K_TXQ_TASK");
 718        if (IS_ERR(wilc->txq_thread)) {
 719                netdev_err(dev, "couldn't create TXQ thread\n");
 720                wilc->close = 0;
 721                return PTR_ERR(wilc->txq_thread);
 722        }
 723        wait_for_completion(&wilc->txq_thread_started);
 724
 725        return 0;
 726}
 727
 728static void wlan_deinitialize_threads(struct net_device *dev)
 729{
 730        struct wilc_vif *vif;
 731        struct wilc *wl;
 732
 733        vif = netdev_priv(dev);
 734        wl = vif->wilc;
 735
 736        wl->close = 1;
 737
 738        if (&wl->txq_event)
 739                complete(&wl->txq_event);
 740
 741        if (wl->txq_thread) {
 742                kthread_stop(wl->txq_thread);
 743                wl->txq_thread = NULL;
 744        }
 745}
 746
 747int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif)
 748{
 749        int ret = 0;
 750        struct wilc *wl = vif->wilc;
 751
 752        if (!wl->initialized) {
 753                wl->mac_status = WILC_MAC_STATUS_INIT;
 754                wl->close = 0;
 755
 756                wlan_init_locks(dev);
 757
 758                ret = wilc_wlan_init(dev);
 759                if (ret < 0) {
 760                        ret = -EIO;
 761                        goto _fail_locks_;
 762                }
 763
 764                if (wl->gpio >= 0 && init_irq(dev)) {
 765                        ret = -EIO;
 766                        goto _fail_locks_;
 767                }
 768
 769                ret = wlan_initialize_threads(dev);
 770                if (ret < 0) {
 771                        ret = -EIO;
 772                        goto _fail_wilc_wlan_;
 773                }
 774
 775                if (!wl->dev_irq_num &&
 776                    wl->hif_func->enable_interrupt &&
 777                    wl->hif_func->enable_interrupt(wl)) {
 778                        ret = -EIO;
 779                        goto _fail_irq_init_;
 780                }
 781
 782                if (wilc_wlan_get_firmware(dev)) {
 783                        ret = -EIO;
 784                        goto _fail_irq_enable_;
 785                }
 786
 787                ret = wilc1000_firmware_download(dev);
 788                if (ret < 0) {
 789                        ret = -EIO;
 790                        goto _fail_irq_enable_;
 791                }
 792
 793                ret = linux_wlan_start_firmware(dev);
 794                if (ret < 0) {
 795                        ret = -EIO;
 796                        goto _fail_irq_enable_;
 797                }
 798
 799                if (wilc_wlan_cfg_get(vif, 1, WID_FIRMWARE_VERSION, 1, 0)) {
 800                        int size;
 801                        char firmware_ver[20];
 802
 803                        size = wilc_wlan_cfg_get_val(WID_FIRMWARE_VERSION,
 804                                                     firmware_ver,
 805                                                     sizeof(firmware_ver));
 806                        firmware_ver[size] = '\0';
 807                        netdev_dbg(dev, "Firmware Ver = %s\n", firmware_ver);
 808                }
 809                ret = linux_wlan_init_test_config(dev, vif);
 810
 811                if (ret < 0) {
 812                        netdev_err(dev, "Failed to configure firmware\n");
 813                        ret = -EIO;
 814                        goto _fail_fw_start_;
 815                }
 816
 817                wl->initialized = true;
 818                return 0;
 819
 820_fail_fw_start_:
 821                wilc_wlan_stop(wl);
 822
 823_fail_irq_enable_:
 824                if (!wl->dev_irq_num &&
 825                    wl->hif_func->disable_interrupt)
 826                        wl->hif_func->disable_interrupt(wl);
 827_fail_irq_init_:
 828                if (wl->dev_irq_num)
 829                        deinit_irq(dev);
 830
 831                wlan_deinitialize_threads(dev);
 832_fail_wilc_wlan_:
 833                wilc_wlan_cleanup(dev);
 834_fail_locks_:
 835                wlan_deinit_locks(dev);
 836                netdev_err(dev, "WLAN Iinitialization FAILED\n");
 837        } else {
 838                netdev_dbg(dev, "wilc1000 already initialized\n");
 839        }
 840        return ret;
 841}
 842
 843static int mac_init_fn(struct net_device *ndev)
 844{
 845        netif_start_queue(ndev);
 846        netif_stop_queue(ndev);
 847
 848        return 0;
 849}
 850
 851int wilc_mac_open(struct net_device *ndev)
 852{
 853        struct wilc_vif *vif;
 854
 855        unsigned char mac_add[ETH_ALEN] = {0};
 856        int ret = 0;
 857        int i = 0;
 858        struct wilc *wl;
 859
 860        vif = netdev_priv(ndev);
 861        wl = vif->wilc;
 862
 863        if (!wl || !wl->dev) {
 864                netdev_err(ndev, "device not ready\n");
 865                return -ENODEV;
 866        }
 867
 868        netdev_dbg(ndev, "MAC OPEN[%p]\n", ndev);
 869
 870        ret = wilc_init_host_int(ndev);
 871        if (ret < 0)
 872                return ret;
 873
 874        ret = wilc1000_wlan_init(ndev, vif);
 875        if (ret < 0) {
 876                wilc_deinit_host_int(ndev);
 877                return ret;
 878        }
 879
 880        for (i = 0; i < wl->vif_num; i++) {
 881                if (ndev == wl->vif[i]->ndev) {
 882                        if (vif->iftype == AP_MODE) {
 883                                wilc_set_wfi_drv_handler(vif,
 884                                                         wilc_get_vif_idx(vif),
 885                                                         0);
 886                        } else if (!wilc_wlan_get_num_conn_ifcs(wl)) {
 887                                wilc_set_wfi_drv_handler(vif,
 888                                                         wilc_get_vif_idx(vif),
 889                                                         wl->open_ifcs);
 890                        } else {
 891                                if (memcmp(wl->vif[i ^ 1]->bssid,
 892                                           wl->vif[i ^ 1]->src_addr, 6))
 893                                        wilc_set_wfi_drv_handler(vif,
 894                                                         wilc_get_vif_idx(vif),
 895                                                         0);
 896                                else
 897                                        wilc_set_wfi_drv_handler(vif,
 898                                                         wilc_get_vif_idx(vif),
 899                                                         1);
 900                        }
 901                        wilc_set_operation_mode(vif, vif->iftype);
 902
 903                        wilc_get_mac_address(vif, mac_add);
 904                        netdev_dbg(ndev, "Mac address: %pM\n", mac_add);
 905                        memcpy(wl->vif[i]->src_addr, mac_add, ETH_ALEN);
 906
 907                        break;
 908                }
 909        }
 910
 911        memcpy(ndev->dev_addr, wl->vif[i]->src_addr, ETH_ALEN);
 912
 913        if (!is_valid_ether_addr(ndev->dev_addr)) {
 914                netdev_err(ndev, "Wrong MAC address\n");
 915                wilc_deinit_host_int(ndev);
 916                wilc1000_wlan_deinit(ndev);
 917                return -EINVAL;
 918        }
 919
 920        wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy,
 921                                 vif->ndev->ieee80211_ptr,
 922                                 vif->frame_reg[0].type,
 923                                 vif->frame_reg[0].reg);
 924        wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy,
 925                                 vif->ndev->ieee80211_ptr,
 926                                 vif->frame_reg[1].type,
 927                                 vif->frame_reg[1].reg);
 928        netif_wake_queue(ndev);
 929        wl->open_ifcs++;
 930        vif->mac_opened = 1;
 931        return 0;
 932}
 933
 934static struct net_device_stats *mac_stats(struct net_device *dev)
 935{
 936        struct wilc_vif *vif = netdev_priv(dev);
 937
 938        return &vif->netstats;
 939}
 940
 941static void wilc_set_multicast_list(struct net_device *dev)
 942{
 943        struct netdev_hw_addr *ha;
 944        struct wilc_vif *vif;
 945        int i = 0;
 946
 947        vif = netdev_priv(dev);
 948
 949        if (dev->flags & IFF_PROMISC)
 950                return;
 951
 952        if ((dev->flags & IFF_ALLMULTI) ||
 953            (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) {
 954                wilc_setup_multicast_filter(vif, false, 0);
 955                return;
 956        }
 957
 958        if ((dev->mc.count) == 0) {
 959                wilc_setup_multicast_filter(vif, true, 0);
 960                return;
 961        }
 962
 963        netdev_for_each_mc_addr(ha, dev) {
 964                memcpy(wilc_multicast_mac_addr_list[i], ha->addr, ETH_ALEN);
 965                netdev_dbg(dev, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i,
 966                           wilc_multicast_mac_addr_list[i][0],
 967                           wilc_multicast_mac_addr_list[i][1],
 968                           wilc_multicast_mac_addr_list[i][2],
 969                           wilc_multicast_mac_addr_list[i][3],
 970                           wilc_multicast_mac_addr_list[i][4],
 971                           wilc_multicast_mac_addr_list[i][5]);
 972                i++;
 973        }
 974
 975        wilc_setup_multicast_filter(vif, true, (dev->mc.count));
 976}
 977
 978static void linux_wlan_tx_complete(void *priv, int status)
 979{
 980        struct tx_complete_data *pv_data = priv;
 981
 982        dev_kfree_skb(pv_data->skb);
 983        kfree(pv_data);
 984}
 985
 986int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
 987{
 988        struct wilc_vif *vif;
 989        struct tx_complete_data *tx_data = NULL;
 990        int queue_count;
 991        char *udp_buf;
 992        struct iphdr *ih;
 993        struct ethhdr *eth_h;
 994        struct wilc *wilc;
 995
 996        vif = netdev_priv(ndev);
 997        wilc = vif->wilc;
 998
 999        if (skb->dev != ndev) {
1000                netdev_err(ndev, "Packet not destined to this device\n");
1001                return 0;
1002        }
1003
1004        tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC);
1005        if (!tx_data) {
1006                dev_kfree_skb(skb);
1007                netif_wake_queue(ndev);
1008                return 0;
1009        }
1010
1011        tx_data->buff = skb->data;
1012        tx_data->size = skb->len;
1013        tx_data->skb  = skb;
1014
1015        eth_h = (struct ethhdr *)(skb->data);
1016        if (eth_h->h_proto == 0x8e88)
1017                netdev_dbg(ndev, "EAPOL transmitted\n");
1018
1019        ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
1020
1021        udp_buf = (char *)ih + sizeof(struct iphdr);
1022        if ((udp_buf[1] == 68 && udp_buf[3] == 67) ||
1023            (udp_buf[1] == 67 && udp_buf[3] == 68))
1024                netdev_dbg(ndev, "DHCP Message transmitted, type:%x %x %x\n",
1025                           udp_buf[248], udp_buf[249], udp_buf[250]);
1026
1027        vif->netstats.tx_packets++;
1028        vif->netstats.tx_bytes += tx_data->size;
1029        tx_data->bssid = wilc->vif[vif->idx]->bssid;
1030        queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data,
1031                                                tx_data->buff, tx_data->size,
1032                                                linux_wlan_tx_complete);
1033
1034        if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
1035                netif_stop_queue(wilc->vif[0]->ndev);
1036                netif_stop_queue(wilc->vif[1]->ndev);
1037        }
1038
1039        return 0;
1040}
1041
1042int wilc_mac_close(struct net_device *ndev)
1043{
1044        struct wilc_priv *priv;
1045        struct wilc_vif *vif;
1046        struct host_if_drv *hif_drv;
1047        struct wilc *wl;
1048
1049        vif = netdev_priv(ndev);
1050
1051        if (!vif || !vif->ndev || !vif->ndev->ieee80211_ptr ||
1052            !vif->ndev->ieee80211_ptr->wiphy)
1053                return 0;
1054
1055        priv = wiphy_priv(vif->ndev->ieee80211_ptr->wiphy);
1056        wl = vif->wilc;
1057
1058        if (!priv)
1059                return 0;
1060
1061        hif_drv = (struct host_if_drv *)priv->hif_drv;
1062
1063        netdev_dbg(ndev, "Mac close\n");
1064
1065        if (!wl)
1066                return 0;
1067
1068        if (!hif_drv)
1069                return 0;
1070
1071        if ((wl->open_ifcs) > 0)
1072                wl->open_ifcs--;
1073        else
1074                return 0;
1075
1076        if (vif->ndev) {
1077                netif_stop_queue(vif->ndev);
1078
1079                wilc_deinit_host_int(vif->ndev);
1080        }
1081
1082        if (wl->open_ifcs == 0) {
1083                netdev_dbg(ndev, "Deinitializing wilc1000\n");
1084                wl->close = 1;
1085                wilc1000_wlan_deinit(ndev);
1086                WILC_WFI_deinit_mon_interface();
1087        }
1088
1089        vif->mac_opened = 0;
1090
1091        return 0;
1092}
1093
1094static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
1095{
1096        u8 *buff = NULL;
1097        s8 rssi;
1098        u32 size = 0, length = 0;
1099        struct wilc_vif *vif;
1100        s32 ret = 0;
1101        struct wilc *wilc;
1102
1103        vif = netdev_priv(ndev);
1104        wilc = vif->wilc;
1105
1106        if (!wilc->initialized)
1107                return 0;
1108
1109        switch (cmd) {
1110        case SIOCSIWPRIV:
1111        {
1112                struct iwreq *wrq = (struct iwreq *)req;
1113
1114                size = wrq->u.data.length;
1115
1116                if (size && wrq->u.data.pointer) {
1117                        buff = memdup_user(wrq->u.data.pointer,
1118                                           wrq->u.data.length);
1119                        if (IS_ERR(buff))
1120                                return PTR_ERR(buff);
1121
1122                        if (strncasecmp(buff, "RSSI", length) == 0) {
1123                                ret = wilc_get_rssi(vif, &rssi);
1124                                netdev_info(ndev, "RSSI :%d\n", rssi);
1125
1126                                rssi += 5;
1127
1128                                snprintf(buff, size, "rssi %d", rssi);
1129
1130                                if (copy_to_user(wrq->u.data.pointer, buff, size)) {
1131                                        netdev_err(ndev, "failed to copy\n");
1132                                        ret = -EFAULT;
1133                                        goto done;
1134                                }
1135                        }
1136                }
1137        }
1138        break;
1139
1140        default:
1141        {
1142                netdev_info(ndev, "Command - %d - has been received\n", cmd);
1143                ret = -EOPNOTSUPP;
1144                goto done;
1145        }
1146        }
1147
1148done:
1149
1150        kfree(buff);
1151
1152        return ret;
1153}
1154
1155void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset)
1156{
1157        unsigned int frame_len = 0;
1158        int stats;
1159        unsigned char *buff_to_send = NULL;
1160        struct sk_buff *skb;
1161        struct net_device *wilc_netdev;
1162        struct wilc_vif *vif;
1163
1164        if (!wilc)
1165                return;
1166
1167        wilc_netdev = get_if_handler(wilc, buff);
1168        if (!wilc_netdev)
1169                return;
1170
1171        buff += pkt_offset;
1172        vif = netdev_priv(wilc_netdev);
1173
1174        if (size > 0) {
1175                frame_len = size;
1176                buff_to_send = buff;
1177
1178                skb = dev_alloc_skb(frame_len);
1179                if (!skb)
1180                        return;
1181
1182                skb->dev = wilc_netdev;
1183
1184                memcpy(skb_put(skb, frame_len), buff_to_send, frame_len);
1185
1186                skb->protocol = eth_type_trans(skb, wilc_netdev);
1187                vif->netstats.rx_packets++;
1188                vif->netstats.rx_bytes += frame_len;
1189                skb->ip_summed = CHECKSUM_UNNECESSARY;
1190                stats = netif_rx(skb);
1191                netdev_dbg(wilc_netdev, "netif_rx ret value is: %d\n", stats);
1192        }
1193}
1194
1195void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
1196{
1197        int i = 0;
1198        struct wilc_vif *vif;
1199
1200        for (i = 0; i < wilc->vif_num; i++) {
1201                vif = netdev_priv(wilc->vif[i]->ndev);
1202                if (vif->monitor_flag) {
1203                        WILC_WFI_monitor_rx(buff, size);
1204                        return;
1205                }
1206        }
1207
1208        vif = netdev_priv(wilc->vif[1]->ndev);
1209        if ((buff[0] == vif->frame_reg[0].type && vif->frame_reg[0].reg) ||
1210            (buff[0] == vif->frame_reg[1].type && vif->frame_reg[1].reg))
1211                WILC_WFI_p2p_rx(wilc->vif[1]->ndev, buff, size);
1212}
1213
1214void wilc_netdev_cleanup(struct wilc *wilc)
1215{
1216        int i = 0;
1217        struct wilc_vif *vif[NUM_CONCURRENT_IFC];
1218
1219        if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
1220                unregister_inetaddr_notifier(&g_dev_notifier);
1221
1222                for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1223                        vif[i] = netdev_priv(wilc->vif[i]->ndev);
1224        }
1225
1226        if (wilc && wilc->firmware) {
1227                release_firmware(wilc->firmware);
1228                wilc->firmware = NULL;
1229        }
1230
1231        if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
1232                for (i = 0; i < NUM_CONCURRENT_IFC; i++)
1233                        if (wilc->vif[i]->ndev)
1234                                if (vif[i]->mac_opened)
1235                                        wilc_mac_close(wilc->vif[i]->ndev);
1236
1237                for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1238                        unregister_netdev(wilc->vif[i]->ndev);
1239                        wilc_free_wiphy(wilc->vif[i]->ndev);
1240                        free_netdev(wilc->vif[i]->ndev);
1241                }
1242        }
1243
1244        kfree(wilc);
1245}
1246EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
1247
1248int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
1249                     int gpio, const struct wilc_hif_func *ops)
1250{
1251        int i, ret;
1252        struct wilc_vif *vif;
1253        struct net_device *ndev;
1254        struct wilc *wl;
1255
1256        wl = kzalloc(sizeof(*wl), GFP_KERNEL);
1257        if (!wl)
1258                return -ENOMEM;
1259
1260        *wilc = wl;
1261        wl->io_type = io_type;
1262        wl->gpio = gpio;
1263        wl->hif_func = ops;
1264
1265        register_inetaddr_notifier(&g_dev_notifier);
1266
1267        for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
1268                ndev = alloc_etherdev(sizeof(struct wilc_vif));
1269                if (!ndev)
1270                        return -ENOMEM;
1271
1272                vif = netdev_priv(ndev);
1273                memset(vif, 0, sizeof(struct wilc_vif));
1274
1275                if (i == 0)
1276                        strcpy(ndev->name, "wlan%d");
1277                else
1278                        strcpy(ndev->name, "p2p%d");
1279
1280                vif->idx = wl->vif_num;
1281                vif->wilc = *wilc;
1282                wl->vif[i] = vif;
1283                wl->vif[wl->vif_num]->ndev = ndev;
1284                wl->vif_num++;
1285                ndev->netdev_ops = &wilc_netdev_ops;
1286
1287                {
1288                        struct wireless_dev *wdev;
1289
1290                        wdev = wilc_create_wiphy(ndev, dev);
1291
1292                        if (dev)
1293                                SET_NETDEV_DEV(ndev, dev);
1294
1295                        if (!wdev) {
1296                                netdev_err(ndev, "Can't register WILC Wiphy\n");
1297                                return -1;
1298                        }
1299
1300                        vif->ndev->ieee80211_ptr = wdev;
1301                        vif->ndev->ml_priv = vif;
1302                        wdev->netdev = vif->ndev;
1303                        vif->netstats.rx_packets = 0;
1304                        vif->netstats.tx_packets = 0;
1305                        vif->netstats.rx_bytes = 0;
1306                        vif->netstats.tx_bytes = 0;
1307                }
1308
1309                ret = register_netdev(ndev);
1310                if (ret)
1311                        return ret;
1312
1313                vif->iftype = STATION_MODE;
1314                vif->mac_opened = 0;
1315        }
1316
1317        return 0;
1318}
1319EXPORT_SYMBOL_GPL(wilc_netdev_init);
1320
1321MODULE_LICENSE("GPL");
1322