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