linux/drivers/staging/wlan-ng/p80211netdev.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
   2/* src/p80211/p80211knetdev.c
   3 *
   4 * Linux Kernel net device interface
   5 *
   6 * Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
   7 * --------------------------------------------------------------------
   8 *
   9 * linux-wlan
  10 *
  11 *   The contents of this file are subject to the Mozilla Public
  12 *   License Version 1.1 (the "License"); you may not use this file
  13 *   except in compliance with the License. You may obtain a copy of
  14 *   the License at http://www.mozilla.org/MPL/
  15 *
  16 *   Software distributed under the License is distributed on an "AS
  17 *   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  18 *   implied. See the License for the specific language governing
  19 *   rights and limitations under the License.
  20 *
  21 *   Alternatively, the contents of this file may be used under the
  22 *   terms of the GNU Public License version 2 (the "GPL"), in which
  23 *   case the provisions of the GPL are applicable instead of the
  24 *   above.  If you wish to allow the use of your version of this file
  25 *   only under the terms of the GPL and not to allow others to use
  26 *   your version of this file under the MPL, indicate your decision
  27 *   by deleting the provisions above and replace them with the notice
  28 *   and other provisions required by the GPL.  If you do not delete
  29 *   the provisions above, a recipient may use your version of this
  30 *   file under either the MPL or the GPL.
  31 *
  32 * --------------------------------------------------------------------
  33 *
  34 * Inquiries regarding the linux-wlan Open Source project can be
  35 * made directly to:
  36 *
  37 * AbsoluteValue Systems Inc.
  38 * info@linux-wlan.com
  39 * http://www.linux-wlan.com
  40 *
  41 * --------------------------------------------------------------------
  42 *
  43 * Portions of the development of this software were funded by
  44 * Intersil Corporation as part of PRISM(R) chipset product development.
  45 *
  46 * --------------------------------------------------------------------
  47 *
  48 * The functions required for a Linux network device are defined here.
  49 *
  50 * --------------------------------------------------------------------
  51 */
  52
  53#include <linux/module.h>
  54#include <linux/kernel.h>
  55#include <linux/sched.h>
  56#include <linux/types.h>
  57#include <linux/skbuff.h>
  58#include <linux/slab.h>
  59#include <linux/proc_fs.h>
  60#include <linux/interrupt.h>
  61#include <linux/netdevice.h>
  62#include <linux/kmod.h>
  63#include <linux/if_arp.h>
  64#include <linux/wireless.h>
  65#include <linux/sockios.h>
  66#include <linux/etherdevice.h>
  67#include <linux/if_ether.h>
  68#include <linux/byteorder/generic.h>
  69#include <linux/bitops.h>
  70#include <linux/uaccess.h>
  71#include <asm/byteorder.h>
  72
  73#ifdef SIOCETHTOOL
  74#include <linux/ethtool.h>
  75#endif
  76
  77#include <net/iw_handler.h>
  78#include <net/net_namespace.h>
  79#include <net/cfg80211.h>
  80
  81#include "p80211types.h"
  82#include "p80211hdr.h"
  83#include "p80211conv.h"
  84#include "p80211mgmt.h"
  85#include "p80211msg.h"
  86#include "p80211netdev.h"
  87#include "p80211ioctl.h"
  88#include "p80211req.h"
  89#include "p80211metastruct.h"
  90#include "p80211metadef.h"
  91
  92#include "cfg80211.c"
  93
  94/* netdevice method functions */
  95static int p80211knetdev_init(struct net_device *netdev);
  96static int p80211knetdev_open(struct net_device *netdev);
  97static int p80211knetdev_stop(struct net_device *netdev);
  98static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb,
  99                                                 struct net_device *netdev);
 100static void p80211knetdev_set_multicast_list(struct net_device *dev);
 101static int p80211knetdev_do_ioctl(struct net_device *dev, struct ifreq *ifr,
 102                                  int cmd);
 103static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr);
 104static void p80211knetdev_tx_timeout(struct net_device *netdev, unsigned int txqueue);
 105static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc);
 106
 107int wlan_watchdog = 5000;
 108module_param(wlan_watchdog, int, 0644);
 109MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds");
 110
 111int wlan_wext_write = 1;
 112module_param(wlan_wext_write, int, 0644);
 113MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
 114
 115/*----------------------------------------------------------------
 116 * p80211knetdev_init
 117 *
 118 * Init method for a Linux netdevice.  Called in response to
 119 * register_netdev.
 120 *
 121 * Arguments:
 122 *      none
 123 *
 124 * Returns:
 125 *      nothing
 126 *----------------------------------------------------------------
 127 */
 128static int p80211knetdev_init(struct net_device *netdev)
 129{
 130        /* Called in response to register_netdev */
 131        /* This is usually the probe function, but the probe has */
 132        /* already been done by the MSD and the create_kdev */
 133        /* function.  All we do here is return success */
 134        return 0;
 135}
 136
 137/*----------------------------------------------------------------
 138 * p80211knetdev_open
 139 *
 140 * Linux netdevice open method.  Following a successful call here,
 141 * the device is supposed to be ready for tx and rx.  In our
 142 * situation that may not be entirely true due to the state of the
 143 * MAC below.
 144 *
 145 * Arguments:
 146 *      netdev          Linux network device structure
 147 *
 148 * Returns:
 149 *      zero on success, non-zero otherwise
 150 *----------------------------------------------------------------
 151 */
 152static int p80211knetdev_open(struct net_device *netdev)
 153{
 154        int result = 0;         /* success */
 155        struct wlandevice *wlandev = netdev->ml_priv;
 156
 157        /* Check to make sure the MSD is running */
 158        if (wlandev->msdstate != WLAN_MSD_RUNNING)
 159                return -ENODEV;
 160
 161        /* Tell the MSD to open */
 162        if (wlandev->open) {
 163                result = wlandev->open(wlandev);
 164                if (result == 0) {
 165                        netif_start_queue(wlandev->netdev);
 166                        wlandev->state = WLAN_DEVICE_OPEN;
 167                }
 168        } else {
 169                result = -EAGAIN;
 170        }
 171
 172        return result;
 173}
 174
 175/*----------------------------------------------------------------
 176 * p80211knetdev_stop
 177 *
 178 * Linux netdevice stop (close) method.  Following this call,
 179 * no frames should go up or down through this interface.
 180 *
 181 * Arguments:
 182 *      netdev          Linux network device structure
 183 *
 184 * Returns:
 185 *      zero on success, non-zero otherwise
 186 *----------------------------------------------------------------
 187 */
 188static int p80211knetdev_stop(struct net_device *netdev)
 189{
 190        int result = 0;
 191        struct wlandevice *wlandev = netdev->ml_priv;
 192
 193        if (wlandev->close)
 194                result = wlandev->close(wlandev);
 195
 196        netif_stop_queue(wlandev->netdev);
 197        wlandev->state = WLAN_DEVICE_CLOSED;
 198
 199        return result;
 200}
 201
 202/*----------------------------------------------------------------
 203 * p80211netdev_rx
 204 *
 205 * Frame receive function called by the mac specific driver.
 206 *
 207 * Arguments:
 208 *      wlandev         WLAN network device structure
 209 *      skb             skbuff containing a full 802.11 frame.
 210 * Returns:
 211 *      nothing
 212 * Side effects:
 213 *
 214 *----------------------------------------------------------------
 215 */
 216void p80211netdev_rx(struct wlandevice *wlandev, struct sk_buff *skb)
 217{
 218        /* Enqueue for post-irq processing */
 219        skb_queue_tail(&wlandev->nsd_rxq, skb);
 220        tasklet_schedule(&wlandev->rx_bh);
 221}
 222
 223#define CONV_TO_ETHER_SKIPPED   0x01
 224#define CONV_TO_ETHER_FAILED    0x02
 225
 226/**
 227 * p80211_convert_to_ether - conversion from 802.11 frame to ethernet frame
 228 * @wlandev: pointer to WLAN device
 229 * @skb: pointer to socket buffer
 230 *
 231 * Returns: 0 if conversion succeeded
 232 *          CONV_TO_ETHER_FAILED if conversion failed
 233 *          CONV_TO_ETHER_SKIPPED if frame is ignored
 234 */
 235static int p80211_convert_to_ether(struct wlandevice *wlandev,
 236                                   struct sk_buff *skb)
 237{
 238        struct p80211_hdr_a3 *hdr;
 239
 240        hdr = (struct p80211_hdr_a3 *)skb->data;
 241        if (p80211_rx_typedrop(wlandev, le16_to_cpu(hdr->fc)))
 242                return CONV_TO_ETHER_SKIPPED;
 243
 244        /* perform mcast filtering: allow my local address through but reject
 245         * anything else that isn't multicast
 246         */
 247        if (wlandev->netdev->flags & IFF_ALLMULTI) {
 248                if (!ether_addr_equal_unaligned(wlandev->netdev->dev_addr,
 249                                                hdr->a1)) {
 250                        if (!is_multicast_ether_addr(hdr->a1))
 251                                return CONV_TO_ETHER_SKIPPED;
 252                }
 253        }
 254
 255        if (skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0) {
 256                wlandev->netdev->stats.rx_packets++;
 257                wlandev->netdev->stats.rx_bytes += skb->len;
 258                netif_rx_ni(skb);
 259                return 0;
 260        }
 261
 262        netdev_dbg(wlandev->netdev, "%s failed.\n", __func__);
 263        return CONV_TO_ETHER_FAILED;
 264}
 265
 266/**
 267 * p80211netdev_rx_bh - deferred processing of all received frames
 268 *
 269 * @t: pointer to the tasklet associated with this handler
 270 */
 271static void p80211netdev_rx_bh(struct tasklet_struct *t)
 272{
 273        struct wlandevice *wlandev = from_tasklet(wlandev, t, rx_bh);
 274        struct sk_buff *skb = NULL;
 275        struct net_device *dev = wlandev->netdev;
 276
 277        /* Let's empty our queue */
 278        while ((skb = skb_dequeue(&wlandev->nsd_rxq))) {
 279                if (wlandev->state == WLAN_DEVICE_OPEN) {
 280                        if (dev->type != ARPHRD_ETHER) {
 281                                /* RAW frame; we shouldn't convert it */
 282                                /* XXX Append the Prism Header here instead. */
 283
 284                                /* set up various data fields */
 285                                skb->dev = dev;
 286                                skb_reset_mac_header(skb);
 287                                skb->ip_summed = CHECKSUM_NONE;
 288                                skb->pkt_type = PACKET_OTHERHOST;
 289                                skb->protocol = htons(ETH_P_80211_RAW);
 290
 291                                dev->stats.rx_packets++;
 292                                dev->stats.rx_bytes += skb->len;
 293                                netif_rx_ni(skb);
 294                                continue;
 295                        } else {
 296                                if (!p80211_convert_to_ether(wlandev, skb))
 297                                        continue;
 298                        }
 299                }
 300                dev_kfree_skb(skb);
 301        }
 302}
 303
 304/*----------------------------------------------------------------
 305 * p80211knetdev_hard_start_xmit
 306 *
 307 * Linux netdevice method for transmitting a frame.
 308 *
 309 * Arguments:
 310 *      skb     Linux sk_buff containing the frame.
 311 *      netdev  Linux netdevice.
 312 *
 313 * Side effects:
 314 *      If the lower layers report that buffers are full. netdev->tbusy
 315 *      will be set to prevent higher layers from sending more traffic.
 316 *
 317 *      Note: If this function returns non-zero, higher layers retain
 318 *            ownership of the skb.
 319 *
 320 * Returns:
 321 *      zero on success, non-zero on failure.
 322 *----------------------------------------------------------------
 323 */
 324static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb,
 325                                                 struct net_device *netdev)
 326{
 327        int result = 0;
 328        int txresult;
 329        struct wlandevice *wlandev = netdev->ml_priv;
 330        union p80211_hdr p80211_hdr;
 331        struct p80211_metawep p80211_wep;
 332
 333        p80211_wep.data = NULL;
 334
 335        if (!skb)
 336                return NETDEV_TX_OK;
 337
 338        if (wlandev->state != WLAN_DEVICE_OPEN) {
 339                result = 1;
 340                goto failed;
 341        }
 342
 343        memset(&p80211_hdr, 0, sizeof(p80211_hdr));
 344        memset(&p80211_wep, 0, sizeof(p80211_wep));
 345
 346        if (netif_queue_stopped(netdev)) {
 347                netdev_dbg(netdev, "called when queue stopped.\n");
 348                result = 1;
 349                goto failed;
 350        }
 351
 352        netif_stop_queue(netdev);
 353
 354        /* Check to see that a valid mode is set */
 355        switch (wlandev->macmode) {
 356        case WLAN_MACMODE_IBSS_STA:
 357        case WLAN_MACMODE_ESS_STA:
 358        case WLAN_MACMODE_ESS_AP:
 359                break;
 360        default:
 361                /* Mode isn't set yet, just drop the frame
 362                 * and return success .
 363                 * TODO: we need a saner way to handle this
 364                 */
 365                if (be16_to_cpu(skb->protocol) != ETH_P_80211_RAW) {
 366                        netif_start_queue(wlandev->netdev);
 367                        netdev_notice(netdev, "Tx attempt prior to association, frame dropped.\n");
 368                        netdev->stats.tx_dropped++;
 369                        result = 0;
 370                        goto failed;
 371                }
 372                break;
 373        }
 374
 375        /* Check for raw transmits */
 376        if (be16_to_cpu(skb->protocol) == ETH_P_80211_RAW) {
 377                if (!capable(CAP_NET_ADMIN)) {
 378                        result = 1;
 379                        goto failed;
 380                }
 381                /* move the header over */
 382                memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr));
 383                skb_pull(skb, sizeof(p80211_hdr));
 384        } else {
 385                if (skb_ether_to_p80211
 386                    (wlandev, wlandev->ethconv, skb, &p80211_hdr,
 387                     &p80211_wep) != 0) {
 388                        /* convert failed */
 389                        netdev_dbg(netdev, "ether_to_80211(%d) failed.\n",
 390                                   wlandev->ethconv);
 391                        result = 1;
 392                        goto failed;
 393                }
 394        }
 395        if (!wlandev->txframe) {
 396                result = 1;
 397                goto failed;
 398        }
 399
 400        netif_trans_update(netdev);
 401
 402        netdev->stats.tx_packets++;
 403        /* count only the packet payload */
 404        netdev->stats.tx_bytes += skb->len;
 405
 406        txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);
 407
 408        if (txresult == 0) {
 409                /* success and more buf */
 410                /* avail, re: hw_txdata */
 411                netif_wake_queue(wlandev->netdev);
 412                result = NETDEV_TX_OK;
 413        } else if (txresult == 1) {
 414                /* success, no more avail */
 415                netdev_dbg(netdev, "txframe success, no more bufs\n");
 416                /* netdev->tbusy = 1;  don't set here, irqhdlr */
 417                /*   may have already cleared it */
 418                result = NETDEV_TX_OK;
 419        } else if (txresult == 2) {
 420                /* alloc failure, drop frame */
 421                netdev_dbg(netdev, "txframe returned alloc_fail\n");
 422                result = NETDEV_TX_BUSY;
 423        } else {
 424                /* buffer full or queue busy, drop frame. */
 425                netdev_dbg(netdev, "txframe returned full or busy\n");
 426                result = NETDEV_TX_BUSY;
 427        }
 428
 429failed:
 430        /* Free up the WEP buffer if it's not the same as the skb */
 431        if ((p80211_wep.data) && (p80211_wep.data != skb->data))
 432                kfree_sensitive(p80211_wep.data);
 433
 434        /* we always free the skb here, never in a lower level. */
 435        if (!result)
 436                dev_kfree_skb(skb);
 437
 438        return result;
 439}
 440
 441/*----------------------------------------------------------------
 442 * p80211knetdev_set_multicast_list
 443 *
 444 * Called from higher layers whenever there's a need to set/clear
 445 * promiscuous mode or rewrite the multicast list.
 446 *
 447 * Arguments:
 448 *      none
 449 *
 450 * Returns:
 451 *      nothing
 452 *----------------------------------------------------------------
 453 */
 454static void p80211knetdev_set_multicast_list(struct net_device *dev)
 455{
 456        struct wlandevice *wlandev = dev->ml_priv;
 457
 458        /* TODO:  real multicast support as well */
 459
 460        if (wlandev->set_multicast_list)
 461                wlandev->set_multicast_list(wlandev, dev);
 462}
 463
 464#ifdef SIOCETHTOOL
 465
 466static int p80211netdev_ethtool(struct wlandevice *wlandev,
 467                                void __user *useraddr)
 468{
 469        u32 ethcmd;
 470        struct ethtool_drvinfo info;
 471        struct ethtool_value edata;
 472
 473        memset(&info, 0, sizeof(info));
 474        memset(&edata, 0, sizeof(edata));
 475
 476        if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
 477                return -EFAULT;
 478
 479        switch (ethcmd) {
 480        case ETHTOOL_GDRVINFO:
 481                info.cmd = ethcmd;
 482                snprintf(info.driver, sizeof(info.driver), "p80211_%s",
 483                         wlandev->nsdname);
 484                snprintf(info.version, sizeof(info.version), "%s",
 485                         WLAN_RELEASE);
 486
 487                if (copy_to_user(useraddr, &info, sizeof(info)))
 488                        return -EFAULT;
 489                return 0;
 490#ifdef ETHTOOL_GLINK
 491        case ETHTOOL_GLINK:
 492                edata.cmd = ethcmd;
 493
 494                if (wlandev->linkstatus &&
 495                    (wlandev->macmode != WLAN_MACMODE_NONE)) {
 496                        edata.data = 1;
 497                } else {
 498                        edata.data = 0;
 499                }
 500
 501                if (copy_to_user(useraddr, &edata, sizeof(edata)))
 502                        return -EFAULT;
 503                return 0;
 504#endif
 505        }
 506
 507        return -EOPNOTSUPP;
 508}
 509
 510#endif
 511
 512/*----------------------------------------------------------------
 513 * p80211knetdev_do_ioctl
 514 *
 515 * Handle an ioctl call on one of our devices.  Everything Linux
 516 * ioctl specific is done here.  Then we pass the contents of the
 517 * ifr->data to the request message handler.
 518 *
 519 * Arguments:
 520 *      dev     Linux kernel netdevice
 521 *      ifr     Our private ioctl request structure, typed for the
 522 *              generic struct ifreq so we can use ptr to func
 523 *              w/o cast.
 524 *
 525 * Returns:
 526 *      zero on success, a negative errno on failure.  Possible values:
 527 *              -ENETDOWN Device isn't up.
 528 *              -EBUSY  cmd already in progress
 529 *              -ETIME  p80211 cmd timed out (MSD may have its own timers)
 530 *              -EFAULT memory fault copying msg from user buffer
 531 *              -ENOMEM unable to allocate kernel msg buffer
 532 *              -EINVAL bad magic, it the cmd really for us?
 533 *              -EintR  sleeping on cmd, awakened by signal, cmd cancelled.
 534 *
 535 * Call Context:
 536 *      Process thread (ioctl caller).  TODO: SMP support may require
 537 *      locks.
 538 *----------------------------------------------------------------
 539 */
 540static int p80211knetdev_do_ioctl(struct net_device *dev,
 541                                  struct ifreq *ifr, int cmd)
 542{
 543        int result = 0;
 544        struct p80211ioctl_req *req = (struct p80211ioctl_req *)ifr;
 545        struct wlandevice *wlandev = dev->ml_priv;
 546        u8 *msgbuf;
 547
 548        netdev_dbg(dev, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
 549
 550#ifdef SIOCETHTOOL
 551        if (cmd == SIOCETHTOOL) {
 552                result =
 553                    p80211netdev_ethtool(wlandev, (void __user *)ifr->ifr_data);
 554                goto bail;
 555        }
 556#endif
 557
 558        /* Test the magic, assume ifr is good if it's there */
 559        if (req->magic != P80211_IOCTL_MAGIC) {
 560                result = -EINVAL;
 561                goto bail;
 562        }
 563
 564        if (cmd == P80211_IFTEST) {
 565                result = 0;
 566                goto bail;
 567        } else if (cmd != P80211_IFREQ) {
 568                result = -EINVAL;
 569                goto bail;
 570        }
 571
 572        msgbuf = memdup_user(req->data, req->len);
 573        if (IS_ERR(msgbuf)) {
 574                result = PTR_ERR(msgbuf);
 575                goto bail;
 576        }
 577
 578        result = p80211req_dorequest(wlandev, msgbuf);
 579
 580        if (result == 0) {
 581                if (copy_to_user
 582                    (req->data, msgbuf, req->len)) {
 583                        result = -EFAULT;
 584                }
 585        }
 586        kfree(msgbuf);
 587
 588bail:
 589        /* If allocate,copyfrom or copyto fails, return errno */
 590        return result;
 591}
 592
 593/*----------------------------------------------------------------
 594 * p80211knetdev_set_mac_address
 595 *
 596 * Handles the ioctl for changing the MACAddress of a netdevice
 597 *
 598 * references: linux/netdevice.h and drivers/net/net_init.c
 599 *
 600 * NOTE: [MSM] We only prevent address changes when the netdev is
 601 * up.  We don't control anything based on dot11 state.  If the
 602 * address is changed on a STA that's currently associated, you
 603 * will probably lose the ability to send and receive data frames.
 604 * Just be aware.  Therefore, this should usually only be done
 605 * prior to scan/join/auth/assoc.
 606 *
 607 * Arguments:
 608 *      dev     netdevice struct
 609 *      addr    the new MACAddress (a struct)
 610 *
 611 * Returns:
 612 *      zero on success, a negative errno on failure.  Possible values:
 613 *              -EBUSY  device is bussy (cmd not possible)
 614 *              -and errors returned by: p80211req_dorequest(..)
 615 *
 616 * by: Collin R. Mulliner <collin@mulliner.org>
 617 *----------------------------------------------------------------
 618 */
 619static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr)
 620{
 621        struct sockaddr *new_addr = addr;
 622        struct p80211msg_dot11req_mibset dot11req;
 623        struct p80211item_unk392 *mibattr;
 624        struct p80211item_pstr6 *macaddr;
 625        struct p80211item_uint32 *resultcode;
 626        int result;
 627
 628        /* If we're running, we don't allow MAC address changes */
 629        if (netif_running(dev))
 630                return -EBUSY;
 631
 632        /* Set up some convenience pointers. */
 633        mibattr = &dot11req.mibattribute;
 634        macaddr = (struct p80211item_pstr6 *)&mibattr->data;
 635        resultcode = &dot11req.resultcode;
 636
 637        /* Set up a dot11req_mibset */
 638        memset(&dot11req, 0, sizeof(dot11req));
 639        dot11req.msgcode = DIDMSG_DOT11REQ_MIBSET;
 640        dot11req.msglen = sizeof(dot11req);
 641        memcpy(dot11req.devname,
 642               ((struct wlandevice *)dev->ml_priv)->name,
 643               WLAN_DEVNAMELEN_MAX - 1);
 644
 645        /* Set up the mibattribute argument */
 646        mibattr->did = DIDMSG_DOT11REQ_MIBSET_MIBATTRIBUTE;
 647        mibattr->status = P80211ENUM_msgitem_status_data_ok;
 648        mibattr->len = sizeof(mibattr->data);
 649
 650        macaddr->did = DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS;
 651        macaddr->status = P80211ENUM_msgitem_status_data_ok;
 652        macaddr->len = sizeof(macaddr->data);
 653        macaddr->data.len = ETH_ALEN;
 654        memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN);
 655
 656        /* Set up the resultcode argument */
 657        resultcode->did = DIDMSG_DOT11REQ_MIBSET_RESULTCODE;
 658        resultcode->status = P80211ENUM_msgitem_status_no_value;
 659        resultcode->len = sizeof(resultcode->data);
 660        resultcode->data = 0;
 661
 662        /* now fire the request */
 663        result = p80211req_dorequest(dev->ml_priv, (u8 *)&dot11req);
 664
 665        /* If the request wasn't successful, report an error and don't
 666         * change the netdev address
 667         */
 668        if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
 669                netdev_err(dev, "Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
 670                result = -EADDRNOTAVAIL;
 671        } else {
 672                /* everything's ok, change the addr in netdev */
 673                memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len);
 674        }
 675
 676        return result;
 677}
 678
 679static const struct net_device_ops p80211_netdev_ops = {
 680        .ndo_init = p80211knetdev_init,
 681        .ndo_open = p80211knetdev_open,
 682        .ndo_stop = p80211knetdev_stop,
 683        .ndo_start_xmit = p80211knetdev_hard_start_xmit,
 684        .ndo_set_rx_mode = p80211knetdev_set_multicast_list,
 685        .ndo_do_ioctl = p80211knetdev_do_ioctl,
 686        .ndo_set_mac_address = p80211knetdev_set_mac_address,
 687        .ndo_tx_timeout = p80211knetdev_tx_timeout,
 688        .ndo_validate_addr = eth_validate_addr,
 689};
 690
 691/*----------------------------------------------------------------
 692 * wlan_setup
 693 *
 694 * Roughly matches the functionality of ether_setup.  Here
 695 * we set up any members of the wlandevice structure that are common
 696 * to all devices.  Additionally, we allocate a linux 'struct device'
 697 * and perform the same setup as ether_setup.
 698 *
 699 * Note: It's important that the caller have setup the wlandev->name
 700 *      ptr prior to calling this function.
 701 *
 702 * Arguments:
 703 *      wlandev         ptr to the wlandev structure for the
 704 *                      interface.
 705 *      physdev         ptr to usb device
 706 * Returns:
 707 *      zero on success, non-zero otherwise.
 708 * Call Context:
 709 *      Should be process thread.  We'll assume it might be
 710 *      interrupt though.  When we add support for statically
 711 *      compiled drivers, this function will be called in the
 712 *      context of the kernel startup code.
 713 *----------------------------------------------------------------
 714 */
 715int wlan_setup(struct wlandevice *wlandev, struct device *physdev)
 716{
 717        int result = 0;
 718        struct net_device *netdev;
 719        struct wiphy *wiphy;
 720        struct wireless_dev *wdev;
 721
 722        /* Set up the wlandev */
 723        wlandev->state = WLAN_DEVICE_CLOSED;
 724        wlandev->ethconv = WLAN_ETHCONV_8021h;
 725        wlandev->macmode = WLAN_MACMODE_NONE;
 726
 727        /* Set up the rx queue */
 728        skb_queue_head_init(&wlandev->nsd_rxq);
 729        tasklet_setup(&wlandev->rx_bh, p80211netdev_rx_bh);
 730
 731        /* Allocate and initialize the wiphy struct */
 732        wiphy = wlan_create_wiphy(physdev, wlandev);
 733        if (!wiphy) {
 734                dev_err(physdev, "Failed to alloc wiphy.\n");
 735                return 1;
 736        }
 737
 738        /* Allocate and initialize the struct device */
 739        netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d",
 740                              NET_NAME_UNKNOWN, ether_setup);
 741        if (!netdev) {
 742                dev_err(physdev, "Failed to alloc netdev.\n");
 743                wlan_free_wiphy(wiphy);
 744                result = 1;
 745        } else {
 746                wlandev->netdev = netdev;
 747                netdev->ml_priv = wlandev;
 748                netdev->netdev_ops = &p80211_netdev_ops;
 749                wdev = netdev_priv(netdev);
 750                wdev->wiphy = wiphy;
 751                wdev->iftype = NL80211_IFTYPE_STATION;
 752                netdev->ieee80211_ptr = wdev;
 753                netdev->min_mtu = 68;
 754                /* 2312 is max 802.11 payload, 20 is overhead,
 755                 * (ether + llc + snap) and another 8 for wep.
 756                 */
 757                netdev->max_mtu = (2312 - 20 - 8);
 758
 759                netif_stop_queue(netdev);
 760                netif_carrier_off(netdev);
 761        }
 762
 763        return result;
 764}
 765
 766/*----------------------------------------------------------------
 767 * wlan_unsetup
 768 *
 769 * This function is paired with the wlan_setup routine.  It should
 770 * be called after unregister_wlandev.  Basically, all it does is
 771 * free the 'struct device' that's associated with the wlandev.
 772 * We do it here because the 'struct device' isn't allocated
 773 * explicitly in the driver code, it's done in wlan_setup.  To
 774 * do the free in the driver might seem like 'magic'.
 775 *
 776 * Arguments:
 777 *      wlandev         ptr to the wlandev structure for the
 778 *                      interface.
 779 * Call Context:
 780 *      Should be process thread.  We'll assume it might be
 781 *      interrupt though.  When we add support for statically
 782 *      compiled drivers, this function will be called in the
 783 *      context of the kernel startup code.
 784 *----------------------------------------------------------------
 785 */
 786void wlan_unsetup(struct wlandevice *wlandev)
 787{
 788        struct wireless_dev *wdev;
 789
 790        tasklet_kill(&wlandev->rx_bh);
 791
 792        if (wlandev->netdev) {
 793                wdev = netdev_priv(wlandev->netdev);
 794                if (wdev->wiphy)
 795                        wlan_free_wiphy(wdev->wiphy);
 796                free_netdev(wlandev->netdev);
 797                wlandev->netdev = NULL;
 798        }
 799}
 800
 801/*----------------------------------------------------------------
 802 * register_wlandev
 803 *
 804 * Roughly matches the functionality of register_netdev.  This function
 805 * is called after the driver has successfully probed and set up the
 806 * resources for the device.  It's now ready to become a named device
 807 * in the Linux system.
 808 *
 809 * First we allocate a name for the device (if not already set), then
 810 * we call the Linux function register_netdevice.
 811 *
 812 * Arguments:
 813 *      wlandev         ptr to the wlandev structure for the
 814 *                      interface.
 815 * Returns:
 816 *      zero on success, non-zero otherwise.
 817 * Call Context:
 818 *      Can be either interrupt or not.
 819 *----------------------------------------------------------------
 820 */
 821int register_wlandev(struct wlandevice *wlandev)
 822{
 823        return register_netdev(wlandev->netdev);
 824}
 825
 826/*----------------------------------------------------------------
 827 * unregister_wlandev
 828 *
 829 * Roughly matches the functionality of unregister_netdev.  This
 830 * function is called to remove a named device from the system.
 831 *
 832 * First we tell linux that the device should no longer exist.
 833 * Then we remove it from the list of known wlan devices.
 834 *
 835 * Arguments:
 836 *      wlandev         ptr to the wlandev structure for the
 837 *                      interface.
 838 * Returns:
 839 *      zero on success, non-zero otherwise.
 840 * Call Context:
 841 *      Can be either interrupt or not.
 842 *----------------------------------------------------------------
 843 */
 844int unregister_wlandev(struct wlandevice *wlandev)
 845{
 846        struct sk_buff *skb;
 847
 848        unregister_netdev(wlandev->netdev);
 849
 850        /* Now to clean out the rx queue */
 851        while ((skb = skb_dequeue(&wlandev->nsd_rxq)))
 852                dev_kfree_skb(skb);
 853
 854        return 0;
 855}
 856
 857/*----------------------------------------------------------------
 858 * p80211netdev_hwremoved
 859 *
 860 * Hardware removed notification. This function should be called
 861 * immediately after an MSD has detected that the underlying hardware
 862 * has been yanked out from under us.  The primary things we need
 863 * to do are:
 864 *   - Mark the wlandev
 865 *   - Prevent any further traffic from the knetdev i/f
 866 *   - Prevent any further requests from mgmt i/f
 867 *   - If there are any waitq'd mgmt requests or mgmt-frame exchanges,
 868 *     shut them down.
 869 *   - Call the MSD hwremoved function.
 870 *
 871 * The remainder of the cleanup will be handled by unregister().
 872 * Our primary goal here is to prevent as much tickling of the MSD
 873 * as possible since the MSD is already in a 'wounded' state.
 874 *
 875 * TODO: As new features are added, this function should be
 876 *       updated.
 877 *
 878 * Arguments:
 879 *      wlandev         WLAN network device structure
 880 * Returns:
 881 *      nothing
 882 * Side effects:
 883 *
 884 * Call context:
 885 *      Usually interrupt.
 886 *----------------------------------------------------------------
 887 */
 888void p80211netdev_hwremoved(struct wlandevice *wlandev)
 889{
 890        wlandev->hwremoved = 1;
 891        if (wlandev->state == WLAN_DEVICE_OPEN)
 892                netif_stop_queue(wlandev->netdev);
 893
 894        netif_device_detach(wlandev->netdev);
 895}
 896
 897/*----------------------------------------------------------------
 898 * p80211_rx_typedrop
 899 *
 900 * Classifies the frame, increments the appropriate counter, and
 901 * returns 0|1|2 indicating whether the driver should handle, ignore, or
 902 * drop the frame
 903 *
 904 * Arguments:
 905 *      wlandev         wlan device structure
 906 *      fc              frame control field
 907 *
 908 * Returns:
 909 *      zero if the frame should be handled by the driver,
 910 *       one if the frame should be ignored
 911 *       anything else means we drop it.
 912 *
 913 * Side effects:
 914 *
 915 * Call context:
 916 *      interrupt
 917 *----------------------------------------------------------------
 918 */
 919static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc)
 920{
 921        u16 ftype;
 922        u16 fstype;
 923        int drop = 0;
 924        /* Classify frame, increment counter */
 925        ftype = WLAN_GET_FC_FTYPE(fc);
 926        fstype = WLAN_GET_FC_FSTYPE(fc);
 927        switch (ftype) {
 928        case WLAN_FTYPE_MGMT:
 929                if ((wlandev->netdev->flags & IFF_PROMISC) ||
 930                    (wlandev->netdev->flags & IFF_ALLMULTI)) {
 931                        drop = 1;
 932                        break;
 933                }
 934                netdev_dbg(wlandev->netdev, "rx'd mgmt:\n");
 935                wlandev->rx.mgmt++;
 936                switch (fstype) {
 937                case WLAN_FSTYPE_ASSOCREQ:
 938                        /* printk("assocreq"); */
 939                        wlandev->rx.assocreq++;
 940                        break;
 941                case WLAN_FSTYPE_ASSOCRESP:
 942                        /* printk("assocresp"); */
 943                        wlandev->rx.assocresp++;
 944                        break;
 945                case WLAN_FSTYPE_REASSOCREQ:
 946                        /* printk("reassocreq"); */
 947                        wlandev->rx.reassocreq++;
 948                        break;
 949                case WLAN_FSTYPE_REASSOCRESP:
 950                        /* printk("reassocresp"); */
 951                        wlandev->rx.reassocresp++;
 952                        break;
 953                case WLAN_FSTYPE_PROBEREQ:
 954                        /* printk("probereq"); */
 955                        wlandev->rx.probereq++;
 956                        break;
 957                case WLAN_FSTYPE_PROBERESP:
 958                        /* printk("proberesp"); */
 959                        wlandev->rx.proberesp++;
 960                        break;
 961                case WLAN_FSTYPE_BEACON:
 962                        /* printk("beacon"); */
 963                        wlandev->rx.beacon++;
 964                        break;
 965                case WLAN_FSTYPE_ATIM:
 966                        /* printk("atim"); */
 967                        wlandev->rx.atim++;
 968                        break;
 969                case WLAN_FSTYPE_DISASSOC:
 970                        /* printk("disassoc"); */
 971                        wlandev->rx.disassoc++;
 972                        break;
 973                case WLAN_FSTYPE_AUTHEN:
 974                        /* printk("authen"); */
 975                        wlandev->rx.authen++;
 976                        break;
 977                case WLAN_FSTYPE_DEAUTHEN:
 978                        /* printk("deauthen"); */
 979                        wlandev->rx.deauthen++;
 980                        break;
 981                default:
 982                        /* printk("unknown"); */
 983                        wlandev->rx.mgmt_unknown++;
 984                        break;
 985                }
 986                /* printk("\n"); */
 987                drop = 2;
 988                break;
 989
 990        case WLAN_FTYPE_CTL:
 991                if ((wlandev->netdev->flags & IFF_PROMISC) ||
 992                    (wlandev->netdev->flags & IFF_ALLMULTI)) {
 993                        drop = 1;
 994                        break;
 995                }
 996                netdev_dbg(wlandev->netdev, "rx'd ctl:\n");
 997                wlandev->rx.ctl++;
 998                switch (fstype) {
 999                case WLAN_FSTYPE_PSPOLL:
1000                        /* printk("pspoll"); */
1001                        wlandev->rx.pspoll++;
1002                        break;
1003                case WLAN_FSTYPE_RTS:
1004                        /* printk("rts"); */
1005                        wlandev->rx.rts++;
1006                        break;
1007                case WLAN_FSTYPE_CTS:
1008                        /* printk("cts"); */
1009                        wlandev->rx.cts++;
1010                        break;
1011                case WLAN_FSTYPE_ACK:
1012                        /* printk("ack"); */
1013                        wlandev->rx.ack++;
1014                        break;
1015                case WLAN_FSTYPE_CFEND:
1016                        /* printk("cfend"); */
1017                        wlandev->rx.cfend++;
1018                        break;
1019                case WLAN_FSTYPE_CFENDCFACK:
1020                        /* printk("cfendcfack"); */
1021                        wlandev->rx.cfendcfack++;
1022                        break;
1023                default:
1024                        /* printk("unknown"); */
1025                        wlandev->rx.ctl_unknown++;
1026                        break;
1027                }
1028                /* printk("\n"); */
1029                drop = 2;
1030                break;
1031
1032        case WLAN_FTYPE_DATA:
1033                wlandev->rx.data++;
1034                switch (fstype) {
1035                case WLAN_FSTYPE_DATAONLY:
1036                        wlandev->rx.dataonly++;
1037                        break;
1038                case WLAN_FSTYPE_DATA_CFACK:
1039                        wlandev->rx.data_cfack++;
1040                        break;
1041                case WLAN_FSTYPE_DATA_CFPOLL:
1042                        wlandev->rx.data_cfpoll++;
1043                        break;
1044                case WLAN_FSTYPE_DATA_CFACK_CFPOLL:
1045                        wlandev->rx.data__cfack_cfpoll++;
1046                        break;
1047                case WLAN_FSTYPE_NULL:
1048                        netdev_dbg(wlandev->netdev, "rx'd data:null\n");
1049                        wlandev->rx.null++;
1050                        break;
1051                case WLAN_FSTYPE_CFACK:
1052                        netdev_dbg(wlandev->netdev, "rx'd data:cfack\n");
1053                        wlandev->rx.cfack++;
1054                        break;
1055                case WLAN_FSTYPE_CFPOLL:
1056                        netdev_dbg(wlandev->netdev, "rx'd data:cfpoll\n");
1057                        wlandev->rx.cfpoll++;
1058                        break;
1059                case WLAN_FSTYPE_CFACK_CFPOLL:
1060                        netdev_dbg(wlandev->netdev, "rx'd data:cfack_cfpoll\n");
1061                        wlandev->rx.cfack_cfpoll++;
1062                        break;
1063                default:
1064                        /* printk("unknown"); */
1065                        wlandev->rx.data_unknown++;
1066                        break;
1067                }
1068
1069                break;
1070        }
1071        return drop;
1072}
1073
1074static void p80211knetdev_tx_timeout(struct net_device *netdev, unsigned int txqueue)
1075{
1076        struct wlandevice *wlandev = netdev->ml_priv;
1077
1078        if (wlandev->tx_timeout) {
1079                wlandev->tx_timeout(wlandev);
1080        } else {
1081                netdev_warn(netdev, "Implement tx_timeout for %s\n",
1082                            wlandev->nsdname);
1083                netif_wake_queue(wlandev->netdev);
1084        }
1085}
1086