mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 07:22:33 +00:00
eb68c90f82
SVN-Revision: 16485
242 lines
6.9 KiB
Diff
242 lines
6.9 KiB
Diff
--- a/drivers/net/r6040.c
|
|
+++ b/drivers/net/r6040.c
|
|
@@ -49,12 +49,12 @@
|
|
#include <asm/processor.h>
|
|
|
|
#define DRV_NAME "r6040"
|
|
-#define DRV_VERSION "0.19"
|
|
-#define DRV_RELDATE "18Dec2008"
|
|
+#define DRV_VERSION "0.22"
|
|
+#define DRV_RELDATE "25Mar2009"
|
|
|
|
/* PHY CHIP Address */
|
|
#define PHY1_ADDR 1 /* For MAC1 */
|
|
-#define PHY2_ADDR 2 /* For MAC2 */
|
|
+#define PHY2_ADDR 3 /* For MAC2 */
|
|
#define PHY_MODE 0x3100 /* PHY CHIP Register 0 */
|
|
#define PHY_CAP 0x01E1 /* PHY CHIP Register 4 */
|
|
|
|
@@ -160,6 +160,7 @@ MODULE_AUTHOR("Sten Wang <sten.wang@rdc.
|
|
"Florian Fainelli <florian@openwrt.org>");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver");
|
|
+MODULE_VERSION(DRV_VERSION " " DRV_RELDATE);
|
|
|
|
/* RX and TX interrupts that we handle */
|
|
#define RX_INTS (RX_FIFO_FULL | RX_NO_DESC | RX_FINISH)
|
|
@@ -200,7 +201,7 @@ struct r6040_private {
|
|
|
|
static char version[] __devinitdata = KERN_INFO DRV_NAME
|
|
": RDC R6040 NAPI net driver,"
|
|
- "version "DRV_VERSION " (" DRV_RELDATE ")\n";
|
|
+ "version "DRV_VERSION " (" DRV_RELDATE ")";
|
|
|
|
static int phy_table[] = { PHY1_ADDR, PHY2_ADDR };
|
|
|
|
@@ -330,7 +331,7 @@ static int r6040_alloc_rxbufs(struct net
|
|
do {
|
|
skb = netdev_alloc_skb(dev, MAX_BUF_SIZE);
|
|
if (!skb) {
|
|
- printk(KERN_ERR "%s: failed to alloc skb for rx\n", dev->name);
|
|
+ printk(KERN_ERR DRV_NAME "%s: failed to alloc skb for rx\n", dev->name);
|
|
rc = -ENOMEM;
|
|
goto err_exit;
|
|
}
|
|
@@ -438,7 +439,6 @@ static void r6040_down(struct net_device
|
|
{
|
|
struct r6040_private *lp = netdev_priv(dev);
|
|
void __iomem *ioaddr = lp->base;
|
|
- struct pci_dev *pdev = lp->pdev;
|
|
int limit = 2048;
|
|
u16 *adrp;
|
|
u16 cmd;
|
|
@@ -457,22 +457,12 @@ static void r6040_down(struct net_device
|
|
iowrite16(adrp[0], ioaddr + MID_0L);
|
|
iowrite16(adrp[1], ioaddr + MID_0M);
|
|
iowrite16(adrp[2], ioaddr + MID_0H);
|
|
- free_irq(dev->irq, dev);
|
|
-
|
|
- /* Free RX buffer */
|
|
- r6040_free_rxbufs(dev);
|
|
-
|
|
- /* Free TX buffer */
|
|
- r6040_free_txbufs(dev);
|
|
-
|
|
- /* Free Descriptor memory */
|
|
- pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
|
|
- pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
|
|
}
|
|
|
|
static int r6040_close(struct net_device *dev)
|
|
{
|
|
struct r6040_private *lp = netdev_priv(dev);
|
|
+ struct pci_dev *pdev = lp->pdev;
|
|
|
|
/* deleted timer */
|
|
del_timer_sync(&lp->timer);
|
|
@@ -481,8 +471,28 @@ static int r6040_close(struct net_device
|
|
napi_disable(&lp->napi);
|
|
netif_stop_queue(dev);
|
|
r6040_down(dev);
|
|
+
|
|
+ free_irq(dev->irq, dev);
|
|
+
|
|
+ /* Free RX buffer */
|
|
+ r6040_free_rxbufs(dev);
|
|
+
|
|
+ /* Free TX buffer */
|
|
+ r6040_free_txbufs(dev);
|
|
+
|
|
spin_unlock_irq(&lp->lock);
|
|
|
|
+ /* Free Descriptor memory */
|
|
+ if (lp->rx_ring) {
|
|
+ pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
|
|
+ lp->rx_ring = NULL;
|
|
+ }
|
|
+
|
|
+ if (lp->tx_ring) {
|
|
+ pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
|
|
+ lp->tx_ring = NULL;
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -598,7 +608,6 @@ static int r6040_rx(struct net_device *d
|
|
|
|
/* Send to upper layer */
|
|
netif_receive_skb(skb_ptr);
|
|
- dev->last_rx = jiffies;
|
|
dev->stats.rx_packets++;
|
|
dev->stats.rx_bytes += descptr->len - 4;
|
|
|
|
@@ -668,7 +677,7 @@ static int r6040_poll(struct napi_struct
|
|
work_done = r6040_rx(dev, budget);
|
|
|
|
if (work_done < budget) {
|
|
- netif_rx_complete(dev, napi);
|
|
+ napi_complete(napi);
|
|
/* Enable RX interrupt */
|
|
iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER);
|
|
}
|
|
@@ -705,7 +714,7 @@ static irqreturn_t r6040_interrupt(int i
|
|
|
|
/* Mask off RX interrupt */
|
|
misr &= ~RX_INTS;
|
|
- netif_rx_schedule(dev, &lp->napi);
|
|
+ napi_schedule(&lp->napi);
|
|
}
|
|
|
|
/* TX interrupt request */
|
|
@@ -1063,20 +1072,20 @@ static int __devinit r6040_init_one(stru
|
|
/* this should always be supported */
|
|
err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
|
|
if (err) {
|
|
- printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses"
|
|
+ printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses"
|
|
"not supported by the card\n");
|
|
goto err_out;
|
|
}
|
|
err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
|
|
if (err) {
|
|
- printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses"
|
|
+ printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses"
|
|
"not supported by the card\n");
|
|
goto err_out;
|
|
}
|
|
|
|
/* IO Size check */
|
|
if (pci_resource_len(pdev, 0) < io_size) {
|
|
- printk(KERN_ERR DRV_NAME "Insufficient PCI resources, aborting\n");
|
|
+ printk(KERN_ERR DRV_NAME ": Insufficient PCI resources, aborting\n");
|
|
err = -EIO;
|
|
goto err_out;
|
|
}
|
|
@@ -1086,7 +1095,7 @@ static int __devinit r6040_init_one(stru
|
|
|
|
dev = alloc_etherdev(sizeof(struct r6040_private));
|
|
if (!dev) {
|
|
- printk(KERN_ERR DRV_NAME "Failed to allocate etherdev\n");
|
|
+ printk(KERN_ERR DRV_NAME ": Failed to allocate etherdev\n");
|
|
err = -ENOMEM;
|
|
goto err_out;
|
|
}
|
|
@@ -1102,11 +1111,15 @@ static int __devinit r6040_init_one(stru
|
|
|
|
ioaddr = pci_iomap(pdev, bar, io_size);
|
|
if (!ioaddr) {
|
|
- printk(KERN_ERR "ioremap failed for device %s\n",
|
|
+ printk(KERN_ERR DRV_NAME ": ioremap failed for device %s\n",
|
|
pci_name(pdev));
|
|
err = -EIO;
|
|
goto err_out_free_res;
|
|
}
|
|
+ /* If PHY status change register is still set to zero it means the
|
|
+ * bootloader didn't initialize it */
|
|
+ if (ioread16(ioaddr + PHY_CC) == 0)
|
|
+ iowrite16(0x9f07, ioaddr + PHY_CC);
|
|
|
|
/* Init system & device */
|
|
lp->base = ioaddr;
|
|
@@ -1123,6 +1136,13 @@ static int __devinit r6040_init_one(stru
|
|
adrp[1] = ioread16(ioaddr + MID_0M);
|
|
adrp[2] = ioread16(ioaddr + MID_0H);
|
|
|
|
+ /* Some bootloader/BIOSes do not initialize
|
|
+ * MAC address, warn about that */
|
|
+ if (!(adrp[0] || adrp[1] || adrp[2])) {
|
|
+ printk(KERN_WARNING DRV_NAME ": MAC address not initialized, generating random\n");
|
|
+ random_ether_addr(dev->dev_addr);
|
|
+ }
|
|
+
|
|
/* Link new device into r6040_root_dev */
|
|
lp->pdev = pdev;
|
|
lp->dev = dev;
|
|
--- a/drivers/net/r6040.c
|
|
+++ b/drivers/net/r6040.c
|
|
@@ -742,6 +742,14 @@ static int r6040_up(struct net_device *d
|
|
struct r6040_private *lp = netdev_priv(dev);
|
|
void __iomem *ioaddr = lp->base;
|
|
int ret;
|
|
+ u16 val;
|
|
+
|
|
+ /* Check presence of a second PHY */
|
|
+ val = r6040_phy_read(ioaddr, lp->phy_addr, 2);
|
|
+ if (val == 0xFFFF) {
|
|
+ printk(KERN_ERR DRV_NAME " no second PHY attached\n");
|
|
+ return -EIO;
|
|
+ }
|
|
|
|
/* Initialise and alloc RX/TX buffers */
|
|
r6040_init_txbufs(dev);
|
|
--- a/drivers/net/r6040.c
|
|
+++ b/drivers/net/r6040.c
|
|
@@ -401,6 +401,9 @@ static void r6040_init_mac_regs(struct n
|
|
* we may got called by r6040_tx_timeout which has left
|
|
* some unsent tx buffers */
|
|
iowrite16(0x01, ioaddr + MTPR);
|
|
+
|
|
+ /* Check media */
|
|
+ mii_check_media(&lp->mii_if, 1, 1);
|
|
}
|
|
|
|
static void r6040_tx_timeout(struct net_device *dev)
|
|
@@ -528,6 +531,8 @@ static int r6040_phy_mode_chk(struct net
|
|
phy_dat = 0x0000;
|
|
}
|
|
|
|
+ mii_check_media(&lp->mii_if, 0, 1);
|
|
+
|
|
return phy_dat;
|
|
};
|
|
|
|
@@ -810,7 +815,6 @@ static void r6040_timer(unsigned long da
|
|
lp->phy_mode = phy_mode;
|
|
lp->mcr0 = (lp->mcr0 & 0x7fff) | phy_mode;
|
|
iowrite16(lp->mcr0, ioaddr);
|
|
- printk(KERN_INFO "Link Change %x \n", ioread16(ioaddr));
|
|
}
|
|
|
|
/* Timer active again */
|