cregit-Linux how code gets into the kernel

Release 4.7 drivers/staging/wlan-ng/p80211netdev.c

/* src/p80211/p80211knetdev.c
*
* Linux Kernel net device interface
*
* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
* --------------------------------------------------------------------
*
* linux-wlan
*
*   The contents of this file are subject to the Mozilla Public
*   License Version 1.1 (the "License"); you may not use this file
*   except in compliance with the License. You may obtain a copy of
*   the License at http://www.mozilla.org/MPL/
*
*   Software distributed under the License is distributed on an "AS
*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
*   implied. See the License for the specific language governing
*   rights and limitations under the License.
*
*   Alternatively, the contents of this file may be used under the
*   terms of the GNU Public License version 2 (the "GPL"), in which
*   case the provisions of the GPL are applicable instead of the
*   above.  If you wish to allow the use of your version of this file
*   only under the terms of the GPL and not to allow others to use
*   your version of this file under the MPL, indicate your decision
*   by deleting the provisions above and replace them with the notice
*   and other provisions required by the GPL.  If you do not delete
*   the provisions above, a recipient may use your version of this
*   file under either the MPL or the GPL.
*
* --------------------------------------------------------------------
*
* Inquiries regarding the linux-wlan Open Source project can be
* made directly to:
*
* AbsoluteValue Systems Inc.
* info@linux-wlan.com
* http://www.linux-wlan.com
*
* --------------------------------------------------------------------
*
* Portions of the development of this software were funded by
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
*
* The functions required for a Linux network device are defined here.
*
* --------------------------------------------------------------------
*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/kmod.h>
#include <linux/if_arp.h>
#include <linux/wireless.h>
#include <linux/sockios.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/byteorder/generic.h>
#include <linux/bitops.h>
#include <linux/uaccess.h>
#include <asm/byteorder.h>

#ifdef SIOCETHTOOL
#include <linux/ethtool.h>
#endif

#include <net/iw_handler.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>

#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211conv.h"
#include "p80211mgmt.h"
#include "p80211msg.h"
#include "p80211netdev.h"
#include "p80211ioctl.h"
#include "p80211req.h"
#include "p80211metastruct.h"
#include "p80211metadef.h"

#include "cfg80211.c"

/* netdevice method functions */
static int p80211knetdev_init(netdevice_t *netdev);
static int p80211knetdev_open(netdevice_t *netdev);
static int p80211knetdev_stop(netdevice_t *netdev);
static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
					 netdevice_t *netdev);
static void p80211knetdev_set_multicast_list(netdevice_t *dev);
static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr,
				  int cmd);
static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr);
static void p80211knetdev_tx_timeout(netdevice_t *netdev);
static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc);


int wlan_watchdog = 5000;
module_param(wlan_watchdog, int, 0644);
MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds");


int wlan_wext_write = 1;
module_param(wlan_wext_write, int, 0644);
MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");

/*----------------------------------------------------------------
* p80211knetdev_init
*
* Init method for a Linux netdevice.  Called in response to
* register_netdev.
*
* Arguments:
*       none
*
* Returns:
*       nothing
----------------------------------------------------------------*/

