patch-2.4.15 linux/drivers/net/pcmcia/3c574_cs.c
Next file: linux/drivers/net/pcmcia/3c589_cs.c
Previous file: linux/drivers/net/ns83820.c
Back to the patch index
Back to the overall index
- Lines: 220
- Date:
Tue Nov 13 09:02:30 2001
- Orig file:
v2.4.14/linux/drivers/net/pcmcia/3c574_cs.c
- Orig date:
Tue Oct 9 17:06:52 2001
diff -u --recursive --new-file v2.4.14/linux/drivers/net/pcmcia/3c574_cs.c linux/drivers/net/pcmcia/3c574_cs.c
@@ -14,10 +14,6 @@
*/
-/* Driver author info must always be in the binary. Version too.. */
-static const char *tc574_version =
-"3c574_cs.c v1.08 9/24/98 Donald Becker/David Hinds, becker@scyld.com.\n";
-
/*
Theory of Operation
@@ -63,7 +59,7 @@
V. References
-http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
+http://www.scyld.com/expert/NWay.html
http://www.national.com/pf/DP/DP83840.html
Thanks to Terry Murphy of 3Com for providing development information for
@@ -100,24 +96,43 @@
#include <pcmcia/ds.h>
#include <pcmcia/mem_op.h>
-/* A few values that may be tweaked. */
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(full_duplex, "i");
+/*====================================================================*/
+
+/* Module parameters */
+
+MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
+MODULE_DESCRIPTION("3Com 3c574 series PCMCIA ethernet driver");
+MODULE_LICENSE("GPL");
+
+#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
/* Now-standard PC card module parameters. */
-static u_int irq_mask = 0xdeb8; /* IRQ3,4,5,7,9,10,11,12,14,15 */
+INT_MODULE_PARM(irq_mask, 0xdeb8);
static int irq_list[4] = { -1 };
-
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT ((800*HZ)/1000)
+MODULE_PARM(irq_list, "1-4i");
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 32;
+INT_MODULE_PARM(max_interrupt_work, 32);
/* Force full duplex modes? */
-static int full_duplex;
+INT_MODULE_PARM(full_duplex, 0);
+
+/* Autodetect link polarity reversal? */
+INT_MODULE_PARM(auto_polarity, 1);
+
+#ifdef PCMCIA_DEBUG
+INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version =
+"3c574_cs.c 1.65 2001/10/13 00:08:50 Donald Becker/David Hinds, becker@scyld.com.\n";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT ((800*HZ)/1000)
/* To minimize the size of the driver source and make the driver more
readable not all constants are symbolically defined.
@@ -197,7 +212,7 @@
dev_node_t node;
struct net_device_stats stats;
u16 advertising, partner; /* NWay media advertisement */
- unsigned char phys[2]; /* MII device addresses. */
+ unsigned char phys; /* MII device address */
unsigned int
autoselect:1, default_media:3; /* Read from the EEPROM/Wn3_Config. */
/* for transceiver monitoring */
@@ -210,17 +225,7 @@
/* Set iff a MII transceiver on any interface requires mdio preamble.
This only set with the original DP83840 on older 3c905 boards, so the extra
code size of a per-interface flag is not worthwhile. */
-static char mii_preamble_required;
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"3c574_cs.c 1.000 1998/1/8 Donald Becker, becker@scyld.com.\n";
-#else
-#define DEBUG(n, args...)
-#endif
+static char mii_preamble_required = 0;
/* Index of functions. */
@@ -509,7 +514,7 @@
}
{
- int phy, phy_idx = 0;
+ int phy;
/* Roadrunner only: Turn on the MII transceiver */
outw(0x8040, ioaddr + Wn3_Options);
@@ -521,29 +526,30 @@
outw(0x8040, ioaddr + Wn3_Options);
EL3WINDOW(4);
- for (phy = 1; phy <= 32 && phy_idx < sizeof(lp->phys); phy++) {
+ for (phy = 1; phy <= 32; phy++) {
int mii_status;
mdio_sync(ioaddr, 32);
mii_status = mdio_read(ioaddr, phy & 0x1f, 1);
if (mii_status != 0xffff) {
- lp->phys[phy_idx++] = phy & 0x1f;
+ lp->phys = phy & 0x1f;
DEBUG(0, " MII transceiver at index %d, status %x.\n",
phy, mii_status);
if ((mii_status & 0x0040) == 0)
mii_preamble_required = 1;
+ break;
}
}
- if (phy_idx == 0) {
+ if (phy > 32) {
printk(KERN_NOTICE " No MII transceivers found!\n");
goto failed;
}
- i = mdio_read(ioaddr, lp->phys[0], 16) | 0x40;
- mdio_write(ioaddr, lp->phys[0], 16, i);
- lp->advertising = mdio_read(ioaddr, lp->phys[0], 4);
+ i = mdio_read(ioaddr, lp->phys, 16) | 0x40;
+ mdio_write(ioaddr, lp->phys, 16, i);
+ lp->advertising = mdio_read(ioaddr, lp->phys, 4);
if (full_duplex) {
/* Only advertise the FD media types. */
lp->advertising &= ~0x02a0;
- mdio_write(ioaddr, lp->phys[0], 4, lp->advertising);
+ mdio_write(ioaddr, lp->phys, 4, lp->advertising);
}
}
@@ -807,7 +813,12 @@
outw(0x0040, ioaddr + Wn4_NetDiag);
/* .. re-sync MII and re-fill what NWay is advertising. */
mdio_sync(ioaddr, 32);
- mdio_write(ioaddr, lp->phys[0], 4, lp->advertising);
+ mdio_write(ioaddr, lp->phys, 4, lp->advertising);
+ if (!auto_polarity) {
+ /* works for TDK 78Q2120 series MII's */
+ int i = mdio_read(ioaddr, lp->phys, 16) | 0x20;
+ mdio_write(ioaddr, lp->phys, 16, i);
+ }
/* Switch to register set 1 for normal use, just for TxFree. */
EL3WINDOW(1);
@@ -1032,8 +1043,8 @@
save_flags(flags);
cli();
EL3WINDOW(4);
- media = mdio_read(ioaddr, lp->phys[0], 1);
- partner = mdio_read(ioaddr, lp->phys[0], 5);
+ media = mdio_read(ioaddr, lp->phys, 1);
+ partner = mdio_read(ioaddr, lp->phys, 5);
EL3WINDOW(1);
restore_flags(flags);
@@ -1122,7 +1133,6 @@
/* BadSSD */ inb(ioaddr + 12);
up = inb(ioaddr + 13);
- lp->stats.rx_bytes += rx + ((up & 0x0f) << 16);
lp->stats.tx_bytes += tx + ((up & 0xf0) << 12);
EL3WINDOW(1);
@@ -1160,10 +1170,8 @@
if (skb != NULL) {
skb->dev = dev;
skb_reserve(skb, 2);
-
insl(ioaddr+RX_FIFO, skb_put(skb, pkt_len),
((pkt_len+3)>>2));
-
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
@@ -1187,7 +1195,7 @@
struct el3_private *lp = (struct el3_private *)dev->priv;
ioaddr_t ioaddr = dev->base_addr;
u16 *data = (u16 *)&rq->ifr_data;
- int phy = lp->phys[0] & 0x1f;
+ int phy = lp->phys & 0x1f;
DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
@@ -1289,8 +1297,6 @@
{
servinfo_t serv;
- /* Always emit the version, before any failure. */
- printk(KERN_INFO"%s", tc574_version);
DEBUG(0, "%s\n", version);
CardServices(GetCardServicesInfo, &serv);
if (serv.Revision != CS_RELEASE_CODE) {
@@ -1312,7 +1318,6 @@
module_init(init_3c574_cs);
module_exit(exit_3c574_cs);
-MODULE_LICENSE("GPL");
/*
* Local variables:
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)