Major update to xe driver:

- Make multicast work
- Fix (some of) the watchdog timeouts after card reset
- Add support for CE2, CEM28 and CEM33 cards
- General code cleanup

Any card that worked previously should still work, as well as a lot that
didn't.

The driver is not yet style(9) compliant; those changes are forthcoming,
once the functional changes are done.

PR:		kern/50644
Reviewed by:	imp
Approved by:	imp
This commit is contained in:
Scott Mitchell 2003-10-14 22:51:35 +00:00
parent 5b28d0d2d9
commit 846b8315a2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=121099
4 changed files with 796 additions and 591 deletions

File diff suppressed because it is too large Load Diff

View File

@ -55,6 +55,12 @@ __FBSDID("$FreeBSD$");
#include <dev/pccard/pccarddevs.h>
#include "card_if.h"
/*
* Set XE_DEBUG to enable debug messages
* Larger values increase verbosity
*/
#define XE_DEBUG 0
#define XE_VENDOR_ID_XIRCOM 0x0105
#define XE_VENDOR_ID_COMPAQ_1 0x0138
#define XE_VENDOR_ID_COMPAQ_2 0x0183
@ -67,7 +73,7 @@ struct xe_vendor_table {
} xe_vendor_devs[] = {
{ XE_VENDOR_ID_XIRCOM, "Xircom" },
{ XE_VENDOR_ID_COMPAQ_1, "Compaq" },
{ XE_VENDOR_ID_COMPAQ_2, "Compaq" },
{ XE_VENDOR_ID_COMPAQ_2, "Compaq" }, /* Maybe Paralon Techologies, Inc */
{ XE_VENDOR_ID_INTEL, "Intel" },
{ XE_VENDOR_ID_UNKNOWN, "Unknown" }
};
@ -76,18 +82,19 @@ struct xe_vendor_table {
#define XE_CARD_TYPE_FLAGS_CE2 0x1
#define XE_CARD_TYPE_FLAGS_MOHAWK 0x2
#define XE_CARD_TYPE_FLAGS_DINGO 0x4
#define XE_PROD_UMASK 0x100f
#define XE_PROD_MODEM_UMASK 0x1000
#define XE_PROD_SINGLE_ID1 0x1
#define XE_PROD_SINGLE_ID2 0x2
#define XE_PROD_SINGLE_ID3 0x3
#define XE_PROD_MULTI_ID1 0x1001
#define XE_PROD_MULTI_ID2 0x1002
#define XE_PROD_MULTI_ID3 0x1003
#define XE_PROD_MULTI_ID4 0x1004
#define XE_PROD_MULTI_ID5 0x1005
#define XE_PROD_MULTI_ID6 0x1006
#define XE_PROD_MULTI_ID7 0x1007
#define XE_PROD_UMASK 0x11000f
#define XE_PROD_ETHER_UMASK 0x010000
#define XE_PROD_MODEM_UMASK 0x100000
#define XE_PROD_SINGLE_ID1 0x010001
#define XE_PROD_SINGLE_ID2 0x010002
#define XE_PROD_SINGLE_ID3 0x010003
#define XE_PROD_MULTI_ID1 0x110001
#define XE_PROD_MULTI_ID2 0x110002
#define XE_PROD_MULTI_ID3 0x110003
#define XE_PROD_MULTI_ID4 0x110004
#define XE_PROD_MULTI_ID5 0x110005
#define XE_PROD_MULTI_ID6 0x110006
#define XE_PROD_MULTI_ID7 0x110007
struct xe_card_type_table {
u_int32_t prod_type;
@ -112,18 +119,19 @@ struct xe_card_type_table {
/*
* Prototypes
*/
static int xe_cem56fix(device_t dev);
static int xe_cemfix(device_t dev);
static struct xe_vendor_table *xe_vendor_lookup(u_int32_t devid,
struct xe_vendor_table *tbl);
static struct xe_card_type_table *xe_card_type_lookup(u_int32_t devid,
struct xe_card_type_table *tbl);
/*
* Fixing for RealPort cards - they need a little furtling to get the
* ethernet working. But this codes don't work well in NEWCARD.
* Fixing for CEM2, CEM3 and CEM56/REM56 cards. These need some magic to
* enable the Ethernet function, which isn't mentioned anywhere in the CIS.
* Despite the register names, most of this isn't Dingo-specific.
*/
static int
xe_cem56fix(device_t dev)
xe_cemfix(device_t dev)
{
struct xe_softc *sc = (struct xe_softc *) device_get_softc(dev);
bus_space_tag_t bst;
@ -132,7 +140,11 @@ xe_cem56fix(device_t dev)
int rid;
int ioport;
device_printf(dev, "Realport port 0x%0lx, size 0x%0lx\n",
#if XE_DEBUG > 1
device_printf(dev, "cemfix\n");
#endif
device_printf(dev, "CEM I/O port 0x%0lx, size 0x%0lx\n",
bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid),
bus_get_resource_count(dev, SYS_RES_IOPORT, sc->port_rid));
@ -158,12 +170,14 @@ xe_cem56fix(device_t dev)
bus_space_write_1(bst, bsh, DINGO_EBAR0, ioport & 0xff);
bus_space_write_1(bst, bsh, DINGO_EBAR1, (ioport >> 8) & 0xff);
bus_space_write_1(bst, bsh, DINGO_DCOR0, DINGO_DCOR0_SF_INT);
bus_space_write_1(bst, bsh, DINGO_DCOR1, DINGO_DCOR1_INT_LEVEL |
DINGO_DCOR1_EEDIO);
bus_space_write_1(bst, bsh, DINGO_DCOR2, 0x00);
bus_space_write_1(bst, bsh, DINGO_DCOR3, 0x00);
bus_space_write_1(bst, bsh, DINGO_DCOR4, 0x00);
if (sc->dingo) {
bus_space_write_1(bst, bsh, DINGO_DCOR0, DINGO_DCOR0_SF_INT);
bus_space_write_1(bst, bsh, DINGO_DCOR1, DINGO_DCOR1_INT_LEVEL |
DINGO_DCOR1_EEDIO);
bus_space_write_1(bst, bsh, DINGO_DCOR2, 0x00);
bus_space_write_1(bst, bsh, DINGO_DCOR3, 0x00);
bus_space_write_1(bst, bsh, DINGO_DCOR4, 0x00);
}
bus_release_resource(dev, SYS_RES_MEMORY, rid, r);
@ -209,6 +223,27 @@ xe_pccard_probe(device_t dev)
struct xe_card_type_table *card_itm;
int i;
#if XE_DEBUG > 1
char* vendor_str = NULL;
char* product_str = NULL;
char* cis4_str = NULL;
device_printf(dev, "pccard_probe\n");
pccard_get_vendor(dev, &vendor);
pccard_get_product(dev, &prodid);
pccard_get_prodext(dev, &prodext);
pccard_get_vendor_str(dev, &vendor_str);
pccard_get_product_str(dev, &product_str);
pccard_get_cis3_str(dev, &cis3_str);
pccard_get_cis4_str(dev, &cis4_str);
device_printf(dev, "vendor = 0x%04x\n", vendor);
device_printf(dev, "product = 0x%04x\n", prodid);
device_printf(dev, "prodext = 0x%02x\n", prodext);
device_printf(dev, "vendor_str = %s\n", vendor_str);
device_printf(dev, "product_str = %s\n", product_str);
device_printf(dev, "cis3_str = %s\n", cis3_str);
device_printf(dev, "cis4_str = %s\n", cis4_str);
#endif
/*
* PCCARD_CISTPL_MANFID = 0x20
*/
@ -245,7 +280,7 @@ xe_pccard_probe(device_t dev)
*/
pccard_get_cis3_str(dev, &cis3_str);
if (strcmp(scp->card_type, "CE") == 0)
if (strcmp(cis3_str, "CE2") ==0)
if (cis3_str != NULL && strcmp(cis3_str, "PS-CE2-10") == 0)
scp->card_type = "CE2"; /* Look for "CE2" string */
/*
@ -274,12 +309,17 @@ xe_pccard_attach(device_t dev)
struct xe_softc *scp = device_get_softc(dev);
int err;
#if XE_DEBUG > 1
device_printf(dev, "pccard_attach\n");
#endif
if ((err = xe_activate(dev)) != 0)
return (err);
/* Hack RealPorts into submission */
if (scp->dingo && xe_cem56fix(dev) < 0) {
device_printf(dev, "Unable to fix your RealPort\n");
if (scp->modem && xe_cemfix(dev) < 0) {
device_printf(dev, "Unable to fix your %s combo card\n",
scp->card_type);
xe_deactivate(dev);
return (ENODEV);
}
@ -301,6 +341,10 @@ xe_pccard_detach(device_t dev)
{
struct xe_softc *sc = device_get_softc(dev);
#if XE_DEBUG > 1
device_printf(dev, "pccard_detach\n");
#endif
sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
ether_ifdetach(&sc->arpcom.ac_if);
xe_deactivate(dev);
@ -309,7 +353,7 @@ xe_pccard_detach(device_t dev)
static const struct pccard_product xe_pccard_products[] = {
PCMCIA_CARD(ACCTON, EN2226, 0),
PCMCIA_CARD(COMPAQ2, CPQ_10_100, 0), /* Maybe Paralon Techologies, Inc */
PCMCIA_CARD(COMPAQ2, CPQ_10_100, 0),
PCMCIA_CARD(INTEL, EEPRO100, 0),
PCMCIA_CARD(XIRCOM, CE, 0),
PCMCIA_CARD(XIRCOM, CE2, 0),
@ -327,11 +371,15 @@ xe_pccard_match(device_t dev)
{
const struct pccard_product *pp;
#if XE_DEBUG > 1
device_printf(dev, "pccard_match\n");
#endif
if ((pp = pccard_product_lookup(dev, xe_pccard_products,
sizeof(xe_pccard_products[0]), NULL)) != NULL) {
if (pp->pp_name != NULL)
device_set_desc(dev, pp->pp_name);
return (0);
sizeof(xe_pccard_products[0]), NULL)) != NULL) {
if (pp->pp_name != NULL)
device_set_desc(dev, pp->pp_name);
return (0);
}
return (EIO);
}

View File

@ -283,11 +283,15 @@
#define XE_IMR0_TX_OVERFLOW 0x01 /* Masks for bits in ISR */
#define XE_IMR0_TX_PACKET 0x02
#define XE_IMR0_MAC_INTR 0x04
#define XE_IMR0_TX_RESGRANT 0x08 /* Tx reservation granted (CE2) */
#define XE_IMR0_RX_EARLY 0x10
#define XE_IMR0_RX_PACKET 0x20
#define XE_IMR0_RX_REJECT 0x40
#define XE_IMR0_FORCE_INTR 0x80
/* XE_IMR1 bits */
#define XE_IMR1_TX_UNDERRUN 0x01
/* XE_ECR bits */
#define XE_ECR_EARLY_TX 0x01 /* Enable early transmit mode */
#define XE_ECR_EARLY_RX 0x02 /* Enable early receive mode */
@ -366,14 +370,15 @@
/* XE_GPR0 bits */
#define XE_GPR0_GP1_OUT 0x01 /* Value written to GP1 line */
#define XE_GPR0_GP2_OUT 0x02 /* Value wirtten to GP2 line */
#define XE_GPR0_GP2_OUT 0x02 /* Value written to GP2 line */
#define XE_GPR0_GP1_SELECT 0x04 /* 1 = GP1 is output, 0 = GP1 is input */
#define XE_GPR0_GP2_SELECT 0x08 /* 1 = GP2 is output, 0 = GP2 is input */
#define XE_GPR0_GP1_IN 0x10 /* Value read from GP1 line */
#define XE_GPR0_GP2_IN 0x20 /* Value read from GP2 line */
/* XE_GPR1 bits */
#define XE_GPR1_POWER_DOWN 0x01 /* Power down analog section (down to 20mA load) */
#define XE_GPR1_POWER_DOWN 0x01 /* 0 = Power down analog section */
#define XE_GPR1_AIC 0x04 /* AIC bit (CE2 only) */
/* XE_BOV values */
#define XE_BOV_DINGO 0x55 /* Dingo in Dingo mode */
@ -471,6 +476,7 @@
#define XE_TXST1_LINK_STATUS 0x10 /* Valid link status */
/* RX0Msk bits */
#define XE_RX0M_MP 0x01 /* Multicast packet? (CE2 only) */
#define XE_RX0M_LONG_PACKET 0x02 /* Masks for bits in RXST0 */
#define XE_RX0M_ALIGN_ERROR 0x04 /* Alignment error (CE2 only) */
#define XE_RX0M_CRC_ERROR 0x08
@ -504,6 +510,7 @@
#define XE_SWC0_LOOPBACK_SOURCE 0x02 /* 1 = Transceiver, 0 = MAC */
#define XE_SWC0_ACCEPT_ERROR 0x04 /* Accept otherwise OK packets with CRC errors */
#define XE_SWC0_ACCEPT_SHORT 0x08 /* Accept otherwise OK packets that are too short */
#define XE_SWC0_NO_SRC_INSERT 0x20 /* Disable source insertion (CE2) */
#define XE_SWC0_NO_CRC_INSERT 0x40 /* Don't add CRC to outgoing packets */
/* SWC1 bits */

View File

@ -49,11 +49,14 @@ struct xe_softc {
int irq_rid;
struct resource *port_res;
int port_rid;
struct resource *ce2_port_res;
int ce2_port_rid;
int srev; /* Silicon revision */
int tx_queued; /* Packets currently waiting to transmit */
int tx_tpr; /* Last value of TPR reg on card */
int tx_collisions; /* Collisions since last successful send */
int tx_timeouts; /* Count of transmit timeouts */
u_int16_t tx_min; /* Smallest packet we can send without padding */
u_int16_t tx_thres; /* Threshold bytes for early transmit */
int autoneg_status; /* Autonegotiation progress state */
int media; /* Private media word */
u_char version; /* Bonding Version register from card */