summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authorjchandra <jchandra@FreeBSD.org>2010-09-16 19:13:55 +0000
committerjchandra <jchandra@FreeBSD.org>2010-09-16 19:13:55 +0000
commit8780a2e4447219001c52c743902d4060d8c1eef5 (patch)
tree3d36a0aa1661a8ab219dca596e9d3c2ae29adcc3 /sys/mips
parent4b1a6e6702fa7bf39aacc4df9778fe1c1f56c5be (diff)
downloadFreeBSD-src-8780a2e4447219001c52c743902d4060d8c1eef5.zip
FreeBSD-src-8780a2e4447219001c52c743902d4060d8c1eef5.tar.gz
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.
Diffstat (limited to 'sys/mips')
-rw-r--r--sys/mips/rmi/dev/nlge/if_nlge.c85
-rw-r--r--sys/mips/rmi/dev/xlr/rge.c66
-rw-r--r--sys/mips/rmi/rmi_mips_exts.h104
3 files changed, 124 insertions, 131 deletions
diff --git a/sys/mips/rmi/dev/nlge/if_nlge.c b/sys/mips/rmi/dev/nlge/if_nlge.c
index a80b267..1a217c0 100644
--- a/sys/mips/rmi/dev/nlge/if_nlge.c
+++ b/sys/mips/rmi/dev/nlge/if_nlge.c
@@ -300,31 +300,13 @@ DRIVER_MODULE(miibus, nlge, miibus_driver, miibus_devclass, 0, 0);
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)
+static __inline void
+atomic_incr_long(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();
+ /* 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 size, int code, int stid,
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_t paddr, int len)
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 *sc, struct msgrng_msg *fmn_msg,
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 *sc, struct msgrng_msg *fmn_msg,
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);
}
diff --git a/sys/mips/rmi/dev/xlr/rge.c b/sys/mips/rmi/dev/xlr/rge.c
index c7a02c2..09045f4 100644
--- a/sys/mips/rmi/dev/xlr/rge.c
+++ b/sys/mips/rmi/dev/xlr/rge.c
@@ -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 paddr, int len)
* 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",
diff --git a/sys/mips/rmi/rmi_mips_exts.h b/sys/mips/rmi/rmi_mips_exts.h
index 6f86ed2..a21f5e0 100644
--- a/sys/mips/rmi/rmi_mips_exts.h
+++ b/sys/mips/rmi/rmi_mips_exts.h
@@ -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
OpenPOWER on IntegriCloud