Author: jchandra
Date: Thu Sep 16 19:13:55 2010
New Revision: 212758
URL: http://svn.freebsd.org/changeset/base/212758

Log:
  Network driver updates.
  
  - Move RMI MIPS extension to atomic increment word (LDADDWU) to common
    header file sys/mips/rmi/rmi_mips_exts.h
  - Fix xlr_ldaddwu() for 64 bit, it is a 32 bit operation, use
    unsigned int* instead of unsigned long* argument
  - Provide dummy xlr_enable_kx/xlr_restore_kx for n32 and n64.
  - Provide xlr_paddr_ld() instead of xlr_paddr_lw(), so that the
    descriptor formats are same for 32 and 64 bit
  - update nlge and rge for the changes
  
  These changes are also needed by the security driver which will be
  added later.

Modified:
  head/sys/mips/rmi/dev/nlge/if_nlge.c
  head/sys/mips/rmi/dev/xlr/rge.c
  head/sys/mips/rmi/rmi_mips_exts.h

Modified: head/sys/mips/rmi/dev/nlge/if_nlge.c
==============================================================================
--- head/sys/mips/rmi/dev/nlge/if_nlge.c        Thu Sep 16 18:37:33 2010        
(r212757)
+++ head/sys/mips/rmi/dev/nlge/if_nlge.c        Thu Sep 16 19:13:55 2010        
(r212758)
@@ -300,31 +300,13 @@ DRIVER_MODULE(miibus, nlge, miibus_drive
 
 static uma_zone_t nl_tx_desc_zone;
 
-/* Function to atomically increment an integer with the given value. */
-static __inline__ unsigned int
-ldadd_wu(unsigned int value, unsigned long *addr)
-{
-       __asm__  __volatile__( ".set push\n"
-                              ".set noreorder\n"
-                              "move $8, %2\n"
-                              "move $9, %3\n"
-                              /* "ldaddwu $8, $9\n" */
-                              ".word 0x71280011\n"
-                              "move %0, $8\n"
-                              ".set pop\n"
-                              : "=&r"(value), "+m"(*addr)
-                              : "0"(value), "r" ((unsigned long)addr)
-                              :  "$8", "$9");
-       return value;
-}
-
-static __inline__ uint32_t
-xlr_enable_kx(void)
+static __inline void
+atomic_incr_long(unsigned long *addr)
 {
-       uint32_t sr = mips_rd_status();
+       /* XXX: fix for 64 bit */
+       unsigned int *iaddr = (unsigned int *)addr;
 
-       mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_KX);
-       return sr;
+       xlr_ldaddwu(1, iaddr);
 }
 
 static int
@@ -683,7 +665,7 @@ nlge_msgring_handler(int bucket, int siz
                if (ifp->if_drv_flags & IFF_DRV_OACTIVE){
                        ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
                }
-               ldadd_wu(1, (tx_error) ? &ifp->if_oerrors: &ifp->if_opackets);
+               atomic_incr_long((tx_error) ? &ifp->if_oerrors: 
&ifp->if_opackets);
        } else if (ctrl == CTRL_SNGL || ctrl == CTRL_START) {
                /* Rx Packet */
 
@@ -766,7 +748,7 @@ fail:
                //ifp->if_drv_flags |= IFF_DRV_OACTIVE;
                //IF_PREPEND(&ifp->if_snd, m);
                m_freem(m);
-               ldadd_wu(1, &ifp->if_iqdrops);
+               atomic_incr_long(&ifp->if_iqdrops);
        }
        return;
 }
