Update the Tigon driver to support 1000baseTX gigE over copper AceNIC

cards. This basically involves switching to the 12.4.13 firmware, plus
a couple of minor tweaks to the driver.

Also changed the jumbo buffer allocation scheme just a little to avoid
'failed to allocate jumbo buffer' conditions in certain cases.
This commit is contained in:
Bill Paul 2000-07-20 22:24:43 +00:00
parent c231f6de29
commit e87631b976
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=63699
9 changed files with 6480 additions and 4868 deletions

View file

@ -65,21 +65,29 @@ vendors that use the Tigon chipset under OEM contract.
The
.Nm
driver has been tested with the following Tigon-based adapters:
.Bl -bullet -offset indent
.Pp
.Bl -bullet -compact -offset indent
.It
The Alteon AceNIC V gigabit ethernet adapter
The Alteon AceNIC V gigabit ethernet adapter (1000baseSX)
.It
The 3Com 3c985-SX gigabit ethernet adapter
The Alteon AceNIC V gigabit ethernet adapter (1000bassTX)
.It
The 3Com 3c985-SX gigabit ethernet adapter (Tigon 1)
.It
The 3Com 3c985B-SX gigabit ethernet adapter (Tigon 2)
.It
The Netgear GA620 gigabit ethernet adapter
.El
.Pp
The following should also be supported but have not yet been tested:
.Bl -bullet -offset indent
.Pp
.Bl -bullet -compact -offset indent
.It
The Digital EtherWORKS 1000SX PCI Gigabit Adapter
.It
Silicon Graphics PCI gigabit ethernet adapter
.It
Farallon PN9000SX Gigabit Ethernet adapter
.El
.Pp
While the Tigon chipset supports 10, 100 and 1000Mbps speeds, support for
@ -195,7 +203,7 @@ the network connection (cable).
.Xr ifconfig 8
.Rs
.%T Alteon Gigabit Ethernet/PCI NIC manuals
.%O http://www.alteon.com/support/openkits
.%O http://sanjose.alteon.com/open.shtml
.Re
.Sh HISTORY
The
@ -206,4 +214,4 @@ device driver first appeared in
The
.Nm
driver was written by
.An Bill Paul Aq wpaul@ctr.columbia.edu .
.An Bill Paul Aq wpaul@bsdi.com .

View file

