Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/rt/if_rt.c
/*- | /*- | ||||
* Copyright (c) 2015, Stanislav Galabov | * Copyright (c) 2015-2016, Stanislav Galabov | ||||
* Copyright (c) 2014, Aleksandr A. Mityaev | * Copyright (c) 2014, Aleksandr A. Mityaev | ||||
* Copyright (c) 2011, Aleksandr Rybalko | * Copyright (c) 2011, Aleksandr Rybalko | ||||
* based on hard work | * based on hard work | ||||
* by Alexander Egorenkov <egorenar@gmail.com> | * by Alexander Egorenkov <egorenar@gmail.com> | ||||
* and by Damien Bergamini <damien.bergamini@free.fr> | * and by Damien Bergamini <damien.bergamini@free.fr> | ||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
Show All 38 Lines | |||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <machine/cache.h> | #include <machine/cache.h> | ||||
#include <machine/cpufunc.h> | #include <machine/cpufunc.h> | ||||
#include <machine/resource.h> | #include <machine/resource.h> | ||||
#include <vm/vm_param.h> | #include <vm/vm_param.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <machine/pmap.h> | |||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/rman.h> | #include <sys/rman.h> | ||||
#include "opt_platform.h" | #include "opt_platform.h" | ||||
#include "opt_rt305x.h" | #include "opt_rt305x.h" | ||||
#ifdef FDT | #ifdef FDT | ||||
#include <dev/ofw/openfirm.h> | #include <dev/ofw/openfirm.h> | ||||
#include <dev/ofw/ofw_bus.h> | #include <dev/ofw/ofw_bus.h> | ||||
#include <dev/ofw/ofw_bus_subr.h> | #include <dev/ofw/ofw_bus_subr.h> | ||||
#endif | #endif | ||||
#include <dev/mii/mii.h> | #include <dev/mii/mii.h> | ||||
#include <dev/mii/miivar.h> | #include <dev/mii/miivar.h> | ||||
#if 0 | |||||
#include <mips/rt305x/rt305x_sysctlvar.h> | #include <mips/rt305x/rt305x_sysctlvar.h> | ||||
#include <mips/rt305x/rt305xreg.h> | #include <mips/rt305x/rt305xreg.h> | ||||
#endif | |||||
#ifdef IF_RT_PHY_SUPPORT | #ifdef IF_RT_PHY_SUPPORT | ||||
#include "miibus_if.h" | #include "miibus_if.h" | ||||
#endif | #endif | ||||
/* | /* | ||||
* Defines and macros | * Defines and macros | ||||
*/ | */ | ||||
#define RT_MAX_AGG_SIZE 3840 | #define RT_MAX_AGG_SIZE 3840 | ||||
#define RT_TX_DATA_SEG0_SIZE MJUMPAGESIZE | #define RT_TX_DATA_SEG0_SIZE MJUMPAGESIZE | ||||
#define RT_MS(_v, _f) (((_v) & _f) >> _f##_S) | #define RT_MS(_v, _f) (((_v) & _f) >> _f##_S) | ||||
#define RT_SM(_v, _f) (((_v) << _f##_S) & _f) | #define RT_SM(_v, _f) (((_v) << _f##_S) & _f) | ||||
#define RT_TX_WATCHDOG_TIMEOUT 5 | #define RT_TX_WATCHDOG_TIMEOUT 5 | ||||
#define RT_CHIPID_RT3050 0x3050 | #define RT_CHIPID_RT3050 0x3050 | ||||
#define RT_CHIPID_RT3052 0x3052 | |||||
#define RT_CHIPID_RT5350 0x5350 | #define RT_CHIPID_RT5350 0x5350 | ||||
#define RT_CHIPID_RT6855 0x6855 | |||||
#define RT_CHIPID_MT7620 0x7620 | #define RT_CHIPID_MT7620 0x7620 | ||||
#define RT_CHIPID_MT7621 0x7621 | |||||
#ifdef FDT | #ifdef FDT | ||||
/* more specific and new models should go first */ | /* more specific and new models should go first */ | ||||
static const struct ofw_compat_data rt_compat_data[] = { | static const struct ofw_compat_data rt_compat_data[] = { | ||||
{ "ralink,rt6855-eth", (uintptr_t)RT_CHIPID_RT6855 }, | { "ralink,rt3050-eth", RT_CHIPID_RT3050 }, | ||||
{ "ralink,rt5350-eth", (uintptr_t)RT_CHIPID_RT5350 }, | { "ralink,rt3352-eth", RT_CHIPID_RT3050 }, | ||||
{ "ralink,rt3052-eth", (uintptr_t)RT_CHIPID_RT3052 }, | { "ralink,rt3883-eth", RT_CHIPID_RT3050 }, | ||||
{ "ralink,rt305x-eth", (uintptr_t)RT_CHIPID_RT3050 }, | { "ralink,rt5350-eth", RT_CHIPID_RT5350 }, | ||||
{ NULL, (uintptr_t)NULL } | { "ralink,mt7620a-eth", RT_CHIPID_MT7620 }, | ||||
{ "ralink,mt7621-eth", RT_CHIPID_MT7621 }, | |||||
{ NULL, 0 } | |||||
}; | }; | ||||
#endif | #endif | ||||
/* | /* | ||||
* Static function prototypes | * Static function prototypes | ||||
*/ | */ | ||||
static int rt_probe(device_t dev); | static int rt_probe(device_t dev); | ||||
static int rt_attach(device_t dev); | static int rt_attach(device_t dev); | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
rt_probe(device_t dev) | rt_probe(device_t dev) | ||||
{ | { | ||||
struct rt_softc *sc = device_get_softc(dev); | struct rt_softc *sc = device_get_softc(dev); | ||||
char buf[80]; | char buf[80]; | ||||
#ifdef FDT | #ifdef FDT | ||||
const struct ofw_compat_data * cd; | const struct ofw_compat_data * cd; | ||||
cd = ofw_bus_search_compatible(dev, rt_compat_data); | cd = ofw_bus_search_compatible(dev, rt_compat_data); | ||||
if (cd->ocd_data == (uintptr_t)NULL) | if (cd->ocd_data == 0) | ||||
return (ENXIO); | return (ENXIO); | ||||
sc->rt_chipid = (unsigned int)(cd->ocd_data); | sc->rt_chipid = (unsigned int)(cd->ocd_data); | ||||
#else | #else | ||||
#if defined(MT7620) | #if defined(MT7620) | ||||
sc->rt_chipid = RT_CHIPID_MT7620; | sc->rt_chipid = RT_CHIPID_MT7620; | ||||
#elif defined(MT7621) | |||||
sc->rt_chipid = RT_CHIPID_MT7621; | |||||
#elif defined(RT5350) | #elif defined(RT5350) | ||||
sc->rt_chipid = RT_CHIPID_RT5350; | sc->rt_chipid = RT_CHIPID_RT5350; | ||||
#else | #else | ||||
sc->rt_chipid = RT_CHIPID_RT3050; | sc->rt_chipid = RT_CHIPID_RT3050; | ||||
#endif | #endif | ||||
#endif | #endif | ||||
snprintf(buf, sizeof(buf), "Ralink RT%x onChip Ethernet driver", | snprintf(buf, sizeof(buf), "Ralink %cT%x onChip Ethernet driver", | ||||
sc->rt_chipid); | sc->rt_chipid >= 0x7600 ? 'M' : 'R', sc->rt_chipid); | ||||
device_set_desc_copy(dev, buf); | device_set_desc_copy(dev, buf); | ||||
return (BUS_PROBE_GENERIC); | return (BUS_PROBE_GENERIC); | ||||
} | } | ||||
/* | /* | ||||
* macaddr_atoi - translate string MAC address to uint8_t array | * macaddr_atoi - translate string MAC address to uint8_t array | ||||
*/ | */ | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | #ifdef IF_RT_DEBUG | ||||
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), | SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), | ||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, | SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, | ||||
"debug", CTLFLAG_RW, &sc->debug, 0, "rt debug level"); | "debug", CTLFLAG_RW, &sc->debug, 0, "rt debug level"); | ||||
#endif | #endif | ||||
/* Reset hardware */ | /* Reset hardware */ | ||||
reset_freng(sc); | reset_freng(sc); | ||||
if (sc->rt_chipid == RT_CHIPID_MT7620) { | |||||
adrian: We should document these RX descriptor bit fields in a header file and include those… | |||||
sgalabovAuthorUnsubmitted Not Done Inline ActionsOops, this escaped me somehow... I can do this before committing if you don't mind? sgalabov: Oops, this escaped me somehow... I can do this before committing if you don't mind? | |||||
sc->csum_fail_ip = (1<<25); | |||||
sc->csum_fail_l4 = (1<<22); | |||||
} else if (sc->rt_chipid == RT_CHIPID_MT7621) { | |||||
sc->csum_fail_ip = (1<<26); | |||||
sc->csum_fail_l4 = (1<<23); | |||||
} else { | |||||
sc->csum_fail_ip = (1<<29);//RXDSXR_SRC_IP_CSUM_FAIL; | |||||
sc->csum_fail_l4 = (1<<28);//RXDSXR_SRC_L4_CSUM_FAIL; | |||||
} | |||||
/* Fill in soc-specific registers map */ | /* Fill in soc-specific registers map */ | ||||
switch(sc->rt_chipid) { | switch(sc->rt_chipid) { | ||||
case RT_CHIPID_MT7620: | case RT_CHIPID_MT7620: | ||||
case RT_CHIPID_MT7621: | |||||
case RT_CHIPID_RT5350: | case RT_CHIPID_RT5350: | ||||
device_printf(dev, "RT%x Ethernet MAC (rev 0x%08x)\n", | device_printf(dev, "%cT%x Ethernet MAC (rev 0x%08x)\n", | ||||
sc->rt_chipid >= 0x7600 ? 'M' : 'R', | |||||
sc->rt_chipid, sc->mac_rev); | sc->rt_chipid, sc->mac_rev); | ||||
/* RT5350: No GDMA, PSE, CDMA, PPE */ | /* RT5350: No GDMA, PSE, CDMA, PPE */ | ||||
RT_WRITE(sc, GE_PORT_BASE + 0x0C00, // UDPCS, TCPCS, IPCS=1 | RT_WRITE(sc, GE_PORT_BASE + 0x0C00, // UDPCS, TCPCS, IPCS=1 | ||||
RT_READ(sc, GE_PORT_BASE + 0x0C00) | (0x7<<16)); | RT_READ(sc, GE_PORT_BASE + 0x0C00) | (0x7<<16)); | ||||
sc->delay_int_cfg=RT5350_PDMA_BASE+RT5350_DELAY_INT_CFG; | sc->delay_int_cfg=RT5350_PDMA_BASE+RT5350_DELAY_INT_CFG; | ||||
sc->fe_int_status=RT5350_FE_INT_STATUS; | sc->fe_int_status=RT5350_FE_INT_STATUS; | ||||
sc->fe_int_enable=RT5350_FE_INT_ENABLE; | sc->fe_int_enable=RT5350_FE_INT_ENABLE; | ||||
sc->pdma_glo_cfg=RT5350_PDMA_BASE+RT5350_PDMA_GLO_CFG; | sc->pdma_glo_cfg=RT5350_PDMA_BASE+RT5350_PDMA_GLO_CFG; | ||||
Show All 11 Lines | switch(sc->rt_chipid) { | ||||
sc->rx_drx_idx[0]=RT5350_PDMA_BASE+RT5350_RX_DRX_IDX0; | sc->rx_drx_idx[0]=RT5350_PDMA_BASE+RT5350_RX_DRX_IDX0; | ||||
sc->rx_base_ptr[1]=RT5350_PDMA_BASE+RT5350_RX_BASE_PTR1; | sc->rx_base_ptr[1]=RT5350_PDMA_BASE+RT5350_RX_BASE_PTR1; | ||||
sc->rx_max_cnt[1]=RT5350_PDMA_BASE+RT5350_RX_MAX_CNT1; | sc->rx_max_cnt[1]=RT5350_PDMA_BASE+RT5350_RX_MAX_CNT1; | ||||
sc->rx_calc_idx[1]=RT5350_PDMA_BASE+RT5350_RX_CALC_IDX1; | sc->rx_calc_idx[1]=RT5350_PDMA_BASE+RT5350_RX_CALC_IDX1; | ||||
sc->rx_drx_idx[1]=RT5350_PDMA_BASE+RT5350_RX_DRX_IDX1; | sc->rx_drx_idx[1]=RT5350_PDMA_BASE+RT5350_RX_DRX_IDX1; | ||||
sc->int_rx_done_mask=RT5350_INT_RXQ0_DONE; | sc->int_rx_done_mask=RT5350_INT_RXQ0_DONE; | ||||
sc->int_tx_done_mask=RT5350_INT_TXQ0_DONE; | sc->int_tx_done_mask=RT5350_INT_TXQ0_DONE; | ||||
break; | break; | ||||
case RT_CHIPID_RT6855: | |||||
device_printf(dev, "RT6855 Ethernet MAC (rev 0x%08x)\n", | |||||
sc->mac_rev); | |||||
break; | |||||
default: | default: | ||||
device_printf(dev, "RT305XF Ethernet MAC (rev 0x%08x)\n", | device_printf(dev, "RT305XF Ethernet MAC (rev 0x%08x)\n", | ||||
sc->mac_rev); | sc->mac_rev); | ||||
RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG, | RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG, | ||||
( | ( | ||||
GDM_ICS_EN | /* Enable IP Csum */ | GDM_ICS_EN | /* Enable IP Csum */ | ||||
GDM_TCS_EN | /* Enable TCP Csum */ | GDM_TCS_EN | /* Enable TCP Csum */ | ||||
GDM_UCS_EN | /* Enable UDP Csum */ | GDM_UCS_EN | /* Enable UDP Csum */ | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | #endif /* IF_RT_PHY_SUPPORT */ | ||||
taskqueue_start_threads(&sc->taskqueue, 1, PI_NET, "%s taskq", | taskqueue_start_threads(&sc->taskqueue, 1, PI_NET, "%s taskq", | ||||
device_get_nameunit(sc->dev)); | device_get_nameunit(sc->dev)); | ||||
rt_sysctl_attach(sc); | rt_sysctl_attach(sc); | ||||
/* set up interrupt */ | /* set up interrupt */ | ||||
error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, | error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, | ||||
NULL, (sc->rt_chipid == RT_CHIPID_RT5350 || | NULL, (sc->rt_chipid == RT_CHIPID_RT5350 || | ||||
sc->rt_chipid == RT_CHIPID_MT7620) ? rt_rt5350_intr : rt_intr, | sc->rt_chipid == RT_CHIPID_MT7620 || | ||||
sc->rt_chipid == RT_CHIPID_MT7621) ? rt_rt5350_intr : rt_intr, | |||||
sc, &sc->irqh); | sc, &sc->irqh); | ||||
if (error != 0) { | if (error != 0) { | ||||
printf("%s: could not set up interrupt\n", | printf("%s: could not set up interrupt\n", | ||||
device_get_nameunit(dev)); | device_get_nameunit(dev)); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
#ifdef IF_RT_DEBUG | #ifdef IF_RT_DEBUG | ||||
device_printf(dev, "debug var at %#08x\n", (u_int)&(sc->debug)); | device_printf(dev, "debug var at %#08x\n", (u_int)&(sc->debug)); | ||||
▲ Show 20 Lines • Show All 213 Lines • ▼ Show 20 Lines | #endif | ||||
RT_SOFTC_ASSERT_LOCKED(sc); | RT_SOFTC_ASSERT_LOCKED(sc); | ||||
/* hardware reset */ | /* hardware reset */ | ||||
//RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET); | //RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET); | ||||
//rt305x_sysctl_set(SYSCTL_RSTCTRL, SYSCTL_RSTCTRL_FRENG); | //rt305x_sysctl_set(SYSCTL_RSTCTRL, SYSCTL_RSTCTRL_FRENG); | ||||
/* Fwd to CPU (uni|broad|multi)cast and Unknown */ | /* Fwd to CPU (uni|broad|multi)cast and Unknown */ | ||||
if(sc->rt_chipid == RT_CHIPID_RT3050 || sc->rt_chipid == RT_CHIPID_RT3052) | if(sc->rt_chipid == RT_CHIPID_RT3050) | ||||
RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG, | RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG, | ||||
( | ( | ||||
GDM_ICS_EN | /* Enable IP Csum */ | GDM_ICS_EN | /* Enable IP Csum */ | ||||
GDM_TCS_EN | /* Enable TCP Csum */ | GDM_TCS_EN | /* Enable TCP Csum */ | ||||
GDM_UCS_EN | /* Enable UDP Csum */ | GDM_UCS_EN | /* Enable UDP Csum */ | ||||
GDM_STRPCRC | /* Strip CRC from packet */ | GDM_STRPCRC | /* Strip CRC from packet */ | ||||
GDM_DST_PORT_CPU << GDM_UFRC_P_SHIFT | /* Forward UCast to CPU */ | GDM_DST_PORT_CPU << GDM_UFRC_P_SHIFT | /* Forward UCast to CPU */ | ||||
GDM_DST_PORT_CPU << GDM_BFRC_P_SHIFT | /* Forward BCast to CPU */ | GDM_DST_PORT_CPU << GDM_BFRC_P_SHIFT | /* Forward BCast to CPU */ | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | for (i = 0; i < sc->rx_ring_count; i++) { | ||||
RT_WRITE(sc, sc->rx_max_cnt[i], | RT_WRITE(sc, sc->rx_max_cnt[i], | ||||
RT_SOFTC_RX_RING_DATA_COUNT); | RT_SOFTC_RX_RING_DATA_COUNT); | ||||
RT_WRITE(sc, sc->rx_calc_idx[i], | RT_WRITE(sc, sc->rx_calc_idx[i], | ||||
RT_SOFTC_RX_RING_DATA_COUNT - 1); | RT_SOFTC_RX_RING_DATA_COUNT - 1); | ||||
} | } | ||||
/* write back DDONE, 16byte burst enable RX/TX DMA */ | /* write back DDONE, 16byte burst enable RX/TX DMA */ | ||||
tmp = FE_TX_WB_DDONE | FE_DMA_BT_SIZE16 | FE_RX_DMA_EN | FE_TX_DMA_EN; | tmp = FE_TX_WB_DDONE | FE_DMA_BT_SIZE16 | FE_RX_DMA_EN | FE_TX_DMA_EN; | ||||
if (sc->rt_chipid == RT_CHIPID_MT7620) | if (sc->rt_chipid == RT_CHIPID_MT7620 || | ||||
sc->rt_chipid == RT_CHIPID_MT7621) | |||||
tmp |= (1<<31); | tmp |= (1<<31); | ||||
RT_WRITE(sc, sc->pdma_glo_cfg, tmp); | RT_WRITE(sc, sc->pdma_glo_cfg, tmp); | ||||
/* disable interrupts mitigation */ | /* disable interrupts mitigation */ | ||||
RT_WRITE(sc, sc->delay_int_cfg, 0); | RT_WRITE(sc, sc->delay_int_cfg, 0); | ||||
/* clear pending interrupts */ | /* clear pending interrupts */ | ||||
RT_WRITE(sc, sc->fe_int_status, 0xffffffff); | RT_WRITE(sc, sc->fe_int_status, 0xffffffff); | ||||
/* enable interrupts */ | /* enable interrupts */ | ||||
if (sc->rt_chipid == RT_CHIPID_RT5350 || | if (sc->rt_chipid == RT_CHIPID_RT5350 || | ||||
sc->rt_chipid == RT_CHIPID_MT7620) | sc->rt_chipid == RT_CHIPID_MT7620 || | ||||
sc->rt_chipid == RT_CHIPID_MT7621) | |||||
tmp = RT5350_INT_TX_COHERENT | | tmp = RT5350_INT_TX_COHERENT | | ||||
RT5350_INT_RX_COHERENT | | RT5350_INT_RX_COHERENT | | ||||
RT5350_INT_TXQ3_DONE | | RT5350_INT_TXQ3_DONE | | ||||
RT5350_INT_TXQ2_DONE | | RT5350_INT_TXQ2_DONE | | ||||
RT5350_INT_TXQ1_DONE | | RT5350_INT_TXQ1_DONE | | ||||
RT5350_INT_TXQ0_DONE | | RT5350_INT_TXQ0_DONE | | ||||
RT5350_INT_RXQ1_DONE | | RT5350_INT_RXQ1_DONE | | ||||
RT5350_INT_RXQ0_DONE; | RT5350_INT_RXQ0_DONE; | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | #ifdef notyet | ||||
taskqueue_drain(sc->taskqueue, &sc->periodic_task); | taskqueue_drain(sc->taskqueue, &sc->periodic_task); | ||||
#endif | #endif | ||||
RT_SOFTC_LOCK(sc); | RT_SOFTC_LOCK(sc); | ||||
/* disable interrupts */ | /* disable interrupts */ | ||||
RT_WRITE(sc, sc->fe_int_enable, 0); | RT_WRITE(sc, sc->fe_int_enable, 0); | ||||
if(sc->rt_chipid == RT_CHIPID_RT5350 || | if(sc->rt_chipid == RT_CHIPID_RT5350 || | ||||
sc->rt_chipid == RT_CHIPID_MT7620) { | sc->rt_chipid == RT_CHIPID_MT7620 || | ||||
sc->rt_chipid == RT_CHIPID_MT7621) { | |||||
} else { | } else { | ||||
/* reset adapter */ | /* reset adapter */ | ||||
RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET); | RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET); | ||||
RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG, | RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG, | ||||
( | ( | ||||
GDM_ICS_EN | /* Enable IP Csum */ | GDM_ICS_EN | /* Enable IP Csum */ | ||||
GDM_TCS_EN | /* Enable TCP Csum */ | GDM_TCS_EN | /* Enable TCP Csum */ | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | rt_tx_data(struct rt_softc *sc, struct mbuf *m, int qid) | ||||
data->m = m; | data->m = m; | ||||
/* set up Tx descs */ | /* set up Tx descs */ | ||||
for (i = 0; i < ndmasegs; i += 2) { | for (i = 0; i < ndmasegs; i += 2) { | ||||
/* TODO: this needs to be refined as MT7620 for example has | /* TODO: this needs to be refined as MT7620 for example has | ||||
* a different word3 layout than RT305x and RT5350 (the last | * a different word3 layout than RT305x and RT5350 (the last | ||||
* one doesn't use word3 at all). | * one doesn't use word3 at all). And so does MT7621... | ||||
*/ | */ | ||||
if (sc->rt_chipid != RT_CHIPID_MT7621) { | |||||
/* Set destination */ | /* Set destination */ | ||||
if (sc->rt_chipid != RT_CHIPID_MT7620) | if (sc->rt_chipid != RT_CHIPID_MT7620) | ||||
desc->dst = (TXDSCR_DST_PORT_GDMA1); | desc->dst = (TXDSCR_DST_PORT_GDMA1); | ||||
if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) | if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) | ||||
desc->dst |= (TXDSCR_IP_CSUM_GEN|TXDSCR_UDP_CSUM_GEN| | desc->dst |= (TXDSCR_IP_CSUM_GEN | | ||||
TXDSCR_TCP_CSUM_GEN); | TXDSCR_UDP_CSUM_GEN | TXDSCR_TCP_CSUM_GEN); | ||||
/* Set queue id */ | /* Set queue id */ | ||||
desc->qn = qid; | desc->qn = qid; | ||||
/* No PPPoE */ | /* No PPPoE */ | ||||
desc->pppoe = 0; | desc->pppoe = 0; | ||||
/* No VLAN */ | /* No VLAN */ | ||||
desc->vid = 0; | desc->vid = 0; | ||||
} else { | |||||
desc->vid = 0; | |||||
desc->pppoe = 0; | |||||
desc->qn = 0; | |||||
desc->dst = 2; | |||||
} | |||||
desc->sdp0 = htole32(dma_seg[i].ds_addr); | desc->sdp0 = htole32(dma_seg[i].ds_addr); | ||||
desc->sdl0 = htole16(dma_seg[i].ds_len | | desc->sdl0 = htole16(dma_seg[i].ds_len | | ||||
( ((i+1) == ndmasegs )?RT_TXDESC_SDL0_LASTSEG:0 )); | ( ((i+1) == ndmasegs )?RT_TXDESC_SDL0_LASTSEG:0 )); | ||||
if ((i+1) < ndmasegs) { | if ((i+1) < ndmasegs) { | ||||
desc->sdp1 = htole32(dma_seg[i+1].ds_addr); | desc->sdp1 = htole32(dma_seg[i+1].ds_addr); | ||||
desc->sdl1 = htole16(dma_seg[i+1].ds_len | | desc->sdl1 = htole16(dma_seg[i+1].ds_len | | ||||
▲ Show 20 Lines • Show All 627 Lines • ▼ Show 20 Lines | for (i = RT_SOFTC_TX_RING_COUNT - 1; i >= 0; i--) { | ||||
} | } | ||||
} | } | ||||
sc->tx_timer = 0; | sc->tx_timer = 0; | ||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | ||||
if(sc->rt_chipid == RT_CHIPID_RT5350 || | if(sc->rt_chipid == RT_CHIPID_RT5350 || | ||||
sc->rt_chipid == RT_CHIPID_MT7620) | sc->rt_chipid == RT_CHIPID_MT7620 || | ||||
sc->rt_chipid == RT_CHIPID_MT7621) | |||||
intr_mask = ( | intr_mask = ( | ||||
RT5350_INT_TXQ3_DONE | | RT5350_INT_TXQ3_DONE | | ||||
RT5350_INT_TXQ2_DONE | | RT5350_INT_TXQ2_DONE | | ||||
RT5350_INT_TXQ1_DONE | | RT5350_INT_TXQ1_DONE | | ||||
RT5350_INT_TXQ0_DONE); | RT5350_INT_TXQ0_DONE); | ||||
else | else | ||||
intr_mask = ( | intr_mask = ( | ||||
INT_TXQ3_DONE | | INT_TXQ3_DONE | | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | #endif | ||||
dma_map = data->dma_map; | dma_map = data->dma_map; | ||||
data->dma_map = ring->spare_dma_map; | data->dma_map = ring->spare_dma_map; | ||||
ring->spare_dma_map = dma_map; | ring->spare_dma_map = dma_map; | ||||
bus_dmamap_sync(ring->data_dma_tag, data->dma_map, | bus_dmamap_sync(ring->data_dma_tag, data->dma_map, | ||||
BUS_DMASYNC_PREREAD); | BUS_DMASYNC_PREREAD); | ||||
m = data->m; | m = data->m; | ||||
desc_flags = desc->src; | desc_flags = desc->word3; | ||||
data->m = mnew; | data->m = mnew; | ||||
/* Add 2 for proper align of RX IP header */ | /* Add 2 for proper align of RX IP header */ | ||||
desc->sdp0 = htole32(segs[0].ds_addr+2); | desc->sdp0 = htole32(segs[0].ds_addr+2); | ||||
desc->sdl0 = htole32(segs[0].ds_len-2); | desc->sdl0 = htole32(segs[0].ds_len-2); | ||||
desc->src = 0; | desc->word3 = 0; | ||||
desc->ai = 0; | |||||
desc->foe = 0; | |||||
RT_DPRINTF(sc, RT_DEBUG_RX, | RT_DPRINTF(sc, RT_DEBUG_RX, | ||||
"Rx frame: rxdesc flags=0x%08x\n", desc_flags); | "Rx frame: rxdesc flags=0x%08x\n", desc_flags); | ||||
m->m_pkthdr.rcvif = ifp; | m->m_pkthdr.rcvif = ifp; | ||||
/* Add 2 to fix data align, after sdp0 = addr + 2 */ | /* Add 2 to fix data align, after sdp0 = addr + 2 */ | ||||
m->m_data += 2; | m->m_data += 2; | ||||
m->m_pkthdr.len = m->m_len = len; | m->m_pkthdr.len = m->m_len = len; | ||||
/* check for crc errors */ | /* check for crc errors */ | ||||
if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) { | if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) { | ||||
/*check for valid checksum*/ | /*check for valid checksum*/ | ||||
if (desc_flags & (RXDSXR_SRC_IP_CSUM_FAIL| | if (desc_flags & (sc->csum_fail_ip|sc->csum_fail_l4)) { | ||||
RXDSXR_SRC_L4_CSUM_FAIL)) { | |||||
RT_DPRINTF(sc, RT_DEBUG_RX, | RT_DPRINTF(sc, RT_DEBUG_RX, | ||||
"rxdesc: crc error\n"); | "rxdesc: crc error\n"); | ||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | ||||
if (!(ifp->if_flags & IFF_PROMISC)) { | if (!(ifp->if_flags & IFF_PROMISC)) { | ||||
m_freem(m); | m_freem(m); | ||||
goto skip; | goto skip; | ||||
} | } | ||||
} | } | ||||
if ((desc_flags & RXDSXR_SRC_IP_CSUM_FAIL) != 0) { | if ((desc_flags & sc->csum_fail_ip) == 0) { | ||||
m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; | m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; | ||||
m->m_pkthdr.csum_flags |= CSUM_IP_VALID; | m->m_pkthdr.csum_flags |= CSUM_IP_VALID; | ||||
m->m_pkthdr.csum_data = 0xffff; | m->m_pkthdr.csum_data = 0xffff; | ||||
} | } | ||||
m->m_flags &= ~M_HASFCS; | m->m_flags &= ~M_HASFCS; | ||||
} | } | ||||
(*ifp->if_input)(ifp, m); | (*ifp->if_input)(ifp, m); | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
rt_watchdog(struct rt_softc *sc) | rt_watchdog(struct rt_softc *sc) | ||||
{ | { | ||||
uint32_t tmp; | uint32_t tmp; | ||||
#ifdef notyet | #ifdef notyet | ||||
int ntries; | int ntries; | ||||
#endif | #endif | ||||
if(sc->rt_chipid != RT_CHIPID_RT5350 && | if(sc->rt_chipid != RT_CHIPID_RT5350 && | ||||
sc->rt_chipid != RT_CHIPID_MT7620) { | sc->rt_chipid != RT_CHIPID_MT7620 && | ||||
sc->rt_chipid != RT_CHIPID_MT7621) { | |||||
tmp = RT_READ(sc, PSE_BASE + CDMA_OQ_STA); | tmp = RT_READ(sc, PSE_BASE + CDMA_OQ_STA); | ||||
RT_DPRINTF(sc, RT_DEBUG_WATCHDOG, | RT_DPRINTF(sc, RT_DEBUG_WATCHDOG, | ||||
"watchdog: PSE_IQ_STA=0x%08x\n", tmp); | "watchdog: PSE_IQ_STA=0x%08x\n", tmp); | ||||
} | } | ||||
/* XXX: do not reset */ | /* XXX: do not reset */ | ||||
#ifdef notyet | #ifdef notyet | ||||
if (((tmp >> P0_IQ_PCNT_SHIFT) & 0xff) != 0) { | if (((tmp >> P0_IQ_PCNT_SHIFT) & 0xff) != 0) { | ||||
▲ Show 20 Lines • Show All 771 Lines • Show Last 20 Lines |
We should document these RX descriptor bit fields in a header file and include those definitions here.