static int p80211knetdev_init(netdevice_t *netdev) { /* Called in response to register_netdev */ /* This is usually the probe function, but the probe has */ /* already been done by the MSD and the create_kdev */ /* function. All we do here is return success */ return 0; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman17100.00%1100.00%
Total17100.00%1100.00%

/*---------------------------------------------------------------- * p80211knetdev_open * * Linux netdevice open method. Following a successful call here, * the device is supposed to be ready for tx and rx. In our * situation that may not be entirely true due to the state of the * MAC below. * * Arguments: * netdev Linux network device structure * * Returns: * zero on success, non-zero otherwise ----------------------------------------------------------------*/
static int p80211knetdev_open(netdevice_t *netdev) { int result = 0; /* success */ wlandevice_t *wlandev = netdev->ml_priv; /* Check to make sure the MSD is running */ if (wlandev->msdstate != WLAN_MSD_RUNNING) return -ENODEV; /* Tell the MSD to open */ if (wlandev->open) { result = wlandev->open(wlandev); if (result == 0) { netif_start_queue(wlandev->netdev); wlandev->state = WLAN_DEVICE_OPEN; } } else { result = -EAGAIN; } return result; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman8395.40%133.33%
solomon peachysolomon peachy33.45%133.33%
wang chenwang chen11.15%133.33%
Total87100.00%3100.00%

/*---------------------------------------------------------------- * p80211knetdev_stop * * Linux netdevice stop (close) method. Following this call, * no frames should go up or down through this interface. * * Arguments: * netdev Linux network device structure * * Returns: * zero on success, non-zero otherwise ----------------------------------------------------------------*/
static int p80211knetdev_stop(netdevice_t *netdev) { int result = 0; wlandevice_t *wlandev = netdev->ml_priv; if (wlandev->close) result = wlandev->close(wlandev); netif_stop_queue(wlandev->netdev); wlandev->state = WLAN_DEVICE_CLOSED; return result; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman5092.59%133.33%
solomon peachysolomon peachy35.56%133.33%
wang chenwang chen11.85%133.33%
Total54100.00%3100.00%

/*---------------------------------------------------------------- * p80211netdev_rx * * Frame receive function called by the mac specific driver. * * Arguments: * wlandev WLAN network device structure * skb skbuff containing a full 802.11 frame. * Returns: * nothing * Side effects: * ----------------------------------------------------------------*/
void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb) { /* Enqueue for post-irq processing */ skb_queue_tail(&wlandev->nsd_rxq, skb); tasklet_schedule(&wlandev->rx_bh); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman3296.97%150.00%
moritz muehlenhoffmoritz muehlenhoff13.03%150.00%
Total33100.00%2100.00%

#define CONV_TO_ETHER_SKIPPED 0x01 #define CONV_TO_ETHER_FAILED 0x02 /** * p80211_convert_to_ether - conversion from 802.11 frame to ethernet frame * @wlandev: pointer to WLAN device * @skb: pointer to socket buffer * * Returns: 0 if conversion succeeded * CONV_TO_ETHER_FAILED if conversion failed * CONV_TO_ETHER_SKIPPED if frame is ignored */
static int p80211_convert_to_ether(wlandevice_t *wlandev, struct sk_buff *skb) { struct p80211_hdr_a3 *hdr; hdr = (struct p80211_hdr_a3 *) skb->data; if (p80211_rx_typedrop(wlandev, hdr->fc)) return CONV_TO_ETHER_SKIPPED; /* perform mcast filtering: allow my local address through but reject * anything else that isn't multicast */ if (wlandev->netdev->flags & IFF_ALLMULTI) { if (!ether_addr_equal_unaligned(wlandev->netdev->dev_addr, hdr->a1)) { if (!is_multicast_ether_addr(hdr->a1)) return CONV_TO_ETHER_SKIPPED; } } if (skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0) { skb->dev->last_rx = jiffies; wlandev->netdev->stats.rx_packets++; wlandev->netdev->stats.rx_bytes += skb->len; netif_rx_ni(skb); return 0; } netdev_dbg(wlandev->netdev, "p80211_convert_to_ether failed.\n"); return CONV_TO_ETHER_FAILED; }

Contributors

PersonTokensPropCommitsCommitProp
denis pithondenis pithon14996.13%685.71%
tobias klausertobias klauser63.87%114.29%
Total155100.00%7100.00%

/** * p80211netdev_rx_bh - deferred processing of all received frames * * @arg: pointer to WLAN network device structure (cast to unsigned long) */
static void p80211netdev_rx_bh(unsigned long arg) { wlandevice_t *wlandev = (wlandevice_t *) arg; struct sk_buff *skb = NULL; netdevice_t *dev = wlandev->netdev; /* Let's empty our our queue */ while ((skb = skb_dequeue(&wlandev->nsd_rxq))) { if (wlandev->state == WLAN_DEVICE_OPEN) { if (dev->type != ARPHRD_ETHER) { /* RAW frame; we shouldn't convert it */ /* XXX Append the Prism Header here instead. */ /* set up various data fields */ skb->dev = dev; skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_NONE; skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_80211_RAW); dev->last_rx = jiffies; dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; netif_rx_ni(skb); continue; } else { if (!p80211_convert_to_ether(wlandev, skb)) continue; } } dev_kfree_skb(skb); } }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman14996.13%125.00%
tobias klausertobias klauser42.58%125.00%
denis pithondenis pithon10.65%125.00%
moritz muehlenhoffmoritz muehlenhoff10.65%125.00%
Total155100.00%4100.00%

/*---------------------------------------------------------------- * p80211knetdev_hard_start_xmit * * Linux netdevice method for transmitting a frame. * * Arguments: * skb Linux sk_buff containing the frame. * netdev Linux netdevice. * * Side effects: * If the lower layers report that buffers are full. netdev->tbusy * will be set to prevent higher layers from sending more traffic. * * Note: If this function returns non-zero, higher layers retain * ownership of the skb. * * Returns: * zero on success, non-zero on failure. ----------------------------------------------------------------*/
static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, netdevice_t *netdev) { int result = 0; int txresult = -1; wlandevice_t *wlandev = netdev->ml_priv; union p80211_hdr p80211_hdr; struct p80211_metawep p80211_wep; p80211_wep.data = NULL; if (!skb) return NETDEV_TX_OK; if (wlandev->state != WLAN_DEVICE_OPEN) { result = 1; goto failed; } memset(&p80211_hdr, 0, sizeof(union p80211_hdr)); memset(&p80211_wep, 0, sizeof(struct p80211_metawep)); if (netif_queue_stopped(netdev)) { netdev_dbg(netdev, "called when queue stopped.\n"); result = 1; goto failed; } netif_stop_queue(netdev); /* Check to see that a valid mode is set */ switch (wlandev->macmode) { case WLAN_MACMODE_IBSS_STA: case WLAN_MACMODE_ESS_STA: case WLAN_MACMODE_ESS_AP: break; default: /* Mode isn't set yet, just drop the frame * and return success . * TODO: we need a saner way to handle this */ if (be16_to_cpu(skb->protocol) != ETH_P_80211_RAW) { netif_start_queue(wlandev->netdev); netdev_notice(netdev, "Tx attempt prior to association, frame dropped.\n"); netdev->stats.tx_dropped++; result = 0; goto failed; } break; } /* Check for raw transmits */ if (be16_to_cpu(skb->protocol) == ETH_P_80211_RAW) { if (!capable(CAP_NET_ADMIN)) { result = 1; goto failed; } /* move the header over */ memcpy(&p80211_hdr, skb->data, sizeof(union p80211_hdr)); skb_pull(skb, sizeof(union p80211_hdr)); } else { if (skb_ether_to_p80211 (wlandev, wlandev->ethconv, skb, &p80211_hdr, &p80211_wep) != 0) { /* convert failed */ netdev_dbg(netdev, "ether_to_80211(%d) failed.\n", wlandev->ethconv); result = 1; goto failed; } } if (!wlandev->txframe) { result = 1; goto failed; } netif_trans_update(netdev); netdev->stats.tx_packets++; /* count only the packet payload */ netdev->stats.tx_bytes += skb->len; txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep); if (txresult == 0) { /* success and more buf */ /* avail, re: hw_txdata */ netif_wake_queue(wlandev->netdev); result = NETDEV_TX_OK; } else if (txresult == 1) { /* success, no more avail */ netdev_dbg(netdev, "txframe success, no more bufs\n"); /* netdev->tbusy = 1; don't set here, irqhdlr */ /* may have already cleared it */ result = NETDEV_TX_OK; } else if (txresult == 2) { /* alloc failure, drop frame */ netdev_dbg(netdev, "txframe returned alloc_fail\n"); result = NETDEV_TX_BUSY; } else { /* buffer full or queue busy, drop frame. */ netdev_dbg(netdev, "txframe returned full or busy\n"); result = NETDEV_TX_BUSY; } failed: /* Free up the WEP buffer if it's not the same as the skb */ if ((p80211_wep.data) && (p80211_wep.data != skb->data)) kzfree(p80211_wep.data); /* we always free the skb here, never in a lower level. */ if (!result) dev_kfree_skb(skb); return result; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman40886.08%17.14%
denis pithondenis pithon183.80%17.14%
edgardo hamesedgardo hames122.53%214.29%
ebru akagunduzebru akagunduz61.27%17.14%
peter huewepeter huewe61.27%17.14%
solomon peachysolomon peachy61.27%17.14%
tobias klausertobias klauser61.27%17.14%
patrick mchardypatrick mchardy51.05%214.29%
florian westphalflorian westphal30.63%17.14%
fu yong quahfu yong quah20.42%17.14%
wang chenwang chen10.21%17.14%
moritz muehlenhoffmoritz muehlenhoff10.21%17.14%
Total474100.00%14100.00%

/*---------------------------------------------------------------- * p80211knetdev_set_multicast_list * * Called from higher layers whenever there's a need to set/clear * promiscuous mode or rewrite the multicast list. * * Arguments: * none * * Returns: * nothing ----------------------------------------------------------------*/
static void p80211knetdev_set_multicast_list(netdevice_t *dev) { wlandevice_t *wlandev = dev->ml_priv; /* TODO: real multicast support as well */ if (wlandev->set_multicast_list) wlandev->set_multicast_list(wlandev, dev); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman3397.06%150.00%
wang chenwang chen12.94%150.00%
Total34100.00%2100.00%

#ifdef SIOCETHTOOL
static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr) { u32 ethcmd; struct ethtool_drvinfo info; struct ethtool_value edata; memset(&info, 0, sizeof(info)); memset(&edata, 0, sizeof(edata)); if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd))) return -EFAULT; switch (ethcmd) { case ETHTOOL_GDRVINFO: info.cmd = ethcmd; snprintf(info.driver, sizeof(info.driver), "p80211_%s", wlandev->nsdname); snprintf(info.version, sizeof(info.version), "%s", WLAN_RELEASE); if (copy_to_user(useraddr, &info, sizeof(info))) return -EFAULT; return 0; #ifdef ETHTOOL_GLINK case ETHTOOL_GLINK: edata.cmd = ethcmd; if (wlandev->linkstatus && (wlandev->macmode != WLAN_MACMODE_NONE)) { edata.data = 1; } else { edata.data = 0; } if (copy_to_user(useraddr, &edata, sizeof(edata))) return -EFAULT; return 0; #endif } return -EOPNOTSUPP; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman21599.08%133.33%
maximiliano david bustosmaximiliano david bustos10.46%133.33%
solomon peachysolomon peachy10.46%133.33%
Total217100.00%3100.00%

#endif /*---------------------------------------------------------------- * p80211knetdev_do_ioctl * * Handle an ioctl call on one of our devices. Everything Linux * ioctl specific is done here. Then we pass the contents of the * ifr->data to the request message handler. * * Arguments: * dev Linux kernel netdevice * ifr Our private ioctl request structure, typed for the * generic struct ifreq so we can use ptr to func * w/o cast. * * Returns: * zero on success, a negative errno on failure. Possible values: * -ENETDOWN Device isn't up. * -EBUSY cmd already in progress * -ETIME p80211 cmd timed out (MSD may have its own timers) * -EFAULT memory fault copying msg from user buffer * -ENOMEM unable to allocate kernel msg buffer * -ENOSYS bad magic, it the cmd really for us? * -EintR sleeping on cmd, awakened by signal, cmd cancelled. * * Call Context: * Process thread (ioctl caller). TODO: SMP support may require * locks. ----------------------------------------------------------------*/
static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) { int result = 0; struct p80211ioctl_req *req = (struct p80211ioctl_req *) ifr; wlandevice_t *wlandev = dev->ml_priv; u8 *msgbuf; netdev_dbg(dev, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len); #ifdef SIOCETHTOOL if (cmd == SIOCETHTOOL) { result = p80211netdev_ethtool(wlandev, (void __user *)ifr->ifr_data); goto bail; } #endif /* Test the magic, assume ifr is good if it's there */ if (req->magic != P80211_IOCTL_MAGIC) { result = -ENOSYS; goto bail; } if (cmd == P80211_IFTEST) { result = 0; goto bail; } else if (cmd != P80211_IFREQ) { result = -ENOSYS; goto bail; } /* Allocate a buf of size req->len */ msgbuf = kmalloc(req->len, GFP_KERNEL); if (msgbuf) { if (copy_from_user(msgbuf, (void __user *)req->data, req->len)) result = -EFAULT; else result = p80211req_dorequest(wlandev, msgbuf); if (result == 0) { if (copy_to_user ((void __user *)req->data, msgbuf, req->len)) { result = -EFAULT; } } kfree(msgbuf); } else { result = -ENOMEM; } bail: /* If allocate,copyfrom or copyto fails, return errno */ return result; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman23694.40%114.29%
edgardo hamesedgardo hames52.00%228.57%
svenne krapsvenne krap41.60%114.29%
denis pithondenis pithon31.20%114.29%
wang chenwang chen10.40%114.29%
solomon peachysolomon peachy10.40%114.29%
Total250100.00%7100.00%

/*---------------------------------------------------------------- * p80211knetdev_set_mac_address * * Handles the ioctl for changing the MACAddress of a netdevice * * references: linux/netdevice.h and drivers/net/net_init.c * * NOTE: [MSM] We only prevent address changes when the netdev is * up. We don't control anything based on dot11 state. If the * address is changed on a STA that's currently associated, you * will probably lose the ability to send and receive data frames. * Just be aware. Therefore, this should usually only be done * prior to scan/join/auth/assoc. * * Arguments: * dev netdevice struct * addr the new MACAddress (a struct) * * Returns: * zero on success, a negative errno on failure. Possible values: * -EBUSY device is bussy (cmd not possible) * -and errors returned by: p80211req_dorequest(..) * * by: Collin R. Mulliner <collin@mulliner.org> ----------------------------------------------------------------*/
static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr) { struct sockaddr *new_addr = addr; struct p80211msg_dot11req_mibset dot11req; p80211item_unk392_t *mibattr; p80211item_pstr6_t *macaddr; p80211item_uint32_t *resultcode; int result; /* If we're running, we don't allow MAC address changes */ if (netif_running(dev)) return -EBUSY; /* Set up some convenience pointers. */ mibattr = &dot11req.mibattribute; macaddr = (p80211item_pstr6_t *) &mibattr->data; resultcode = &dot11req.resultcode; /* Set up a dot11req_mibset */ memset(&dot11req, 0, sizeof(struct p80211msg_dot11req_mibset)); dot11req.msgcode = DIDmsg_dot11req_mibset; dot11req.msglen = sizeof(struct p80211msg_dot11req_mibset); memcpy(dot11req.devname, ((wlandevice_t *) dev->ml_priv)->name, WLAN_DEVNAMELEN_MAX - 1); /* Set up the mibattribute argument */ mibattr->did = DIDmsg_dot11req_mibset_mibattribute; mibattr->status = P80211ENUM_msgitem_status_data_ok; mibattr->len = sizeof(mibattr->data); macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress; macaddr->status = P80211ENUM_msgitem_status_data_ok; macaddr->len = sizeof(macaddr->data); macaddr->data.len = ETH_ALEN; memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN); /* Set up the resultcode argument */ resultcode->did = DIDmsg_dot11req_mibset_resultcode; resultcode->status = P80211ENUM_msgitem_status_no_value; resultcode->len = sizeof(resultcode->data); resultcode->data = 0; /* now fire the request */ result = p80211req_dorequest(dev->ml_priv, (u8 *) &dot11req); /* If the request wasn't successful, report an error and don't * change the netdev address */ if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) { netdev_err(dev, "Low-level driver failed dot11req_mibset(dot11MACAddress).\n"); result = -EADDRNOTAVAIL; } else { /* everything's ok, change the addr in netdev */ memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len); } return result; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman28595.32%116.67%
edgardo hamesedgardo hames62.01%116.67%
denis pithondenis pithon31.00%116.67%
moritz muehlenhoffmoritz muehlenhoff20.67%116.67%
wang chenwang chen20.67%116.67%
solomon peachysolomon peachy10.33%116.67%
Total299100.00%6100.00%


