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

📄 natsemi.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef NATSEMI_DEBUG	printf("write_eeprom: %08x, %04hx, %04hx\n",		dev->iobase + ee_addr, write_cmd, value);#endif	/* Shift the write enable command bits out. */	for (i = 9; i >= 0; i--) {		short cmdval = (wren_cmd & (1 << i)) ? EE_Write1 : EE_Write0;		OUTL(dev, cmdval, ee_addr);		eeprom_delay(ee_addr);		OUTL(dev, cmdval | EE_ShiftClk, ee_addr);		eeprom_delay(ee_addr);	}	OUTL(dev, 0, ee_addr); /*bring chip select low*/	OUTL(dev, EE_ShiftClk, ee_addr);	eeprom_delay(ee_addr);	/* Shift the write command bits out. */	for (i = 9; i >= 0; i--) {		short cmdval = (write_cmd & (1 << i)) ? EE_Write1 : EE_Write0;		OUTL(dev, cmdval, ee_addr);		eeprom_delay(ee_addr);		OUTL(dev, cmdval | EE_ShiftClk, ee_addr);		eeprom_delay(ee_addr);	}	for (i = 0; i < 16; i++) {		short cmdval = (value & (1 << i)) ? EE_Write1 : EE_Write0;		OUTL(dev, cmdval, ee_addr);		eeprom_delay(ee_addr);		OUTL(dev, cmdval | EE_ShiftClk, ee_addr);		eeprom_delay(ee_addr);	}	OUTL(dev, 0, ee_addr); /*bring chip select low*/	OUTL(dev, EE_ShiftClk, ee_addr);	for (i = 0; i < 200000; i++) {		OUTL(dev, EE_Write0, ee_addr); /*poll for done*/		if (INL(dev, ee_addr) & EE_DataOut) {		    break; /*finished*/		}	}	eeprom_delay(ee_addr);	/* Terminate the EEPROM access. */	OUTL(dev, EE_Write0, ee_addr);	OUTL(dev, 0, ee_addr);	return;}#endifstatic intread_eeprom(struct eth_device *dev, long addr, int location){	int i;	int retval = 0;	int ee_addr = (typeof(ee_addr))addr;	int read_cmd = location | EE_ReadCmd;	OUTL(dev, EE_Write0, ee_addr);	/* Shift the read command bits out. */	for (i = 10; i >= 0; i--) {		short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;		OUTL(dev, dataval, ee_addr);		eeprom_delay(ee_addr);		OUTL(dev, dataval | EE_ShiftClk, ee_addr);		eeprom_delay(ee_addr);	}	OUTL(dev, EE_ChipSelect, ee_addr);	eeprom_delay(ee_addr);	for (i = 0; i < 16; i++) {		OUTL(dev, EE_ChipSelect | EE_ShiftClk, ee_addr);		eeprom_delay(ee_addr);		retval |= (INL(dev, ee_addr) & EE_DataOut) ? 1 << i : 0;		OUTL(dev, EE_ChipSelect, ee_addr);		eeprom_delay(ee_addr);	}	/* Terminate the EEPROM access. */	OUTL(dev, EE_Write0, ee_addr);	OUTL(dev, 0, ee_addr);#ifdef NATSEMI_DEBUG	if (natsemi_debug)		printf("read_eeprom: %08x, %08x, retval %08x\n",			dev->iobase + ee_addr, read_cmd, retval);#endif	return retval;}/*  MII transceiver control section.	The 83815 series has an internal transceiver, and we present the	management registers as if they were MII connected. */static intmdio_read(struct eth_device *dev, int phy_id, int location){	if (phy_id == 1 && location < 32)		return INL(dev, BasicControl+(location<<2))&0xffff;	else		return 0xffff;}/* Function: natsemi_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 intnatsemi_init(struct eth_device *dev, bd_t * bis){	natsemi_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);	natsemi_init_rxfilter(dev);	natsemi_init_txd(dev);	natsemi_init_rxd(dev);	/* Configure the PCI bus bursts and FIFO thresholds. */	tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | (0x1002);	rx_config = RxMxdma_256 | 0x20;#ifdef NATSEMI_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);	natsemi_check_duplex(dev);	natsemi_set_rx_mode(dev);	OUTL(dev, (RxOn | TxOn), ChipCmd);	return 1;}/* * Function: natsemi_reset * * Description: soft resets the controller chip * * Arguments: struct eth_device *dev:          NIC data structure * * Returns:   void. */static voidnatsemi_reset(struct eth_device *dev){	OUTL(dev, ChipReset, ChipCmd);	/* On page 78 of the spec, they recommend some settings for "optimum	   performance" to be done in sequence.  These settings optimize some	   of the 100Mbit autodetection circuitry.  Also, we only want to do	   this for rev C of the chip.  */	if (INL(dev, SiliconRev) == 0x302) {		OUTW(dev, 0x0001, PGSEL);		OUTW(dev, 0x189C, PMDCSR);		OUTW(dev, 0x0000, TSTDAT);		OUTW(dev, 0x5040, DSPCFG);		OUTW(dev, 0x008C, SDCFG);	}	/* Disable interrupts using the mask. */	OUTL(dev, 0, IntrMask);	OUTL(dev, 0, IntrEnable);}/* Function: natsemi_init_rxfilter * * Description: sets receive filter address to our MAC address * * Arguments: struct eth_device *dev:          NIC data structure * * returns:   void. */static voidnatsemi_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: natsemi_init_txd * * Description: initializes the Tx descriptor * * Arguments: struct eth_device *dev:          NIC data structure * * returns:   void. */static voidnatsemi_init_txd(struct eth_device *dev){	txd.link = (u32) 0;	txd.cmdsts = (u32) 0;	txd.bufptr = (u32) & txb[0];	/* load Transmit Descriptor Register */	OUTL(dev, (u32) & txd, TxRingPtr);#ifdef NATSEMI_DEBUG	printf("natsemi_init_txd: TX descriptor reg loaded with: %#08X\n",	       INL(dev, TxRingPtr));#endif}/* Function: natsemi_init_rxd * * Description: initializes the Rx descriptor ring * * Arguments: struct eth_device *dev:          NIC data structure * * Returns:   void. */static voidnatsemi_init_rxd(struct eth_device *dev){	int i;	cur_rx = 0;	/* init RX descriptor */	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].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);		rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);#ifdef NATSEMI_DEBUG		printf		    ("natsemi_init_rxd: rxd[%d]=%p link=%X cmdsts=%lX bufptr=%X\n",		     	i, &rxd[i], le32_to_cpu(rxd[i].link),		     		rxd[i].cmdsts, rxd[i].bufptr);#endif	}	/* load Receive Descriptor Register */	OUTL(dev, (u32) & rxd[0], RxRingPtr);#ifdef NATSEMI_DEBUG	printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",	       INL(dev, RxRingPtr));#endif}/* Function: natsemi_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 voidnatsemi_set_rx_mode(struct eth_device *dev){	u32 rx_mode = AcceptBroadcast | AcceptMyPhys;	OUTL(dev, rx_mode, RxFilterAddr);}static voidnatsemi_check_duplex(struct eth_device *dev){	int duplex = INL(dev, ChipConfig) & FullDuplex ? 1 : 0;#ifdef NATSEMI_DEBUG	printf("%s: Setting %s-duplex based on negotiated link"	       " capability.\n", dev->name, duplex ? "full" : "half");#endif	if (duplex) {		rx_config |= RxAcceptTx;		tx_config |= (TxCarrierIgn | TxHeartIgn);	} else {		rx_config &= ~RxAcceptTx;		tx_config &= ~(TxCarrierIgn | TxHeartIgn);	}	OUTL(dev, tx_config, TxConfig);	OUTL(dev, rx_config, RxConfig);}/* Function: natsemi_send * * Description: transmits a packet and waits for completion or timeout. * * Returns:   void.  */static intnatsemi_send(struct eth_device *dev, volatile void *packet, int length){	u32 i, status = 0;	u32 tx_status = 0;	/* Stop the transmitter */	OUTL(dev, TxOff, ChipCmd);#ifdef NATSEMI_DEBUG	if (natsemi_debug)		printf("natsemi_send: sending %d bytes\n", (int) length);#endif	/* set the transmit buffer descriptor and enable Transmit State Machine */	txd.link = cpu_to_le32(0);	txd.bufptr = cpu_to_le32(phys_to_bus((u32) packet));	txd.cmdsts = cpu_to_le32(DescOwn | length);	/* load Transmit Descriptor Register */	OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);#ifdef NATSEMI_DEBUG	if (natsemi_debug)	    printf("natsemi_send: TX descriptor register loaded with: %#08X\n",	     INL(dev, TxRingPtr));#endif	/* restart the transmitter */	OUTL(dev, TxOn, ChipCmd);	for (i = 0;	     ((vu_long)tx_status = 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_status);			goto Done;		}	}	if (!(tx_status & DescPktOK)) {		printf("natsemi_send: Transmit error, Tx status %X.\n",		       tx_status);		goto Done;	}	status = 1;      Done:	return status;}/* Function: natsemi_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 intnatsemi_poll(struct eth_device *dev){	int retstat = 0;	int length = 0;	u32 rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);	if (!(rx_status & (u32) DescOwn))		return retstat;#ifdef NATSEMI_DEBUG	if (natsemi_debug)		printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",		       cur_rx, rx_status);#endif	length = (rx_status & DSIZE) - CRC_SIZE;	if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {		printf		    ("natsemi_poll: Corrupted packet received, buffer status = %X\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: natsemi_disable * * Description: Turns off interrupts and stops Tx and Rx engines * * Arguments: struct eth_device *dev:          NIC data structure * * Returns:   void. */static voidnatsemi_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 + -