diff options
Diffstat (limited to 'drivers/staging/wlan-ng/p80211netdev.c')
| -rw-r--r-- | drivers/staging/wlan-ng/p80211netdev.c | 168 |
1 files changed, 79 insertions, 89 deletions
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index b7b4a733b46..00b186c5972 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -90,9 +90,6 @@ #include "cfg80211.c" -/* Support functions */ -static void p80211netdev_rx_bh(unsigned long arg); - /* netdevice method functions */ static int p80211knetdev_init(netdevice_t *netdev); static struct net_device_stats *p80211knetdev_get_stats(netdevice_t *netdev); @@ -150,7 +147,7 @@ static int p80211knetdev_init(netdevice_t *netdev) * Returns: * the address of the statistics structure ----------------------------------------------------------------*/ -static struct net_device_stats *p80211knetdev_get_stats(netdevice_t * netdev) +static struct net_device_stats *p80211knetdev_get_stats(netdevice_t *netdev) { wlandevice_t *wlandev = netdev->ml_priv; @@ -240,32 +237,62 @@ 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); +} + +#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->linux_stats.rx_packets++; + wlandev->linux_stats.rx_bytes += skb->len; + netif_rx_ni(skb); + return 0; + } - return; + netdev_dbg(wlandev->netdev, "p80211_convert_to_ether failed.\n"); + return CONV_TO_ETHER_FAILED; } -/*---------------------------------------------------------------- -* p80211netdev_rx_bh -* -* Deferred processing of all received frames. -* -* Arguments: -* wlandev WLAN network device structure -* skb skbuff containing a full 802.11 frame. -* Returns: -* nothing -* Side effects: -* -----------------------------------------------------------------*/ +/** + * 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; - struct p80211_hdr_a3 *hdr; - u16 fc; /* Let's empty our our queue */ while ((skb = skb_dequeue(&wlandev->nsd_rxq))) { @@ -288,37 +315,8 @@ static void p80211netdev_rx_bh(unsigned long arg) netif_rx_ni(skb); continue; } else { - hdr = (struct p80211_hdr_a3 *) skb->data; - fc = le16_to_cpu(hdr->fc); - if (p80211_rx_typedrop(wlandev, fc)) { - dev_kfree_skb(skb); - continue; - } - - /* perform mcast filtering */ - if (wlandev->netdev->flags & IFF_ALLMULTI) { - /* allow my local address through */ - if (memcmp - (hdr->a1, wlandev->netdev->dev_addr, - ETH_ALEN) != 0) { - /* but reject anything else that isn't multicast */ - if (!(hdr->a1[0] & 0x01)) { - dev_kfree_skb(skb); - continue; - } - } - } - - if (skb_p80211_to_ether - (wlandev, wlandev->ethconv, skb) == 0) { - skb->dev->last_rx = jiffies; - wlandev->linux_stats.rx_packets++; - wlandev->linux_stats.rx_bytes += - skb->len; - netif_rx_ni(skb); + if (!p80211_convert_to_ether(wlandev, skb)) continue; - } - pr_debug("p80211_to_ether failed.\n"); } } dev_kfree_skb(skb); @@ -353,6 +351,8 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, union p80211_hdr p80211_hdr; struct p80211_metawep p80211_wep; + p80211_wep.data = NULL; + if (skb == NULL) return NETDEV_TX_OK; @@ -365,7 +365,7 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, memset(&p80211_wep, 0, sizeof(struct p80211_metawep)); if (netif_queue_stopped(netdev)) { - pr_debug("called when queue stopped.\n"); + netdev_dbg(netdev, "called when queue stopped.\n"); result = 1; goto failed; } @@ -385,8 +385,7 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, */ if (skb->protocol != ETH_P_80211_RAW) { netif_start_queue(wlandev->netdev); - printk(KERN_NOTICE - "Tx attempt prior to association, frame dropped.\n"); + netdev_notice(netdev, "Tx attempt prior to association, frame dropped.\n"); wlandev->linux_stats.tx_dropped++; result = 0; goto failed; @@ -408,8 +407,8 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, (wlandev, wlandev->ethconv, skb, &p80211_hdr, &p80211_wep) != 0) { /* convert failed */ - pr_debug("ether_to_80211(%d) failed.\n", - wlandev->ethconv); + netdev_dbg(netdev, "ether_to_80211(%d) failed.\n", + wlandev->ethconv); result = 1; goto failed; } @@ -434,17 +433,17 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, result = NETDEV_TX_OK; } else if (txresult == 1) { /* success, no more avail */ - pr_debug("txframe success, no more bufs\n"); + 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 */ - pr_debug("txframe returned alloc_fail\n"); + netdev_dbg(netdev, "txframe returned alloc_fail\n"); result = NETDEV_TX_BUSY; } else { /* buffer full or queue busy, drop frame. */ - pr_debug("txframe returned full or busy\n"); + netdev_dbg(netdev, "txframe returned full or busy\n"); result = NETDEV_TX_BUSY; } @@ -463,7 +462,7 @@ failed: /*---------------------------------------------------------------- * p80211knetdev_set_multicast_list * -* Called from higher lavers whenever there's a need to set/clear +* Called from higher layers whenever there's a need to set/clear * promiscuous mode or rewrite the multicast list. * * Arguments: @@ -564,7 +563,7 @@ static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) wlandevice_t *wlandev = dev->ml_priv; u8 *msgbuf; - pr_debug("rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len); + netdev_dbg(dev, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len); #ifdef SIOCETHTOOL if (cmd == SIOCETHTOOL) { @@ -643,7 +642,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr) p80211item_unk392_t *mibattr; p80211item_pstr6_t *macaddr; p80211item_uint32_t *resultcode; - int result = 0; + int result; /* If we're running, we don't allow MAC address changes */ if (netif_running(dev)) @@ -685,8 +684,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr) * change the netdev address */ if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) { - printk(KERN_ERR - "Low-level driver failed dot11req_mibset(dot11MACAddress).\n"); + netdev_err(dev, "Low-level driver failed dot11req_mibset(dot11MACAddress).\n"); result = -EADDRNOTAVAIL; } else { /* everything's ok, change the addr in netdev */ @@ -714,7 +712,7 @@ static const struct net_device_ops p80211_netdev_ops = { .ndo_stop = p80211knetdev_stop, .ndo_get_stats = p80211knetdev_get_stats, .ndo_start_xmit = p80211knetdev_hard_start_xmit, - .ndo_set_multicast_list = p80211knetdev_set_multicast_list, + .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, @@ -765,14 +763,15 @@ int wlan_setup(wlandevice_t *wlandev, struct device *physdev) /* Allocate and initialize the wiphy struct */ wiphy = wlan_create_wiphy(physdev, wlandev); if (wiphy == NULL) { - printk(KERN_ERR "Failed to alloc wiphy.\n"); + 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", ether_setup); + netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d", + ether_setup); if (netdev == NULL) { - printk(KERN_ERR "Failed to alloc netdev.\n"); + dev_err(physdev, "Failed to alloc netdev.\n"); wlan_free_wiphy(wiphy); result = 1; } else { @@ -804,15 +803,13 @@ int wlan_setup(wlandevice_t *wlandev, struct device *physdev) * Arguments: * wlandev ptr to the wlandev structure for the * interface. -* 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_unsetup(wlandevice_t *wlandev) +void wlan_unsetup(wlandevice_t *wlandev) { struct wireless_dev *wdev; @@ -825,8 +822,6 @@ int wlan_unsetup(wlandevice_t *wlandev) free_netdev(wlandev->netdev); wlandev->netdev = NULL; } - - return 0; } /*---------------------------------------------------------------- @@ -850,13 +845,7 @@ int wlan_unsetup(wlandevice_t *wlandev) ----------------------------------------------------------------*/ int register_wlandev(wlandevice_t *wlandev) { - int i = 0; - - i = register_netdev(wlandev->netdev); - if (i) - return i; - - return 0; + return register_netdev(wlandev->netdev); } /*---------------------------------------------------------------- @@ -958,7 +947,8 @@ static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc) ftype = WLAN_GET_FC_FTYPE(fc); fstype = WLAN_GET_FC_FSTYPE(fc); #if 0 - pr_debug("rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype); + netdev_dbg(wlandev->netdev, "rx_typedrop : ftype=%d fstype=%d.\n", + ftype, fstype); #endif switch (ftype) { case WLAN_FTYPE_MGMT: @@ -967,7 +957,7 @@ static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc) drop = 1; break; } - pr_debug("rx'd mgmt:\n"); + netdev_dbg(wlandev->netdev, "rx'd mgmt:\n"); wlandev->rx.mgmt++; switch (fstype) { case WLAN_FSTYPE_ASSOCREQ: @@ -1029,7 +1019,7 @@ static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc) drop = 1; break; } - pr_debug("rx'd ctl:\n"); + netdev_dbg(wlandev->netdev, "rx'd ctl:\n"); wlandev->rx.ctl++; switch (fstype) { case WLAN_FSTYPE_PSPOLL: @@ -1081,19 +1071,19 @@ static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc) wlandev->rx.data__cfack_cfpoll++; break; case WLAN_FSTYPE_NULL: - pr_debug("rx'd data:null\n"); + netdev_dbg(wlandev->netdev, "rx'd data:null\n"); wlandev->rx.null++; break; case WLAN_FSTYPE_CFACK: - pr_debug("rx'd data:cfack\n"); + netdev_dbg(wlandev->netdev, "rx'd data:cfack\n"); wlandev->rx.cfack++; break; case WLAN_FSTYPE_CFPOLL: - pr_debug("rx'd data:cfpoll\n"); + netdev_dbg(wlandev->netdev, "rx'd data:cfpoll\n"); wlandev->rx.cfpoll++; break; case WLAN_FSTYPE_CFACK_CFPOLL: - pr_debug("rx'd data:cfack_cfpoll\n"); + netdev_dbg(wlandev->netdev, "rx'd data:cfack_cfpoll\n"); wlandev->rx.cfack_cfpoll++; break; default: @@ -1114,8 +1104,8 @@ static void p80211knetdev_tx_timeout(netdevice_t *netdev) if (wlandev->tx_timeout) { wlandev->tx_timeout(wlandev); } else { - printk(KERN_WARNING "Implement tx_timeout for %s\n", - wlandev->nsdname); + netdev_warn(netdev, "Implement tx_timeout for %s\n", + wlandev->nsdname); netif_wake_queue(wlandev->netdev); } } |