static int wlan_change_mtu(netdevice_t *dev, int new_mtu) { /* 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap) and another 8 for wep. */ if ((new_mtu < 68) || (new_mtu > (2312 - 20 - 8))) return -EINVAL; dev->mtu = new_mtu; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman4697.87%150.00%
moritz muehlenhoffmoritz muehlenhoff12.13%150.00%
Total47100.00%2100.00%

static const struct net_device_ops p80211_netdev_ops = { .ndo_init = p80211knetdev_init, .ndo_open = p80211knetdev_open, .ndo_stop = p80211knetdev_stop, .ndo_start_xmit = p80211knetdev_hard_start_xmit, .ndo_set_rx_mode = p80211knetdev_set_multicast_list, .ndo_do_ioctl = p80211knetdev_do_ioctl, .ndo_set_mac_address = p80211knetdev_set_mac_address, .ndo_tx_timeout = p80211knetdev_tx_timeout, .ndo_change_mtu = wlan_change_mtu, .ndo_validate_addr = eth_validate_addr, }; /*---------------------------------------------------------------- * wlan_setup * * Roughly matches the functionality of ether_setup. Here * we set up any members of the wlandevice structure that are common * to all devices. Additionally, we allocate a linux 'struct device' * and perform the same setup as ether_setup. * * Note: It's important that the caller have setup the wlandev->name * ptr prior to calling this function. * * Arguments: * wlandev ptr to the wlandev structure for the * interface. * physdev ptr to usb device * Returns: * zero on success, non-zero otherwise. * Call Context: * Should be process thread. We'll assume it might be * interrupt though. When we add support for statically * compiled drivers, this function will be called in the * context of the kernel startup code. ----------------------------------------------------------------*/
int wlan_setup(wlandevice_t *wlandev, struct device *physdev) { int result = 0; netdevice_t *netdev; struct wiphy *wiphy; struct wireless_dev *wdev; /* Set up the wlandev */ wlandev->state = WLAN_DEVICE_CLOSED; wlandev->ethconv = WLAN_ETHCONV_8021h; wlandev->macmode = WLAN_MACMODE_NONE; /* Set up the rx queue */ skb_queue_head_init(&wlandev->nsd_rxq); tasklet_init(&wlandev->rx_bh, p80211netdev_rx_bh, (unsigned long)wlandev); /* Allocate and initialize the wiphy struct */ wiphy = wlan_create_wiphy(physdev, wlandev); if (!wiphy) { dev_err(physdev, "Failed to alloc wiphy.\n"); return 1; } /* Allocate and initialize the struct device */ netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d", NET_NAME_UNKNOWN, ether_setup); if (!netdev) { dev_err(physdev, "Failed to alloc netdev.\n"); wlan_free_wiphy(wiphy); result = 1; } else { wlandev->netdev = netdev; netdev->ml_priv = wlandev; netdev->netdev_ops = &p80211_netdev_ops; wdev = netdev_priv(netdev); wdev->wiphy = wiphy; wdev->iftype = NL80211_IFTYPE_STATION; netdev->ieee80211_ptr = wdev; netif_stop_queue(netdev); netif_carrier_off(netdev); } return result; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman10953.17%112.50%
karl reltonkarl relton7838.05%112.50%
denis pithondenis pithon62.93%112.50%
richard kennedyrichard kennedy41.95%112.50%
alexander beregalovalexander beregalov31.46%112.50%
tom gundersentom gundersen20.98%112.50%
fu yong quahfu yong quah20.98%112.50%
wang chenwang chen10.49%112.50%
Total205100.00%8100.00%

/*---------------------------------------------------------------- * wlan_unsetup * * This function is paired with the wlan_setup routine. It should * be called after unregister_wlandev. Basically, all it does is * free the 'struct device' that's associated with the wlandev. * We do it here because the 'struct device' isn't allocated * explicitly in the driver code, it's done in wlan_setup. To * do the free in the driver might seem like 'magic'. * * Arguments: * wlandev ptr to the wlandev structure for the * interface. * Call Context: * Should be process thread. We'll assume it might be * interrupt though. When we add support for statically * compiled drivers, this function will be called in the * context of the kernel startup code. ----------------------------------------------------------------*/
void wlan_unsetup(wlandevice_t *wlandev) { struct wireless_dev *wdev; tasklet_kill(&wlandev->rx_bh); if (wlandev->netdev) { wdev = netdev_priv(wlandev->netdev); if (wdev->wiphy) wlan_free_wiphy(wdev->wiphy); free_netdev(wlandev->netdev); wlandev->netdev = NULL; } }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman4264.62%133.33%
karl reltonkarl relton2233.85%133.33%
devendra nagadevendra naga11.54%133.33%
Total65100.00%3100.00%

/*---------------------------------------------------------------- * register_wlandev * * Roughly matches the functionality of register_netdev. This function * is called after the driver has successfully probed and set up the * resources for the device. It's now ready to become a named device * in the Linux system. * * First we allocate a name for the device (if not already set), then * we call the Linux function register_netdevice. * * Arguments: * wlandev ptr to the wlandev structure for the * interface. * Returns: * zero on success, non-zero otherwise. * Call Context: * Can be either interrupt or not. ----------------------------------------------------------------*/
int register_wlandev(wlandevice_t *wlandev) { return register_netdev(wlandev->netdev); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman1694.12%150.00%
devendra nagadevendra naga15.88%150.00%
Total17100.00%2100.00%

/*---------------------------------------------------------------- * unregister_wlandev * * Roughly matches the functionality of unregister_netdev. This * function is called to remove a named device from the system. * * First we tell linux that the device should no longer exist. * Then we remove it from the list of known wlan devices. * * Arguments: * wlandev ptr to the wlandev structure for the * interface. * Returns: * zero on success, non-zero otherwise. * Call Context: * Can be either interrupt or not. ----------------------------------------------------------------*/
int unregister_wlandev(wlandevice_t *wlandev) { struct sk_buff *skb; unregister_netdev(wlandev->netdev); /* Now to clean out the rx queue */ while ((skb = skb_dequeue(&wlandev->nsd_rxq))) dev_kfree_skb(skb); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman44100.00%1100.00%
Total44100.00%1100.00%

/*---------------------------------------------------------------- * p80211netdev_hwremoved * * Hardware removed notification. This function should be called * immediately after an MSD has detected that the underlying hardware * has been yanked out from under us. The primary things we need * to do are: * - Mark the wlandev * - Prevent any further traffic from the knetdev i/f * - Prevent any further requests from mgmt i/f * - If there are any waitq'd mgmt requests or mgmt-frame exchanges, * shut them down. * - Call the MSD hwremoved function. * * The remainder of the cleanup will be handled by unregister(). * Our primary goal here is to prevent as much tickling of the MSD * as possible since the MSD is already in a 'wounded' state. * * TODO: As new features are added, this function should be * updated. * * Arguments: * wlandev WLAN network device structure * Returns: * nothing * Side effects: * * Call context: * Usually interrupt. ----------------------------------------------------------------*/
void p80211netdev_hwremoved(wlandevice_t *wlandev) { wlandev->hwremoved = 1; if (wlandev->state == WLAN_DEVICE_OPEN) netif_stop_queue(wlandev->netdev); netif_device_detach(wlandev->netdev); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman3491.89%150.00%
solomon peachysolomon peachy38.11%150.00%
Total37100.00%2100.00%

/*---------------------------------------------------------------- * p80211_rx_typedrop * * Classifies the frame, increments the appropriate counter, and * returns 0|1|2 indicating whether the driver should handle, ignore, or * drop the frame * * Arguments: * wlandev wlan device structure * fc frame control field * * Returns: * zero if the frame should be handled by the driver, * one if the frame should be ignored * anything else means we drop it. * * Side effects: * * Call context: * interrupt ----------------------------------------------------------------*/
static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc) { u16 ftype; u16 fstype; int drop = 0; /* Classify frame, increment counter */ ftype = WLAN_GET_FC_FTYPE(fc); fstype = WLAN_GET_FC_FSTYPE(fc); #if 0 netdev_dbg(wlandev->netdev, "rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype); #endif switch (ftype) { case WLAN_FTYPE_MGMT: if ((wlandev->netdev->flags & IFF_PROMISC) || (wlandev->netdev->flags & IFF_ALLMULTI)) { drop = 1; break; } netdev_dbg(wlandev->netdev, "rx'd mgmt:\n"); wlandev->rx.mgmt++; switch (fstype) { case WLAN_FSTYPE_ASSOCREQ: /* printk("assocreq"); */ wlandev->rx.assocreq++; break; case WLAN_FSTYPE_ASSOCRESP: /* printk("assocresp"); */ wlandev->rx.assocresp++; break; case WLAN_FSTYPE_REASSOCREQ: /* printk("reassocreq"); */ wlandev->rx.reassocreq++; break; case WLAN_FSTYPE_REASSOCRESP: /* printk("reassocresp"); */ wlandev->rx.reassocresp++; break; case WLAN_FSTYPE_PROBEREQ: /* printk("probereq"); */ wlandev->rx.probereq++; break; case WLAN_FSTYPE_PROBERESP: /* printk("proberesp"); */ wlandev->rx.proberesp++; break; case WLAN_FSTYPE_BEACON: /* printk("beacon"); */ wlandev->rx.beacon++; break; case WLAN_FSTYPE_ATIM: /* printk("atim"); */ wlandev->rx.atim++; break; case WLAN_FSTYPE_DISASSOC: /* printk("disassoc"); */ wlandev->rx.disassoc++; break; case WLAN_FSTYPE_AUTHEN: /* printk("authen"); */ wlandev->rx.authen++; break; case WLAN_FSTYPE_DEAUTHEN: /* printk("deauthen"); */ wlandev->rx.deauthen++; break; default: /* printk("unknown"); */ wlandev->rx.mgmt_unknown++; break; } /* printk("\n"); */ drop = 2; break; case WLAN_FTYPE_CTL: if ((wlandev->netdev->flags & IFF_PROMISC) || (wlandev->netdev->flags & IFF_ALLMULTI)) { drop = 1; break; } netdev_dbg(wlandev->netdev, "rx'd ctl:\n"); wlandev->rx.ctl++; switch (fstype) { case WLAN_FSTYPE_PSPOLL: /* printk("pspoll"); */ wlandev->rx.pspoll++; break; case WLAN_FSTYPE_RTS: /* printk("rts"); */ wlandev->rx.rts++; break; case WLAN_FSTYPE_CTS: /* printk("cts"); */ wlandev->rx.cts++; break; case WLAN_FSTYPE_ACK: /* printk("ack"); */ wlandev->rx.ack++; break; case WLAN_FSTYPE_CFEND: /* printk("cfend"); */ wlandev->rx.cfend++; break; case WLAN_FSTYPE_CFENDCFACK: /* printk("cfendcfack"); */ wlandev->rx.cfendcfack++; break; default: /* printk("unknown"); */ wlandev->rx.ctl_unknown++; break; } /* printk("\n"); */ drop = 2; break; case WLAN_FTYPE_DATA: wlandev->rx.data++; switch (fstype) { case WLAN_FSTYPE_DATAONLY: wlandev->rx.dataonly++; break; case WLAN_FSTYPE_DATA_CFACK: wlandev->rx.data_cfack++; break; case WLAN_FSTYPE_DATA_CFPOLL: wlandev->rx.data_cfpoll++; break; case WLAN_FSTYPE_DATA_CFACK_CFPOLL: wlandev->rx.data__cfack_cfpoll++; break; case WLAN_FSTYPE_NULL: netdev_dbg(wlandev->netdev, "rx'd data:null\n"); wlandev->rx.null++; break; case WLAN_FSTYPE_CFACK: netdev_dbg(wlandev->netdev, "rx'd data:cfack\n"); wlandev->rx.cfack++; break; case WLAN_FSTYPE_CFPOLL: netdev_dbg(wlandev->netdev, "rx'd data:cfpoll\n"); wlandev->rx.cfpoll++; break; case WLAN_FSTYPE_CFACK_CFPOLL: netdev_dbg(wlandev->netdev, "rx'd data:cfack_cfpoll\n"); wlandev->rx.cfack_cfpoll++; break; default: /* printk("unknown"); */ wlandev->rx.data_unknown++; break; } break; } return drop; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman51593.81%133.33%
denis pithondenis pithon315.65%133.33%
solomon peachysolomon peachy30.55%133.33%
Total549100.00%3100.00%


static void p80211knetdev_tx_timeout(netdevice_t *netdev) { wlandevice_t *wlandev = netdev->ml_priv; if (wlandev->tx_timeout) { wlandev->tx_timeout(wlandev); } else { netdev_warn(netdev, "Implement tx_timeout for %s\n", wlandev->nsdname); netif_wake_queue(wlandev->netdev); } }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman4787.04%125.00%
denis pithondenis pithon35.56%125.00%
solomon peachysolomon peachy35.56%125.00%
wang chenwang chen11.85%125.00%
Total54100.00%4100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman257182.09%12.70%
denis pithondenis pithon2247.15%718.92%
karl reltonkarl relton1073.42%12.70%
solomon peachysolomon peachy682.17%38.11%
alexander beregalovalexander beregalov601.92%12.70%
edgardo hamesedgardo hames230.73%410.81%
tobias klausertobias klauser160.51%12.70%
moritz muehlenhoffmoritz muehlenhoff140.45%410.81%
wang chenwang chen90.29%12.70%
peter huewepeter huewe60.19%12.70%
ebru akagunduzebru akagunduz60.19%12.70%
patrick mchardypatrick mchardy50.16%25.41%
richard kennedyrichard kennedy40.13%12.70%
fu yong quahfu yong quah40.13%12.70%
svenne krapsvenne krap40.13%12.70%
florian westphalflorian westphal30.10%12.70%
devendra nagadevendra naga30.10%25.41%
tom gundersentom gundersen20.06%12.70%
maximiliano david bustosmaximiliano david bustos10.03%12.70%
justin mattockjustin mattock10.03%12.70%
jiri pirkojiri pirko10.03%12.70%
Total3132100.00%37100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}