aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/wlan-ng/p80211netdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/wlan-ng/p80211netdev.c')
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c168
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);
}
}