patch-2.4.18 linux/drivers/net/winbond-840.c
Next file: linux/drivers/net/wireless/airo.c
Previous file: linux/drivers/net/wavelan.c
Back to the patch index
Back to the overall index
- Lines: 226
- Date:
Wed Feb 13 16:40:58 2002
- Orig file:
linux.orig/drivers/net/winbond-840.c
- Orig date:
Mon Feb 18 20:18:39 2002
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/winbond-840.c linux/drivers/net/winbond-840.c
@@ -36,6 +36,8 @@
power management.
support for big endian descriptors
Copyright (C) 2001 Manfred Spraul
+ * ethtool support (jgarzik)
+ * Replace some MII-related magic numbers with constants (jgarzik)
TODO:
* enable pci_power_off
@@ -43,8 +45,8 @@
*/
#define DRV_NAME "winbond-840"
-#define DRV_VERSION "1.01-c"
-#define DRV_RELDATE "6/30/2000"
+#define DRV_VERSION "1.01-d"
+#define DRV_RELDATE "Nov-17-2001"
/* Automatically extracted configuration info:
@@ -344,7 +346,7 @@
struct w840_rx_desc *rx_ring;
dma_addr_t rx_addr[RX_RING_SIZE];
struct w840_tx_desc *tx_ring;
- dma_addr_t tx_addr[RX_RING_SIZE];
+ dma_addr_t tx_addr[TX_RING_SIZE];
dma_addr_t ring_dma_addr;
/* The addresses of receive-in-place skbuffs. */
struct sk_buff* rx_skbuff[RX_RING_SIZE];
@@ -363,14 +365,11 @@
unsigned int cur_tx, dirty_tx;
unsigned int tx_q_bytes;
unsigned int tx_full; /* The Tx queue is full. */
- /* These values are keep track of the transceiver/media in use. */
- unsigned int full_duplex:1; /* Full-duplex operation requested. */
- unsigned int duplex_lock:1;
/* MII transceiver section. */
int mii_cnt; /* MII device addresses. */
- u16 advertising; /* NWay media advertisement */
unsigned char phys[MII_CNT]; /* MII device addresses, but only the first is used */
u32 mii;
+ struct mii_if_info mii_if;
};
static int eeprom_read(long ioaddr, int location);
@@ -453,6 +452,9 @@
np->chip_id = chip_idx;
np->drv_flags = pci_id_tbl[chip_idx].drv_flags;
spin_lock_init(&np->lock);
+ np->mii_if.dev = dev;
+ np->mii_if.mdio_read = mdio_read;
+ np->mii_if.mdio_write = mdio_write;
pci_set_drvdata(pdev, dev);
@@ -462,16 +464,16 @@
/* The lower four bits are the media type. */
if (option > 0) {
if (option & 0x200)
- np->full_duplex = 1;
+ np->mii_if.full_duplex = 1;
if (option & 15)
printk(KERN_INFO "%s: ignoring user supplied media type %d",
dev->name, option & 15);
}
if (find_cnt < MAX_UNITS && full_duplex[find_cnt] > 0)
- np->full_duplex = 1;
+ np->mii_if.full_duplex = 1;
- if (np->full_duplex)
- np->duplex_lock = 1;
+ if (np->mii_if.full_duplex)
+ np->mii_if.duplex_lock = 1;
/* The chip-specific entries in the device structure. */
dev->open = &netdev_open;
@@ -496,18 +498,19 @@
if (np->drv_flags & CanHaveMII) {
int phy, phy_idx = 0;
for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
- int mii_status = mdio_read(dev, phy, 1);
+ int mii_status = mdio_read(dev, phy, MII_BMSR);
if (mii_status != 0xffff && mii_status != 0x0000) {
np->phys[phy_idx++] = phy;
- np->advertising = mdio_read(dev, phy, 4);
- np->mii = (mdio_read(dev, phy, 2) << 16)+
- mdio_read(dev, phy, 3);
+ np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
+ np->mii = (mdio_read(dev, phy, MII_PHYSID1) << 16)+
+ mdio_read(dev, phy, MII_PHYSID2);
printk(KERN_INFO "%s: MII PHY %8.8xh found at address %d, status "
"0x%4.4x advertising %4.4x.\n",
- dev->name, np->mii, phy, mii_status, np->advertising);
+ dev->name, np->mii, phy, mii_status, np->mii_if.advertising);
}
}
np->mii_cnt = phy_idx;
+ np->mii_if.phy_id = np->phys[0];
if (phy_idx == 0) {
printk(KERN_WARNING "%s: MII PHY not found -- this device may "
"not operate correctly.\n", dev->name);
@@ -654,7 +657,7 @@
int i;
if (location == 4 && phy_id == np->phys[0])
- np->advertising = value;
+ np->mii_if.advertising = value;
if (mii_preamble_required)
mdio_sync(mdio_addr);
@@ -728,12 +731,12 @@
int duplex, fasteth, result, mii_reg;
/* BSMR */
- mii_reg = mdio_read(dev, np->phys[0], 1);
+ mii_reg = mdio_read(dev, np->phys[0], MII_BMSR);
if (mii_reg == 0xffff)
return np->csr6;
/* reread: the link status bit is sticky */
- mii_reg = mdio_read(dev, np->phys[0], 1);
+ mii_reg = mdio_read(dev, np->phys[0], MII_BMSR);
if (!(mii_reg & 0x4)) {
if (netif_carrier_ok(dev)) {
if (debug)
@@ -759,18 +762,18 @@
* Instead bit 9 and 13 of the BMCR are updated to the result
* of the negotiation..
*/
- mii_reg = mdio_read(dev, np->phys[0], 0);
- duplex = mii_reg & 0x100;
- fasteth = mii_reg & 0x2000;
+ mii_reg = mdio_read(dev, np->phys[0], MII_BMCR);
+ duplex = mii_reg & BMCR_FULLDPLX;
+ fasteth = mii_reg & BMCR_SPEED100;
} else {
int negotiated;
- mii_reg = mdio_read(dev, np->phys[0], 5);
- negotiated = mii_reg & np->advertising;
+ mii_reg = mdio_read(dev, np->phys[0], MII_LPA);
+ negotiated = mii_reg & np->mii_if.advertising;
- duplex = (negotiated & 0x0100) || ((negotiated & 0x02C0) == 0x0040);
+ duplex = (negotiated & LPA_100FULL) || ((negotiated & 0x02C0) == LPA_10FULL);
fasteth = negotiated & 0x380;
}
- duplex |= np->duplex_lock;
+ duplex |= np->mii_if.duplex_lock;
/* remove fastether and fullduplex */
result = np->csr6 & ~0x20000200;
if (duplex)
@@ -822,7 +825,7 @@
/* and restart them with the new configuration */
writel(np->csr6, ioaddr + NetworkConfig);
if (new & 0x200)
- np->full_duplex = 1;
+ np->mii_if.full_duplex = 1;
}
static void netdev_timer(unsigned long data)
@@ -1131,7 +1134,7 @@
if (tx_status & 0x0C80) np->stats.tx_carrier_errors++;
if (tx_status & 0x0200) np->stats.tx_window_errors++;
if (tx_status & 0x0002) np->stats.tx_fifo_errors++;
- if ((tx_status & 0x0080) && np->full_duplex == 0)
+ if ((tx_status & 0x0080) && np->mii_if.full_duplex == 0)
np->stats.tx_heartbeat_errors++;
#ifdef ETHER_STATS
if (tx_status & 0x0100) np->stats.collisions16++;
@@ -1484,6 +1487,56 @@
return 0;
}
+ /* get settings */
+ case ETHTOOL_GSET: {
+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ spin_lock_irq(&np->lock);
+ mii_ethtool_gset(&np->mii_if, &ecmd);
+ spin_unlock_irq(&np->lock);
+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
+ return -EFAULT;
+ return 0;
+ }
+ /* set settings */
+ case ETHTOOL_SSET: {
+ int r;
+ struct ethtool_cmd ecmd;
+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
+ return -EFAULT;
+ spin_lock_irq(&np->lock);
+ r = mii_ethtool_sset(&np->mii_if, &ecmd);
+ spin_unlock_irq(&np->lock);
+ return r;
+ }
+ /* restart autonegotiation */
+ case ETHTOOL_NWAY_RST: {
+ return mii_nway_restart(&np->mii_if);
+ }
+ /* get link status */
+ case ETHTOOL_GLINK: {
+ struct ethtool_value edata = {ETHTOOL_GLINK};
+ edata.data = mii_link_ok(&np->mii_if);
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+
+ /* get message-level */
+ case ETHTOOL_GMSGLVL: {
+ struct ethtool_value edata = {ETHTOOL_GMSGLVL};
+ edata.data = debug;
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+ /* set message-level */
+ case ETHTOOL_SMSGLVL: {
+ struct ethtool_value edata;
+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
+ return -EFAULT;
+ debug = edata.data;
+ return 0;
+ }
}
return -EOPNOTSUPP;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)