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);
 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 * @arg: pointer to WLAN network device structure (cast to unsigned long)
 270 */
 271static void p80211netdev_rx_bh(unsigned long arg)
 272{
 273        struct wlandevice *wlandev = (struct wlandevice *)arg;
 274        struct sk_buff *skb = NULL;
 275        struct net_device *dev = wlandev->netdev;
 276
 277        /* Let's empty our 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 = -1;
 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                kzfree(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        /* Allocate a buf of size req->len */
 573        msgbuf = kmalloc(req->len, GFP_KERNEL);
 574        if (msgbuf) {
 575                if (copy_from_user(msgbuf, (void __user *)req->data, req->len))
 576                        result = -EFAULT;
 577                else
 578                        result = p80211req_dorequest(wlandev, msgbuf);
 579
 580                if (result == 0) {
 581                        if (copy_to_user
 582                            ((void __user *)req->data, msgbuf, req->len)) {
 583                                result = -EFAULT;
 584                        }
 585                }
 586                kfree(msgbuf);
 587        } else {
 588                result = -ENOMEM;
 589        }
 590bail:
 591        /* If allocate,copyfrom or copyto fails, return errno */
 592        return result;
 593}
 594
 595/*----------------------------------------------------------------
 596 * p80211knetdev_set_mac_address
 597 *
 598 * Handles the ioctl for changing the MACAddress of a netdevice
 599 *
 600 * references: linux/netdevice.h and drivers/net/net_init.c
 601 *
 602 * NOTE: [MSM] We only prevent address changes when the netdev is
 603 * up.  We don't control anything based on dot11 state.  If the
 604 * address is changed on a STA that's currently associated, you
 605 * will probably lose the ability to send and receive data frames.
 606 * Just be aware.  Therefore, this should usually only be done
 607 * prior to scan/join/auth/assoc.
 608 *
 609 * Arguments:
 610 *      dev     netdevice struct
 611 *      addr    the new MACAddress (a struct)
 612 *
 613 * Returns:
 614 *      zero on success, a negative errno on failure.  Possible values:
 615 *              -EBUSY  device is bussy (cmd not possible)
 616 *              -and errors returned by: p80211req_dorequest(..)
 617 *
 618 * by: Collin R. Mulliner <collin@mulliner.org>
 619 *----------------------------------------------------------------
 620 */
 621static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr)
 622{
 623        struct sockaddr *new_addr = addr;
 624        struct p80211msg_dot11req_mibset dot11req;
 625        struct p80211item_unk392 *mibattr;
 626        struct p80211item_pstr6 *macaddr;
 627        struct p80211item_uint32 *resultcode;
 628        int result;
 629
 630        /* If we're running, we don't allow MAC address changes */
 631        if (netif_running(dev))
 632                return -EBUSY;
 633
 634        /* Set up some convenience pointers. */
 635        mibattr = &dot11req.mibattribute;
 636        macaddr = (struct p80211item_pstr6 *)&mibattr->data;
 637        resultcode = &dot11req.resultcode;
 638
 639        /* Set up a dot11req_mibset */
 640        memset(&dot11req, 0, sizeof(dot11req));
 641        dot11req.msgcode = DIDMSG_DOT11REQ_MIBSET;
 642        dot11req.msglen = sizeof(dot11req);
 643        memcpy(dot11req.devname,
 644               ((struct wlandevice *)dev->ml_priv)->name,
 645               WLAN_DEVNAMELEN_MAX - 1);
 646
 647        /* Set up the mibattribute argument */
 648        mibattr->did = DIDMSG_DOT11REQ_MIBSET_MIBATTRIBUTE;
 649        mibattr->status = P80211ENUM_msgitem_status_data_ok;
 650        mibattr->len = sizeof(mibattr->data);
 651
 652        macaddr->did = DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS;
 653        macaddr->status = P80211ENUM_msgitem_status_data_ok;
 654        macaddr->len = sizeof(macaddr->data);
 655        macaddr->data.len = ETH_ALEN;
 656        memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN);
 657
 658        /* Set up the resultcode argument */
 659        resultcode->did = DIDMSG_DOT11REQ_MIBSET_RESULTCODE;
 660        resultcode->status = P80211ENUM_msgitem_status_no_value;
 661        resultcode->len = sizeof(resultcode->data);
 662        resultcode->data = 0;
 663
 664        /* now fire the request */
 665        result = p80211req_dorequest(dev->ml_priv, (u8 *)&dot11req);
 666
 667        /* If the request wasn't successful, report an error and don't
 668         * change the netdev address
 669         */
 670        if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
 671                netdev_err(dev, "Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
 672                result = -EADDRNOTAVAIL;
 673        } else {
 674                /* everything's ok, change the addr in netdev */
 675                memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len);
 676        }
 677
 678        return result;
 679}
 680
 681static const struct net_device_ops p80211_netdev_ops = {
 682        .ndo_init = p80211knetdev_init,
 683        .ndo_open = p80211knetdev_open,
 684        .ndo_stop = p80211knetdev_stop,
 685        .ndo_start_xmit = p80211knetdev_hard_start_xmit,
 686        .ndo_set_rx_mode = p80211knetdev_set_multicast_list,
 687        .ndo_do_ioctl = p80211knetdev_do_ioctl,
 688        .ndo_set_mac_address = p80211knetdev_set_mac_address,
 689        .ndo_tx_timeout = p80211knetdev_tx_timeout,
 690        .ndo_validate_addr = eth_validate_addr,
 691};
 692
 693/*----------------------------------------------------------------
 694 * wlan_setup
 695 *
 696 * Roughly matches the functionality of ether_setup.  Here
 697 * we set up any members of the wlandevice structure that are common
 698 * to all devices.  Additionally, we allocate a linux 'struct device'
 699 * and perform the same setup as ether_setup.
 700 *
 701 * Note: It's important that the caller have setup the wlandev->name
 702 *      ptr prior to calling this function.
 703 *
 704 * Arguments:
 705 *      wlandev         ptr to the wlandev structure for the
 706 *                      interface.
 707 *      physdev         ptr to usb device
 708 * Returns:
 709 *      zero on success, non-zero otherwise.
 710 * Call Context:
 711 *      Should be process thread.  We'll assume it might be
 712 *      interrupt though.  When we add support for statically
 713 *      compiled drivers, this function will be called in the
 714 *      context of the kernel startup code.
 715 *----------------------------------------------------------------
 716 */
 717int wlan_setup(struct wlandevice *wlandev, struct device *physdev)
 718{
 719        int result = 0;
 720        struct net_device *netdev;
 721        struct wiphy *wiphy;
 722        struct wireless_dev *wdev;
 723
 724        /* Set up the wlandev */
 725        wlandev->state = WLAN_DEVICE_CLOSED;
 726        wlandev->ethconv = WLAN_ETHCONV_8021h;
 727        wlandev->macmode = WLAN_MACMODE_NONE;
 728
 729        /* Set up the rx queue */
 730        skb_queue_head_init(&wlandev->nsd_rxq);
 731        tasklet_init(&wlandev->rx_bh,
 732                     p80211netdev_rx_bh, (unsigned long)wlandev);
 733
 734        /* Allocate and initialize the wiphy struct */
 735        wiphy = wlan_create_wiphy(physdev, wlandev);
 736        if (!wiphy) {
 737                dev_err(physdev, "Failed to alloc wiphy.\n");
 738                return 1;
 739        }
 740
 741        /* Allocate and initialize the struct device */
 742        netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d",
 743                              NET_NAME_UNKNOWN, ether_setup);
 744        if (!netdev) {
 745                dev_err(physdev, "Failed to alloc netdev.\n");
 746                wlan_free_wiphy(wiphy);
 747                result = 1;
 748        } else {
 749                wlandev->netdev = netdev;
 750                netdev->ml_priv = wlandev;
 751                netdev->netdev_ops = &p80211_netdev_ops;
 752                wdev = netdev_priv(netdev);
 753                wdev->wiphy = wiphy;
 754                wdev->iftype = NL80211_IFTYPE_STATION;
 755                netdev->ieee80211_ptr = wdev;
 756                netdev->min_mtu = 68;
 757                /* 2312 is max 802.11 payload, 20 is overhead,
 758                 * (ether + llc + snap) and another 8 for wep.
 759                 */
 760                netdev->max_mtu = (2312 - 20 - 8);
 761
 762                netif_stop_queue(netdev);
 763                netif_carrier_off(netdev);
 764        }
 765
 766        return result;
 767}
 768
 769/*----------------------------------------------------------------
 770 * wlan_unsetup
 771 *
 772 * This function is paired with the wlan_setup routine.  It should
 773 * be called after unregister_wlandev.  Basically, all it does is
 774 * free the 'struct device' that's associated with the wlandev.
 775 * We do it here because the 'struct device' isn't allocated
 776 * explicitly in the driver code, it's done in wlan_setup.  To
 777 * do the free in the driver might seem like 'magic'.
 778 *
 779 * Arguments:
 780 *      wlandev         ptr to the wlandev structure for the
 781 *                      interface.
 782 * Call Context:
 783 *      Should be process thread.  We'll assume it might be
 784 *      interrupt though.  When we add support for statically
 785 *      compiled drivers, this function will be called in the
 786 *      context of the kernel startup code.
 787 *----------------------------------------------------------------
 788 */
 789void wlan_unsetup(struct wlandevice *wlandev)
 790{
 791        struct wireless_dev *wdev;
 792
 793        tasklet_kill(&wlandev->rx_bh);
 794
 795        if (wlandev->netdev) {
 796                wdev = netdev_priv(wlandev->netdev);
 797                if (wdev->wiphy)
 798                        wlan_free_wiphy(wdev->wiphy);
 799                free_netdev(wlandev->netdev);
 800                wlandev->netdev = NULL;
 801        }
 802}
 803
 804/*----------------------------------------------------------------
 805 * register_wlandev
 806 *
 807 * Roughly matches the functionality of register_netdev.  This function
 808 * is called after the driver has successfully probed and set up the
 809 * resources for the device.  It's now ready to become a named device
 810 * in the Linux system.
 811 *
 812 * First we allocate a name for the device (if not already set), then
 813 * we call the Linux function register_netdevice.
 814 *
 815 * Arguments:
 816 *      wlandev         ptr to the wlandev structure for the
 817 *                      interface.
 818 * Returns:
 819 *      zero on success, non-zero otherwise.
 820 * Call Context:
 821 *      Can be either interrupt or not.
 822 *----------------------------------------------------------------
 823 */
 824int register_wlandev(struct wlandevice *wlandev)
 825{
 826        return register_netdev(wlandev->netdev);
 827}
 828
 829/*----------------------------------------------------------------
 830 * unregister_wlandev
 831 *
 832 * Roughly matches the functionality of unregister_netdev.  This
 833 * function is called to remove a named device from the system.
 834 *
 835 * First we tell linux that the device should no longer exist.
 836 * Then we remove it from the list of known wlan devices.
 837 *
 838 * Arguments:
 839 *      wlandev         ptr to the wlandev structure for the
 840 *                      interface.
 841 * Returns:
 842 *      zero on success, non-zero otherwise.
 843 * Call Context:
 844 *      Can be either interrupt or not.
 845 *----------------------------------------------------------------
 846 */
 847int unregister_wlandev(struct wlandevice *wlandev)
 848{
 849        struct sk_buff *skb;
 850
 851        unregister_netdev(wlandev->netdev);
 852
 853        /* Now to clean out the rx queue */
 854        while ((skb = skb_dequeue(&wlandev->nsd_rxq)))
 855                dev_kfree_skb(skb);
 856
 857        return 0;
 858}
 859
 860/*----------------------------------------------------------------
 861 * p80211netdev_hwremoved
 862 *
 863 * Hardware removed notification. This function should be called
 864 * immediately after an MSD has detected that the underlying hardware
 865 * has been yanked out from under us.  The primary things we need
 866 * to do are:
 867 *   - Mark the wlandev
 868 *   - Prevent any further traffic from the knetdev i/f
 869 *   - Prevent any further requests from mgmt i/f
 870 *   - If there are any waitq'd mgmt requests or mgmt-frame exchanges,
 871 *     shut them down.
 872 *   - Call the MSD hwremoved function.
 873 *
 874 * The remainder of the cleanup will be handled by unregister().
 875 * Our primary goal here is to prevent as much tickling of the MSD
 876 * as possible since the MSD is already in a 'wounded' state.
 877 *
 878 * TODO: As new features are added, this function should be
 879 *       updated.
 880 *
 881 * Arguments:
 882 *      wlandev         WLAN network device structure
 883 * Returns:
 884 *      nothing
 885 * Side effects:
 886 *
 887 * Call context:
 888 *      Usually interrupt.
 889 *----------------------------------------------------------------
 890 */
 891void p80211netdev_hwremoved(struct wlandevice *wlandev)
 892{
 893        wlandev->hwremoved = 1;
 894        if (wlandev->state == WLAN_DEVICE_OPEN)
 895                netif_stop_queue(wlandev->netdev);
 896
 897        netif_device_detach(wlandev->netdev);
 898}
 899
 900/*----------------------------------------------------------------
 901 * p80211_rx_typedrop
 902 *
 903 * Classifies the frame, increments the appropriate counter, and
 904 * returns 0|1|2 indicating whether the driver should handle, ignore, or
 905 * drop the frame
 906 *
 907 * Arguments:
 908 *      wlandev         wlan device structure
 909 *      fc              frame control field
 910 *
 911 * Returns:
 912 *      zero if the frame should be handled by the driver,
 913 *       one if the frame should be ignored
 914 *       anything else means we drop it.
 915 *
 916 * Side effects:
 917 *
 918 * Call context:
 919 *      interrupt
 920 *----------------------------------------------------------------
 921 */
 922static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc)
 923{
 924        u16 ftype;
 925        u16 fstype;
 926        int drop = 0;
 927        /* Classify frame, increment counter */
 928        ftype = WLAN_GET_FC_FTYPE(fc);
 929        fstype = WLAN_GET_FC_FSTYPE(fc);
 930        switch (ftype) {
 931        case WLAN_FTYPE_MGMT:
 932                if ((wlandev->netdev->flags & IFF_PROMISC) ||
 933                    (wlandev->netdev->flags & IFF_ALLMULTI)) {
 934                        drop = 1;
 935                        break;
 936                }
 937                netdev_dbg(wlandev->netdev, "rx'd mgmt:\n");
 938                wlandev->rx.mgmt++;
 939                switch (fstype) {
 940                case WLAN_FSTYPE_ASSOCREQ:
 941                        /* printk("assocreq"); */
 942                        wlandev->rx.assocreq++;
 943                        break;
 944                case WLAN_FSTYPE_ASSOCRESP:
 945                        /* printk("assocresp"); */
 946                        wlandev->rx.assocresp++;
 947                        break;
 948                case WLAN_FSTYPE_REASSOCREQ:
 949                        /* printk("reassocreq"); */
 950                        wlandev->rx.reassocreq++;
 951                        break;
 952                case WLAN_FSTYPE_REASSOCRESP:
 953                        /* printk("reassocresp"); */
 954                        wlandev->rx.reassocresp++;
 955                        break;
 956                case WLAN_FSTYPE_PROBEREQ:
 957                        /* printk("probereq"); */
 958                        wlandev->rx.probereq++;
 959                        break;
 960                case WLAN_FSTYPE_PROBERESP:
 961                        /* printk("proberesp"); */
 962                        wlandev->rx.proberesp++;
 963                        break;
 964                case WLAN_FSTYPE_BEACON:
 965                        /* printk("beacon"); */
 966                        wlandev->rx.beacon++;
 967                        break;
 968                case WLAN_FSTYPE_ATIM:
 969                        /* printk("atim"); */
 970                        wlandev->rx.atim++;
 971                        break;
 972                case WLAN_FSTYPE_DISASSOC:
 973                        /* printk("disassoc"); */
 974                        wlandev->rx.disassoc++;
 975                        break;
 976                case WLAN_FSTYPE_AUTHEN:
 977                        /* printk("authen"); */
 978                        wlandev->rx.authen++;
 979                        break;
 980                case WLAN_FSTYPE_DEAUTHEN:
 981                        /* printk("deauthen"); */
 982                        wlandev->rx.deauthen++;
 983                        break;
 984                default:
 985                        /* printk("unknown"); */
 986                        wlandev->rx.mgmt_unknown++;
 987                        break;
 988                }
 989                /* printk("\n"); */
 990                drop = 2;
 991                break;
 992
 993        case WLAN_FTYPE_CTL:
 994                if ((wlandev->netdev->flags & IFF_PROMISC) ||
 995                    (wlandev->netdev->flags & IFF_ALLMULTI)) {
 996                        drop = 1;
 997                        break;
 998                }
 999                netdev_dbg(wlandev->netdev, "rx'd ctl:\n");
1000                wlandev->rx.ctl++;
1001                switch (fstype) {
1002                case WLAN_FSTYPE_PSPOLL:
1003                        /* printk("pspoll"); */
1004                        wlandev->rx.pspoll++;
1005                        break;
1006                case WLAN_FSTYPE_RTS:
1007                        /* printk("rts"); */
1008                        wlandev->rx.rts++;
1009                        break;
1010                case WLAN_FSTYPE_CTS:
1011                        /* printk("cts"); */
1012                        wlandev->rx.cts++;
1013                        break;
1014                case WLAN_FSTYPE_ACK:
1015                        /* printk("ack"); */
1016                        wlandev->rx.ack++;
1017                        break;
1018                case WLAN_FSTYPE_CFEND:
1019                        /* printk("cfend"); */
1020                        wlandev->rx.cfend++;
1021                        break;
1022                case WLAN_FSTYPE_CFENDCFACK:
1023                        /* printk("cfendcfack"); */
1024                        wlandev->rx.cfendcfack++;
1025                        break;
1026                default:
1027                        /* printk("unknown"); */
1028                        wlandev->rx.ctl_unknown++;
1029                        break;
1030                }
1031                /* printk("\n"); */
1032                drop = 2;
1033                break;
1034
1035        case WLAN_FTYPE_DATA:
1036                wlandev->rx.data++;
1037                switch (fstype) {
1038                case WLAN_FSTYPE_DATAONLY:
1039                        wlandev->rx.dataonly++;
1040                        break;
1041                case WLAN_FSTYPE_DATA_CFACK:
1042                        wlandev->rx.data_cfack++;
1043                        break;
1044                case WLAN_FSTYPE_DATA_CFPOLL:
1045                        wlandev->rx.data_cfpoll++;
1046                        break;
1047                case WLAN_FSTYPE_DATA_CFACK_CFPOLL:
1048                        wlandev->rx.data__cfack_cfpoll++;
1049                        break;
1050                case WLAN_FSTYPE_NULL:
1051                        netdev_dbg(wlandev->netdev, "rx'd data:null\n");
1052                        wlandev->rx.null++;
1053                        break;
1054                case WLAN_FSTYPE_CFACK:
1055                        netdev_dbg(wlandev->netdev, "rx'd data:cfack\n");
1056                        wlandev->rx.cfack++;
1057                        break;
1058                case WLAN_FSTYPE_CFPOLL:
1059                        netdev_dbg(wlandev->netdev, "rx'd data:cfpoll\n");
1060                        wlandev->rx.cfpoll++;
1061                        break;
1062                case WLAN_FSTYPE_CFACK_CFPOLL:
1063                        netdev_dbg(wlandev->netdev, "rx'd data:cfack_cfpoll\n");
1064                        wlandev->rx.cfack_cfpoll++;
1065                        break;
1066                default:
1067                        /* printk("unknown"); */
1068                        wlandev->rx.data_unknown++;
1069                        break;
1070                }
1071
1072                break;
1073        }
1074        return drop;
1075}
1076
1077static void p80211knetdev_tx_timeout(struct net_device *netdev)
1078{
1079        struct wlandevice *wlandev = netdev->ml_priv;
1080
1081        if (wlandev->tx_timeout) {
1082                wlandev->tx_timeout(wlandev);
1083        } else {
1084                netdev_warn(netdev, "Implement tx_timeout for %s\n",
1085                            wlandev->nsdname);
1086                netif_wake_queue(wlandev->netdev);
1087        }
1088}
1089