⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_gt.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    /* Initialize Rx index */    sc->rx_next_out = 0;}intgt_ioctl(ifp, command, data)        struct ifnet *ifp;        u_long command;        caddr_t data;{        struct gt_softc *sc = ifp->if_softc;        int s, error = 0;        s = splimp();        switch (command) {        case SIOCPOLL:                gt_intr(sc);        	break;        case SIOCSIFADDR:                error = ether_ioctl(ifp, command, data);                break;        case SIOCSIFFLAGS:                printf("case SIOCSIFFLAGS, marking interface up/down...\n");                //sc->all_mcasts = (ifp->if_flags & IFF_ALLMULTI) ? 1 : 0;                /*                 * If interface is marked up and not running, then start it.                 * If it is marked down and running, stop it.                 * XXX If it's up then re-initialize it. This is so flags                 * such as IFF_PROMISC are handled.                 */                if (ifp->if_flags & IFF_UP) {                        gt_init(sc);                } else {                        if (ifp->if_flags & IFF_RUNNING)                                gt_stop(sc, 1);                }                break;#if USE_GT_MULTICAST        case SIOCADDMULTI:        case SIOCDELMULTI:                //sc->all_mcasts = (ifp->if_flags & IFF_ALLMULTI) ? 1 : 0;                error = (command == SIOCADDMULTI) ?                    ether_addmulti(ifr, &sc->arpcom) :                    ether_delmulti(ifr, &sc->arpcom);                if (error == ENETRESET) {                        /*                         * Multicast list has changed; set the hardware                         * filter accordingly.                         */                        /*if (!sc->all_mcasts)                                fxp_mc_setup(sc);*/                        /*                         * fxp_mc_setup() can turn on all_mcasts if we run                         * out of space, so check it again rather than else {}.                         */                        /*if (sc->all_mcasts)*/                        if (0)                                gt_init(sc);                        error = 0;                }                break;#endif        case SIOCSIFMEDIA:        case SIOCGIFMEDIA:                /*error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);*/                break;        default:                error = EINVAL;        }        (void) splx(s);        return (error);}voidgt_init(xsc)    void *xsc;{    struct gt_softc *sc = xsc;    struct ifnet *ifp = &sc->arpcom.ac_if;    /*s = splimp();*/    /*     * Cancel any pending I/O     */    ifp->if_flags |= IFF_RUNNING;    /* Stop and disable port, or reset to stable state */    /*gt_stop(sc,0);*/}static intgt_ether_ioctl(ifp, cmd, data)        struct ifnet *ifp;        u_int32_t cmd;        caddr_t data;{        struct ifaddr *ifa = (struct ifaddr *) data;        struct gt_softc *sc = ifp->if_softc;        switch (cmd) {#ifdef PMON        case SIOCPOLL:                gt_intr(sc);                break;#endif        case SIOCSIFADDR:                ifp->if_flags |= IFF_UP;                switch (ifa->ifa_addr->sa_family) {#ifdef INET                case AF_INET:                        gt_init(sc);                        arp_ifinit(&sc->arpcom, ifa);                        break;#endif#ifdef NS                case AF_NS:                    {                         struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;                         if (ns_nullhost(*ina))                                ina->x_host = *(union ns_host *)                                    LLADDR(ifp->if_sadl);                         else                                bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),                                    ifp->if_addrlen);                         /* Set new address. */                         gt_init(sc);                         break;                    }#endif                default:                        gt_init(sc);                        break;                }                break;        default:                return (EINVAL);        }        return (0);}static intgt_intr(arg)    void *arg;{    struct gt_softc *sc = arg;    struct ifnet *ifp = &sc->arpcom.ac_if;    uint icr, psr;    /*     *  Read Interrupt Cause Register and ACK interrupts      */    icr = GTETH_READ(sc, ETH0_INTERRUPT_CAUSE_REG);    GTETH_WRITE(sc, ETH0_INTERRUPT_CAUSE_REG, 0);    /*     *  Process incoming packets if Rx descriptor returned to CPU ownership     */    gt_rx(sc, icr);    /*     *  Transmit more packets if queue isn't empty     */    if (ifp->if_snd.ifq_head != NULL)        gt_start(ifp);   /*      *  Check for Tx errors    */    if (icr & icrTxErrorLow)        printf("%s: Tx resource error (low priority)\n", sc->sc_dev.dv_xname);    if (icr & icrTxUdr)        printf("%s: Tx underrun error\n", sc->sc_dev.dv_xname);   /*      *  Check for Rx errors    */    if (icr & icrRxError) {        printf("%s: Rx resource error. Resetting Rx\n", sc->sc_dev.dv_xname);        reset_rx(sc);	/* Restart receive engine */        GTETH_WRITE(sc, ETH0_SDMA_COMMAND_REG, sdcmrERD);    }    if (icr & icrRxOVR)        printf("%s: Rx overrun\n", sc->sc_dev.dv_xname);    /*      *  Check port status errors     */    psr = GTETH_READ(sc, ETH0_PORT_STATUS_REG);    if (psr & psrPause)        printf("%s: Pause!\n", sc->sc_dev.dv_xname);    return(0);}static intgt_rx(struct gt_softc *sc, u_int32_t status){    struct ifnet *ifp = &sc->arpcom.ac_if;    struct mbuf *m;    int nextRx, cdp;    RX_DESC *rd;    u_int32_t cmdstat;    u_int16_t total_len;    /*     *  Determine index to current descriptor     */    cdp = (GTETH_READ(sc, ETH0_CURRENT_RX_DESC_PTR0)           - (u_int32_t)sc->rx_ring) / sizeof(RX_DESC);    /*      *  Process to current descriptor     */    for (nextRx = sc->rx_next_out; nextRx != cdp;         nextRx = (nextRx + 1) % RX_RING_SIZE) {        rd = &sc->rx_ring[nextRx];	CACHESYNC(rd, sizeof(RX_DESC), SYNC_R);        cmdstat = (u_int32_t)rd->cmdstat;	/*          *  Bail if gt owns descriptor.  This is the workaround for         *  not relying on the icr register.         */        if (cmdstat & (u_int32_t)rxOwn) {            break;	}        /*          *  Must be first and last (ie only) buffer of packet         */        if (!(cmdstat & (u_int32_t)rxFirst) || !(cmdstat & (u_int32_t)rxLast)) {            printf("%s: descriptor not first and last!\n", sc->sc_dev.dv_xname);            goto next;        }        /*          *  Drop this packet if there were any errors         */        if ((cmdstat & (u_int32_t)rxErrorSummary) || (status & icrRxError)) {#ifdef DEBUG_GT            printf("%s: dropped packet %p:%p\n",		sc->sc_dev.dv_xname, cmdstat, status);#endif            goto next;        }	if((total_len = (rd->byte_sz_cnt & 0xffff)) > MCLBYTES) {	    printf("%s: bad packet length %d\n", sc->sc_dev.dv_xname, total_len);	    goto next;	}        /*          *  This is where the packets start to get processed to send         *  to upper layers of the protocol stack.         */	m = sc->rx_m[nextRx];        /*          *  Add a new buffer to the receive descriptor. The old	 *  buffer is recycled if it fails to get a new buffer	 *  and true is returned by gt_add_rfabuf.         */	if (!gt_add_rfabuf(sc, &sc->rx_m[nextRx])) {	    struct ether_header *eh;		rd->buff_ptr = VA_TO_PA(sc->rx_m[nextRx]->m_data);	    total_len = rd->byte_sz_cnt & 0xffff;	    if (total_len < sizeof(struct ether_header)) {                printf("%s: buffer too small, freeing mbuf\n", sc->sc_dev.dv_xname);	        m_freem(m);		goto next;	    }	    m->m_pkthdr.rcvif = ifp;	    m->m_pkthdr.len = m->m_len = total_len - sizeof(struct ether_header);            /*              *  Realign data in mbuf. Discovery require receive buffer	     *  to be 64 bit aligned so we can't do this before receive.             */            bcopy(m->m_data, m->m_data + RFA_ALIGNMENT_FUDGE, total_len);	    m->m_data += RFA_ALIGNMENT_FUDGE;            /*             *  Send packet to upper layer             */            eh = mtod(m, struct ether_header *);	    m->m_data += sizeof(struct ether_header);	    ether_input(ifp, eh, m);	}	else {	    printf("%s: gt recycling rxbuf!\n", sc->sc_dev.dv_xname);	}next:	/*          *  Release ownership to device, set first and last, enable interrupt         */	rd->cmdstat = (u_int32_t)(rxFirst | rxLast | rxOwn | rxEI);	CACHESYNC(rd, sizeof(RX_DESC), SYNC_W);    }    sc->rx_next_out = nextRx;    return 0;}/* * Get a receive buffer and return it's data address. * Return 0 if recycled. The buffer is prepares such that * the pointer to "m" is stored in front of the data. */intgt_add_rfabuf(sc, oldm)	struct gt_softc *sc;	struct mbuf **oldm;{	struct mbuf *m, *pm;	if(oldm != NULL) {		pm = *oldm;	}	else {		pm = NULL;	}	MGETHDR(m, M_DONTWAIT, MT_DATA);	if (m != NULL) {		MCLGET(m, M_DONTWAIT);		if ((m->m_flags & M_EXT) == 0) {			m_freem(m);			if (pm == NULL) {                                printf("gt_add_rfabuf: error 1\n");				return -1;                        }			/* Recycle */			m = pm;			m->m_data = m->m_ext.ext_buf;		}	}	else { /* Recycle */		if (pm == NULL) {                        printf("gt_add_rfabuf: error 2\n");			return 1;                }		m = pm;		m->m_data = m->m_ext.ext_buf;	}	/*	 * Move the data pointer up so that the incoming data packet	 * will be 64-bit aligned as requiered by the Discovery.	 * The ether header is not a multiple of 4 bytes but the upper layer	 * assumes data to be aligned so we will have to adjust this later.	 */	m->m_data = (void *)ALIGN(m->m_data);	CACHESYNC((void *)m->m_data, RX_BUF_SZ, SYNC_R);	*oldm = m;	return (m == pm);}void read_mib_counters (sc)    struct gt_softc *sc;{    u_int32_t *mib_reg = (u_int32_t *)&sc->mib;    int i;    for (i=0; i<sizeof(mib_counters_t)/sizeof(u_int32_t); i++) {        mib_reg[i] = GTETH_READ(sc, ETH0_MIB_COUNTER_BASE + i*sizeof(u_int32_t));    }}intgt_miibus_readreg(arg, phy, reg)	void *arg;	int phy;	int reg;{	struct gt_softc *sc = (struct gt_softc *)arg;	unsigned int data = 0;	u_int32_t phyreg;	phyreg = GT_READ(ETH_PHY_ADDR_REG);	if ((sc->sc_dev.dv_unit == 0 && (phyreg & 0x1f) != phy) ||	    (sc->sc_dev.dv_unit == 1 && (phyreg & 0x3e0) != (phy << 5)) ||	    (sc->sc_dev.dv_unit == 2 && (phyreg & 0x7c00) != (phy << 10)) ||	    (sc->sc_dev.dv_unit > 2)) {		return (0xffff);	}	phyreg = ((reg << SMIR_REGADBIT) & SMIR_REGADMASK) |		 ((phy << SMIR_PHYADBIT) & SMIR_PHYADMASK) |		 SMIR_READOP;	GT_WRITE(ETH_SMI_REG, phyreg);	do {		phyreg = GT_READ(ETH_SMI_REG);	} while (phyreg & SMIR_BUSY);	data = GT_READ(ETH_SMI_REG);	return (data & 0xffff);}intgt_miibus_writereg(arg, phy, reg, data)	void *arg;	int phy;	int reg;	int data;{	struct gt_softc *sc = (struct gt_softc *)arg;	u_int32_t phyreg;	phyreg = GT_READ(ETH_PHY_ADDR_REG);	if ((sc->sc_dev.dv_unit == 0 && (phyreg & 0x1f) != phy) ||	    (sc->sc_dev.dv_unit == 1 && (phyreg & 0x3e0) != (phy << 5)) ||	    (sc->sc_dev.dv_unit == 2 && (phyreg & 0x7c00) != (phy << 10)) ||	    (sc->sc_dev.dv_unit > 2)) {		return (0xffff);	}	phyreg = ((reg << SMIR_REGADBIT) & SMIR_REGADMASK) |		 ((phy << SMIR_PHYADBIT) & SMIR_PHYADMASK) |		 (data & SMIR_DATAMASK);	GT_WRITE(ETH_SMI_REG, phyreg);	do {		phyreg = GT_READ(ETH_SMI_REG);	} while (phyreg & SMIR_BUSY);	return (0);}#define NUM_ETH_PORTS 	3 unsigned int addressTableHashMode[NUM_ETH_PORTS];     unsigned int addressTableHashSize[NUM_ETH_PORTS];     unsigned int addressTableBase[NUM_ETH_PORTS];     /****************************************************************************** * boolean_t initAddressTable(int port,int hashMode,int hashSize,int hashDefaultMode)* * This function will initialize the address table* and will enableFiltering.* Inputs* hashMode - hash mode 0 or hash mode 1.* hashSize - the size of the hash table (0=8K ,1=1/2K)* hashDefaultMode - 0 = discard addresses not found in the address table ,* 1 = pass addresses not found in the address table.* port - ETHERNET port number.* Outputs                                                      * address table is allocated and initialized.* TRUE if success.* FALSE if fail to make the assignment.*/int initAddressTable(int port,int hashMode,int hashSize,int hashDefaultMode)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -