root/drivers/staging/wlan-ng/p80211netdev.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. p80211knetdev_init
  2. p80211knetdev_open
  3. p80211knetdev_stop
  4. p80211netdev_rx
  5. p80211_convert_to_ether
  6. p80211netdev_rx_bh
  7. p80211knetdev_hard_start_xmit
  8. p80211knetdev_set_multicast_list
  9. p80211netdev_ethtool
  10. p80211knetdev_do_ioctl
  11. p80211knetdev_set_mac_address
  12. wlan_setup
  13. wlan_unsetup
  14. register_wlandev
  15. unregister_wlandev
  16. p80211netdev_hwremoved
  17. p80211_rx_typedrop
  18. p80211knetdev_tx_timeout

   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 */
  95 static int p80211knetdev_init(struct net_device *netdev);
  96 static int p80211knetdev_open(struct net_device *netdev);
  97 static int p80211knetdev_stop(struct net_device *netdev);
  98 static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb,
  99                                                  struct net_device *netdev);
 100 static void p80211knetdev_set_multicast_list(struct net_device *dev);
 101 static int p80211knetdev_do_ioctl(struct net_device *dev, struct ifreq *ifr,
 102                                   int cmd);
 103 static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr);
 104 static void p80211knetdev_tx_timeout(struct net_device *netdev);
 105 static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc);
 106 
 107 int wlan_watchdog = 5000;
 108 module_param(wlan_watchdog, int, 0644);
 109 MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds");
 110 
 111 int wlan_wext_write = 1;
 112 module_param(wlan_wext_write, int, 0644);
 113 MODULE_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  */
 128 static 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  */
 152 static 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  */
 188 static 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  */
 216 void 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  */
 235 static 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  */
 271 static 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  */
 324 static 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 
 429 failed:
 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  */
 454 static 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 
 466 static 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  */
 540 static 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         }
 590 bail:
 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  */
 621 static 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 
 681 static 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  */
 717 int 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  */
 789 void 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  */
 824 int 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  */
 847 int 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  */
 891 void 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  */
 922 static 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 
1077 static 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 }

/* [<][>][^][v][top][bottom][index][help] */