- Close PR #11136: add PCI ID for another new cyclone device: the

3c900B-TPC (twisted pair and coax). Treated similarly to the
  3c900B-COMBO, except no AUI port.

- Fix media selection so that it's possible to select the AUI and BNC
  ports on the 3c905B-COMBO. This board is now fully supported.

- Change TX queueing strategy to hopefully be more efficient by avoiding
  register accesses in xl_start(). Should provide small performance
  improvement and a little better reliability.
This commit is contained in:
Bill Paul 1999-04-15 03:18:33 +00:00
parent 9b0f83b7fb
commit ae1a2d45d9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=45693
2 changed files with 61 additions and 32 deletions

View File

@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_xl.c,v 1.75 1999/04/12 20:23:08 wpaul Exp $
* $Id: if_xl.c,v 1.83 1999/04/15 02:34:54 wpaul Exp $
*/
/*
@ -45,6 +45,7 @@
* 3Com 3c905-T4 10/100Mbps/RJ-45
* 3Com 3c900B-TPO 10Mbps/RJ-45
* 3Com 3c900B-COMBO 10Mbps/RJ-45,AUI,BNC
* 3Com 3c900B-TPC 10Mbps/RJ-45,BNC
* 3Com 3c905B-COMBO 10/100Mbps/RJ-45,AUI,BNC
* 3Com 3c905B-TX 10/100Mbps/RJ-45
* 3Com 3c905B-FL/FX 10/100Mbps/Fiber-optic
@ -152,7 +153,7 @@
#if !defined(lint)
static const char rcsid[] =
"$Id: if_xl.c,v 1.75 1999/04/12 20:23:08 wpaul Exp $";
"$Id: if_xl.c,v 1.83 1999/04/15 02:34:54 wpaul Exp $";
#endif
/*
@ -171,6 +172,10 @@ static struct xl_type xl_devs[] = {
"3Com 3c900B-TPO Etherlink XL" },
{ TC_VENDORID, TC_DEVICEID_CYCLONE_10BT_COMBO,
"3Com 3c900B-COMBO Etherlink XL" },
{ TC_VENDORID, TC_DEVICEID_CYCLONE_10BT_TPC,
"3Com 3c900B-TPC Etherlink XL" },
{ TC_VENDORID, TC_DEVICEID_CYCLONE_10FL,
"3Com 3c900B-FL Etherlink XL" },
{ TC_VENDORID, TC_DEVICEID_CYCLONE_10_100BT,
"3Com 3c905B-TX Fast Etherlink XL" },
{ TC_VENDORID, TC_DEVICEID_CYCLONE_10_100BT4,
@ -448,8 +453,6 @@ static int xl_mii_writereg(sc, frame)
{
int s;
s = splimp();
/*
* Set up frame for TX.
@ -748,6 +751,21 @@ static void xl_autoneg_xmit(sc)
struct xl_softc *sc;
{
u_int16_t phy_sts;
u_int32_t icfg;
xl_reset(sc);
XL_SEL_WIN(3);
icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
icfg &= ~XL_ICFG_CONNECTOR_MASK;
if (sc->xl_media & XL_MEDIAOPT_MII ||
sc->xl_media & XL_MEDIAOPT_BT4)
icfg |= (XL_XCVR_MII << XL_ICFG_CONNECTOR_BITS);
if (sc->xl_media & XL_MEDIAOPT_BTX)
icfg |= (XL_XCVR_AUTO << XL_ICFG_CONNECTOR_BITS);
if (sc->xl_media & XL_MEDIAOPT_BFX)
icfg |= (XL_XCVR_100BFX << XL_ICFG_CONNECTOR_BITS);
CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
xl_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);
DELAY(500);
@ -1290,6 +1308,11 @@ static void xl_mediacheck(sc)
sc->xl_xcvr = XL_XCVR_10BT;
printf("xl%d: guessing COMBO (AUI/BNC/TP)\n", sc->xl_unit);
break;
case TC_DEVICEID_CYCLONE_10BT_TPC: /* 3c900B-TPC */
sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC;
sc->xl_xcvr = XL_XCVR_10BT;
printf("xl%d: guessing TPC (BNC/TP)\n", sc->xl_unit);
break;
case TC_DEVICEID_BOOMERANG_10_100BT: /* 3c905-TX */
sc->xl_media = XL_MEDIAOPT_MII;
sc->xl_xcvr = XL_XCVR_MII;
@ -1302,13 +1325,17 @@ static void xl_mediacheck(sc)
printf("xl%d: guessing 100BaseT4/MII\n", sc->xl_unit);
break;
case TC_DEVICEID_CYCLONE_10_100BT: /* 3c905B-TX */
case TC_DEVICEID_CYCLONE_10_100_COMBO: /* 3c905B-COMBO */
case TC_DEVICEID_CYCLONE_10_100BT_SERV: /* 3c980-TX */
case TC_DEVICEID_HURRICANE_SOHO100TX: /* 3cSOHO100-TX */
sc->xl_media = XL_MEDIAOPT_BTX;
sc->xl_xcvr = XL_XCVR_AUTO;
printf("xl%d: guessing 10/100 internal\n", sc->xl_unit);
break;
case TC_DEVICEID_CYCLONE_10_100_COMBO: /* 3c905B-COMBO */
sc->xl_media = XL_MEDIAOPT_BTX|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
sc->xl_xcvr = XL_XCVR_AUTO;
printf("xl%d: guessing 10/100 plus BNC/AUI\n", sc->xl_unit);
break;
default:
printf("xl%d: unknown device ID: %x -- "
"defaulting to 10baseT\n", sc->xl_unit, devid);
@ -1740,6 +1767,7 @@ static int xl_list_tx_init(sc)
ld = sc->xl_ldata;
for (i = 0; i < XL_TX_LIST_CNT; i++) {
cd->xl_tx_chain[i].xl_ptr = &ld->xl_tx_list[i];
cd->xl_tx_chain[i].xl_unsent = 0;
if (i == (XL_TX_LIST_CNT - 1))
cd->xl_tx_chain[i].xl_next = NULL;
else
@ -1889,6 +1917,7 @@ static void xl_rxeof(sc)
continue;
}
ifp->if_ipackets++;
eh = mtod(m, struct ether_header *);
m->m_pkthdr.rcvif = ifp;
#if NBPFILTER > 0
@ -1970,14 +1999,15 @@ static void xl_txeof(sc)
while(sc->xl_cdata.xl_tx_head != NULL) {
cur_tx = sc->xl_cdata.xl_tx_head;
if ((sc->xl_type == XL_TYPE_905B &&
!(cur_tx->xl_ptr->xl_status & XL_TXSTAT_DL_COMPLETE)) ||
CSR_READ_4(sc, XL_DOWNLIST_PTR)) {
!(cur_tx->xl_ptr->xl_status & XL_TXSTAT_DL_COMPLETE)) ||
(CSR_READ_1(sc, XL_TX_STATUS) & XL_TXSTATUS_COMPLETE) ||
cur_tx->xl_unsent) {
break;
}
sc->xl_cdata.xl_tx_head = cur_tx->xl_next;
m_freem(cur_tx->xl_mbuf);
cur_tx->xl_mbuf = NULL;
ifp->if_opackets++;
cur_tx->xl_next = sc->xl_cdata.xl_tx_free;
sc->xl_cdata.xl_tx_free = cur_tx;
@ -1989,8 +2019,8 @@ static void xl_txeof(sc)
if (sc->xl_want_auto)
xl_autoneg_mii(sc, XL_FLAG_SCHEDDELAY, 1);
} else {
if (CSR_READ_4(sc, XL_DMACTL) & XL_DMACTL_DOWN_STALLED ||
!CSR_READ_4(sc, XL_DOWNLIST_PTR)) {
if (sc->xl_cdata.xl_tx_head->xl_unsent) {
sc->xl_cdata.xl_tx_head->xl_unsent = 0;
CSR_WRITE_4(sc, XL_DOWNLIST_PTR,
vtophys(sc->xl_cdata.xl_tx_head->xl_ptr));
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
@ -2136,9 +2166,6 @@ static void xl_stats_update(xsc)
for (i = 0; i < 16; i++)
*p++ = CSR_READ_1(sc, XL_W6_CARRIER_LOST + i);
ifp->if_ipackets += xl_rx_goodframes(xl_stats);
ifp->if_opackets += xl_tx_goodframes(xl_stats);
ifp->if_ierrors += xl_stats.xl_rx_overrun;
ifp->if_collisions += xl_stats.xl_tx_multi_collision +
@ -2322,28 +2349,16 @@ static void xl_start(ifp)
*/
cur_tx->xl_ptr->xl_status |= XL_TXSTAT_DL_INTR;
/*
* Queue the packets. If the TX channel is clear, update
* the downlist pointer register.
*/
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_STALL);
xl_wait(sc);
if (CSR_READ_4(sc, XL_DOWNLIST_PTR)) {
sc->xl_cdata.xl_tx_tail->xl_next = start_tx;
sc->xl_cdata.xl_tx_tail->xl_ptr->xl_next =
vtophys(start_tx->xl_ptr);
sc->xl_cdata.xl_tx_tail->xl_ptr->xl_status &=
~XL_TXSTAT_DL_INTR;
sc->xl_cdata.xl_tx_tail = cur_tx;
} else {
if (sc->xl_cdata.xl_tx_head == NULL) {
sc->xl_cdata.xl_tx_head = start_tx;
sc->xl_cdata.xl_tx_tail = cur_tx;
CSR_WRITE_4(sc, XL_DOWNLIST_PTR, vtophys(start_tx->xl_ptr));
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
} else {
start_tx->xl_unsent++;
sc->xl_cdata.xl_tx_tail->xl_next = start_tx;
sc->xl_cdata.xl_tx_tail = cur_tx;
}
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
XL_SEL_WIN(7);
/*
* Set a timeout in case the chip goes out to lunch.
@ -2568,6 +2583,17 @@ static int xl_ifmedia_upd(ifp)
if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
return(EINVAL);
switch(IFM_SUBTYPE(ifm->ifm_media)) {
case IFM_100_FX:
case IFM_10_2:
case IFM_10_5:
xl_setmode(sc, ifm->ifm_media);
return(0);
break;
default:
break;
}
if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX
|| sc->xl_media & XL_MEDIAOPT_BT4) {
if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO)

View File

@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_xlreg.h,v 1.22 1999/04/12 20:23:08 wpaul Exp $
* $Id: if_xlreg.h,v 1.25 1999/04/14 22:21:36 wpaul Exp $
*/
#define XL_EE_READ 0x0080 /* read, 5 bit address */
@ -451,6 +451,7 @@ struct xl_chain {
struct xl_list *xl_ptr;
struct mbuf *xl_mbuf;
struct xl_chain *xl_next;
u_int8_t xl_unsent;
};
struct xl_chain_onefrag {
@ -618,6 +619,8 @@ struct xl_stats {
#define TC_DEVICEID_BOOMERANG_100BT4 0x9051
#define TC_DEVICEID_CYCLONE_10BT 0x9004
#define TC_DEVICEID_CYCLONE_10BT_COMBO 0x9005
#define TC_DEVICEID_CYCLONE_10BT_TPC 0x9006
#define TC_DEVICEID_CYCLONE_10FL 0x900A
#define TC_DEVICEID_CYCLONE_10_100BT 0x9055
#define TC_DEVICEID_CYCLONE_10_100BT4 0x9056
#define TC_DEVICEID_CYCLONE_10_100_COMBO 0x9058