Add support for the 3Com 556 and 556B mini-pci adapters used on some
laptops. I've checked that this still works with the other cards and it works with the 3c556 that I have access to, but I want to check that it works with the 556B mentioned in PR #20878 before I close out the PR and merge to -stable.
This commit is contained in:
parent
b7823d1fde
commit
4e2499823f
@ -55,6 +55,8 @@
|
||||
* 3Com 3c980C-TX 10/100Mbps server adapter (Tornado ASIC)
|
||||
* 3Com 3cSOHO100-TX 10/100Mbps/RJ-45 (Hurricane ASIC)
|
||||
* 3Com 3c450-TX 10/100Mbps/RJ-45 (Tornado ASIC)
|
||||
* 3Com 3c556 10/100Mbps/RJ-45 (MiniPCI, Hurricane ASIC)
|
||||
* 3Com 3c556B 10/100Mbps/RJ-45 (MiniPCI, Hurricane ASIC)
|
||||
* Dell Optiplex GX1 on-board 3c918 10/100Mbps/RJ-45
|
||||
* Dell on-board 3c920 10/100Mbps/RJ-45
|
||||
* Dell Precision on-board 3c905B 10/100Mbps/RJ-45
|
||||
@ -186,6 +188,10 @@ static struct xl_type xl_devs[] = {
|
||||
"3Com 3cSOHO100-TX OfficeConnect" },
|
||||
{ TC_VENDORID, TC_DEVICEID_TORNADO_HOMECONNECT,
|
||||
"3Com 3c450-TX HomeConnect" },
|
||||
{ TC_VENDORID, TC_DEVICEID_HURRICANE_556,
|
||||
"3Com 3c556 Fast Etherlink XL" },
|
||||
{ TC_VENDORID, TC_DEVICEID_HURRICANE_556B,
|
||||
"3Com 3c556B Fast Etherlink XL" },
|
||||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
@ -532,6 +538,8 @@ static int xl_miibus_readreg(dev, phy, reg)
|
||||
struct xl_softc *sc;
|
||||
struct xl_mii_frame frame;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
/*
|
||||
* Pretend that PHYs are only available at MII address 24.
|
||||
* This is to guard against problems with certain 3Com ASIC
|
||||
@ -539,11 +547,9 @@ static int xl_miibus_readreg(dev, phy, reg)
|
||||
* control registers at all MII addresses. This can cause
|
||||
* the miibus code to attach the same PHY several times over.
|
||||
*/
|
||||
if (phy != 24)
|
||||
if ((!(sc->xl_flags & XL_FLAG_PHYOK)) && phy != 24)
|
||||
return(0);
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
bzero((char *)&frame, sizeof(frame));
|
||||
|
||||
frame.mii_phyaddr = phy;
|
||||
@ -560,11 +566,11 @@ static int xl_miibus_writereg(dev, phy, reg, data)
|
||||
struct xl_softc *sc;
|
||||
struct xl_mii_frame frame;
|
||||
|
||||
if (phy != 24)
|
||||
return(0);
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if ((!(sc->xl_flags & XL_FLAG_PHYOK)) && phy != 24)
|
||||
return(0);
|
||||
|
||||
bzero((char *)&frame, sizeof(frame));
|
||||
|
||||
frame.mii_phyaddr = phy;
|
||||
@ -686,14 +692,25 @@ static int xl_read_eeprom(sc, dest, off, cnt, swap)
|
||||
{
|
||||
int err = 0, i;
|
||||
u_int16_t word = 0, *ptr;
|
||||
|
||||
#define EEPROM_5BIT_OFFSET(A) ((((A) << 2) & 0x7F00) | ((A) & 0x003F))
|
||||
/* WARNING! DANGER!
|
||||
* It's easy to accidentally overwrite the rom content!
|
||||
* Note: the 3c575 uses 8bit EEPROM offsets.
|
||||
*/
|
||||
XL_SEL_WIN(0);
|
||||
|
||||
if (xl_eeprom_wait(sc))
|
||||
return(1);
|
||||
|
||||
if (sc->xl_flags & XL_FLAG_EEPROM_OFFSET_30)
|
||||
off += 0x30;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
CSR_WRITE_2(sc, XL_W0_EE_CMD, XL_EE_READ | (off + i));
|
||||
if (sc->xl_flags & XL_FLAG_8BITROM)
|
||||
CSR_WRITE_2(sc, XL_W0_EE_CMD, (2<<8) | (off + i));
|
||||
else
|
||||
CSR_WRITE_2(sc, XL_W0_EE_CMD,
|
||||
XL_EE_READ | EEPROM_5BIT_OFFSET(off + i));
|
||||
err = xl_eeprom_wait(sc);
|
||||
if (err)
|
||||
break;
|
||||
@ -984,7 +1001,8 @@ static void xl_reset(sc)
|
||||
register int i;
|
||||
|
||||
XL_SEL_WIN(0);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET |
|
||||
((sc->xl_flags & XL_FLAG_WEIRDRESET)?0xFF:0));
|
||||
|
||||
for (i = 0; i < XL_TIMEOUT; i++) {
|
||||
DELAY(10);
|
||||
@ -1003,6 +1021,12 @@ static void xl_reset(sc)
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
|
||||
xl_wait(sc);
|
||||
|
||||
if (sc->xl_flags & XL_FLAG_WEIRDRESET) {
|
||||
XL_SEL_WIN(2);
|
||||
CSR_WRITE_2(sc, XL_W2_RESET_OPTIONS, CSR_READ_2(sc,
|
||||
XL_W2_RESET_OPTIONS) | 0x4010);
|
||||
}
|
||||
|
||||
/* Wait a little while for the chip to get its brains in order. */
|
||||
DELAY(100000);
|
||||
return;
|
||||
@ -1126,6 +1150,8 @@ static void xl_choose_xcvr(sc, verbose)
|
||||
printf("xl%d: guessing 10baseFL\n", sc->xl_unit);
|
||||
break;
|
||||
case TC_DEVICEID_BOOMERANG_10_100BT: /* 3c905-TX */
|
||||
case TC_DEVICEID_HURRICANE_556: /* 3c556 */
|
||||
case TC_DEVICEID_HURRICANE_556B: /* 3c556B */
|
||||
sc->xl_media = XL_MEDIAOPT_MII;
|
||||
sc->xl_xcvr = XL_XCVR_MII;
|
||||
if (verbose)
|
||||
@ -1186,6 +1212,14 @@ static int xl_attach(dev)
|
||||
sc = device_get_softc(dev);
|
||||
unit = device_get_unit(dev);
|
||||
|
||||
sc->xl_flags = 0;
|
||||
if (pci_get_device(dev) == TC_DEVICEID_HURRICANE_556 ||
|
||||
pci_get_device(dev) == TC_DEVICEID_HURRICANE_556B)
|
||||
sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
|
||||
XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_WEIRDRESET;
|
||||
if (pci_get_device(dev) == TC_DEVICEID_HURRICANE_556)
|
||||
sc->xl_flags |= XL_FLAG_8BITROM;
|
||||
|
||||
/*
|
||||
* If this is a 3c905B, we have to check one extra thing.
|
||||
* The 905B supports power management and may be placed in
|
||||
@ -1264,12 +1298,31 @@ static int xl_attach(dev)
|
||||
sc->xl_btag = rman_get_bustag(sc->xl_res);
|
||||
sc->xl_bhandle = rman_get_bushandle(sc->xl_res);
|
||||
|
||||
if (sc->xl_flags & XL_FLAG_FUNCREG) {
|
||||
rid = XL_PCI_FUNCMEM;
|
||||
sc->xl_fres = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
|
||||
if (sc->xl_fres == NULL) {
|
||||
printf ("xl%d: couldn't map ports/memory\n", unit);
|
||||
bus_release_resource(dev, XL_RES, XL_RID, sc->xl_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->xl_ftag = rman_get_bustag(sc->xl_fres);
|
||||
sc->xl_fhandle = rman_get_bushandle(sc->xl_fres);
|
||||
}
|
||||
|
||||
rid = 0;
|
||||
sc->xl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
|
||||
if (sc->xl_irq == NULL) {
|
||||
printf("xl%d: couldn't map interrupt\n", unit);
|
||||
if (sc->xl_fres != NULL)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
XL_PCI_FUNCMEM, sc->xl_fres);
|
||||
bus_release_resource(dev, XL_RES, XL_RID, sc->xl_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
@ -1280,6 +1333,9 @@ static int xl_attach(dev)
|
||||
|
||||
if (error) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
|
||||
if (sc->xl_fres != NULL)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
XL_PCI_FUNCMEM, sc->xl_fres);
|
||||
bus_release_resource(dev, XL_RES, XL_RID, sc->xl_res);
|
||||
printf("xl%d: couldn't set up irq\n", unit);
|
||||
goto fail;
|
||||
@ -1295,6 +1351,9 @@ static int xl_attach(dev)
|
||||
printf("xl%d: failed to read station address\n", sc->xl_unit);
|
||||
bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
|
||||
if (sc->xl_fres != NULL)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
XL_PCI_FUNCMEM, sc->xl_fres);
|
||||
bus_release_resource(dev, XL_RES, XL_RID, sc->xl_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
@ -1316,6 +1375,9 @@ static int xl_attach(dev)
|
||||
printf("xl%d: no memory for list buffers!\n", unit);
|
||||
bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
|
||||
if (sc->xl_fres != NULL)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
XL_PCI_FUNCMEM, sc->xl_fres);
|
||||
bus_release_resource(dev, XL_RES, XL_RID, sc->xl_res);
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
@ -1524,6 +1586,9 @@ static int xl_detach(dev)
|
||||
|
||||
bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq);
|
||||
if (sc->xl_fres != NULL)
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
XL_PCI_FUNCMEM, sc->xl_fres);
|
||||
bus_release_resource(dev, XL_RES, XL_RID, sc->xl_res);
|
||||
|
||||
ifmedia_removeall(&sc->ifmedia);
|
||||
@ -2545,6 +2610,7 @@ static void xl_init(xsc)
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|XL_INTRS);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
|
||||
if (sc->xl_flags & XL_FLAG_FUNCREG) bus_space_write_4 (sc->xl_ftag, sc->xl_fhandle, 4, 0x8000);
|
||||
|
||||
/* Set the RX early threshold */
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_THRESH|(XL_PACKET_SIZE >>2));
|
||||
@ -2814,6 +2880,7 @@ static void xl_stop(sc)
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|XL_STAT_INTLATCH);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|0);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
|
||||
if (sc->xl_flags & XL_FLAG_FUNCREG) bus_space_write_4 (sc->xl_ftag, sc->xl_fhandle, 4, 0x8000);
|
||||
|
||||
/* Stop the stats updater. */
|
||||
untimeout(xl_stats_update, sc, sc->xl_stat_ch);
|
||||
|
@ -548,6 +548,12 @@ struct xl_mii_frame {
|
||||
#define XL_TYPE_905B 1
|
||||
#define XL_TYPE_90X 2
|
||||
|
||||
#define XL_FLAG_FUNCREG 0x0001
|
||||
#define XL_FLAG_PHYOK 0x0002
|
||||
#define XL_FLAG_EEPROM_OFFSET_30 0x0004
|
||||
#define XL_FLAG_WEIRDRESET 0x0008
|
||||
#define XL_FLAG_8BITROM 0x0010
|
||||
|
||||
struct xl_softc {
|
||||
struct arpcom arpcom; /* interface info */
|
||||
struct ifmedia ifmedia; /* media info */
|
||||
@ -569,6 +575,10 @@ struct xl_softc {
|
||||
struct xl_list_data *xl_ldata;
|
||||
struct xl_chain_data xl_cdata;
|
||||
struct callout_handle xl_stat_ch;
|
||||
int xl_flags;
|
||||
struct resource *xl_fres;
|
||||
bus_space_handle_t xl_fhandle;
|
||||
bus_space_tag_t xl_ftag;
|
||||
};
|
||||
|
||||
#define xl_rx_goodframes(x) \
|
||||
@ -641,6 +651,8 @@ struct xl_stats {
|
||||
#define TC_DEVICEID_TORNADO_10_100BT_SERV 0x9805
|
||||
#define TC_DEVICEID_HURRICANE_SOHO100TX 0x7646
|
||||
#define TC_DEVICEID_TORNADO_HOMECONNECT 0x4500
|
||||
#define TC_DEVICEID_HURRICANE_556 0x6055
|
||||
#define TC_DEVICEID_HURRICANE_556B 0x6056
|
||||
|
||||
/*
|
||||
* PCI low memory base and low I/O base register, and
|
||||
@ -657,6 +669,7 @@ struct xl_stats {
|
||||
#define XL_PCI_HEADER_TYPE 0x0E
|
||||
#define XL_PCI_LOIO 0x10
|
||||
#define XL_PCI_LOMEM 0x14
|
||||
#define XL_PCI_FUNCMEM 0x18
|
||||
#define XL_PCI_BIOSROM 0x30
|
||||
#define XL_PCI_INTLINE 0x3C
|
||||
#define XL_PCI_INTPIN 0x3D
|
||||
|
Loading…
Reference in New Issue
Block a user