Commit 13f4b95d authored by Jean Tourrilhes's avatar Jean Tourrilhes Committed by Jeff Garzik

This add spinlock protection to the Netwave wireless driver and gets

rid of save_flags();cli();. I was pleasantly surprised that the driver
was working fine on my SMP system with those obvious fixes. Tested on
2.5.32 SMP.
parent 22ef997f
...@@ -324,6 +324,7 @@ struct site_survey { ...@@ -324,6 +324,7 @@ struct site_survey {
typedef struct netwave_private { typedef struct netwave_private {
dev_link_t link; dev_link_t link;
struct net_device dev; struct net_device dev;
spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
dev_node_t node; dev_node_t node;
u_char *ramBase; u_char *ramBase;
int timeoutCounter; int timeoutCounter;
...@@ -415,8 +416,7 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev) ...@@ -415,8 +416,7 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
wstats = &priv->iw_stats; wstats = &priv->iw_stats;
save_flags(flags); spin_lock_irqsave(&priv->spinlock, flags);
cli();
netwave_snapshot( priv, ramBase, iobase); netwave_snapshot( priv, ramBase, iobase);
...@@ -428,7 +428,7 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev) ...@@ -428,7 +428,7 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
wstats->discard.code = 0L; wstats->discard.code = 0L;
wstats->discard.misc = 0L; wstats->discard.misc = 0L;
restore_flags(flags); spin_unlock_irqrestore(&priv->spinlock, flags);
return &priv->iw_stats; return &priv->iw_stats;
} }
...@@ -491,6 +491,10 @@ static dev_link_t *netwave_attach(void) ...@@ -491,6 +491,10 @@ static dev_link_t *netwave_attach(void)
link->conf.ConfigIndex = 1; link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
/* Netwave private struct init. link/dev/node already taken care of,
* other stuff zero'd - Jean II */
spin_lock_init(&priv->spinlock);
/* Netwave specific entries in the device structure */ /* Netwave specific entries in the device structure */
dev->hard_start_xmit = &netwave_start_xmit; dev->hard_start_xmit = &netwave_start_xmit;
dev->set_config = &netwave_config; dev->set_config = &netwave_config;
...@@ -640,8 +644,7 @@ static int netwave_set_nwid(struct net_device *dev, ...@@ -640,8 +644,7 @@ static int netwave_set_nwid(struct net_device *dev,
u_char *ramBase = priv->ramBase; u_char *ramBase = priv->ramBase;
/* Disable interrupts & save flags */ /* Disable interrupts & save flags */
save_flags(flags); spin_lock_irqsave(&priv->spinlock, flags);
cli();
#if WIRELESS_EXT > 8 #if WIRELESS_EXT > 8
if(!wrqu->nwid.disabled) { if(!wrqu->nwid.disabled) {
...@@ -660,7 +663,7 @@ static int netwave_set_nwid(struct net_device *dev, ...@@ -660,7 +663,7 @@ static int netwave_set_nwid(struct net_device *dev,
} }
/* ReEnable interrupts & restore flags */ /* ReEnable interrupts & restore flags */
restore_flags(flags); spin_unlock_irqrestore(&priv->spinlock, flags);
return 0; return 0;
} }
...@@ -699,8 +702,7 @@ static int netwave_set_scramble(struct net_device *dev, ...@@ -699,8 +702,7 @@ static int netwave_set_scramble(struct net_device *dev,
u_char *ramBase = priv->ramBase; u_char *ramBase = priv->ramBase;
/* Disable interrupts & save flags */ /* Disable interrupts & save flags */
save_flags(flags); spin_lock_irqsave(&priv->spinlock, flags);
cli();
scramble_key = (key[0] << 8) | key[1]; scramble_key = (key[0] << 8) | key[1];
wait_WOC(iobase); wait_WOC(iobase);
...@@ -710,7 +712,7 @@ static int netwave_set_scramble(struct net_device *dev, ...@@ -710,7 +712,7 @@ static int netwave_set_scramble(struct net_device *dev,
writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3); writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
/* ReEnable interrupts & restore flags */ /* ReEnable interrupts & restore flags */
restore_flags(flags); spin_unlock_irqrestore(&priv->spinlock, flags);
return 0; return 0;
} }
...@@ -816,8 +818,7 @@ static int netwave_get_snap(struct net_device *dev, ...@@ -816,8 +818,7 @@ static int netwave_get_snap(struct net_device *dev,
u_char *ramBase = priv->ramBase; u_char *ramBase = priv->ramBase;
/* Disable interrupts & save flags */ /* Disable interrupts & save flags */
save_flags(flags); spin_lock_irqsave(&priv->spinlock, flags);
cli();
/* Take snapshot of environment */ /* Take snapshot of environment */
netwave_snapshot( priv, ramBase, iobase); netwave_snapshot( priv, ramBase, iobase);
...@@ -827,7 +828,7 @@ static int netwave_get_snap(struct net_device *dev, ...@@ -827,7 +828,7 @@ static int netwave_get_snap(struct net_device *dev,
priv->lastExec = jiffies; priv->lastExec = jiffies;
/* ReEnable interrupts & restore flags */ /* ReEnable interrupts & restore flags */
restore_flags(flags); spin_unlock_irqrestore(&priv->spinlock, flags);
return(0); return(0);
} }
...@@ -1376,8 +1377,7 @@ static int netwave_hw_xmit(unsigned char* data, int len, ...@@ -1376,8 +1377,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
ioaddr_t iobase = dev->base_addr; ioaddr_t iobase = dev->base_addr;
/* Disable interrupts & save flags */ /* Disable interrupts & save flags */
save_flags(flags); spin_lock_irqsave(&priv->spinlock, flags);
cli();
/* Check if there are transmit buffers available */ /* Check if there are transmit buffers available */
wait_WOC(iobase); wait_WOC(iobase);
...@@ -1385,7 +1385,7 @@ static int netwave_hw_xmit(unsigned char* data, int len, ...@@ -1385,7 +1385,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
/* No buffers available */ /* No buffers available */
printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n", printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n",
dev->name); dev->name);
restore_flags(flags); spin_unlock_irqrestore(&priv->spinlock, flags);
return 1; return 1;
} }
...@@ -1426,7 +1426,7 @@ static int netwave_hw_xmit(unsigned char* data, int len, ...@@ -1426,7 +1426,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2); writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3); writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
restore_flags( flags); spin_unlock_irqrestore(&priv->spinlock, flags);
return 0; return 0;
} }
...@@ -1618,16 +1618,15 @@ static struct net_device_stats *netwave_get_stats(struct net_device *dev) { ...@@ -1618,16 +1618,15 @@ static struct net_device_stats *netwave_get_stats(struct net_device *dev) {
} }
static void update_stats(struct net_device *dev) { static void update_stats(struct net_device *dev) {
unsigned long flags; //unsigned long flags;
/* netwave_private *priv = (netwave_private*) dev->priv; */
save_flags(flags); //spin_lock_irqsave(&priv->spinlock, flags);
cli();
/* netwave_private *priv = (netwave_private*) dev->priv; /* priv->stats.rx_packets = readb(priv->ramBase + 0x18e);
priv->stats.rx_packets = readb(priv->ramBase + 0x18e);
priv->stats.tx_packets = readb(priv->ramBase + 0x18f); */ priv->stats.tx_packets = readb(priv->ramBase + 0x18f); */
restore_flags(flags); //spin_unlock_irqrestore(&priv->spinlock, flags);
} }
static int netwave_rx(struct net_device *dev) { static int netwave_rx(struct net_device *dev) {
......
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