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

📄 ns8382x.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
		OUTL(dev, SavedClkRun & ~0x100, ClkRun);		eth_register(dev);		card_number++;		pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x60);		udelay(10 * 1000);	}	return card_number;}/*  MII transceiver control section.	Read and write MII registers using software-generated serial MDIO	protocol.  See the MII specifications or DP83840A data sheet for details.	The maximum data clock rate is 2.5 Mhz.  To meet minimum timing we	must flush writes to the PCI bus with a PCI read. */#define mdio_delay(mdio_addr) INL(dev, mdio_addr)#define MDIO_EnbIn  (0)#define MDIO_WRITE0 (MDIO_EnbOutput)#define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)/* Generate the preamble required for initial synchronization and   a few older transceivers. */static voidmdio_sync(struct eth_device *dev, u32 offset){	int bits = 32;	/* Establish sync by sending at least 32 logic ones. */	while (--bits >= 0) {		OUTL(dev, MDIO_WRITE1, offset);		mdio_delay(offset);		OUTL(dev, MDIO_WRITE1 | MDIO_ShiftClk, offset);		mdio_delay(offset);	}}static intmdio_read(struct eth_device *dev, int phy_id, int addr){	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | addr;	int i, retval = 0;	/* Shift the read command bits out. */	for (i = 15; i >= 0; i--) {		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;		OUTL(dev, dataval, EECtrl);		mdio_delay(EECtrl);		OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);		mdio_delay(EECtrl);	}	/* Read the two transition, 16 data, and wire-idle bits. */	for (i = 19; i > 0; i--) {		OUTL(dev, MDIO_EnbIn, EECtrl);		mdio_delay(EECtrl);		retval =		    (retval << 1) | ((INL(dev, EECtrl) & MDIO_Data) ? 1 : 0);		OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);		mdio_delay(EECtrl);	}	return (retval >> 1) & 0xffff;}static voidmdio_write(struct eth_device *dev, int phy_id, int addr, int value){	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (addr << 18) | value;	int i;	/* Shift the command bits out. */	for (i = 31; i >= 0; i--) {		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;		OUTL(dev, dataval, EECtrl);		mdio_delay(EECtrl);		OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);		mdio_delay(EECtrl);	}	/* Clear out extra bits. */	for (i = 2; i > 0; i--) {		OUTL(dev, MDIO_EnbIn, EECtrl);		mdio_delay(EECtrl);		OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);		mdio_delay(EECtrl);	}	return;}/* Function: ns8382x_init * Description: resets the ethernet controller chip and configures *    registers and data structures required for sending and receiving packets. * Arguments: struct eth_device *dev:       NIC data structure * returns:  	int. */static intns8382x_init(struct eth_device *dev, bd_t * bis){	u32 config;	ns8382x_reset(dev);	/* Disable PME:	 * The PME bit is initialized from the EEPROM contents.	 * PCI cards probably have PME disabled, but motherboard	 * implementations may have PME set to enable WakeOnLan.	 * With PME set the chip will scan incoming packets but	 * nothing will be written to memory. */	OUTL(dev, SavedClkRun & ~0x100, ClkRun);	ns8382x_init_rxfilter(dev);	ns8382x_init_txd(dev);	ns8382x_init_rxd(dev);	/*set up ChipConfig */	config = INL(dev, ChipConfig);	/*turn off 64 bit ops && Ten-bit interface	 * && big-endian mode && extended status */	config &= ~(TBIEn | Mode1000 | T64En | D64En | M64En | BEMode | PhyDis | ExtStEn);	OUTL(dev, config, ChipConfig);	/* Configure the PCI bus bursts and FIFO thresholds. */	tx_config = TxCarrierIgn | TxHeartIgn | TxAutoPad	    | TxCollRetry | TxMxdma_1024 | (0x1002);	rx_config = RxMxdma_1024 | 0x20;#ifdef NS8382X_DEBUG	printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);	printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);#endif	OUTL(dev, tx_config, TxConfig);	OUTL(dev, rx_config, RxConfig);	/*turn off priority queueing */	OUTL(dev, 0x0, PriQueue);	ns8382x_check_duplex(dev);	ns8382x_set_rx_mode(dev);	OUTL(dev, (RxOn | TxOn), ChipCmd);	return 1;}/* Function: ns8382x_reset * Description: soft resets the controller chip * Arguments: struct eth_device *dev:          NIC data structure * Returns:   void. */static voidns8382x_reset(struct eth_device *dev){	OUTL(dev, ChipReset, ChipCmd);	while (INL(dev, ChipCmd))		/*wait until done */ ;	OUTL(dev, 0, IntrMask);	OUTL(dev, 0, IntrEnable);}/* Function: ns8382x_init_rxfilter * Description: sets receive filter address to our MAC address * Arguments: struct eth_device *dev:          NIC data structure * returns:   void. */static voidns8382x_init_rxfilter(struct eth_device *dev){	int i;	for (i = 0; i < ETH_ALEN; i += 2) {		OUTL(dev, i, RxFilterAddr);		OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),		     RxFilterData);	}}/* Function: ns8382x_init_txd * Description: initializes the Tx descriptor * Arguments: struct eth_device *dev:          NIC data structure * returns:   void. */static voidns8382x_init_txd(struct eth_device *dev){	txd.link = (u32) 0;	txd.bufptr = cpu_to_le32((u32) & txb[0]);	txd.cmdsts = (u32) 0;	txd.extsts = (u32) 0;	OUTL(dev, 0x0, TxRingPtrHi);	OUTL(dev, phys_to_bus((u32)&txd), TxRingPtr);#ifdef NS8382X_DEBUG	printf("ns8382x_init_txd: TX descriptor register loaded with: %#08X (&txd: %p)\n",	       INL(dev, TxRingPtr), &txd);#endif}/* Function: ns8382x_init_rxd * Description: initializes the Rx descriptor ring * Arguments: struct eth_device *dev:          NIC data structure * Returns:   void. */static voidns8382x_init_rxd(struct eth_device *dev){	int i;	OUTL(dev, 0x0, RxRingPtrHi);	cur_rx = 0;	for (i = 0; i < NUM_RX_DESC; i++) {		rxd[i].link =		    cpu_to_le32((i + 1 <				 NUM_RX_DESC) ? (u32) & rxd[i +							    1] : (u32) &				rxd[0]);		rxd[i].extsts = cpu_to_le32((u32) 0x0);		rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);		rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);#ifdef NS8382X_DEBUG		printf		    ("ns8382x_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",		     i, &rxd[i], le32_to_cpu(rxd[i].link),		     le32_to_cpu(rxd[i].cmdsts), le32_to_cpu(rxd[i].bufptr));#endif	}	OUTL(dev, phys_to_bus((u32) & rxd), RxRingPtr);#ifdef NS8382X_DEBUG	printf("ns8382x_init_rxd: RX descriptor register loaded with: %X\n",	       INL(dev, RxRingPtr));#endif}/* Function: ns8382x_set_rx_mode * Description: *    sets the receive mode to accept all broadcast packets and packets *    with our MAC address, and reject all multicast packets. * Arguments: struct eth_device *dev:          NIC data structure * Returns:   void. */static voidns8382x_set_rx_mode(struct eth_device *dev){	u32 rx_mode = 0x0;	/*spec says RxFilterEnable has to be 0 for rest of	 * this stuff to be properly configured. Linux driver	 * seems to support this*//*	OUTL(dev, rx_mode, RxFilterAddr);*/	rx_mode = (RxFilterEnable | AcceptAllBroadcast | AcceptPerfectMatch);	OUTL(dev, rx_mode, RxFilterAddr);	printf("ns8382x_set_rx_mode: set to %X\n", rx_mode);	/*now we turn RxFilterEnable back on */	/*rx_mode |= RxFilterEnable;	OUTL(dev, rx_mode, RxFilterAddr);*/}static voidns8382x_check_duplex(struct eth_device *dev){	int gig = 0;	int hun = 0;	int duplex = 0;	int config = (INL(dev, ChipConfig) ^ SpeedStatus_Polarity);	duplex = (config & FullDuplex) ? 1 : 0;	gig = (config & GigSpeed) ? 1 : 0;	hun = (config & HundSpeed) ? 1 : 0;#ifdef NS8382X_DEBUG	printf("%s: Setting 10%s %s-duplex based on negotiated link"	       " capability.\n", dev->name, (gig) ? "00" : (hun) ? "0" : "",	       duplex ? "full" : "half");#endif	if (duplex) {		rx_config |= RxAcceptTx;		tx_config |= (TxCarrierIgn | TxHeartIgn);	} else {		rx_config &= ~RxAcceptTx;		tx_config &= ~(TxCarrierIgn | TxHeartIgn);	}#ifdef NS8382X_DEBUG	printf("%s: Resetting TxConfig Register %#08X\n", dev->name, tx_config);	printf("%s: Resetting RxConfig Register %#08X\n", dev->name, rx_config);#endif	OUTL(dev, tx_config, TxConfig);	OUTL(dev, rx_config, RxConfig);	/*if speed is 10 or 100, remove MODE1000,	 * if it's 1000, then set it */	config = INL(dev, ChipConfig);	if (gig)		config |= Mode1000;	else		config &= ~Mode1000;#ifdef NS8382X_DEBUG	printf("%s: %setting Mode1000\n", dev->name, (gig) ? "S" : "Uns");#endif	OUTL(dev, config, ChipConfig);}/* Function: ns8382x_send * Description: transmits a packet and waits for completion or timeout. * Returns:   void.  */static intns8382x_send(struct eth_device *dev, volatile void *packet, int length){	u32 i, status = 0;	u32 tx_stat = 0;	/* Stop the transmitter */	OUTL(dev, TxOff, ChipCmd);#ifdef NS8382X_DEBUG	printf("ns8382x_send: sending %d bytes\n", (int)length);#endif	/* set the transmit buffer descriptor and enable Transmit State Machine */	txd.link = cpu_to_le32(0x0);	txd.bufptr = cpu_to_le32(phys_to_bus((u32)packet));	txd.extsts = cpu_to_le32(0x0);	txd.cmdsts = cpu_to_le32(DescOwn | length);	/* load Transmit Descriptor Register */	OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);#ifdef NS8382X_DEBUG	printf("ns8382x_send: TX descriptor register loaded with: %#08X\n",	       INL(dev, TxRingPtr));	printf("\ttxd.link:%X\tbufp:%X\texsts:%X\tcmdsts:%X\n",	       le32_to_cpu(txd.link), le32_to_cpu(txd.bufptr),	       le32_to_cpu(txd.extsts), le32_to_cpu(txd.cmdsts));#endif	/* restart the transmitter */	OUTL(dev, TxOn, ChipCmd);	for (i = 0; ((vu_long)tx_stat = le32_to_cpu(txd.cmdsts)) & DescOwn; i++) {		if (i >= TOUT_LOOP) {			printf ("%s: tx error buffer not ready: txd.cmdsts %#X\n",			     dev->name, tx_stat);			goto Done;		}	}	if (!(tx_stat & DescPktOK)) {		printf("ns8382x_send: Transmit error, Tx status %X.\n", tx_stat);		goto Done;	}#ifdef NS8382X_DEBUG	printf("ns8382x_send: tx_stat: %#08X\n", tx_stat);#endif	status = 1;      Done:	return status;}/* Function: ns8382x_poll * Description: checks for a received packet and returns it if found. * Arguments: struct eth_device *dev:          NIC data structure * Returns:   1 if    packet was received. *            0 if no packet was received. * Side effects: *            Returns (copies) the packet to the array dev->packet. *            Returns the length of the packet. */static intns8382x_poll(struct eth_device *dev){	int retstat = 0;	int length = 0;	vu_long rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);	if (!(rx_status & (u32) DescOwn))		return retstat;#ifdef NS8382X_DEBUG	printf("ns8382x_poll: got a packet: cur_rx:%u, status:%lx\n",	       cur_rx, rx_status);#endif	length = (rx_status & DSIZE) - CRC_SIZE;	if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {		/* corrupted packet received */		printf("ns8382x_poll: Corrupted packet, status:%lx\n", rx_status);		retstat = 0;	} else {		/* give packet to higher level routine */		NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);		retstat = 1;	}	/* return the descriptor and buffer to receive ring */	rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);	rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);	if (++cur_rx == NUM_RX_DESC)		cur_rx = 0;	/* re-enable the potentially idle receive state machine */	OUTL(dev, RxOn, ChipCmd);	return retstat;}/* Function: ns8382x_disable * Description: Turns off interrupts and stops Tx and Rx engines * Arguments: struct eth_device *dev:          NIC data structure * Returns:   void. */static voidns8382x_disable(struct eth_device *dev){	/* Disable interrupts using the mask. */	OUTL(dev, 0, IntrMask);	OUTL(dev, 0, IntrEnable);	/* Stop the chip's Tx and Rx processes. */	OUTL(dev, (RxOff | TxOff), ChipCmd);	/* Restore PME enable bit */	OUTL(dev, SavedClkRun, ClkRun);}#endif

⌨️ 快捷键说明

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