Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci Pull up FreeBSD changes:



details:   https://anonhg.NetBSD.org/src/rev/a2f1ab28c012
branches:  trunk
changeset: 499346:a2f1ab28c012
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Fri Nov 17 19:33:25 2000 +0000

description:
Pull up FreeBSD changes:
1.39:
Have if_ti stop "hiding" the softc pointer in the buffer region. Rather,
use the available void * passed to the free routine and pass the softc
pointer through there.
1.33:
Add support for the Netgear GA620T copper gigabit card.
1.32:
Tweak probe message so that 1000baseSX and 1000baseT cards are
explicitly identified.
1.31:
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.

NetBSD changes:
get rid of ti_inuse, the mbuf ref counting code should call ti_free() when
needed.
Use hardware 802.1q support.

diffstat:

 sys/dev/pci/if_ti.c    |  205 +++++++++++++++++++++++++++---------------------
 sys/dev/pci/if_tireg.h |   14 +--
 2 files changed, 119 insertions(+), 100 deletions(-)

diffs (truncated from 437 to 300 lines):

diff -r 91005bc38e3c -r a2f1ab28c012 sys/dev/pci/if_ti.c
--- a/sys/dev/pci/if_ti.c       Fri Nov 17 19:23:35 2000 +0000
+++ b/sys/dev/pci/if_ti.c       Fri Nov 17 19:33:25 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ti.c,v 1.14 2000/11/15 01:02:15 thorpej Exp $ */
+/* $NetBSD: if_ti.c,v 1.15 2000/11/17 19:33:25 bouyer Exp $ */
 
 /*
  * Copyright (c) 1997, 1998, 1999
@@ -137,11 +137,15 @@
 
 static struct ti_type ti_devs[] = {
        { PCI_VENDOR_ALTEON,    PCI_PRODUCT_ALTEON_ACENIC,
-               "Alteon AceNIC Gigabit Ethernet" },
+               "Alteon AceNIC 1000baseSX Gigabit Ethernet" },
+       { PCI_VENDOR_ALTEON,    PCI_PRODUCT_ALTEON_ACENIC_COPPER,
+               "Alteon AceNIC 1000baseT Gigabit Ethernet" },
        { PCI_VENDOR_3COM,      PCI_PRODUCT_3COM_3C985,
                "3Com 3c985-SX Gigabit Ethernet" },
        { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620,
-               "Netgear GA620 Gigabit Ethernet" },
+               "Netgear GA620 1000baseSX Gigabit Ethernet" },
+       { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620T,
+               "Netgear GA620 1000baseT Gigabit Ethernet" },
        { PCI_VENDOR_SGI, PCI_PRODUCT_SGI_TIGON,
                "Silicon Graphics Gigabit Ethernet" },
        { 0, 0, NULL }
@@ -627,21 +631,12 @@
 
        /*
         * Now divide it up into 9K pieces and save the addresses
-        * in an array. Note that we play an evil trick here by using
-        * the first few bytes in the buffer to hold the address
-        * of the softc structure for this interface. This is because
-        * ti_jfree() needs it, but it is called by the mbuf management
-        * code which will not pass it to us explicitly.
+        * in an array.
         */
        ptr = sc->ti_cdata.ti_jumbo_buf;
        for (i = 0; i < TI_JSLOTS; i++) {
-               u_int64_t               **aptr;
-               aptr = (u_int64_t **)ptr;
-               aptr[0] = (u_int64_t *)sc;
-               ptr += sizeof(u_int64_t);
-               sc->ti_cdata.ti_jslots[i].ti_buf = ptr;
-               sc->ti_cdata.ti_jslots[i].ti_inuse = 0;
-               ptr += (TI_JLEN - sizeof(u_int64_t));
+               sc->ti_cdata.ti_jslots[i] = ptr;
+               ptr += TI_JLEN;
                entry = malloc(sizeof(struct ti_jpool_entry), 
                               M_DEVBUF, M_NOWAIT);
                if (entry == NULL) {
@@ -676,8 +671,7 @@
 
        SIMPLEQ_REMOVE_HEAD(&sc->ti_jfree_listhead, entry, jpool_entries);
        SIMPLEQ_INSERT_HEAD(&sc->ti_jinuse_listhead, entry, jpool_entries);
-       sc->ti_cdata.ti_jslots[entry->slot].ti_inuse = 1;
-       return(sc->ti_cdata.ti_jslots[entry->slot].ti_buf);
+       return(sc->ti_cdata.ti_jslots[entry->slot]);
 }
 
 /*
@@ -686,45 +680,33 @@
 static void ti_jfree(buf, size, arg)
        caddr_t                 buf;
        u_int                   size;
-       void *arg; /* XXX NetBSD: we should really use it */
+       void *arg;
 {
        struct ti_softc         *sc;
-       u_int64_t               **aptr;
        int                     i;
        struct ti_jpool_entry   *entry;
 
        /* Extract the softc struct pointer. */
-       aptr = (u_int64_t **)(buf - sizeof(u_int64_t));
-       sc = (struct ti_softc *)(aptr[0]);
+       sc = (struct ti_softc *)arg;
 
        if (sc == NULL)
-               panic("ti_jfree: can't find softc pointer!");
-
-       if (size != TI_JUMBO_FRAMELEN)
-               panic("ti_jfree: freeing buffer of wrong size!");
+               panic("ti_jfree: didn't get softc pointer!");
 
        /* calculate the slot this buffer belongs to */
 
-       i = ((caddr_t)aptr 
+       i = ((caddr_t)buf
             - (caddr_t)sc->ti_cdata.ti_jumbo_buf) / TI_JLEN;
 
        if ((i < 0) || (i >= TI_JSLOTS))
                panic("ti_jfree: asked to free buffer that we don't manage!");
-       else if (sc->ti_cdata.ti_jslots[i].ti_inuse == 0)
-               panic("ti_jfree: buffer already free!");
-       else {
-               sc->ti_cdata.ti_jslots[i].ti_inuse--;
-               if(sc->ti_cdata.ti_jslots[i].ti_inuse == 0) {
-                       entry = SIMPLEQ_FIRST(&sc->ti_jinuse_listhead);
-                       if (entry == NULL)
-                               panic("ti_jfree: buffer not in use!");
-                       entry->slot = i;
-                       SIMPLEQ_REMOVE_HEAD(&sc->ti_jinuse_listhead, 
-                                           entry, jpool_entries);
-                       SIMPLEQ_INSERT_HEAD(&sc->ti_jfree_listhead, 
-                                            entry, jpool_entries);
-               }
-       }
+       entry = SIMPLEQ_FIRST(&sc->ti_jinuse_listhead);
+       if (entry == NULL)
+               panic("ti_jfree: buffer not in use!");
+       entry->slot = i;
+       SIMPLEQ_REMOVE_HEAD(&sc->ti_jinuse_listhead, 
+           entry, jpool_entries);
+       SIMPLEQ_INSERT_HEAD(&sc->ti_jfree_listhead, 
+            entry, jpool_entries);
 
        return;
 }
@@ -1486,9 +1468,7 @@
 #ifdef TI_CSUM_OFFLOAD
        rcb->ti_flags |= TI_RCB_FLAG_TCP_UDP_CKSUM|TI_RCB_FLAG_IP_CKSUM;
 #endif
-#if NVLAN > 0
        rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST;
-#endif
 
        /* Set up the jumbo receive ring. */
        rcb = &sc->ti_rdata->ti_info.ti_jumbo_rx_rcb;
@@ -1499,9 +1479,7 @@
 #ifdef TI_CSUM_OFFLOAD
        rcb->ti_flags |= TI_RCB_FLAG_TCP_UDP_CKSUM|TI_RCB_FLAG_IP_CKSUM;
 #endif
-#if NVLAN > 0
        rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST;
-#endif
 
        /*
         * Set up the mini ring. Only activated on the
@@ -1519,9 +1497,7 @@
 #ifdef TI_CSUM_OFFLOAD
        rcb->ti_flags |= TI_RCB_FLAG_TCP_UDP_CKSUM|TI_RCB_FLAG_IP_CKSUM;
 #endif
-#if NVLAN > 0
        rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST;
-#endif
 
        /*
         * Set up the receive return ring.
@@ -1556,9 +1532,7 @@
                rcb->ti_flags = 0;
        else
                rcb->ti_flags = TI_RCB_FLAG_HOST_RING;
-#if NVLAN > 0
        rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST;
-#endif
        rcb->ti_max_len = TI_TX_RING_CNT;
        if (sc->ti_hwrev == TI_HWREV_TIGON)
                TI_HOSTADDR(rcb->ti_hostaddr) = TI_TX_RING_BASE;
@@ -1787,6 +1761,21 @@
                goto fail2;
        }
 
+       /*
+        * 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_VENDOR(pa->pa_id) == PCI_VENDOR_ALTEON &&
+           PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALTEON_ACENIC_COPPER) ||
+           (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETGEAR &&
+           PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETGEAR_GA620T))
+               sc->ti_copper = 1;
+       else
+               sc->ti_copper = 0;
+
        /* Set default tuneable values. */
        sc->ti_stat_ticks = 2 * TI_TICKS_PER_SEC;
        sc->ti_rx_coal_ticks = TI_TICKS_PER_SEC / 5000;
@@ -1808,16 +1797,34 @@
        /*
         * We can support 802.1Q VLAN-sized frames.
         */
-       sc->ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
+       sc->ethercom.ec_capabilities |=
+           ETHERCAP_VLAN_MTU | ETHERCAP_VLAN_HWTAGGING;
 
        /* 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);
 
@@ -1856,10 +1863,8 @@
                struct ti_rx_desc       *cur_rx;
                u_int32_t               rxidx;
                struct mbuf             *m = NULL;
-#if NVLAN > 0
                u_int16_t               vlan_tag = 0;
                int                     have_tag = 0;
-#endif
 #ifdef TI_CSUM_OFFLOAD
                struct ip               *ip;
 #endif
@@ -1870,12 +1875,10 @@
                rxidx = cur_rx->ti_idx;
                TI_INC(sc->ti_rx_saved_considx, TI_RETURN_RING_CNT);
 
-#if NVLAN > 0
                if (cur_rx->ti_flags & TI_BDFLAG_VLAN_TAG) {
                        have_tag = 1;
                        vlan_tag = cur_rx->ti_vlan_tag;
                }
-#endif
 
                if (cur_rx->ti_flags & TI_BDFLAG_JUMBO_RING) {
                        TI_INC(sc->ti_jumbo, TI_JUMBO_RX_RING_CNT);
@@ -1950,17 +1953,19 @@
                        m->m_flags |= M_HWCKSUM;
 #endif
 
-#if NVLAN > 0 /* XXX NetBSD: broken because m points to ether pkt */
-               /*
-                * If we received a packet with a vlan tag, pass it
-                * to vlan_input() instead of ether_input().
-                */
                if (have_tag) {
-                       vlan_input_tag(eh, m, vlan_tag);
+                       struct mbuf *n;
+                       n = m_aux_add(m, AF_LINK, ETHERTYPE_VLAN);
+                       if (n) {
+                               *mtod(n, int *) = vlan_tag;
+                               n->m_len = sizeof(int);
+                       } else {
+                               printf("%s: no mbuf for tag\n", ifp->if_xname);
+                               m_freem(m);
+                               continue;
+                       }
                        have_tag = vlan_tag = 0;
-                       continue;
                }
-#endif
                (*ifp->if_input)(ifp, m);
        }
 
@@ -2099,14 +2104,7 @@
        struct txdmamap_pool_entry *dma;
        bus_dmamap_t dmamap;
        int error, i;
-#if NVLAN > 0
-       struct ifvlan           *ifv = NULL;
-
-       if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-           m_head->m_pkthdr.rcvif != NULL &&
-           m_head->m_pkthdr.rcvif->if_type == IFT_8021_VLAN)
-               ifv = m_head->m_pkthdr.rcvif->if_softc;
-#endif
+       struct mbuf *n;
 
        dma = SIMPLEQ_FIRST(&sc->txdma_list);
        if (dma == NULL) {
@@ -2154,14 +2152,13 @@
                        TI_HOSTADDR(f->ti_addr) = dmamap->dm_segs[i].ds_addr;
                        f->ti_len = dmamap->dm_segs[i].ds_len;
                        f->ti_flags = 0;
-#if NVLAN > 0
-                       if (ifv != NULL) {
+                       n = m_aux_find(m_head, AF_LINK, ETHERTYPE_VLAN);
+                       if (n) {



Home | Main Index | Thread Index | Old Index