projects
/
powerpc.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
[PPP]: handle misaligned accesses
[powerpc.git]
/
drivers
/
net
/
smc91x.c
diff --git
a/drivers/net/smc91x.c
b/drivers/net/smc91x.c
index
fd80048
..
74d5f1a
100644
(file)
--- a/
drivers/net/smc91x.c
+++ b/
drivers/net/smc91x.c
@@
-77,7
+77,7
@@
static const char version[] =
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/crc32.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/crc32.h>
-#include <linux/device.h>
+#include <linux/
platform_
device.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
@@
-315,15
+315,25
@@
static void smc_reset(struct net_device *dev)
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
unsigned int ctl, cfg;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
unsigned int ctl, cfg;
+ struct sk_buff *pending_skb;
DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
- /* Disable all interrupts */
+ /* Disable all interrupts
, block TX tasklet
*/
spin_lock(&lp->lock);
SMC_SELECT_BANK(2);
SMC_SET_INT_MASK(0);
spin_lock(&lp->lock);
SMC_SELECT_BANK(2);
SMC_SET_INT_MASK(0);
+ pending_skb = lp->pending_tx_skb;
+ lp->pending_tx_skb = NULL;
spin_unlock(&lp->lock);
spin_unlock(&lp->lock);
+ /* free any pending tx skb */
+ if (pending_skb) {
+ dev_kfree_skb(pending_skb);
+ lp->stats.tx_errors++;
+ lp->stats.tx_aborted_errors++;
+ }
+
/*
* This resets the registers mostly to defaults, but doesn't
* affect EEPROM. That seems unnecessary
/*
* This resets the registers mostly to defaults, but doesn't
* affect EEPROM. That seems unnecessary
@@
-389,14
+399,6
@@
static void smc_reset(struct net_device *dev)
SMC_SELECT_BANK(2);
SMC_SET_MMU_CMD(MC_RESET);
SMC_WAIT_MMU_BUSY();
SMC_SELECT_BANK(2);
SMC_SET_MMU_CMD(MC_RESET);
SMC_WAIT_MMU_BUSY();
-
- /* clear anything saved */
- if (lp->pending_tx_skb != NULL) {
- dev_kfree_skb (lp->pending_tx_skb);
- lp->pending_tx_skb = NULL;
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
- }
}
/*
}
/*
@@
-440,6
+442,7
@@
static void smc_shutdown(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
{
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
+ struct sk_buff *pending_skb;
DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
@@
-447,7
+450,11
@@
static void smc_shutdown(struct net_device *dev)
spin_lock(&lp->lock);
SMC_SELECT_BANK(2);
SMC_SET_INT_MASK(0);
spin_lock(&lp->lock);
SMC_SELECT_BANK(2);
SMC_SET_INT_MASK(0);
+ pending_skb = lp->pending_tx_skb;
+ lp->pending_tx_skb = NULL;
spin_unlock(&lp->lock);
spin_unlock(&lp->lock);
+ if (pending_skb)
+ dev_kfree_skb(pending_skb);
/* and tell the card to stay away from that nasty outside world */
SMC_SELECT_BANK(0);
/* and tell the card to stay away from that nasty outside world */
SMC_SELECT_BANK(0);
@@
-627,7
+634,12
@@
static void smc_hardware_send_pkt(unsigned long data)
}
skb = lp->pending_tx_skb;
}
skb = lp->pending_tx_skb;
+ if (unlikely(!skb)) {
+ smc_special_unlock(&lp->lock);
+ return;
+ }
lp->pending_tx_skb = NULL;
lp->pending_tx_skb = NULL;
+
packet_no = SMC_GET_AR();
if (unlikely(packet_no & AR_FAILED)) {
printk("%s: Memory allocation failed.\n", dev->name);
packet_no = SMC_GET_AR();
if (unlikely(packet_no & AR_FAILED)) {
printk("%s: Memory allocation failed.\n", dev->name);
@@
-702,7
+714,6
@@
static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
BUG_ON(lp->pending_tx_skb != NULL);
DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
BUG_ON(lp->pending_tx_skb != NULL);
- lp->pending_tx_skb = skb;
/*
* The MMU wants the number of pages to be the number of 256 bytes
/*
* The MMU wants the number of pages to be the number of 256 bytes
@@
-718,7
+729,6
@@
static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
numPages = ((skb->len & ~1) + (6 - 1)) >> 8;
if (unlikely(numPages > 7)) {
printk("%s: Far too big packet error.\n", dev->name);
numPages = ((skb->len & ~1) + (6 - 1)) >> 8;
if (unlikely(numPages > 7)) {
printk("%s: Far too big packet error.\n", dev->name);
- lp->pending_tx_skb = NULL;
lp->stats.tx_errors++;
lp->stats.tx_dropped++;
dev_kfree_skb(skb);
lp->stats.tx_errors++;
lp->stats.tx_dropped++;
dev_kfree_skb(skb);
@@
-745,6
+755,7
@@
static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
smc_special_unlock(&lp->lock);
smc_special_unlock(&lp->lock);
+ lp->pending_tx_skb = skb;
if (!poll_count) {
/* oh well, wait until the chip finds memory later */
netif_stop_queue(dev);
if (!poll_count) {
/* oh well, wait until the chip finds memory later */
netif_stop_queue(dev);
@@
-1062,7
+1073,7
@@
static void smc_phy_powerdown(struct net_device *dev)
above). linkwatch_event() also wants the netlink semaphore.
*/
while(lp->work_pending)
above). linkwatch_event() also wants the netlink semaphore.
*/
while(lp->work_pending)
-
schedule
();
+
yield
();
bmcr = smc_phy_read(dev, phy, MII_BMCR);
smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN);
bmcr = smc_phy_read(dev, phy, MII_BMCR);
smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN);
@@
-1606,14
+1617,8
@@
static int smc_close(struct net_device *dev)
/* clear everything */
smc_shutdown(dev);
/* clear everything */
smc_shutdown(dev);
-
+ tasklet_kill(&lp->tx_task);
smc_phy_powerdown(dev);
smc_phy_powerdown(dev);
-
- if (lp->pending_tx_skb) {
- dev_kfree_skb(lp->pending_tx_skb);
- lp->pending_tx_skb = NULL;
- }
-
return 0;
}
return 0;
}
@@
-1978,6
+1983,10
@@
static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
if (lp->version >= (CHIP_91100 << 4))
smc_phy_detect(dev);
if (lp->version >= (CHIP_91100 << 4))
smc_phy_detect(dev);
+ /* then shut everything down to save power */
+ smc_shutdown(dev);
+ smc_phy_powerdown(dev);
+
/* Set default parameters */
lp->msg_enable = NETIF_MSG_LINK;
lp->ctl_rfduplx = 0;
/* Set default parameters */
lp->msg_enable = NETIF_MSG_LINK;
lp->ctl_rfduplx = 0;
@@
-1993,7
+2002,7
@@
static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
if (retval)
goto err_out;
if (retval)
goto err_out;
- set_irq_type(dev->irq,
IRQT_RISING
);
+ set_irq_type(dev->irq,
SMC_IRQ_TRIGGER_TYPE
);
#ifdef SMC_USE_PXA_DMA
{
#ifdef SMC_USE_PXA_DMA
{
@@
-2286,11
+2295,11
@@
static int smc_drv_remove(struct device *dev)
return 0;
}
return 0;
}
-static int smc_drv_suspend(struct device *dev, pm_message_t state
, u32 level
)
+static int smc_drv_suspend(struct device *dev, pm_message_t state)
{
struct net_device *ndev = dev_get_drvdata(dev);
{
struct net_device *ndev = dev_get_drvdata(dev);
- if (ndev
&& level == SUSPEND_DISABLE
) {
+ if (ndev) {
if (netif_running(ndev)) {
netif_device_detach(ndev);
smc_shutdown(ndev);
if (netif_running(ndev)) {
netif_device_detach(ndev);
smc_shutdown(ndev);
@@
-2300,12
+2309,12
@@
static int smc_drv_suspend(struct device *dev, pm_message_t state, u32 level)
return 0;
}
return 0;
}
-static int smc_drv_resume(struct device *dev
, u32 level
)
+static int smc_drv_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = dev_get_drvdata(dev);
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = dev_get_drvdata(dev);
- if (ndev
&& level == RESUME_ENABLE
) {
+ if (ndev) {
struct smc_local *lp = netdev_priv(ndev);
smc_enable_device(pdev);
if (netif_running(ndev)) {
struct smc_local *lp = netdev_priv(ndev);
smc_enable_device(pdev);
if (netif_running(ndev)) {