1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-13 10:02:38 +00:00

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:
Bill Paul 2000-08-28 20:40:03 +00:00
parent b7823d1fde
commit 4e2499823f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=65170
2 changed files with 89 additions and 9 deletions

View File

@ -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);

View File

@ -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