Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-2-0]: src/sys/dev/pci Pull up revision 1.11 (requested by abs in ...



details:   https://anonhg.NetBSD.org/src/rev/b8db9e9df6e4
branches:  netbsd-2-0
changeset: 564642:b8db9e9df6e4
user:      jdc <jdc%NetBSD.org@localhost>
date:      Fri Jan 07 12:13:50 2005 +0000

description:
Pull up revision 1.11 (requested by abs in ticket #973).

Fix Yukon ram sizing.
Fix tx queue (slist can be corrupted when tx interrupts hit within tx_encap.
Lower interrupt moderation timer to (improves performance).
Improve chip identification. (from linux sk98lin driver).
Keep tx queue running by kicking the tx bmu repeatedly.

diffstat:

 sys/dev/pci/if_sk.c |  156 ++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 127 insertions(+), 29 deletions(-)

diffs (truncated from 338 to 300 lines):

diff -r 6043302b2376 -r b8db9e9df6e4 sys/dev/pci/if_sk.c
--- a/sys/dev/pci/if_sk.c       Fri Jan 07 11:44:22 2005 +0000
+++ b/sys/dev/pci/if_sk.c       Fri Jan 07 12:13:50 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_sk.c,v 1.7.2.3 2004/05/25 01:32:30 jmc Exp $        */
+/*     $NetBSD: if_sk.c,v 1.7.2.4 2005/01/07 12:13:50 jdc Exp $        */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -407,7 +407,7 @@
        sc->sk_vpd_readonly = malloc(res.vr_len, M_DEVBUF, M_NOWAIT);
        if (sc->sk_vpd_readonly == NULL)
                panic("sk_vpd_read");
-       for (i = 0; i < res.vr_len + 1; i++)
+       for (i = 0; i < res.vr_len ; i++)
                sc->sk_vpd_readonly[i] = sk_vpd_readbyte(sc, i + pos);
 }
 
@@ -624,6 +624,8 @@
                SK_XM_WRITE_4(sc_if, XM_MAR2, 0);
                break;
        case SK_YUKON:
+       case SK_YUKON_LITE:
+       case SK_YUKON_LP:
                SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0);
                SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0);
                SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0);
@@ -663,6 +665,8 @@
                                        h = sk_xmac_hash(enm->enm_addrlo);
                                        break;
                                case SK_YUKON:
+                               case SK_YUKON_LITE:
+                               case SK_YUKON_LP:
                                        h = sk_yukon_hash(enm->enm_addrlo);
                                        break;
                                }
@@ -684,6 +688,8 @@
                SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]);
                break;
        case SK_YUKON:
+       case SK_YUKON_LITE:
+       case SK_YUKON_LP:
                SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff);
                SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff);
                SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff);
@@ -879,6 +885,8 @@
                                            XM_MODE_RX_PROMISC);
                                        break;
                                case SK_YUKON:
+                               case SK_YUKON_LITE:
+                               case SK_YUKON_LP:
                                        SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
                                            YU_RCR_UFLEN | YU_RCR_MUFLEN);
                                        break;
@@ -893,6 +901,8 @@
                                            XM_MODE_RX_PROMISC);
                                        break;
                                case SK_YUKON:
+                               case SK_YUKON_LITE:
+                               case SK_YUKON_LP:
                                        SK_YU_SETBIT_2(sc_if, YUKON_RCR,
                                            YU_RCR_UFLEN | YU_RCR_MUFLEN);
                                        break;
@@ -977,14 +987,14 @@
 
        CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_RESET);
        CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_RESET);
-       if (sc->sk_type == SK_YUKON)
+       if (SK_YUKON_FAMILY(sc->sk_type))
                CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET);
 
        DELAY(1000);
        CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_UNRESET);
        DELAY(2);
        CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_UNRESET);
-       if (sc->sk_type == SK_YUKON)
+       if (SK_YUKON_FAMILY(sc->sk_type))
                CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR);
 
        DPRINTFN(2, ("sk_reset: sk_csr=%x\n", CSR_READ_2(sc, SK_CSR)));
@@ -1011,7 +1021,7 @@
         * register represents 18.825ns, so to specify a timeout in
         * microseconds, we have to multiply by 54.
         */
-        sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(200));
+        sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(100));
         sk_win_write_4(sc, SK_IMMR, SK_ISR_TX1_S_EOF|SK_ISR_TX2_S_EOF|
            SK_ISR_RX1_EOF|SK_ISR_RX2_EOF);
         sk_win_write_1(sc, SK_IMTIMERCTL, SK_IMCTL_START);
@@ -1168,7 +1178,7 @@
        for (i = 0; i < SK_RX_RING_CNT; i++)
                sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf = NULL;
 