@ -136,6 +136,8 @@ static const char rcsid[] =
static struct ti_type ti_devs[] = {
{ ALT_VENDORID, ALT_DEVICEID_ACENIC,
"Alteon AceNIC Gigabit Ethernet" },
{ ALT_VENDORID, ALT_DEVICEID_ACENIC_COPPER,
"Alteon AceNIC 1000baseTX Gigabit Ethernet" },
{ TC_VENDORID, TC_DEVICEID_3C985,
"3Com 3c985-SX Gigabit Ethernet" },
{ NG_VENDORID, NG_DEVICEID_GA620,
@ -946,7 +948,7 @@ static int ti_init_rx_ring_jumbo(sc)
register int i;
struct ti_cmd_desc cmd;
for (i = 0; i < (TI_JSLOTS - 20); i++) {
for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) {
if (ti_newbuf_jumbo(sc, i, NULL) == ENOBUFS)
return(ENOBUFS);
};
@ -1688,6 +1690,17 @@ static int ti_attach(dev)
goto fail;
}
/*
* We really need a better way to tell a 1000baseTX card
* from a 1000baseSX one, since in theory there could be
* OEMed 1000baseTX cards from lame vendors who aren't
* clever enough to change the PCI ID. For the moment
* though, the AceNIC is the only copper card available.
*/
if (pci_get_vendor(dev) == ALT_VENDORID &&
pci_get_device(dev) == ALT_DEVICEID_ACENIC_COPPER)
sc->ti_copper = 1;
/* Set default tuneable values. */
sc->ti_stat_ticks = 2 * TI_TICKS_PER_SEC;
sc->ti_rx_coal_ticks = TI_TICKS_PER_SEC / 5000;
@ -1712,12 +1725,30 @@ static int ti_attach(dev)
/* Set up ifmedia support. */
ifmedia_init(&sc->ifmedia, IFM_IMASK, ti_ifmedia_upd, ti_ifmedia_sts);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_FL, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_FL|IFM_FDX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_FX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_FX|IFM_FDX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_SX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_SX|IFM_FDX, 0, NULL);
if (sc->ti_copper) {
/*
* Copper cards allow manual 10/100 mode selection,
* but not manual 1000baseTX mode selection. Why?
* Becuase currently there's no way to specify the
* master/slave setting through the firmware interface,
* so Alteon decided to just bag it and handle it
* via autonegotiation.
*/
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
ifmedia_add(&sc->ifmedia,
IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
ifmedia_add(&sc->ifmedia,
IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_TX, 0, NULL);
ifmedia_add(&sc->ifmedia,
IFM_ETHER|IFM_1000_TX|IFM_FDX, 0, NULL);
} else {
/* Fiber cards don't support 10/100 modes. */
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_SX, 0, NULL);
ifmedia_add(&sc->ifmedia,
IFM_ETHER|IFM_1000_SX|IFM_FDX, 0, NULL);
}
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO);
@ -2297,17 +2328,24 @@ static int ti_ifmedia_upd(ifp)
TI_CMD_CODE_NEGOTIATE_BOTH, 0);
break;
case IFM_1000_SX:
case IFM_1000_TX:
CSR_WRITE_4(sc, TI_GCR_GLINK, TI_GLNK_PREF|TI_GLNK_1000MB|
TI_GLNK_FULL_DUPLEX|TI_GLNK_RX_FLOWCTL_Y|TI_GLNK_ENB);
TI_GLNK_RX_FLOWCTL_Y|TI_GLNK_ENB);
CSR_WRITE_4(sc, TI_GCR_LINK, 0);
if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) {
TI_SETBIT(sc, TI_GCR_GLINK, TI_GLNK_FULL_DUPLEX);
}
TI_DO_CMD(TI_CMD_LINK_NEGOTIATION,
TI_CMD_CODE_NEGOTIATE_GIGABIT, 0);
break;
case IFM_100_FX:
case IFM_10_FL:
case IFM_100_TX:
case IFM_10_T:
CSR_WRITE_4(sc, TI_GCR_GLINK, 0);
CSR_WRITE_4(sc, TI_GCR_LINK, TI_LNK_ENB|TI_LNK_PREF);
if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_FX) {
if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_FX ||
IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX) {
TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_100MB);
} else {
TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_10MB);
@ -2333,6 +2371,7 @@ static void ti_ifmedia_sts(ifp, ifmr)
struct ifmediareq *ifmr;
{
struct ti_softc *sc;
u_int32_t media = 0;
sc = ifp->if_softc;
@ -2344,15 +2383,29 @@ static void ti_ifmedia_sts(ifp, ifmr)
ifmr->ifm_status |= IFM_ACTIVE;
if (sc->ti_linkstat == TI_EV_CODE_GIG_LINK_UP)
ifmr->ifm_active |= IFM_1000_SX|IFM_FDX;
else if (sc->ti_linkstat == TI_EV_CODE_LINK_UP) {
u_int32_t media;
if (sc->ti_linkstat == TI_EV_CODE_GIG_LINK_UP) {
media = CSR_READ_4(sc, TI_GCR_GLINK_STAT);
if (sc->ti_copper)
ifmr->ifm_active |= IFM_1000_TX;
else
ifmr->ifm_active |= IFM_1000_SX;
if (media & TI_GLNK_FULL_DUPLEX)
ifmr->ifm_active |= IFM_FDX;
else
ifmr->ifm_active |= IFM_HDX;
} else if (sc->ti_linkstat == TI_EV_CODE_LINK_UP) {
media = CSR_READ_4(sc, TI_GCR_LINK_STAT);
if (media & TI_LNK_100MB)
ifmr->ifm_active |= IFM_100_FX;
if (media & TI_LNK_10MB)
ifmr->ifm_active |= IFM_10_FL;
if (sc->ti_copper) {
if (media & TI_LNK_100MB)
ifmr->ifm_active |= IFM_100_TX;
if (media & TI_LNK_10MB)
ifmr->ifm_active |= IFM_10_T;
} else {
if (media & TI_LNK_100MB)
ifmr->ifm_active |= IFM_100_FX;
if (media & TI_LNK_10MB)
ifmr->ifm_active |= IFM_10_FL;
}
if (media & TI_LNK_FULL_DUPLEX)
ifmr->ifm_active |= IFM_FDX;
if (media & TI_LNK_HALF_DUPLEX)

View file

@ -60,6 +60,7 @@
*/
#define ALT_VENDORID 0x12AE
#define ALT_DEVICEID_ACENIC 0x0001
#define ALT_DEVICEID_ACENIC_COPPER 0x0002
/*
* 3Com 3c985 PCI vendor/device ID.
@ -134,8 +135,8 @@
* Firmware revision that we want.
*/
#define TI_FIRMWARE_MAJOR 0xc
#define TI_FIRMWARE_MINOR 0x3
#define TI_FIRMWARE_FIX 0x15
#define TI_FIRMWARE_MINOR 0x4
#define TI_FIRMWARE_FIX 0xd
/*
* Miscelaneous Local Control register.
@ -1033,7 +1034,7 @@ struct ti_event_desc {
#define TI_SSLOTS 256
#define TI_MSLOTS 256
#define TI_JSLOTS 256
#define TI_JSLOTS 384
#define TI_JRAWLEN (TI_JUMBO_FRAMELEN + ETHER_ALIGN + sizeof(u_int64_t))
#define TI_JLEN (TI_JRAWLEN + (sizeof(u_int64_t) - \
@ -1122,6 +1123,7 @@ struct ti_softc {
struct ifmedia ifmedia; /* media info */
u_int8_t ti_unit; /* interface number */
u_int8_t ti_hwrev; /* Tigon rev (1 or 2) */
u_int8_t ti_copper; /* 1000baseTX card */
u_int8_t ti_linkstat; /* Link state */
struct ti_ring_data *ti_rdata; /* rings */
struct ti_chain_data ti_cdata; /* mbufs */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -136,6 +136,8 @@ static const char rcsid[] =
static struct ti_type ti_devs[] = {
{ ALT_VENDORID, ALT_DEVICEID_ACENIC,
"Alteon AceNIC Gigabit Ethernet" },
{ ALT_VENDORID, ALT_DEVICEID_ACENIC_COPPER,
"Alteon AceNIC 1000baseTX Gigabit Ethernet" },
{ TC_VENDORID, TC_DEVICEID_3C985,
"3Com 3c985-SX Gigabit Ethernet" },
{ NG_VENDORID, NG_DEVICEID_GA620,
@ -946,7 +948,7 @@ static int ti_init_rx_ring_jumbo(sc)
register int i;
struct ti_cmd_desc cmd;
for (i = 0; i < (TI_JSLOTS - 20); i++) {
for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) {
if (ti_newbuf_jumbo(sc, i, NULL) == ENOBUFS)
return(ENOBUFS);
};
@ -1688,6 +1690,17 @@ static int ti_attach(dev)
goto fail;
}
/*
* We really need a better way to tell a 1000baseTX card
* from a 1000baseSX one, since in theory there could be
* OEMed 1000baseTX cards from lame vendors who aren't
* clever enough to change the PCI ID. For the moment
* though, the AceNIC is the only copper card available.
*/
if (pci_get_vendor(dev) == ALT_VENDORID &&
pci_get_device(dev) == ALT_DEVICEID_ACENIC_COPPER)
sc->ti_copper = 1;
/* Set default tuneable values. */
sc->ti_stat_ticks = 2 * TI_TICKS_PER_SEC;
sc->ti_rx_coal_ticks = TI_TICKS_PER_SEC / 5000;
@ -1712,12 +1725,30 @@ static int ti_attach(dev)
/* Set up ifmedia support. */
ifmedia_init(&sc->ifmedia, IFM_IMASK, ti_ifmedia_upd, ti_ifmedia_sts);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_FL, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_FL|IFM_FDX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_FX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_FX|IFM_FDX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_SX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_SX|IFM_FDX, 0, NULL);
if (sc->ti_copper) {
/*
* Copper cards allow manual 10/100 mode selection,
* but not manual 1000baseTX mode selection. Why?
* Becuase currently there's no way to specify the
* master/slave setting through the firmware interface,
* so Alteon decided to just bag it and handle it
* via autonegotiation.
*/
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
ifmedia_add(&sc->ifmedia,
IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
ifmedia_add(&sc->ifmedia,
IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_TX, 0, NULL);
ifmedia_add(&sc->ifmedia,
IFM_ETHER|IFM_1000_TX|IFM_FDX, 0, NULL);
} else {
/* Fiber cards don't support 10/100 modes. */
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_1000_SX, 0, NULL);
ifmedia_add(&sc->ifmedia,
IFM_ETHER|IFM_1000_SX|IFM_FDX, 0, NULL);
}
ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO);
@ -2297,17 +2328,24 @@ static int ti_ifmedia_upd(ifp)
TI_CMD_CODE_NEGOTIATE_BOTH, 0);
break;
case IFM_1000_SX:
case IFM_1000_TX:
CSR_WRITE_4(sc, TI_GCR_GLINK, TI_GLNK_PREF|TI_GLNK_1000MB|
TI_GLNK_FULL_DUPLEX|TI_GLNK_RX_FLOWCTL_Y|TI_GLNK_ENB);
TI_GLNK_RX_FLOWCTL_Y|TI_GLNK_ENB);
CSR_WRITE_4(sc, TI_GCR_LINK, 0);
if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) {
TI_SETBIT(sc, TI_GCR_GLINK, TI_GLNK_FULL_DUPLEX);
}
TI_DO_CMD(TI_CMD_LINK_NEGOTIATION,
TI_CMD_CODE_NEGOTIATE_GIGABIT, 0);
break;
case IFM_100_FX:
case IFM_10_FL:
case IFM_100_TX:
case IFM_10_T:
CSR_WRITE_4(sc, TI_GCR_GLINK, 0);
CSR_WRITE_4(sc, TI_GCR_LINK, TI_LNK_ENB|TI_LNK_PREF);
if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_FX) {
if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_FX ||
IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX) {
TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_100MB);
} else {
TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_10MB);
@ -2333,6 +2371,7 @@ static void ti_ifmedia_sts(ifp, ifmr)
struct ifmediareq *ifmr;
{
struct ti_softc *sc;
u_int32_t media = 0;
sc = ifp->if_softc;
@ -2344,15 +2383,29 @@ static void ti_ifmedia_sts(ifp, ifmr)
ifmr->ifm_status |= IFM_ACTIVE;
if (sc->ti_linkstat == TI_EV_CODE_GIG_LINK_UP)
ifmr->ifm_active |= IFM_1000_SX|IFM_FDX;
else if (sc->ti_linkstat == TI_EV_CODE_LINK_UP) {
u_int32_t media;
if (sc->ti_linkstat == TI_EV_CODE_GIG_LINK_UP) {
media = CSR_READ_4(sc, TI_GCR_GLINK_STAT);
if (sc->ti_copper)
ifmr->ifm_active |= IFM_1000_TX;
else
ifmr->ifm_active |= IFM_1000_SX;
if (media & TI_GLNK_FULL_DUPLEX)
ifmr->ifm_active |= IFM_FDX;
else
ifmr->ifm_active |= IFM_HDX;
} else if (sc->ti_linkstat == TI_EV_CODE_LINK_UP) {
media = CSR_READ_4(sc, TI_GCR_LINK_STAT);
if (media & TI_LNK_100MB)
ifmr->ifm_active |= IFM_100_FX;
if (media & TI_LNK_10MB)
ifmr->ifm_active |= IFM_10_FL;
if (sc->ti_copper) {
if (media & TI_LNK_100MB)
ifmr->ifm_active |= IFM_100_TX;
if (media & TI_LNK_10MB)
ifmr->ifm_active |= IFM_10_T;
} else {
if (media & TI_LNK_100MB)
ifmr->ifm_active |= IFM_100_FX;
if (media & TI_LNK_10MB)
ifmr->ifm_active |= IFM_10_FL;
}
if (media & TI_LNK_FULL_DUPLEX)
ifmr->ifm_active |= IFM_FDX;
if (media & TI_LNK_HALF_DUPLEX)

View file

@ -60,6 +60,7 @@
*/
#define ALT_VENDORID 0x12AE
#define ALT_DEVICEID_ACENIC 0x0001
#define ALT_DEVICEID_ACENIC_COPPER 0x0002
/*
* 3Com 3c985 PCI vendor/device ID.
@ -134,8 +135,8 @@
* Firmware revision that we want.
*/
#define TI_FIRMWARE_MAJOR 0xc
#define TI_FIRMWARE_MINOR 0x3
#define TI_FIRMWARE_FIX 0x15
#define TI_FIRMWARE_MINOR 0x4
#define TI_FIRMWARE_FIX 0xd
/*
* Miscelaneous Local Control register.
@ -1033,7 +1034,7 @@ struct ti_event_desc {
#define TI_SSLOTS 256
#define TI_MSLOTS 256
#define TI_JSLOTS 256
#define TI_JSLOTS 384
#define TI_JRAWLEN (TI_JUMBO_FRAMELEN + ETHER_ALIGN + sizeof(u_int64_t))
#define TI_JLEN (TI_JRAWLEN + (sizeof(u_int64_t) - \
@ -1122,6 +1123,7 @@ struct ti_softc {
struct ifmedia ifmedia; /* media info */
u_int8_t ti_unit; /* interface number */
u_int8_t ti_hwrev; /* Tigon rev (1 or 2) */
u_int8_t ti_copper; /* 1000baseTX card */
u_int8_t ti_linkstat; /* Link state */
struct ti_ring_data *ti_rdata; /* rings */
struct ti_chain_data ti_cdata; /* mbufs */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff