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

📄 if_gtx.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
		txp->vbuff_ptr = (char *)(sc->tx_buff + (i * TX_BUF_SZ));		txp->buff_ptr = (u_int32_t)VA_TO_PA(txp->vbuff_ptr);#endif		CACHESYNC(txp, sizeof(TX_DESC), SYNC_W);	}	/* Wrap the ring. */	sc->tx_ring[i-1].next = OCRAM_TO_PA(sc->tx_ring);	CACHESYNC(&sc->tx_ring[i-1], sizeof(TX_DESC), SYNC_W);	/* setup only the lowest priority TxCDP reg */	GT_WRITE(ETH_TX_CURRENT_QUEUE_DESC_PTR_0(sc->sc_port),		OCRAM_TO_PA(sc->tx_ring));	GT_WRITE(ETH_TX_CURRENT_QUEUE_DESC_PTR_1(sc->sc_port), 0);	/* Initialize Tx indeces and packet counter */	sc->tx_next_in = 0;	sc->tx_next_out = 0;	sc->tx_count = 0;}static voidreset_rx(struct gtx_softc *sc){	int i;	for (i=0; i<RX_RING_SIZE; i++) {		RX_DESC *rx_desc;		struct mbuf *m;		rx_desc = &sc->rx_ring[i];		if (rx_desc->rx_mbuf == NULL) {			m = NULL;			if(gtx_add_rfabuf(sc, &m) < 0) {				printf("%s:malloc fail\n", sc->sc_dev.dv_xname);				break;			}			rx_desc->rx_mbuf = m;		}#if defined JAGUAR_ATX		rx_desc->vbuff_ptr = (char *)sc->rx_buff + (i * RX_BUF_SZ);		rx_desc->buff_ptr  = OCRAM_TO_PA(rx_desc->vbuff_ptr);#else		rx_desc->vbuff_ptr = NULL;		rx_desc->buff_ptr = VA_TO_PA(m->m_data);#endif		rx_desc->buf_size = RX_BUF_SZ;		rx_desc->byte_cnt = 0;		rx_desc->next     = OCRAM_TO_PA((sc->rx_ring + (i+1)));		/*		 *  Give ownership to device, set first and last,		 * enable interrupt		 */		sc->rx_ring[i].cmdstat = (RX_F | RX_L | RX_O | RX_EI);		CACHESYNC(&sc->rx_ring[i], sizeof(RX_DESC), SYNC_W);	}	/* Wrap the ring */	sc->rx_ring[i-1].next = OCRAM_TO_PA(sc->rx_ring);	CACHESYNC(&sc->rx_ring[i-1], sizeof(RX_DESC), SYNC_W);	/* Setup only the lowest priority regs */	for (i=0; i<4; i++) {		if (i == 0) {			GT_WRITE(ETH_RX_CURRENT_QUEUE_DESC_PTR_0(sc->sc_port),				OCRAM_TO_PA(sc->rx_ring));		}		else {			GT_WRITE(ETH_RX_CURRENT_QUEUE_DESC_PTR_0(sc->sc_port)				+ i*4, 0);		}	}	sc->rx_next_out = 0;}intgtx_ioctl(ifp, command, data)        struct ifnet *ifp;        u_long command;        caddr_t data;{        struct gtx_softc *sc = ifp->if_softc;        int s, error = 0;        s = splimp();        switch (command) {        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) {                        gtx_init(sc);                } else {                        if (ifp->if_flags & IFF_RUNNING)                                gtx_reset(sc, 1);                }                break;        case SIOCSIFMEDIA:        case SIOCGIFMEDIA:                /*error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);*/                break;        default:                error = EINVAL;        }        (void) splx(s);        return (error);}voidgtx_init(xsc)    void *xsc;{    struct gtx_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 */    /*gtx_reset(sc,0);*/}static intgtx_ether_ioctl(ifp, cmd, data)        struct ifnet *ifp;        u_int32_t cmd;        caddr_t data;{        struct ifaddr *ifa = (struct ifaddr *) data;        struct gtx_softc *sc = ifp->if_softc;        switch (cmd) {        case SIOCSIFADDR:                ifp->if_flags |= IFF_UP;                switch (ifa->ifa_addr->sa_family) {#ifdef INET                case AF_INET:                        gtx_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. */                         gtx_init(sc);                         break;                    }#endif                default:                        gtx_init(sc);                        break;                }                break;        default:                return (EINVAL);        }        return (0);}static intgtx_intr(arg)    void *arg;{	struct gtx_softc *sc = arg;	struct ifnet *ifp = &sc->arpcom.ac_if;	u_int32_t icr, xicr;	/* Read Interrupt Cause Register and ACK interrupts */	icr = GT_READ(ETH_INTERRUPT_CAUSE_REG(sc->sc_port));	GT_WRITE(ETH_INTERRUPT_CAUSE_REG(sc->sc_port), 0);	xicr = GT_READ(ETH_INTERRUPT_CAUSE_EXTEND_REG(sc->sc_port));	GT_WRITE(ETH_INTERRUPT_CAUSE_EXTEND_REG(sc->sc_port), 0);	/* Process incoming packets if Rx descriptor returned to CPU */	gtx_rx(sc, icr, xicr);	/* Transmit more packets if queue isn't empty */	if (ifp->if_snd.ifq_head != NULL)		gtx_start(ifp);	/* Check for Tx errors */	if (icr & ICR_TXEND(0)) {		if (xicr & XICR_TXERROR(0))			printf("%s: Tx error\n", sc->sc_dev.dv_xname);	}	/* Check for Rx errors */	if (icr & ICR_RXERROR) {		printf("%s: Rx. Resetting Rx\n", sc->sc_dev.dv_xname);		reset_rx(sc);		/* Restart receive engine */		GT_WRITE(ETH_RECEIVE_QUEUE_COMMAND_REG(sc->sc_port), 0x01);	}	if (xicr & XICR_RXOVR)		printf("%s: Rx overrun\n", sc->sc_dev.dv_xname);#if 0	/* Check port status errors */	psr = GT_READ(ETH_PORT_STATUS_REG(sc->sc_port));	if (psr & psrPause)		printf("%s: Pause!\n", sc->sc_dev.dv_xname);#endif	return(0);}static intgtx_rx(struct gtx_softc *sc, u_int32_t status, u_int32_t xstatus){	struct ifnet *ifp = &sc->arpcom.ac_if;	struct mbuf *m;	int nextRx;	RX_DESC *rd;	u_int32_t cmdstat;	u_int16_t total_len;	/* 	 *  Process to current descriptor	 */	for (nextRx = sc->rx_next_out;; nextRx = (nextRx + 1) % RX_RING_SIZE) {		/* This is the only place where we touch rx descriptors */		rd = &sc->rx_ring[nextRx];		cmdstat = (u_int32_t)rd->cmdstat;		/* 		 *  Bail if gt owns descriptor.  This is the workaround for		 *  not relying on the icr register.		 */		if (cmdstat & RX_O) {			CACHESYNC(rd, sizeof(RX_DESC), SYNC_R);  /* Push back */			break;		}		/* 		 *  Must be first and last (ie only) buffer of packet		 */		if (!(cmdstat & RX_F) || !(cmdstat & RX_L)) {			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 & RX_ES) || (status & ICR_RXERROR)) {			printf("%s: dropped packet %p:%p\n",			    sc->sc_dev.dv_xname, cmdstat, status);			goto next;		}		if((total_len = rd->byte_cnt) > 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 = rd->rx_mbuf;		/* 		 *  Add a new buffer to the receive descriptor. The old		 *  buffer is recycled if we fail to get a new buffer		 *  and true is returned by gtx_add_rfabuf.		 */		if (!gtx_add_rfabuf(sc, &rd->rx_mbuf)) {			struct ether_header *eh;#ifdef JAGUAR_ATX			bcopy(rd->vbuff_ptr, m->m_data, rd->byte_cnt + 2);			CACHESYNC(rd->vbuff_ptr, RX_BUF_SZ, SYNC_R);#else			/*  Attach the new buffer to this descriptor */			rd->buff_ptr = VA_TO_PA(rd->rx_mbuf->m_data);#endif			/* extract, save, and reset the length of this packet */			total_len = rd->byte_cnt;			rd->byte_cnt = 0;			if (total_len < sizeof(struct ether_header)) {				printf("%s: short packet received\n",				    sc->sc_dev.dv_xname);				m_freem(m);				goto next;			}			/* set up packet header interface and length */			m->m_pkthdr.rcvif = ifp;			m->m_len = total_len - sizeof(struct ether_header);			m->m_pkthdr.len = m->m_len;			/* 			 *  Realign m_data to point actual input data.			 *  The DiscoveryII puts data into the buffer			 *  starting at a 2 byte offset (thanks gyus,			 *  no more copy!). The receive buffer pointer			 *  must be 64 bit aligned though so we adjust			 *  the pointer here before sending up to input.			 */			m->m_data += RFA_ALIGNMENT_FUDGE;			eh = mtod(m, struct ether_header *);			m->m_data += sizeof(struct ether_header);			ether_input(ifp, eh, m);		}		else {			printf("%s: recycling rxbuf!\n", sc->sc_dev.dv_xname);		}next:		/*  Release ownership to device */		rd->cmdstat = RX_F | RX_L | RX_O | RX_EI;		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.  */intgtx_add_rfabuf(sc, oldm)	struct gtx_softc *sc;	struct mbuf **oldm;{	struct mbuf *m, *pm;	pm = *oldm;	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("gtx_add_rfabuf: error 1\n");				return -1;                        }			/* Recycle */			m = pm;			m->m_data = m->m_ext.ext_buf;		}	}	else { /* Recycle */		if (pm == NULL) {                        printf("gtx_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 gtx_read_mib_counters (sc)    struct gtx_softc *sc;{#if 0    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));    }#endif}static voidmii_write (phyaddr, reg, value)    int phyaddr;    int reg;    int value;{    int data;    /* wait for device to become non-busy */    while (GT_READ(ETH_SMI_REG) & (0x1 << 28)) ;    data = value & 0xffff;    data |= (phyaddr & 0x1f) << 16;    data |= (reg & 0x1f) << 21;    GT_WRITE(ETH_SMI_REG, data);}static intmii_read (phyaddr, reg)    int phyaddr;    int reg;{    int data;	/* wait for device to become non-busy */	while (GT_READ(ETH_SMI_REG) & (0x1 << 28)) ;	data = 0x04000000;	data |= (phyaddr & 0x1f) << 16;	data |= (reg & 0x1f) << 21;	GT_WRITE(ETH_SMI_REG, data);	while (GT_READ(ETH_SMI_REG) & (0x1 << 28)) ;	return data & 0xffff;}

⌨️ 快捷键说明

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