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.
This commit is contained in:
parent
d0d7bcdf92
commit
f0613ab15b
@ -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;
|
||||
}
|
||||
/* XXX: fix for 64 bit */
|
||||
unsigned int *iaddr = (unsigned int *)addr;
|
||||
|
||||
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;
|
||||
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 @@ nlge_start_locked(struct ifnet *ifp, struct nlge_softc *sc)
|
||||
//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 @@ nlge_start_locked(struct ifnet *ifp, struct nlge_softc *sc)
|
||||
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);
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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 tmp;
|
||||
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)
|
||||
{
|
||||
|
||||
mips_wr_status(sr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user