@@ -774,14 +756,15 @@ fail:
 static void
 nlge_rx(struct nlge_softc *sc, vm_paddr_t paddr, int len)
 {
-       struct ifnet   *ifp;
-       struct mbuf    *m;
-       uint32_t tm, mag, sr;
+       struct ifnet    *ifp;
+       struct mbuf     *m;
+       uint64_t        tm, mag;
+       uint32_t        sr;
 
        sr = xlr_enable_kx();
-       tm = xlr_paddr_lw(paddr - XLR_CACHELINE_SIZE);
-       mag = xlr_paddr_lw(paddr - XLR_CACHELINE_SIZE + sizeof(uint32_t));
-       mips_wr_status(sr);
+       tm = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE);
+       mag = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE + sizeof(uint64_t));
+       xlr_restore_kx(sr);
 
        m = (struct mbuf *)(intptr_t)tm;
        if (mag != 0xf00bad) {
@@ -797,7 +780,7 @@ nlge_rx(struct nlge_softc *sc, vm_paddr_
        m->m_pkthdr.len = m->m_len = len;
        m->m_pkthdr.rcvif = ifp;
 
-       ldadd_wu(1, &ifp->if_ipackets);
+       atomic_incr_long(&ifp->if_ipackets);
        (*ifp->if_input)(ifp, m);
 }
 
@@ -1895,15 +1878,11 @@ prepare_fmn_message(struct nlge_softc *s
                                        return 2;
                                }
                                /*
-                                * As we currently use xlr_paddr_lw on a 32-bit
-                                * OS, both the pointers are laid out in one
-                                * 64-bit location - this makes it easy to
-                                * retrieve the pointers when processing the
-                                * tx free-back descriptor.
+                                * Save the virtual address in the descriptor,
+                                * it makes freeing easy.
                                 */
                                p2p->frag[XLR_MAX_TX_FRAGS] =
-                                   (((uint64_t) (vm_offset_t) p2p) << 32) |
-                                   ((vm_offset_t) mbuf_chain);
+                                   (uint64_t)(vm_offset_t)p2p;
                                cur_p2d = &p2p->frag[0];
                                is_p2p = 1;
                        } else if (msg_sz == (FMN_SZ - 2 + XLR_MAX_TX_FRAGS)) {
@@ -1932,7 +1911,7 @@ prepare_fmn_message(struct nlge_softc *s
 
        cur_p2d[-1] |= (1ULL << 63); /* set eop in most-recent p2d */
        *cur_p2d = (1ULL << 63) | ((uint64_t)fb_stn_id << 54) |
-            (vm_offset_t) mbuf_chain;
+            (vm_offset_t) mbuf_chain;   /* XXX: fix 64 bit */
        *tx_desc = p2p;
 
        if (is_p2p) {
@@ -1973,39 +1952,41 @@ release_tx_desc(vm_paddr_t paddr)
 {
        struct nlge_tx_desc *tx_desc;
        uint32_t        sr;
-       uint32_t        val1, val2;
+       uint64_t        vaddr;
 
        paddr += (XLR_MAX_TX_FRAGS * sizeof(uint64_t));
        sr = xlr_enable_kx();
-       val1 = xlr_paddr_lw(paddr);
-       paddr += sizeof(void *);
-       val2 = xlr_paddr_lw(paddr);
-       mips_wr_status(sr);
+       vaddr = xlr_paddr_ld(paddr);
+       xlr_restore_kx(sr);
 
-       tx_desc = (struct nlge_tx_desc*)(intptr_t) val1;
+       tx_desc = (struct nlge_tx_desc*)(intptr_t)vaddr;
        uma_zfree(nl_tx_desc_zone, tx_desc);
 }
 
 static void *
 get_buf(void)
 {
-       struct mbuf    *m_new;
-       vm_paddr_t      temp1, temp2;
-       unsigned int    *md;
+       struct mbuf     *m_new;
+       uint64_t        *md;
+#ifdef INVARIANTS
+       vm_paddr_t      temp1, temp2;
+#endif
 
        if ((m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR)) == NULL)
-               return NULL;
+               return (NULL);
        m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
        m_adj(m_new, XLR_CACHELINE_SIZE - ((unsigned int)m_new->m_data & 0x1f));
-       md = (unsigned int *)m_new->m_data;
-       md[0] = (unsigned int)m_new;    /* Back Ptr */
+       md = (uint64_t *)m_new->m_data;
+       md[0] = (intptr_t)m_new;        /* Back Ptr */
        md[1] = 0xf00bad;
        m_adj(m_new, XLR_CACHELINE_SIZE);
 
+#ifdef INVARIANTS
        temp1 = vtophys((vm_offset_t) m_new->m_data);
        temp2 = vtophys((vm_offset_t) m_new->m_data + 1536);
        if ((temp1 + 1536) != temp2)
                panic("ALLOCED BUFFER IS NOT CONTIGUOUS\n");
+#endif
 
        return ((void *)m_new->m_data);
 }

Modified: head/sys/mips/rmi/dev/xlr/rge.c
==============================================================================
--- head/sys/mips/rmi/dev/xlr/rge.c     Thu Sep 16 18:37:33 2010        
(r212757)
+++ head/sys/mips/rmi/dev/xlr/rge.c     Thu Sep 16 19:13:55 2010        
(r212758)
@@ -184,35 +184,8 @@ int xlr_rge_tx_ok_done[MAXCPU];
 int xlr_rge_rx_done[MAXCPU];
 int xlr_rge_repl_done[MAXCPU];
 
-static __inline__ unsigned int
-ldadd_wu(unsigned int value, unsigned long *addr)
-{
-       __asm__ __volatile__(".set push\n"
-                   ".set noreorder\n"
-                   "move $8, %2\n"
-                   "move $9, %3\n"
-       /* "ldaddwu $8, $9\n" */
-                   ".word 0x71280011\n"
-                   "move %0, $8\n"
-                   ".set pop\n"
-           :       "=&r"(value), "+m"(*addr)
-           :       "0"(value), "r"((unsigned long)addr)
-           :       "$8", "$9");
-
-       return value;
-}
-
-static __inline__ uint32_t 
-xlr_enable_kx(void)
-{
-       uint32_t sr = mips_rd_status();
-
-       mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_KX);
-       return sr;
-}
-
 /* #define mac_stats_add(x, val) ({(x) += (val);}) */
-#define mac_stats_add(x, val) ldadd_wu(val, &x)
+#define mac_stats_add(x, val) xlr_ldaddwu(val, &x)
 
 #define XLR_MAX_CORE 8
 #define RGE_LOCK_INIT(_sc, _name) \
@@ -611,25 +584,16 @@ static void
 free_buf(vm_paddr_t paddr)
 {
        struct mbuf *m;
-       uint32_t mag;
-#ifdef __mips_n64
-       uint64_t *vaddr;
-
-       vaddr = (uint64_t *)MIPS_PHYS_TO_XKPHYS_CACHED(paddr);
-       m = (struct mbuf *)vaddr[0];
-       mag = (uint32_t)vaddr[1];
-#else
+       uint64_t mag;
        uint32_t sr;
 
        sr = xlr_enable_kx();
-       m = (struct mbuf *)(intptr_t)xlr_paddr_lw(paddr - XLR_CACHELINE_SIZE + 
sizeof(uint32_t));
-       mag = xlr_paddr_lw(paddr - XLR_CACHELINE_SIZE + 3 * sizeof(uint32_t));
-       mips_wr_status(sr);
-#endif
-
+       m = (struct mbuf *)(intptr_t)xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE);
+       mag = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE + sizeof(uint64_t));
+       xlr_restore_kx(sr);
        if (mag != 0xf00bad) {
-               printf("Something is wrong kseg:%lx found mag:%x not 
0xf00bad\n",
-                   (u_long)paddr, mag);
+               printf("Something is wrong kseg:%lx found mag:%lx not 
0xf00bad\n",
+                   (u_long)paddr, (u_long)mag);
                return;
        }
        if (m != NULL)
