patch-2.4.18 linux/drivers/net/epic100.c
Next file: linux/drivers/net/fc/Makefile
Previous file: linux/drivers/net/eexpress.c
Back to the patch index
Back to the overall index
- Lines: 304
- Date:
Wed Feb 6 20:41:06 2002
- Orig file:
linux.orig/drivers/net/epic100.c
- Orig date:
Mon Feb 18 20:18:39 2002
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/epic100.c linux/drivers/net/epic100.c
@@ -53,11 +53,18 @@
LK1.1.10:
* revert MII transceiver init change (jgarzik)
+ LK1.1.11:
+ * implement ETHTOOL_[GS]SET, _NWAY_RST, _[GS]MSGLVL, _GLINK (jgarzik)
+ * replace some MII-related magic numbers with constants
+
+ LK1.1.12:
+ * fix power-up sequence
+
*/
#define DRV_NAME "epic100"
-#define DRV_VERSION "1.11+LK1.1.10"
-#define DRV_RELDATE "July 6, 2001"
+#define DRV_VERSION "1.11+LK1.1.12"
+#define DRV_RELDATE "Jan 18, 2002"
/* The user-configurable values.
@@ -317,12 +324,9 @@
/* Ring pointers. */
spinlock_t lock; /* Group with Tx control cache line. */
unsigned int cur_tx, dirty_tx;
- struct descriptor *last_tx_desc;
unsigned int cur_rx, dirty_rx;
unsigned int rx_buf_sz; /* Based on MTU+slack. */
- struct descriptor *last_rx_desc;
- long last_rx_time; /* Last Rx, in jiffies. */
struct pci_dev *pci_dev; /* PCI bus location. */
int chip_id, chip_flags;
@@ -334,13 +338,9 @@
signed char phys[4]; /* MII device addresses. */
u16 advertising; /* NWay media advertisement */
int mii_phy_cnt;
+ struct mii_if_info mii;
unsigned int tx_full:1; /* The Tx queue is full. */
- unsigned int full_duplex:1; /* Current duplex setting. */
- unsigned int duplex_lock:1; /* Duplex forced by the user. */
unsigned int default_port:4; /* Last dev->if_port value. */
- unsigned int media2:4; /* Secondary monitored media port. */
- unsigned int medialock:1; /* Don't sense media type. */
- unsigned int mediasense:1; /* Media sensing in progress. */
};
static int epic_open(struct net_device *dev);
@@ -419,6 +419,9 @@
pci_set_drvdata(pdev, dev);
ep = dev->priv;
+ ep->mii.dev = dev;
+ ep->mii.mdio_read = mdio_read;
+ ep->mii.mdio_write = mdio_write;
ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);
if (!ring_space)
@@ -480,7 +483,7 @@
{
int phy, phy_idx = 0;
for (phy = 1; phy < 32 && phy_idx < sizeof(ep->phys); 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) {
ep->phys[phy_idx++] = phy;
printk(KERN_INFO DRV_NAME "(%s): MII transceiver #%d control "
@@ -491,16 +494,17 @@
ep->mii_phy_cnt = phy_idx;
if (phy_idx != 0) {
phy = ep->phys[0];
- ep->advertising = mdio_read(dev, phy, 4);
+ ep->mii.advertising = mdio_read(dev, phy, MII_ADVERTISE);
printk(KERN_INFO DRV_NAME "(%s): Autonegotiation advertising %4.4x link "
"partner %4.4x.\n",
- pdev->slot_name, ep->advertising, mdio_read(dev, phy, 5));
+ pdev->slot_name, ep->mii.advertising, mdio_read(dev, phy, 5));
} else if ( ! (ep->chip_flags & NO_MII)) {
printk(KERN_WARNING DRV_NAME "(%s): ***WARNING***: No MII transceiver found!\n",
pdev->slot_name);
/* Use the known PHY address of the EPII. */
ep->phys[0] = 3;
}
+ ep->mii.phy_id = ep->phys[0];
}
/* Turn off the MII xcvr (175 only!), leave the chip in low-power mode. */
@@ -510,13 +514,11 @@
/* The lower four bits are the media type. */
if (duplex) {
- ep->duplex_lock = ep->full_duplex = 1;
+ ep->mii.duplex_lock = ep->mii.full_duplex = 1;
printk(KERN_INFO DRV_NAME "(%s): Forced full duplex operation requested.\n",
pdev->slot_name);
}
dev->if_port = ep->default_port = option;
- if (ep->default_port)
- ep->medialock = 1;
/* The Epic-specific entries in the device structure. */
dev->open = &epic_open;
@@ -675,9 +677,8 @@
required by the details of which bits are reset and the transceiver
wiring on the Ositech CardBus card.
*/
-#if 0
- outl(dev->if_port == 1 ? 0x13 : 0x12, ioaddr + MIICfg);
-#endif
+
+ outl(0x12, ioaddr + MIICfg);
if (ep->chip_flags & MII_PWRDWN)
outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
@@ -699,29 +700,29 @@
if (media2miictl[dev->if_port & 15]) {
if (ep->mii_phy_cnt)
- mdio_write(dev, ep->phys[0], 0, media2miictl[dev->if_port&15]);
+ mdio_write(dev, ep->phys[0], MII_BMCR, media2miictl[dev->if_port&15]);
if (dev->if_port == 1) {
if (debug > 1)
printk(KERN_INFO "%s: Using the 10base2 transceiver, MII "
"status %4.4x.\n",
- dev->name, mdio_read(dev, ep->phys[0], 1));
+ dev->name, mdio_read(dev, ep->phys[0], MII_BMSR));
}
} else {
- int mii_reg5 = mdio_read(dev, ep->phys[0], 5);
- if (mii_reg5 != 0xffff) {
- if ((mii_reg5 & 0x0100) || (mii_reg5 & 0x01C0) == 0x0040)
- ep->full_duplex = 1;
- else if (! (mii_reg5 & 0x4000))
- mdio_write(dev, ep->phys[0], 0, 0x1200);
+ int mii_lpa = mdio_read(dev, ep->phys[0], MII_LPA);
+ if (mii_lpa != 0xffff) {
+ if ((mii_lpa & LPA_100FULL) || (mii_lpa & 0x01C0) == LPA_10FULL)
+ ep->mii.full_duplex = 1;
+ else if (! (mii_lpa & LPA_LPACK))
+ mdio_write(dev, ep->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART);
if (debug > 1)
printk(KERN_INFO "%s: Setting %s-duplex based on MII xcvr %d"
" register read of %4.4x.\n", dev->name,
- ep->full_duplex ? "full" : "half",
- ep->phys[0], mii_reg5);
+ ep->mii.full_duplex ? "full" : "half",
+ ep->phys[0], mii_lpa);
}
}
- outl(ep->full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
+ outl(ep->mii.full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
outl(ep->rx_ring_dma, ioaddr + PRxCDAR);
outl(ep->tx_ring_dma, ioaddr + PTxCDAR);
@@ -741,7 +742,7 @@
printk(KERN_DEBUG "%s: epic_open() ioaddr %lx IRQ %d status %4.4x "
"%s-duplex.\n",
dev->name, ioaddr, dev->irq, (int)inl(ioaddr + GENCTL),
- ep->full_duplex ? "full" : "half");
+ ep->mii.full_duplex ? "full" : "half");
/* Set the timer to switch to check for link beat and perhaps switch
to an alternate media type. */
@@ -810,7 +811,7 @@
ep->tx_threshold = TX_FIFO_THRESH;
outl(ep->tx_threshold, ioaddr + TxThresh);
- outl(ep->full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
+ outl(ep->mii.full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
outl(ep->rx_ring_dma + (ep->cur_rx%RX_RING_SIZE)*
sizeof(struct epic_rx_desc), ioaddr + PRxCDAR);
outl(ep->tx_ring_dma + (ep->dirty_tx%TX_RING_SIZE)*
@@ -836,20 +837,20 @@
{
struct epic_private *ep = dev->priv;
long ioaddr = dev->base_addr;
- int mii_reg5 = ep->mii_phy_cnt ? mdio_read(dev, ep->phys[0], 5) : 0;
- int negotiated = mii_reg5 & ep->advertising;
+ int mii_lpa = ep->mii_phy_cnt ? mdio_read(dev, ep->phys[0], MII_LPA) : 0;
+ int negotiated = mii_lpa & ep->mii.advertising;
int duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
- if (ep->duplex_lock)
+ if (ep->mii.duplex_lock)
return;
- if (mii_reg5 == 0xffff) /* Bogus read */
+ if (mii_lpa == 0xffff) /* Bogus read */
return;
- if (ep->full_duplex != duplex) {
- ep->full_duplex = duplex;
+ if (ep->mii.full_duplex != duplex) {
+ ep->mii.full_duplex = duplex;
printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d link"
" partner capability of %4.4x.\n", dev->name,
- ep->full_duplex ? "full" : "half", ep->phys[0], mii_reg5);
- outl(ep->full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
+ ep->mii.full_duplex ? "full" : "half", ep->phys[0], mii_lpa);
+ outl(ep->mii.full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
}
}
@@ -913,7 +914,6 @@
ep->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
ep->dirty_tx = ep->cur_tx = 0;
ep->cur_rx = ep->dirty_rx = 0;
- ep->last_rx_time = jiffies;
ep->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
/* Initialize all Rx descriptors. */
@@ -1371,17 +1371,66 @@
return -EFAULT;
switch (ethcmd) {
- case ETHTOOL_GDRVINFO:
- {
- struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
- strcpy (info.driver, DRV_NAME);
- strcpy (info.version, DRV_VERSION);
- strcpy (info.bus_info, np->pci_dev->slot_name);
- if (copy_to_user (useraddr, &info, sizeof (info)))
- return -EFAULT;
- return 0;
- }
+ case ETHTOOL_GDRVINFO: {
+ struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+ strcpy (info.driver, DRV_NAME);
+ strcpy (info.version, DRV_VERSION);
+ strcpy (info.bus_info, np->pci_dev->slot_name);
+ if (copy_to_user (useraddr, &info, sizeof (info)))
+ return -EFAULT;
+ return 0;
+ }
+ /* get settings */
+ case ETHTOOL_GSET: {
+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ spin_lock_irq(&np->lock);
+ mii_ethtool_gset(&np->mii, &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, &ecmd);
+ spin_unlock_irq(&np->lock);
+ return r;
+ }
+ /* restart autonegotiation */
+ case ETHTOOL_NWAY_RST: {
+ return mii_nway_restart(&np->mii);
+ }
+ /* get link status */
+ case ETHTOOL_GLINK: {
+ struct ethtool_value edata = {ETHTOOL_GLINK};
+ edata.data = mii_link_ok(&np->mii);
+ 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;
+ }
default:
break;
}
@@ -1432,11 +1481,11 @@
switch (data->reg_num) {
case 0:
/* Check for autonegotiation on or reset. */
- ep->duplex_lock = (value & 0x9000) ? 0 : 1;
- if (ep->duplex_lock)
- ep->full_duplex = (value & 0x0100) ? 1 : 0;
+ ep->mii.duplex_lock = (value & 0x9000) ? 0 : 1;
+ if (ep->mii.duplex_lock)
+ ep->mii.full_duplex = (value & 0x0100) ? 1 : 0;
break;
- case 4: ep->advertising = value; break;
+ case 4: ep->mii.advertising = value; break;
}
/* Perhaps check_duplex(dev), depending on chip semantics. */
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)