Commit 8128c97e authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://gkernel.bkbits.net/net-drivers-2.5

into home.osdl.org:/home/torvalds/v2.5/linux
parents 42098570 0fa2e9bd
This diff is collapsed.
...@@ -140,8 +140,7 @@ static const char *howto_msg = ...@@ -140,8 +140,7 @@ static const char *howto_msg =
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/if.h> #include <net/if_arp.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/if_bonding.h> #include <linux/if_bonding.h>
#include <linux/sockios.h> #include <linux/sockios.h>
......
...@@ -109,7 +109,8 @@ in the event that chatty debug messages are desired - jjs 12/30/98 */ ...@@ -109,7 +109,8 @@ in the event that chatty debug messages are desired - jjs 12/30/98 */
#include <linux/module.h> #include <linux/module.h>
#ifdef PCMCIA #ifdef PCMCIA /* required for ibmtr_cs.c to build */
#undef MODULE /* yes, really */
#undef ENABLE_PAGING #undef ENABLE_PAGING
#else #else
#define ENABLE_PAGING 1 #define ENABLE_PAGING 1
......
...@@ -1021,6 +1021,8 @@ struct airo_info { ...@@ -1021,6 +1021,8 @@ struct airo_info {
#define FLAG_UPDATE_MULTI 0x40 #define FLAG_UPDATE_MULTI 0x40
#define FLAG_UPDATE_UNI 0x80 #define FLAG_UPDATE_UNI 0x80
#define FLAG_802_11 0x200 #define FLAG_802_11 0x200
#define FLAG_PENDING_XMIT 0x400
#define FLAG_PENDING_XMIT11 0x800
int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen, int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
int whichbap); int whichbap);
unsigned short *flash; unsigned short *flash;
...@@ -1345,6 +1347,7 @@ static void airo_do_xmit(struct net_device *dev) { ...@@ -1345,6 +1347,7 @@ static void airo_do_xmit(struct net_device *dev) {
u32 *fids = priv->fids; u32 *fids = priv->fids;
if (down_trylock(&priv->sem) != 0) { if (down_trylock(&priv->sem) != 0) {
priv->flags |= FLAG_PENDING_XMIT;
netif_stop_queue(dev); netif_stop_queue(dev);
priv->xmit.task.func = (void (*)(void *))airo_do_xmit; priv->xmit.task.func = (void (*)(void *))airo_do_xmit;
priv->xmit.task.data = (void *)dev; priv->xmit.task.data = (void *)dev;
...@@ -1353,6 +1356,7 @@ static void airo_do_xmit(struct net_device *dev) { ...@@ -1353,6 +1356,7 @@ static void airo_do_xmit(struct net_device *dev) {
} }
status = transmit_802_3_packet (priv, fids[fid], skb->data); status = transmit_802_3_packet (priv, fids[fid], skb->data);
up(&priv->sem); up(&priv->sem);
priv->flags &= ~FLAG_PENDING_XMIT;
i = 0; i = 0;
if ( status == SUCCESS ) { if ( status == SUCCESS ) {
...@@ -1364,14 +1368,12 @@ static void airo_do_xmit(struct net_device *dev) { ...@@ -1364,14 +1368,12 @@ static void airo_do_xmit(struct net_device *dev) {
} }
if (i < MAX_FIDS / 2) if (i < MAX_FIDS / 2)
netif_wake_queue(dev); netif_wake_queue(dev);
else
netif_stop_queue(dev);
dev_kfree_skb(skb); dev_kfree_skb(skb);
} }
static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) { static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
s16 len; s16 len;
int i; int i, j;
struct airo_info *priv = dev->priv; struct airo_info *priv = dev->priv;
u32 *fids = priv->fids; u32 *fids = priv->fids;
...@@ -1382,19 +1384,23 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) { ...@@ -1382,19 +1384,23 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
/* Find a vacant FID */ /* Find a vacant FID */
for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ ); for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
for( j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++ );
if ( i == MAX_FIDS / 2 ) { if ( j >= MAX_FIDS / 2 ) {
priv->stats.tx_fifo_errors++; netif_stop_queue(dev);
dev_kfree_skb(skb);
} else { if (i == MAX_FIDS / 2) {
/* check min length*/ priv->stats.tx_fifo_errors++;
len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; return 1;
/* Mark fid as used & save length for later */ }
fids[i] |= (len << 16);
priv->xmit.skb = skb;
priv->xmit.fid = i;
airo_do_xmit(dev);
} }
/* check min length*/
len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
/* Mark fid as used & save length for later */
fids[i] |= (len << 16);
priv->xmit.skb = skb;
priv->xmit.fid = i;
airo_do_xmit(dev);
return 0; return 0;
} }
...@@ -1407,6 +1413,7 @@ static void airo_do_xmit11(struct net_device *dev) { ...@@ -1407,6 +1413,7 @@ static void airo_do_xmit11(struct net_device *dev) {
u32 *fids = priv->fids; u32 *fids = priv->fids;
if (down_trylock(&priv->sem) != 0) { if (down_trylock(&priv->sem) != 0) {
priv->flags |= FLAG_PENDING_XMIT11;
netif_stop_queue(dev); netif_stop_queue(dev);
priv->xmit11.task.func = (void (*)(void *))airo_do_xmit11; priv->xmit11.task.func = (void (*)(void *))airo_do_xmit11;
priv->xmit11.task.data = (void *)dev; priv->xmit11.task.data = (void *)dev;
...@@ -1415,6 +1422,7 @@ static void airo_do_xmit11(struct net_device *dev) { ...@@ -1415,6 +1422,7 @@ static void airo_do_xmit11(struct net_device *dev) {
} }
status = transmit_802_11_packet (priv, fids[fid], skb->data); status = transmit_802_11_packet (priv, fids[fid], skb->data);
up(&priv->sem); up(&priv->sem);
priv->flags &= ~FLAG_PENDING_XMIT11;
i = MAX_FIDS / 2; i = MAX_FIDS / 2;
if ( status == SUCCESS ) { if ( status == SUCCESS ) {
...@@ -1426,14 +1434,12 @@ static void airo_do_xmit11(struct net_device *dev) { ...@@ -1426,14 +1434,12 @@ static void airo_do_xmit11(struct net_device *dev) {
} }
if (i < MAX_FIDS) if (i < MAX_FIDS)
netif_wake_queue(dev); netif_wake_queue(dev);
else
netif_stop_queue(dev);
dev_kfree_skb(skb); dev_kfree_skb(skb);
} }
static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
s16 len; s16 len;
int i; int i, j;
struct airo_info *priv = dev->priv; struct airo_info *priv = dev->priv;
u32 *fids = priv->fids; u32 *fids = priv->fids;
...@@ -1444,19 +1450,23 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { ...@@ -1444,19 +1450,23 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
/* Find a vacant FID */ /* Find a vacant FID */
for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ ); for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );
for( j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++ );
if ( i == MAX_FIDS ) { if ( j >= MAX_FIDS ) {
priv->stats.tx_fifo_errors++; netif_stop_queue(dev);
dev_kfree_skb(skb);
} else { if (i == MAX_FIDS) {
/* check min length*/ priv->stats.tx_fifo_errors++;
len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; return 1;
/* Mark fid as used & save length for later */ }
fids[i] |= (len << 16);
priv->xmit11.skb = skb;
priv->xmit11.fid = i;
airo_do_xmit11(dev);
} }
/* check min length*/
len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
/* Mark fid as used & save length for later */
fids[i] |= (len << 16);
priv->xmit11.skb = skb;
priv->xmit11.fid = i;
airo_do_xmit11(dev);
return 0; return 0;
} }
...@@ -1593,6 +1603,8 @@ void stop_airo_card( struct net_device *dev, int freeres ) ...@@ -1593,6 +1603,8 @@ void stop_airo_card( struct net_device *dev, int freeres )
{ {
struct airo_info *ai = dev->priv; struct airo_info *ai = dev->priv;
flush_scheduled_work(); flush_scheduled_work();
disable_interrupts(ai);
free_irq( dev->irq, dev );
if (ai->flash) if (ai->flash)
kfree(ai->flash); kfree(ai->flash);
if (ai->rssi) if (ai->rssi)
...@@ -1607,8 +1619,6 @@ void stop_airo_card( struct net_device *dev, int freeres ) ...@@ -1607,8 +1619,6 @@ void stop_airo_card( struct net_device *dev, int freeres )
} }
ai->registered = 0; ai->registered = 0;
} }
disable_interrupts(ai);
free_irq( dev->irq, dev );
if (auto_wep) del_timer_sync(&ai->timer); if (auto_wep) del_timer_sync(&ai->timer);
if (freeres) { if (freeres) {
/* PCMCIA frees this stuff, so only for PCI and ISA */ /* PCMCIA frees this stuff, so only for PCI and ISA */
...@@ -2188,7 +2198,13 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) ...@@ -2188,7 +2198,13 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC)); OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
/* Set up to be used again */ /* Set up to be used again */
apriv->fids[index] &= 0xffff; apriv->fids[index] &= 0xffff;
netif_wake_queue(dev); if (index < MAX_FIDS / 2) {
if (!(apriv->flags & FLAG_PENDING_XMIT))
netif_wake_queue(dev);
} else {
if (!(apriv->flags & FLAG_PENDING_XMIT11))
netif_wake_queue(apriv->wifidev);
}
} else { } else {
OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC)); OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" ); printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" );
...@@ -2710,6 +2726,7 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid, ...@@ -2710,6 +2726,7 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid,
one for now. */ one for now. */
static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw) static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
{ {
unsigned int loop = 3000;
Cmd cmd; Cmd cmd;
Resp rsp; Resp rsp;
u16 txFid; u16 txFid;
...@@ -2730,7 +2747,12 @@ static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw) ...@@ -2730,7 +2747,12 @@ static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
/* wait for the allocate event/indication /* wait for the allocate event/indication
* It makes me kind of nervous that this can just sit here and spin, * It makes me kind of nervous that this can just sit here and spin,
* but in practice it only loops like four times. */ * but in practice it only loops like four times. */
while ( (IN4500(ai, EVSTAT) & EV_ALLOC) == 0) ; while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
if (!loop) {
txFid = ERROR;
goto done;
}
// get the allocated fid and acknowledge // get the allocated fid and acknowledge
txFid = IN4500(ai, TXALLOCFID); txFid = IN4500(ai, TXALLOCFID);
OUT4500(ai, EVACK, EV_ALLOC); OUT4500(ai, EVACK, EV_ALLOC);
...@@ -3288,15 +3310,18 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) { ...@@ -3288,15 +3310,18 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
ai->config.rmode &= 0xfe00; ai->config.rmode &= 0xfe00;
ai->flags &= ~FLAG_802_11; ai->flags &= ~FLAG_802_11;
ai->config.opmode &= 0xFF00; ai->config.opmode &= 0xFF00;
ai->config.scanMode = SCANMODE_ACTIVE;
if ( line[0] == 'a' ) { if ( line[0] == 'a' ) {
ai->config.opmode |= 0; ai->config.opmode |= 0;
} else { } else {
ai->config.opmode |= 1; ai->config.opmode |= 1;
if ( line[0] == 'r' ) { if ( line[0] == 'r' ) {
ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER; ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
ai->config.scanMode = SCANMODE_PASSIVE;
ai->flags |= FLAG_802_11; ai->flags |= FLAG_802_11;
} else if ( line[0] == 'y' ) { } else if ( line[0] == 'y' ) {
ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER; ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
ai->config.scanMode = SCANMODE_PASSIVE;
ai->flags |= FLAG_802_11; ai->flags |= FLAG_802_11;
} else if ( line[0] == 'l' ) } else if ( line[0] == 'l' )
ai->config.rmode |= RXMODE_LANMON; ai->config.rmode |= RXMODE_LANMON;
...@@ -4571,24 +4596,28 @@ static int airo_set_mode(struct net_device *dev, ...@@ -4571,24 +4596,28 @@ static int airo_set_mode(struct net_device *dev,
local->config.opmode &= 0xFF00; local->config.opmode &= 0xFF00;
local->config.opmode |= MODE_STA_IBSS; local->config.opmode |= MODE_STA_IBSS;
local->config.rmode &= 0xfe00; local->config.rmode &= 0xfe00;
local->config.scanMode = SCANMODE_ACTIVE;
local->flags &= ~FLAG_802_11; local->flags &= ~FLAG_802_11;
break; break;
case IW_MODE_INFRA: case IW_MODE_INFRA:
local->config.opmode &= 0xFF00; local->config.opmode &= 0xFF00;
local->config.opmode |= MODE_STA_ESS; local->config.opmode |= MODE_STA_ESS;
local->config.rmode &= 0xfe00; local->config.rmode &= 0xfe00;
local->config.scanMode = SCANMODE_ACTIVE;
local->flags &= ~FLAG_802_11; local->flags &= ~FLAG_802_11;
break; break;
case IW_MODE_MASTER: case IW_MODE_MASTER:
local->config.opmode &= 0xFF00; local->config.opmode &= 0xFF00;
local->config.opmode |= MODE_AP; local->config.opmode |= MODE_AP;
local->config.rmode &= 0xfe00; local->config.rmode &= 0xfe00;
local->config.scanMode = SCANMODE_ACTIVE;
local->flags &= ~FLAG_802_11; local->flags &= ~FLAG_802_11;
break; break;
case IW_MODE_REPEAT: case IW_MODE_REPEAT:
local->config.opmode &= 0xFF00; local->config.opmode &= 0xFF00;
local->config.opmode |= MODE_AP_RPTR; local->config.opmode |= MODE_AP_RPTR;
local->config.rmode &= 0xfe00; local->config.rmode &= 0xfe00;
local->config.scanMode = SCANMODE_ACTIVE;
local->flags &= ~FLAG_802_11; local->flags &= ~FLAG_802_11;
break; break;
case IW_MODE_MONITOR: case IW_MODE_MONITOR:
...@@ -4596,6 +4625,7 @@ static int airo_set_mode(struct net_device *dev, ...@@ -4596,6 +4625,7 @@ static int airo_set_mode(struct net_device *dev,
local->config.opmode |= MODE_STA_ESS; local->config.opmode |= MODE_STA_ESS;
local->config.rmode &= 0xfe00; local->config.rmode &= 0xfe00;
local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER; local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
local->config.scanMode = SCANMODE_PASSIVE;
local->flags |= FLAG_802_11; local->flags |= FLAG_802_11;
break; break;
default: default:
...@@ -5952,7 +5982,6 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -5952,7 +5982,6 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
* *
* TODO : * TODO :
* o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs) * o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
* o Find the noise level
* *
* Jean * Jean
*/ */
...@@ -5976,8 +6005,13 @@ struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) ...@@ -5976,8 +6005,13 @@ struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm; local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm;
else else
local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2; local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
local->wstats.qual.noise = 0; if (status_rid.len >= 124) {
local->wstats.qual.updated = 3; local->wstats.qual.noise = 256 - status_rid.noisedBm;
local->wstats.qual.updated = 7;
} else {
local->wstats.qual.noise = 0;
local->wstats.qual.updated = 3;
}
/* Packets discarded in the wireless adapter due to wireless /* Packets discarded in the wireless adapter due to wireless
* specific problems */ * specific problems */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment