Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Sep 2010 19:13:55 +0000 (UTC)
From:      "Jayachandran C." <jchandra@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r212758 - in head/sys/mips/rmi: . dev/nlge dev/xlr
Message-ID:  <201009161913.o8GJDtOo004197@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009161913.o8GJDtOo004197>