-       SLIST_INIT(&sc_if->sk_txmap_listhead);
+       SIMPLEQ_INIT(&sc_if->sk_txmap_head);
        for (i = 0; i < SK_TX_RING_CNT; i++) {
                sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf = NULL;
 
@@ -1197,7 +1207,7 @@
                        goto fail;
                }
                entry->dmamap = dmamap;
-               SLIST_INSERT_HEAD(&sc_if->sk_txmap_listhead, entry, link);
+               SIMPLEQ_INSERT_HEAD(&sc_if->sk_txmap_head, entry, link);
        }
 
         sc_if->sk_rdata = (struct sk_ring_data *)kva;
@@ -1229,6 +1239,8 @@
                sk_init_xmac(sc_if);
                break;
        case SK_YUKON:
+       case SK_YUKON_LITE:
+       case SK_YUKON_LP:
                sk_init_yukon(sc_if);
                break;
        default:
@@ -1246,6 +1258,8 @@
                sc_if->sk_mii.mii_statchg = sk_xmac_miibus_statchg;
                break;
        case SK_YUKON:
+       case SK_YUKON_LITE:
+       case SK_YUKON_LP:
                sc_if->sk_mii.mii_readreg = sk_marv_miibus_readreg;
                sc_if->sk_mii.mii_writereg = sk_marv_miibus_writereg;
                sc_if->sk_mii.mii_statchg = sk_marv_miibus_statchg;
@@ -1322,6 +1336,7 @@
        bus_size_t iosize;
        int s;
        u_int32_t command;
+       char *revstr;
 
        DPRINTFN(2, ("begin skc_attach\n"));
 
@@ -1367,22 +1382,6 @@
        pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
        command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
 