@@ -2022,15 +1986,8 @@ static void
 rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len)
 {
        struct mbuf *m;
-       uint32_t mag;
        struct ifnet *ifp = sc->rge_ifp;
-#ifdef __mips_n64
-       uint64_t *vaddr;
-
-       vaddr =(uint64_t *)MIPS_PHYS_TO_XKPHYS_CACHED(paddr - 
XLR_CACHELINE_SIZE);
-       m = (struct mbuf *)vaddr[0];
-       mag = (uint32_t)vaddr[1];
-#else
+       uint64_t mag;
        uint32_t sr;
        /*
         * On 32 bit machines we use XKPHYS to get the values stores with
@@ -2038,10 +1995,9 @@ rge_rx(struct rge_softc *sc, vm_paddr_t 
         * KX is enabled to prevent this setting leaking to other code.
         */
        sr = xlr_enable_kx();
-       m = (struct mbuf *)(intptr_t)xlr_paddr_lw(paddr - XLR_CACHELINE_SIZE + 
sizeof(uint32_t));
-       mag = xlr_paddr_lw(paddr - XLR_CACHELINE_SIZE + 3 * sizeof(uint32_t));
-       mips_wr_status(sr);
-#endif
+       m = (struct mbuf *)(intptr_t)xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE);
+       mag = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE + sizeof(uint64_t));
+       xlr_restore_kx(sr);
        if (mag != 0xf00bad) {
                /* somebody else packet Error - FIXME in intialization */
                printf("cpu %d: *ERROR* Not my packet paddr %p\n",

Modified: head/sys/mips/rmi/rmi_mips_exts.h
==============================================================================
--- head/sys/mips/rmi/rmi_mips_exts.h   Thu Sep 16 18:37:33 2010        
(r212757)
+++ head/sys/mips/rmi/rmi_mips_exts.h   Thu Sep 16 19:13:55 2010        
(r212758)
@@ -348,7 +348,7 @@ write_c0_eimr64(uint64_t val)
        write_c0_register64(9, 7, val);
 }
 
-static __inline__ int 
+static __inline int 
 xlr_test_and_set(int *lock)
 {
        int oldval = 0;
@@ -367,10 +367,10 @@ xlr_test_and_set(int *lock)
            : "$8", "$9"
        );
 
-       return (oldval == 0 ? 1 /* success */ : 0 /* failure */ );
+       return (oldval == 0 ? 1 /* success */ : 0 /* failure */);
 }
 
