RX bottom half.

This commit is contained in:
solomon 2002-11-14 15:32:31 +00:00
parent 49383a393f
commit b906d24b62
3 changed files with 64 additions and 20 deletions

View File

@ -41,6 +41,7 @@
* Intersil Corporation as part of PRISM(R) chipset product development.
*
* --------------------------------------------------------------------
- Moved RX processing to a bottom half instead of hard irq context.
- Further script improvements: signal strength filtering, and some
space handling stuff. The latter is not complete yet.
- lnxreq_commsquality wasn't setting the status field properly on the

View File

@ -169,10 +169,8 @@ extern struct iw_handler_def p80211wext_handler_def;
/* WLAN device type */
typedef struct wlandevice
{
void *priv; /* private data for MSD */
struct wlandevice *next; /* link for list of devices */
UINT32 nsdcaps; /* NSD Capabilities flags */
void *priv; /* private data for MSD */
/* Subsystem State */
char *name; /* Dev name, from register_wlandev()*/
@ -185,6 +183,7 @@ typedef struct wlandevice
UINT iobase;
UINT membase;
char slotname[16]; /* physical bus location */
UINT32 nsdcaps; /* NSD Capabilities flags */
/* Config vars */
UINT ethconv;
@ -225,6 +224,10 @@ typedef struct wlandevice
struct proc_dir_entry *procwlandev;
#endif
/* Rx bottom half */
struct tq_struct rx_bh;
struct sk_buff_head nsd_rxq;
/* 802.11 device statistics */
struct p80211_frmrx_t rx;

View File

@ -122,6 +122,8 @@ static struct proc_dir_entry *proc_p80211;
static int wlandev_get_index(wlandevice_t *wlandev);
static void wlandev_clear_index(wlandevice_t *wlandev);
static void p80211netdev_rx_bh(void *arg);
/* netdevice method functions */
static int p80211knetdev_init( netdevice_t *netdev);
static struct net_device_stats* p80211knetdev_get_stats(netdevice_t *netdev);
@ -326,7 +328,6 @@ int p80211knetdev_stop( netdevice_t *netdev )
return result;
}
/*----------------------------------------------------------------
* p80211netdev_rx
*
@ -340,34 +341,67 @@ int p80211knetdev_stop( netdevice_t *netdev )
* Side effects:
*
----------------------------------------------------------------*/
void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
void
p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb )
{
DBFENTER;
/* Enqueue for post-irq processing */
skb_queue_tail(&wlandev->nsd_rxq, skb);
queue_task(&wlandev->rx_bh, &tq_immediate);
mark_bh(IMMEDIATE_BH);
DBFEXIT;
return;
}
/*----------------------------------------------------------------
* 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:
*
----------------------------------------------------------------*/
void p80211netdev_rx_bh(void *arg)
{
wlandevice_t *wlandev = (wlandevice_t *) arg;
struct sk_buff *skb = NULL;
netdevice_t *dev = wlandev->netdev;
DBFENTER;
if (wlandev->state == WLAN_DEVICE_OPEN) {
/* 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 */
skb->dev->last_rx = jiffies;
wlandev->linux_stats.rx_packets++;
wlandev->linux_stats.rx_bytes += skb->len;
netif_rx(skb);
goto done;
} else {
if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) {
if (dev->type != ARPHRD_ETHER) {
/* RAW frame; we shouldn't convert it */
skb->dev->last_rx = jiffies;
wlandev->linux_stats.rx_packets++;
wlandev->linux_stats.rx_bytes += skb->len;
netif_rx(skb);
goto done;
}
WLAN_LOG_DEBUG0(1, "p80211_to_ether failed.\n");
continue;
} else {
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(skb);
continue;
}
WLAN_LOG_DEBUG0(1, "p80211_to_ether failed.\n");
}
}
dev_kfree_skb(skb);
}
dev_kfree_skb(skb);
done:
DBFEXIT;
}
@ -814,6 +848,12 @@ int wlan_setup(wlandevice_t *wlandev)
init_waitqueue_head(&wlandev->reqwq);
/* Set up the rx queue */
skb_queue_head_init(&wlandev->nsd_rxq);
INIT_TQUEUE(&wlandev->rx_bh,
p80211netdev_rx_bh,
(void*)wlandev);
/* Allocate and initialize the struct device */
dev = kmalloc(sizeof(netdevice_t), GFP_ATOMIC);
if ( dev == NULL ) {