-       switch (PCI_PRODUCT(pa->pa_id)) {
-       case PCI_PRODUCT_SCHNEIDERKOCH_SKNET_GE:
-               sc->sk_type = SK_GENESIS;
-               break;
-       case PCI_PRODUCT_SCHNEIDERKOCH_SK9821v2:
-       case PCI_PRODUCT_3COM_3C940:
-       case PCI_PRODUCT_DLINK_DGE530T:
-       case PCI_PRODUCT_LINKSYS_EG1032:
-       case PCI_PRODUCT_LINKSYS_EG1064:
-               sc->sk_type = SK_YUKON;
-               break;
-       default:
-               aprint_error(": unknown device!\n");
-               goto fail;
-       }
-
 #ifdef SK_USEIOSPACE
        if (!(command & PCI_COMMAND_IO_ENABLE)) {
                aprint_error(": failed to enable I/O ports!\n");
@@ -1419,6 +1418,14 @@
 #endif
        sc->sc_dmatag = pa->pa_dmat;
 
+       sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
+       sc->sk_rev  = (sk_win_read_1(sc, SK_CONFIG) >> 4);
+
+       /* bail out here if chip is not recognized */
+       if ( sc->sk_type != SK_GENESIS && ! SK_YUKON_FAMILY(sc->sk_type)) {
+               aprint_error("%s: unknown chip type\n",sc->sk_dev.dv_xname);
+               goto fail;
+       }
        DPRINTFN(2, ("skc_attach: allocate interrupt\n"));
 
        /* Allocate interrupt */
@@ -1474,7 +1481,8 @@
                             sc->sk_ramsize, sc->sk_ramsize / 1024,
                             sc->sk_rboff));
        } else {
-               sc->sk_ramsize = 0x20000;
+               u_int8_t val = sk_win_read_1(sc, SK_EPROM0);
+               sc->sk_ramsize =  ( val == 0 ) ?  0x20000 : (( val * 4 )*1024);
                sc->sk_rboff = SK_RBOFF_0;
 
                DPRINTFN(2, ("skc_attach: ramsize=%dk (%d), rboff=%d\n",
@@ -1502,8 +1510,91 @@
                goto fail;
        }
 
+       /* determine whether to name it with vpd or just make it up */
+       /* Marvell Yukon VPD's can freqently be bogus */
+
+       switch (pa->pa_id) {
+       case PCI_ID_CODE(PCI_VENDOR_SCHNEIDERKOCH,
+                        PCI_PRODUCT_SCHNEIDERKOCH_SKNET_GE):
+       case PCI_PRODUCT_SCHNEIDERKOCH_SK9821v2:
+       case PCI_PRODUCT_3COM_3C940:
+       case PCI_PRODUCT_DLINK_DGE530T:
+       case PCI_PRODUCT_LINKSYS_EG1032:
+       case PCI_PRODUCT_LINKSYS_EG1064:
+       case PCI_ID_CODE(PCI_VENDOR_SCHNEIDERKOCH,
+                        PCI_PRODUCT_SCHNEIDERKOCH_SK9821v2):
+       case PCI_ID_CODE(PCI_VENDOR_3COM,PCI_PRODUCT_3COM_3C940):
+       case PCI_ID_CODE(PCI_VENDOR_DLINK,PCI_PRODUCT_DLINK_DGE530T):
+       case PCI_ID_CODE(PCI_VENDOR_LINKSYS,PCI_PRODUCT_LINKSYS_EG1032):
+       case PCI_ID_CODE(PCI_VENDOR_LINKSYS,PCI_PRODUCT_LINKSYS_EG1064):
+               sc->sk_name = sc->sk_vpd_prodname;
+               break;
+       case PCI_ID_CODE(PCI_VENDOR_GALILEO,PCI_PRODUCT_GALILEO_SKNET):
+       /* whoops yukon vpd prodname bears no resemblance to reality */
+               switch (sc->sk_type) {
+               case SK_GENESIS:
+                       sc->sk_name = sc->sk_vpd_prodname;
+                       break;
+               case SK_YUKON:
+                       sc->sk_name = "Marvell Yukon Gigabit Ethernet";
+                       break;
+               case SK_YUKON_LITE:
+                       sc->sk_name = "Marvell Yukon Lite Gigabit Ethernet";
+                       break;
+               case SK_YUKON_LP:
+                       sc->sk_name = "Marvell Yukon LP Gigabit Ethernet";
+                       break;
+               default:
+                       sc->sk_name = "Marvell Yukon (Unknown) Gigabit Ethernet";
+               }
+
+       /* Yukon Lite Rev A0 needs special test, from sk98lin driver */
+
+               if ( sc->sk_type == SK_YUKON ) {
+                       uint32_t flashaddr;
+                       uint8_t testbyte;
+                       
+                       flashaddr = sk_win_read_4(sc,SK_EP_ADDR);
+                       
+                       /* test Flash-Address Register */
+                       sk_win_write_1(sc,SK_EP_ADDR+3, 0xff);
+                       testbyte = sk_win_read_1(sc, SK_EP_ADDR+3);
+                       
+                       if (testbyte != 0) {
+                               /* this is yukon lite Rev. A0 */
+                               sc->sk_type = SK_YUKON_LITE;
+                               sc->sk_rev = SK_YUKON_LITE_REV_A0;
+                               /* restore Flash-Address Register */
+                               sk_win_write_4(sc,SK_EP_ADDR,flashaddr);
+                       }
+               }
+               break;
+       default:
+               sc->sk_name = "Unkown Marvell";
+       }
+
+               
+       if ( sc->sk_type == SK_YUKON_LITE ) {
+               switch (sc->sk_rev) {
+               case SK_YUKON_LITE_REV_A0:
+                       revstr = "A0";
+                       break;
+               case SK_YUKON_LITE_REV_A1:
+                       revstr = "A1";
+                       break;
+               case SK_YUKON_LITE_REV_A3:
+                       revstr = "A3";
+                       break;
+               default:
+                       revstr = "";
+               }
+       } else {
+               revstr = "";
+       }
+
        /* Announce the product name. */
-       aprint_normal("%s: %s\n", sc->sk_dev.dv_xname, sc->sk_vpd_prodname);
+       aprint_normal("%s: %s rev. %s(0x%x)\n", sc->sk_dev.dv_xname,
+                             sc->sk_name, revstr, sc->sk_rev);
 
        skca.skc_port = SK_PORT_A;
        (void)config_found(&sc->sk_dev, &skca, skcprint);
@@ -1532,7 +1623,7 @@
 
        DPRINTFN(3, ("sk_encap\n"));
 
-       entry = SLIST_FIRST(&sc_if->sk_txmap_listhead);
+       entry = SIMPLEQ_FIRST(&sc_if->sk_txmap_head);
        if (entry == NULL) {
                DPRINTFN(3, ("sk_encap: no txmap available\n"));
                return ENOBUFS;
@@ -1582,7 +1673,8 @@
        }
 
        sc_if->sk_cdata.sk_tx_chain[cur].sk_mbuf = m_head;
-       SLIST_REMOVE_HEAD(&sc_if->sk_txmap_listhead, link);
+       SIMPLEQ_REMOVE_HEAD(&sc_if->sk_txmap_head, link);
+
        sc_if->sk_cdata.sk_tx_map[cur] = entry;
        sc_if->sk_rdata->sk_tx_ring[cur].sk_ctl |=
                SK_TXCTL_LASTFRAG|SK_TXCTL_EOF_INTR;
@@ -1827,7 +1919,7 @@
                            entry->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
 
                        bus_dmamap_unload(sc->sc_dmatag, entry->dmamap);
-                       SLIST_INSERT_HEAD(&sc_if->sk_txmap_listhead, entry,
+                       SIMPLEQ_INSERT_TAIL(&sc_if->sk_txmap_head, entry,
                                          link);



Home | Main Index | Thread Index | Old Index