-static __inline__ uint32_t 
+static __inline uint32_t 
 xlr_mfcr(uint32_t reg)
 {
        uint32_t val;
@@ -385,7 +385,7 @@ xlr_mfcr(uint32_t reg)
        return val;
 }
 
-static __inline__ void 
+static __inline void 
 xlr_mtcr(uint32_t reg, uint32_t val)
 {
        __asm__ __volatile__(
@@ -396,26 +396,47 @@ xlr_mtcr(uint32_t reg, uint32_t val)
            : "$8", "$9");
 }
 
+/*
+ * Atomic increment a unsigned  int
+ */
+static __inline unsigned int
+xlr_ldaddwu(unsigned int value, unsigned int *addr)
+{
+       __asm__  __volatile__(
+           ".set       push\n"
+           ".set       noreorder\n"
+           "move       $8, %2\n"
+           "move       $9, %3\n"
+           ".word      0x71280011\n"  /* ldaddwu $8, $9 */
+           "move       %0, $8\n"
+           ".set       pop\n"
+           : "=&r"(value), "+m"(*addr)
+           : "0"(value), "r" ((unsigned long)addr)
+           :  "$8", "$9");
+
+       return (value);
+}
+
 #if defined(__mips_n64)
-static __inline__ uint32_t
-xlr_paddr_lw(uint64_t paddr)
+static __inline uint64_t
+xlr_paddr_ld(uint64_t paddr)
 {
        
        paddr |= 0x9800000000000000ULL;
-       return (*(uint32_t *)(uintptr_t)paddr);
+       return (*(uint64_t *)(uintptr_t)paddr);
 }
 
 #elif defined(__mips_n32)
-static __inline__ uint32_t
-xlr_paddr_lw(uint64_t paddr)
+static __inline uint64_t
+xlr_paddr_ld(uint64_t paddr)
 {
-       uint32_t val;
+       uint64_t val;
 
        paddr |= 0x9800000000000000ULL;
        __asm__ __volatile__(
            ".set       push            \n\t"
            ".set       mips64          \n\t"
-           "lw         %0, 0(%1)       \n\t"
+           "ld         %0, 0(%1)       \n\t"
            ".set       pop             \n"
            : "=r"(val)
            : "r"(paddr));
@@ -423,27 +444,62 @@ xlr_paddr_lw(uint64_t paddr)
        return (val);
 }
 #else
-static __inline__ uint32_t
-xlr_paddr_lw(uint64_t paddr)
+static __inline uint32_t
+xlr_paddr_ld(uint64_t paddr)
 {
-       uint32_t high, low, tmp;
+       uint32_t addrh, addrl;
+               uint32_t valh, vall;
 
-       high = 0x98000000 | (paddr >> 32);
-       low = paddr & 0xffffffff;
+       addrh = 0x98000000 | (paddr >> 32);
+       addrl = paddr & 0xffffffff;
 
        __asm__ __volatile__(
            ".set push         \n\t"
            ".set mips64       \n\t"
-           "dsll32 %1, %1, 0  \n\t"
-           "dsll32 %2, %2, 0  \n\t"  /* get rid of the */
-           "dsrl32 %2, %2, 0  \n\t"  /* sign extend */
-           "or     %1, %1, %2 \n\t"
-           "lw     %0, 0(%1)  \n\t"
+           "dsll32 %2, %2, 0  \n\t"
+           "dsll32 %3, %3, 0  \n\t"  /* get rid of the */
+           "dsrl32 %3, %3, 0  \n\t"  /* sign extend */
+           "or     %2, %2, %3 \n\t"
+           "lw     %0, 0(%2)  \n\t"
+           "lw     %1, 4(%2)  \n\t"
            ".set pop           \n"
-           :       "=r"(tmp)
-           :       "r"(high), "r"(low));
+           :       "=&r"(valh), "=r"(vall)
+           :       "r"(addrh), "r"(addrl));
+
+       return (((uint64_t)valh << 32) | vall);
+}
+#endif
+
+/*
+ * XXX: Not really needed in n32 or n64, retain for now
+ */
+#if defined(__mips_n64) || defined(__mips_n32)
+static __inline uint32_t
+xlr_enable_kx(void)
+{
+
+       return (0);
+}
+
+static __inline void
+xlr_restore_kx(uint32_t sr)
+{
+}
+#else
+static __inline uint32_t 
+xlr_enable_kx(void)
+{
+       uint32_t sr = mips_rd_status();
+
+       mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_KX);
+       return (sr);
+}
+
+static __inline void
+xlr_restore_kx(uint32_t sr)
+{
 
-       return tmp;
+       mips_wr_status(sr);
 }
 #endif
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to