summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/Makefile1
-rwxr-xr-xdrivers/i2c/aspeed_i2c.c286
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/aspeednic.c1528
4 files changed, 1816 insertions, 0 deletions
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 72e85a349a..2b35587e3d 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
COBJS-$(CONFIG_TEGRA_I2C) += tegra_i2c.o
COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
+COBJS-$(CONFIG_DRIVER_ASPEED_I2C) += aspeed_i2c.o
COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
COBJS-$(CONFIG_SH_I2C) += sh_i2c.o
COBJS-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
diff --git a/drivers/i2c/aspeed_i2c.c b/drivers/i2c/aspeed_i2c.c
new file mode 100755
index 0000000000..ff6c7565ba
--- /dev/null
+++ b/drivers/i2c/aspeed_i2c.c
@@ -0,0 +1,286 @@
+/*
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/aspeed_i2c.h>
+
+#ifdef CONFIG_DRIVER_ASPEED_I2C
+
+void i2c_init (int speed, int slaveadd)
+{
+ unsigned long SCURegister;
+//I2C Reset
+ SCURegister = inl (SCU_BASE + SCU_RESET_CONTROL);
+ outl (SCURegister & ~(0x04), SCU_BASE + SCU_RESET_CONTROL);
+//I2C Multi-Pin
+ SCURegister = inl (SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL5_REG);
+ outl ((SCURegister | 0x30000), SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL5_REG);
+//Reset
+ outl (0, I2C_FUNCTION_CONTROL_REGISTER);
+//Set AC Timing, we use fix AC timing for eeprom in u-boot
+ outl (AC_TIMING, I2C_AC_TIMING_REGISTER_1);
+ outl (0, I2C_AC_TIMING_REGISTER_2);
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+//Enable Master Mode
+ outl (MASTER_ENABLE, I2C_FUNCTION_CONTROL_REGISTER);
+//Enable Interrupt, STOP Interrupt has bug in AST2000
+ outl (0xAF, I2C_INTERRUPT_CONTROL_REGISTER);
+//Set Slave address, should not use for eeprom
+ outl (slaveadd, I2C_DEVICE_ADDRESS_REGISTER);
+}
+
+static int i2c_read_byte (u8 devaddr, u16 regoffset, u8 * value, int alen)
+{
+ int i2c_error = 0;
+ u32 status, count = 0;
+
+//Start and Send Device Address
+ outl (devaddr, I2C_BYTE_BUFFER_REGISTER);
+ outl (MASTER_START_COMMAND | MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
+//Wait Tx ACK
+ do {
+ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
+ count++;
+ if (count == LOOP_COUNT) {
+ i2c_error = 1;
+ printf ("Start and Send Device Address can't get ACK back\n");
+ return i2c_error;
+ }
+ } while (status != TX_ACK);
+ count = 0;
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+//Check if address length equals to 16bits
+ if (alen != 1) {
+//Send Device Register Offset (HIGH BYTE)
+ outl ((regoffset & 0xFF00) >> 8, I2C_BYTE_BUFFER_REGISTER);
+ outl (MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
+//Wait Tx ACK
+ do {
+ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
+ count++;
+ if (count == LOOP_COUNT) {
+ i2c_error = 1;
+ printf ("Send Device Register Offset can't get ACK back\n");
+ return i2c_error;
+ }
+ } while (status != TX_ACK);
+ count = 0;
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+ }
+//Send Device Register Offset(LOW)
+ outl (regoffset & 0xFF, I2C_BYTE_BUFFER_REGISTER);
+ outl (MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
+//Wait Tx ACK
+ do {
+ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
+ count++;
+ if (count == LOOP_COUNT) {
+ i2c_error = 1;
+ printf ("Send Device Register Offset can't get ACK back\n");
+ return i2c_error;
+ }
+ } while (status != TX_ACK);
+ count = 0;
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+//Start, Send Device Address + 1 (Read Mode), Receive Data
+ outl (devaddr + 1, I2C_BYTE_BUFFER_REGISTER);
+ outl (MASTER_START_COMMAND | MASTER_TX_COMMAND | MASTER_RX_COMMAND | RX_COMMAND_LIST, I2C_COMMAND_REGISTER);
+//Wait Rx Done
+ do {
+ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & RX_DONE);
+ count++;
+ if (count == LOOP_COUNT) {
+ i2c_error = 1;
+ printf ("Can't get RX_DONE back\n");
+ return i2c_error;
+ }
+ } while (status != RX_DONE);
+ count = 0;
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+//Enable Interrupt + Stop Interrupt
+ outl (0xBF, I2C_INTERRUPT_CONTROL_REGISTER);
+//Issue Stop Command
+ outl (MASTER_STOP_COMMAND, I2C_COMMAND_REGISTER);
+//Wait Stop
+ do {
+ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & STOP_DONE);
+ count++;
+ if (count == LOOP_COUNT) {
+ i2c_error = 1;
+ printf ("Can't get STOP back\n");
+ return i2c_error;
+ }
+ } while (status != STOP_DONE);
+//Disable Stop Interrupt
+ outl (0xAF, I2C_INTERRUPT_CONTROL_REGISTER);
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+//Read Received Data
+ *value = ((inl (I2C_BYTE_BUFFER_REGISTER) & 0xFF00) >> 8);
+
+ return i2c_error;
+}
+
+static int i2c_write_byte (u8 devaddr, u16 regoffset, u8 value, int alen)
+{
+ int i2c_error = 0;
+ u32 status, count = 0;
+
+//Start and Send Device Address
+ outl (devaddr, I2C_BYTE_BUFFER_REGISTER);
+ outl (MASTER_START_COMMAND | MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
+//Wait Tx ACK
+ do {
+ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
+ count++;
+ if (status == TX_NACK) {
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+//Re-send Start and Send Device Address while NACK return
+ outl (devaddr, I2C_BYTE_BUFFER_REGISTER);
+ outl (MASTER_START_COMMAND | MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
+ }
+ else {
+ if (count == LOOP_COUNT) {
+ i2c_error = 1;
+ printf ("Start and Send Device Address can't get ACK back\n");
+ return i2c_error;
+ }
+ }
+ } while (status != TX_ACK);
+ count = 0;
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+//Check if address length equals to 16bits
+ if (alen != 1) {
+//Send Device Register Offset (HIGH BYTE)
+ outl ((regoffset & 0xFF00) >> 8, I2C_BYTE_BUFFER_REGISTER);
+ outl (MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
+//Wait Tx ACK
+ do {
+ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
+ count++;
+ if (count == LOOP_COUNT) {
+ i2c_error = 1;
+ printf ("Send Device Register Offset can't get ACK back\n");
+ return i2c_error;
+ }
+ } while (status != TX_ACK);
+ count = 0;
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+ }
+//Send Device Register Offset
+ outl (regoffset & 0xFF, I2C_BYTE_BUFFER_REGISTER);
+ outl (MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
+//Wait Tx ACK
+ do {
+ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
+ count++;
+ if (count == LOOP_COUNT) {
+ i2c_error = 1;
+ printf ("Send Device Register Offset can't get ACK back\n");
+ return i2c_error;
+ }
+ } while (status != TX_ACK);
+ count = 0;
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+//Send Device Register Value
+ outl (value, I2C_BYTE_BUFFER_REGISTER);
+ outl (MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
+//Wait Tx ACK
+ do {
+ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
+ count++;
+ if (count == LOOP_COUNT) {
+ i2c_error = 1;
+ printf ("Send Device Register Value can't get ACK back\n");
+ return i2c_error;
+ }
+ } while (status != TX_ACK);
+ count = 0;
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+//Enable Interrupt + Stop Interrupt
+ outl (0xBF, I2C_INTERRUPT_CONTROL_REGISTER);
+//Issue Stop Command
+ outl (MASTER_STOP_COMMAND, I2C_COMMAND_REGISTER);
+//Wait Stop
+ do {
+ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & STOP_DONE);
+ count++;
+ if (count == LOOP_COUNT) {
+ i2c_error = 1;
+ printf ("Can't get STOP back\n");
+ return i2c_error;
+ }
+ } while (status != STOP_DONE);
+//Disable Stop Interrupt
+ outl (0xAF, I2C_INTERRUPT_CONTROL_REGISTER);
+//Clear Interrupt
+ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
+
+ return i2c_error;
+}
+
+int i2c_probe (uchar chip)
+{
+//Suppose IP is always on chip
+ int res = 0;
+
+ return res;
+}
+
+int i2c_read (uchar device_addr, uint register_offset, int alen, uchar * buffer, int len)
+{
+ int i;
+
+ if ((alen == 1) && ((register_offset + len) > 256)) {
+ printf ("Register index overflow\n");
+ }
+
+ for (i = 0; i < len; i++) {
+ if (i2c_read_byte (device_addr, register_offset + i, &buffer[i], alen)) {
+ printf ("I2C read: I/O error\n");
+ i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int i2c_write (uchar device_addr, uint register_offset, int alen, uchar * buffer, int len)
+{
+ int i;
+
+ if ((alen == 1) && ((register_offset + len) > 256)) {
+ printf ("Register index overflow\n");
+ }
+
+ for (i = 0; i < len; i++) {
+ if (i2c_write_byte (device_addr, register_offset + i, buffer[i], alen)) {
+ printf ("I2C read: I/O error\n");
+ i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_DRIVER_ASPEED_I2C */
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 9cf2983d18..a1d19ca0fe 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -68,6 +68,7 @@ COBJS-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o
COBJS-$(CONFIG_RTL8139) += rtl8139.o
COBJS-$(CONFIG_RTL8169) += rtl8169.o
COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
+COBJS-$(CONFIG_ASPEEDNIC) += aspeednic.o
COBJS-$(CONFIG_SMC91111) += smc91111.o
COBJS-$(CONFIG_SMC911X) += smc911x.o
COBJS-$(CONFIG_SUNXI_WEMAC) += sunxi_wemac.o
diff --git a/drivers/net/aspeednic.c b/drivers/net/aspeednic.c
new file mode 100644
index 0000000000..6b1ce05e8d
--- /dev/null
+++ b/drivers/net/aspeednic.c
@@ -0,0 +1,1528 @@
+/*
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && defined(CONFIG_ASPEEDNIC)
+
+#include <malloc.h>
+#include <net.h>
+#include <pci.h>
+
+
+/*
+ SCU88 D[31]: MAC1 MDIO
+ SCU88 D[30]: MAC1 MDC
+ SCU90 D[2]: MAC2 MDC/MDIO
+ SCU80 D[0]: MAC1 Link
+ SCU80 D[1]: MAC2 Link
+*/
+#define pci_find_devices NULL
+#define pci_read_config_dword NULL
+#if defined(CONFIG_AST1300)
+#define SCU_BASE CONFIG_SCUREG_BASE
+#else
+#define SCU_BASE 0x1E6E2000
+#endif
+#define SCU_RESET_CONTROL 0x04
+#define SCU_CLOCK_SELECTION 0x08
+#define SCU_CLOCK_CONTROL 0x0C
+#define SCU_MAC_CLOCK_DELAY 0x48
+#define SCU_SCRATCH_REGISTER 0x40
+#define SCU_HARDWARE_TRAPPING 0x70
+#define SCU_PIN_MUX 0x74
+#define SCU_MULTIFUNCTION_PIN_CTL1_REG 0x80
+#define SCU_MULTIFUNCTION_PIN_CTL3_REG 0x88
+#define SCU_MULTIFUNCTION_PIN_CTL5_REG 0x90
+#define MAC_INTERFACE 0x1C0
+#define GMII 0x0
+#define MII 0x40
+#define MAC1_CLOCK_ENABLE (1 << 20)
+#define MAC2_CLOCK_ENABLE (1 << 21)
+#define MAC_AHB_CLOCK_DIVIDER (0x07 << 16)
+#if defined(CONFIG_AST2300_FPGA_2) || defined(CONFIG_AST2300) || defined(CONFIG_AST3100) || defined(CONFIG_AST2400)
+#define MAC1_MDIO (1 << 31)
+#define MAC1_MDC (1 << 30)
+#define MAC1_PHY_LINK (1 << 0)
+#define MAC2_MDC_MDIO (1 << 2)
+#define MAC1_PHY_LINK (1 << 0)
+#define MAC2_PHY_LINK (1 << 1)
+#else
+#define MAC2_MDC_MDIO (1 << 20)
+#define MAC2_MII (1 << 21)
+#define MAC1_PHY_LINK (1 << 25)
+#define MAC2_PHY_LINK (1 << 26)
+#endif
+
+#if defined(CONFIG_AST1300)
+unsigned int aspeednic_iobase[1] = {CONFIG_MACREG_BASE};
+#else
+unsigned int aspeednic_iobase[CONFIG_ASPEED_MAC_NUMBER] = {
+ 0x1E660000, 0x1E680000};
+#endif
+
+#undef DEBUG_SROM
+#undef DEBUG_SROM2
+
+#undef UPDATE_SROM
+
+/* PCI Registers.
+ */
+#define PCI_CFDA_PSM 0x43
+
+#define CFRV_RN 0x000000f0 /* Revision Number */
+
+#define WAKEUP 0x00 /* Power Saving Wakeup */
+#define SLEEP 0x80 /* Power Saving Sleep Mode */
+
+#define DC2114x_BRK 0x0020 /* CFRV break between DC21142 & DC21143 */
+
+/* MAC chip register */
+#define ISR_REG 0x00 // interrups status register
+#define IER_REG 0x04 // interrupt maks register
+#define MAC_MADR_REG 0x08 // MAC address (Most significant)
+#define MAC_LADR_REG 0x0c // MAC address (Least significant)
+
+#define MAHT0_REG 0x10 // Multicast Address Hash Table 0 register
+#define MAHT1_REG 0x14 // Multicast Address Hash Table 1 register
+#define TXPD_REG 0x18 // Transmit Poll Demand register
+#define RXPD_REG 0x1c // Receive Poll Demand register
+#define TXR_BADR_REG 0x20 // Transmit Ring Base Address register
+#define RXR_BADR_REG 0x24 // Receive Ring Base Address register
+
+#define HPTXPD_REG 0x28 //
+#define HPTXR_BADR_REG 0x2c //
+
+#define ITC_REG 0x30 // interrupt timer control register
+#define APTC_REG 0x34 // Automatic Polling Timer control register
+#define DBLAC_REG 0x38 // DMA Burst Length and Arbitration control register
+
+#define DMAFIFOS_REG 0x3c //
+#define FEAR_REG 0x44 //
+#define TPAFCR_REG 0x48 //
+#define RBSR_REG 0x4c //for NC Body
+#define MACCR_REG 0x50 // MAC control register
+#define MACSR_REG 0x54 // MAC status register
+#define PHYCR_REG 0x60 // PHY control register
+#define PHYDATA_REG 0x64 // PHY Write Data register
+#define FCR_REG 0x68 // Flow Control register
+#define BPR_REG 0x6c // back pressure register
+#define WOLCR_REG 0x70 // Wake-On-Lan control register
+#define WOLSR_REG 0x74 // Wake-On-Lan status register
+#define WFCRC_REG 0x78 // Wake-up Frame CRC register
+#define WFBM1_REG 0x80 // wake-up frame byte mask 1st double word register
+#define WFBM2_REG 0x84 // wake-up frame byte mask 2nd double word register
+#define WFBM3_REG 0x88 // wake-up frame byte mask 3rd double word register
+#define WFBM4_REG 0x8c // wake-up frame byte mask 4th double word register
+
+
+// --------------------------------------------------------------------
+// MACCR_REG
+// --------------------------------------------------------------------
+
+#define SW_RST_bit (1UL<<31) // software reset/
+#define DIRPATH_bit (1UL<<21)
+#define RX_IPCS_FAIL_bit (1UL<<20) //
+#define RX_TCPCS_FAIL_bit (1UL<<19) //
+#define SPEED_100M_MODE_bit (1UL<<19)
+#define RX_UDPCS_FAIL_bit (1UL<<18) //
+#define RX_BROADPKT_bit (1UL<<17) // Receiving broadcast packet
+#define RX_MULTIPKT_bit (1UL<<16) // receiving multicast packet
+#define RX_HT_EN_bit (1UL<<15)
+#define RX_ALLADR_bit (1UL<<14) // not check incoming packet's destination address
+#define JUMBO_LF_bit (1UL<<13) //
+#define RX_RUNT_bit (1UL<<12) // Store incoming packet even its length is les than 64 byte
+#define CRC_CHK_bit (1UL<<11) //
+#define CRC_APD_bit (1UL<<10) // append crc to transmit packet
+#define GMAC_MODE_bit (1UL<<9) //
+#define FULLDUP_bit (1UL<<8) // full duplex
+#define ENRX_IN_HALFTX_bit (1UL<<7) //
+#define LOOP_EN_bit (1UL<<6) // Internal loop-back
+#define HPTXR_EN_bit (1UL<<5) //
+#define REMOVE_VLAN_bit (1UL<<4) //
+#define RXMAC_EN_bit (1UL<<3) // receiver enable
+#define TXMAC_EN_bit (1UL<<2) // transmitter enable
+#define RXDMA_EN_bit (1UL<<1) // enable DMA receiving channel
+#define TXDMA_EN_bit (1UL<<0) // enable DMA transmitting channel
+
+//---------------------------------------------------
+// PHY R/W Register Bit
+//---------------------------------------------------
+#define MIIWR (1UL<<27)
+#define MIIRD (1UL<<26)
+#define MDC_CYCTHR 0x34
+#define PHY_SPEED_MASK 0xC000
+#define PHY_DUPLEX_MASK 0x2000
+#define SPEED_1000M 0x02
+#define SPEED_100M 0x01
+#define SPEED_10M 0x00
+#define DUPLEX_FULL 0x01
+#define DUPLEX_HALF 0x00
+#define RESOLVED_BIT 0x800
+
+#define PHY_SPEED_DUPLEX_MASK 0x01E0
+#define PHY_100M_DUPLEX 0x0100
+#define PHY_100M_HALF 0x0080
+#define PHY_10M_DUPLEX 0x0040
+#define PHY_10M_HALF 0x0020
+
+
+
+/* Descriptor bits.
+ */
+#define TXDMA_OWN 0x80000000 /* Own Bit */
+#define RXPKT_RDY 0x00000000
+#define RXPKT_STATUS 0x80000000
+//#define EDORR 0x00008000 /* Receive End Of Ring */
+#define EDORR 0x40000000 /* Receive End Of Ring */
+#define LRS 0x10000000 /* Last Descriptor */
+#define RD_ES 0x00008000 /* Error Summary */
+//#define EDOTR 0x00008000 /* Transmit End Of Ring */
+#define EDOTR 0x40000000 /* Transmit End Of Ring */
+#define T_OWN 0x80000000 /* Own Bit */
+#define LTS 0x10000000 /* Last Segment */
+#define FTS 0x20000000 /* First Segment */
+#define CRC_ERR 0x00080000
+#define TD_ES 0x00008000 /* Error Summary */
+#define TD_SET 0x08000000 /* Setup Packet */
+#define RX_ERR 0x00040000
+#define FTL 0x00100000
+#define RUNT 0x00200000
+#define RX_ODD_NB 0x00400000
+
+#define POLL_DEMAND 1
+#define RESET_DE4X5(dev) { \
+ int i; \
+ i=INL(dev, MACCR_REG); \
+ udelay(1000); \
+ OUTL(dev, i | SW_RST_bit, MACCR_REG); \
+ for (; (INL(dev, MACCR_REG ) & SW_RST_bit) != 0; ) {udelay(1000);} \
+ OUTL(dev, 0, IER_REG ); \
+ }
+
+#define START_MAC(dev) { \
+ s32 omr; \
+ omr = INL(dev, MACCR_REG); \
+ omr |= RXMAC_EN_bit | TXMAC_EN_bit | RXDMA_EN_bit | TXDMA_EN_bit; \
+ OUTL(dev, omr, MACCR_REG); /* Enable the TX and/or RX */ \
+ }
+
+#define STOP_MAC(dev) { \
+ s32 omr; \
+ omr = INL(dev, MACCR_REG); \
+ omr &= ~(RXMAC_EN_bit | TXMAC_EN_bit | RXDMA_EN_bit | TXDMA_EN_bit); \
+ OUTL(dev, omr, MACCR_REG); /* Disable the TX and/or RX */ \
+ }
+
+#define NUM_RX_DESC PKTBUFSRX
+#define NUM_TX_DESC 1 /* Number of TX descriptors */
+#define RX_BUFF_SZ PKTSIZE_ALIGN
+#define TX_BUFF_SZ 1514
+
+#define TOUT_LOOP 1000000
+#define PHY_LOOP 250
+#define ETH_ALEN 6
+#define NCSI_LOOP 1500000
+#define RETRY_COUNT 1
+
+struct de4x5_desc {
+ volatile s32 status;
+ u32 des1;
+ u32 reserved;
+ u32 buf;
+};
+
+//PHY Information
+#define PHYID_VENDOR_MASK 0xfffffc00
+#define PHYID_VENDOR_MODEL_MASK 0xfffffff0
+#define PHYID_VENDOR_MARVELL 0x01410c00
+#define PHYID_VENDOR_BROADCOM 0x00406000
+#define PHYID_VENDOR_REALTEK 0x001cc800
+#define PHYID_RTL8201EL 0x001cc810
+#define PHYID_RTL8211 0x001cc910
+#define PHYID_BCM54612E 0x03625E6A
+
+//NCSI define & structure
+//NC-SI Command Packet
+typedef struct {
+//Ethernet Header
+ unsigned char DA[6];
+ unsigned char SA[6];
+ unsigned short EtherType; //DMTF NC-SI
+//NC-SI Control Packet
+ unsigned char MC_ID; //Management Controller should set this field to 0x00
+ unsigned char Header_Revision; //For NC-SI 1.0 spec, this field has to set 0x01
+ unsigned char Reserved_1; //Reserved has to set to 0x00
+ unsigned char IID; //Instance ID
+ unsigned char Command;
+ unsigned char Channel_ID;
+ unsigned short Payload_Length; //Payload Length = 12 bits, 4 bits are reserved
+ unsigned long Reserved_2;
+ unsigned long Reserved_3;
+} NCSI_Command_Packet;
+
+unsigned char Payload_Data[16];
+unsigned char Payload_Pad[4] = {0x00, 0x00, 0x00, 0x00};
+unsigned long Payload_Checksum = 0x00000000;
+
+
+//Command and Response Type
+#define CLEAR_INITIAL_STATE 0x00 //M
+#define SELECT_PACKAGE 0x01 //M
+#define DESELECT_PACKAGE 0x02 //M
+#define ENABLE_CHANNEL 0x03 //M
+#define DISABLE_CHANNEL 0x04 //M
+#define RESET_CHANNEL 0x05 //M
+#define ENABLE_CHANNEL_NETWORK_TX 0x06 //M
+#define DISABLE_CHANNEL_NETWORK_TX 0x07 //M
+#define AEN_ENABLE 0x08
+#define SET_LINK 0x09 //M
+#define GET_LINK_STATUS 0x0A //M
+#define SET_VLAN_FILTER 0x0B //M
+#define ENABLE_VLAN 0x0C //M
+#define DISABLE_VLAN 0x0D //M
+#define SET_MAC_ADDRESS 0x0E //M
+#define ENABLE_BROADCAST_FILTERING 0x10 //M
+#define DISABLE_BROADCAST_FILTERING 0x11 //M
+#define ENABLE_GLOBAL_MULTICAST_FILTERING 0x12
+#define DISABLE_GLOBAL_MULTICAST_FILTERING 0x13
+#define SET_NCSI_FLOW_CONTROL 0x14
+#define GET_VERSION_ID 0x15 //M
+#define GET_CAPABILITIES 0x16 //M
+#define GET_PARAMETERS 0x17 //M
+#define GET_CONTROLLER_PACKET_STATISTICS 0x18
+#define GET_NCSI_STATISTICS 0x19
+#define GET_NCSI_PASS_THROUGH_STATISTICS 0x1A
+
+//NC-SI Response Packet
+typedef struct {
+ unsigned char DA[6];
+ unsigned char SA[6];
+ unsigned short EtherType; //DMTF NC-SI
+//NC-SI Control Packet
+ unsigned char MC_ID; //Management Controller should set this field to 0x00
+ unsigned char Header_Revision; //For NC-SI 1.0 spec, this field has to set 0x01
+ unsigned char Reserved_1; //Reserved has to set to 0x00
+ unsigned char IID; //Instance ID
+ unsigned char Command;
+ unsigned char Channel_ID;
+ unsigned short Payload_Length; //Payload Length = 12 bits, 4 bits are reserved
+ unsigned short Reserved_2;
+ unsigned short Reserved_3;
+ unsigned short Reserved_4;
+ unsigned short Reserved_5;
+ unsigned short Response_Code;
+ unsigned short Reason_Code;
+ unsigned char Payload_Data[64];
+} NCSI_Response_Packet;
+
+NCSI_Command_Packet NCSI_Request;
+NCSI_Response_Packet NCSI_Respond;
+
+//Standard Response Code
+#define COMMAND_COMPLETED 0x00
+#define COMMAND_FAILED 0x01
+#define COMMAND_UNAVAILABLE 0x02
+#define COMMAND_UNSUPPORTED 0x03
+
+//Standard Reason Code
+#define NO_ERROR 0x0000
+#define INTERFACE_INITIALIZATION_REQUIRED 0x0001
+#define PARAMETER_IS_INVALID 0x0002
+#define CHANNEL_NOT_READY 0x0003
+#define PACKAGE_NOT_READY 0x0004
+#define INVALID_PAYLOAD_LENGTH 0x0005
+#define UNKNOWN_COMMAND_TYPE 0x7FFF
+
+
+struct AEN_Packet {
+//Ethernet Header
+ unsigned char DA[6];
+ unsigned char SA[6]; //Network Controller SA = FF:FF:FF:FF:FF:FF
+ unsigned short EtherType; //DMTF NC-SI
+//AEN Packet Format
+ unsigned char MC_ID; //Network Controller should set this field to 0x00
+ unsigned char Header_Revision; //For NC-SI 1.0 spec, this field has to set 0x01
+ unsigned char Reserved_1; //Reserved has to set to 0x00
+// unsigned char IID = 0x00; //Instance ID = 0 in Network Controller
+// unsigned char Command = 0xFF; //AEN = 0xFF
+ unsigned char Channel_ID;
+// unsigned short Payload_Length = 0x04; //Payload Length = 4 in Network Controller AEN Packet
+ unsigned long Reserved_2;
+ unsigned long Reserved_3;
+ unsigned char AEN_Type;
+// unsigned char Reserved_4[3] = {0x00, 0x00, 0x00};
+ unsigned long Optional_AEN_Data;
+ unsigned long Payload_Checksum;
+};
+
+//AEN Type
+#define LINK_STATUS_CHANGE 0x0
+#define CONFIGURATION_REQUIRED 0x1
+#define HOST_NC_DRIVER_STATUS_CHANGE 0x2
+
+typedef struct {
+ unsigned char Package_ID;
+ unsigned char Channel_ID;
+ unsigned long Capabilities_Flags;
+ unsigned long Broadcast_Packet_Filter_Capabilities;
+ unsigned long Multicast_Packet_Filter_Capabilities;
+ unsigned long Buffering_Capabilities;
+ unsigned long AEN_Control_Support;
+} NCSI_Capability;
+NCSI_Capability NCSI_Cap;
+
+//SET_MAC_ADDRESS
+#define UNICAST (0x00 << 5)
+#define MULTICAST (0x01 << 5)
+#define DISABLE_MAC_ADDRESS_FILTER 0x00
+#define ENABLE_MAC_ADDRESS_FILTER 0x01
+
+//GET_LINK_STATUS
+#define LINK_DOWN 0
+#define LINK_UP 1
+
+static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring */
+static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring */
+static int rx_new; /* RX descriptor ring pointer */
+static int tx_new; /* TX descriptor ring pointer */
+static unsigned char tx_buffer[NUM_TX_DESC][TX_BUFF_SZ] __attribute__ ((aligned(32)));
+static unsigned char rx_buffer[NUM_RX_DESC][RX_BUFF_SZ] __attribute__ ((aligned(32)));
+
+
+static char rxRingSize;
+static char txRingSize;
+static unsigned int InstanceID = 0;
+static int Retry = 0;
+
+static int aspeednic_init(struct eth_device* dev, bd_t* bis);
+static int aspeednic_send(struct eth_device* dev, volatile void *packet, int length);
+static int aspeednic_recv(struct eth_device* dev);
+static void aspeednic_halt(struct eth_device* dev);
+static void set_mac_address (struct eth_device* dev, bd_t* bis);
+static void phy_write_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address, u16 PHY_Data);
+static u16 phy_read_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address);
+static void set_mac_control_register(struct eth_device* dev);
+
+#if defined(CONFIG_E500)
+#define phys_to_bus(a) (a)
+#else
+#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
+#endif
+
+static int INL(struct eth_device* dev, u_long addr)
+{
+ return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase));
+}
+
+static void OUTL(struct eth_device* dev, int command, u_long addr)
+{
+ *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command);
+}
+
+
+struct eth_device aspeednic_device[CONFIG_ASPEED_MAC_NUMBER];
+
+void NCSI_Struct_Initialize(void)
+{
+ unsigned long i;
+
+ for (i = 0; i < 6; i++) {
+ NCSI_Request.DA[i] = 0xFF;
+ NCSI_Respond.DA[i] = 0xFF;
+ NCSI_Respond.SA[i] = 0xFF;
+ }
+ NCSI_Request.EtherType = 0xF888;
+ NCSI_Request.MC_ID = 0;
+ NCSI_Request.Header_Revision = 0x01;
+ NCSI_Request.Reserved_1 = 0;
+ NCSI_Request.Reserved_2 = 0;
+ NCSI_Request.Reserved_3 = 0;
+ NCSI_Respond.EtherType = 0xF888;
+ NCSI_Respond.MC_ID = 0;
+ NCSI_Respond.Header_Revision = 0x01;
+ NCSI_Respond.Reserved_1 = 0;
+ NCSI_Respond.Reserved_2 = 0;
+ NCSI_Respond.Reserved_3 = 0;
+}
+
+int aspeednic_initialize(bd_t *bis)
+{
+ int card_number = 0;
+ unsigned int iobase, SCURegister;
+ struct eth_device* dev;
+
+#if defined(CONFIG_AST2300_FPGA_2) || defined(CONFIG_AST2300) || defined(CONFIG_AST3100) || defined(CONFIG_AST2400)
+//AST2300
+//MAC1 CLOCK/RESET/PHY_LINK/MDC_MDIO in SCU
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
+ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister | 0x800);
+ udelay(100);
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_CLOCK_CONTROL));
+ *(volatile u_long *)(SCU_BASE + SCU_CLOCK_CONTROL) = cpu_to_le32(SCURegister & ~(MAC1_CLOCK_ENABLE));
+ udelay(10000);
+//Add Clock Selection in AST2300 A1, Please check the datasheet for more detail
+//The current sample code uses 0: H-PLL/2 because all EVBs have RGMII interface
+// SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_CLOCK_SELECTION));
+// *(volatile u_long *)(SCU_BASE + SCU_CLOCK_SELECTION) = cpu_to_le32(SCURegister & ~(MAC_AHB_CLOCK_DIVIDER));
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
+ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister & ~(0x800));
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL3_REG));
+ *(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL3_REG) = cpu_to_le32(SCURegister | (MAC1_MDIO | MAC1_MDC));
+// SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MAC_CLOCK_DELAY));
+//Currently we use fix value in MAC timing on EVB
+// *(volatile u_long *)(SCU_BASE + SCU_MAC_CLOCK_DELAY) = CONFIG_MAC_INTERFACE_CLOCK_DELAY;
+#ifdef CONFIG_MAC1_PHY_LINK_INTERRUPT
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL1_REG));
+ *(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL1_REG) = cpu_to_le32(SCURegister | (MAC1_PHY_LINK));
+#endif
+
+//MAC2 CLOCK/RESET/PHY_LINK/MDC_MDIO
+#ifdef CONFIG_MAC2_ENABLE
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
+ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister | 0x1000);
+ udelay(10);
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_CLOCK_CONTROL));
+ *(volatile u_long *)(SCU_BASE + SCU_CLOCK_CONTROL) = cpu_to_le32(SCURegister & ~(MAC2_CLOCK_ENABLE));
+ udelay(10000);
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
+ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister & ~(0x1000));
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL5_REG));
+ *(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL5_REG) = cpu_to_le32(SCURegister | (MAC2_MDC_MDIO));
+#endif
+#ifdef CONFIG_MAC2_PHY_LINK_INTERRUPT
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL1_REG));
+ *(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL1_REG) = cpu_to_le32(SCURegister | (MAC2_PHY_LINK));
+#endif
+#else
+//AST1100/AST2050/AST2100
+//MAC1 RESET/PHY_LINK in SCU
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
+ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister & ~(0x800));
+#ifdef CONFIG_MAC1_PHY_LINK_INTERRUPT
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_PIN_MUX));
+ *(volatile u_long *)(SCU_BASE + SCU_PIN_MUX) = cpu_to_le32(SCURegister | (MAC1_PHY_LINK));
+#endif
+
+//MAC2
+#ifdef CONFIG_MAC2_ENABLE
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
+ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister & ~(0x1000));
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_PIN_MUX));
+ *(volatile u_long *)(SCU_BASE + SCU_PIN_MUX) = cpu_to_le32(SCURegister | (MAC2_MDC_MDIO));
+#endif
+#ifdef CONFIG_MAC2_MII_ENABLE
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_PIN_MUX));
+ *(volatile u_long *)(SCU_BASE + SCU_PIN_MUX) = cpu_to_le32(SCURegister | (MAC2_MII));
+#endif
+#ifdef CONFIG_MAC2_PHY_LINK_INTERRUPT
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_PIN_MUX));
+ *(volatile u_long *)(SCU_BASE + SCU_PIN_MUX) = cpu_to_le32(SCURegister | (MAC2_PHY_LINK));
+#endif
+#endif
+
+ iobase = aspeednic_iobase[card_number];
+
+ dev = &aspeednic_device[card_number];
+
+
+ sprintf(dev->name, "aspeednic#%d", card_number);
+
+ dev->iobase = iobase;
+
+ if (CONFIG_MAC1_PHY_SETTING >= 1) {
+//NCSI Struct Initialize
+ NCSI_Struct_Initialize();
+ }
+//Set Scratch register (0x1E6E2040 D[15:14])(0x1E6E2041 D[7:6]) to inform kernel MAC1 driver
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_SCRATCH_REGISTER));
+ *(volatile u_long *)(SCU_BASE + SCU_SCRATCH_REGISTER) = cpu_to_le32((SCURegister & ~(0xc000)) | (CONFIG_MAC1_PHY_SETTING << 14));
+//Set Scratch register (0x1E6E2040 D[13:12])(0x1E6E2041 D[5:4]) to inform kernel MAC2 driver
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_SCRATCH_REGISTER));
+ *(volatile u_long *)(SCU_BASE + SCU_SCRATCH_REGISTER) = cpu_to_le32((SCURegister & ~(0x3000)) | (CONFIG_MAC2_PHY_SETTING << 12));
+
+
+ dev->init = aspeednic_init;
+ dev->halt = aspeednic_halt;
+ dev->send = aspeednic_send;
+ dev->recv = aspeednic_recv;
+
+ /* Ensure we're not sleeping. */
+ if (CONFIG_MAC1_PHY_SETTING >= 1) {
+ udelay(2000000); //2.0 sec
+ }
+ else {
+ udelay(10 * 1000);
+ }
+
+
+ dev->init(dev, bis);
+
+ eth_register(dev);
+
+
+ return card_number;
+}
+
+void Calculate_Checksum(unsigned char *buffer_base, int Length)
+{
+ unsigned int i, CheckSum = 0;
+ unsigned int Data, Data1;
+
+ for (i = 0; i < ((Length - 14) / 2); i++) {
+ Data = buffer_base[i * 2];
+ Data1 = buffer_base[i * 2 + 1];
+ CheckSum += ((Data << 8) + Data1);
+ }
+ Payload_Checksum = (~(CheckSum) + 1); //2's complement
+//Inverse for insert into buffer
+ Data = (Payload_Checksum & 0xFF000000) >> 24;
+ Data1 = (Payload_Checksum & 0x000000FF) << 24;
+ Payload_Checksum = (Payload_Checksum & 0x00FFFF00) + Data + Data1;
+ Data = (Payload_Checksum & 0x00FF0000) >> 8;
+ Data1 = (Payload_Checksum & 0x0000FF00) << 8;
+ Payload_Checksum = (Payload_Checksum & 0xFF0000FF) + Data + Data1;
+}
+
+void copy_data (int Length)
+{
+ memcpy ((unsigned char *)(tx_ring[tx_new].buf + 30), &Payload_Data, Length);
+ Calculate_Checksum((unsigned char *)(tx_ring[tx_new].buf + 14), 30 + Length);
+ memcpy ((unsigned char *)(tx_ring[tx_new].buf + 30 + Length), &Payload_Checksum, 4);
+}
+
+void NCSI_Rx (void)
+{
+ unsigned long status, length, i = 0;
+
+ do {
+ status = (s32)le32_to_cpu(rx_ring[rx_new].status);
+ i++;
+ } while (!(((status & RXPKT_STATUS) != 0) || (i >= NCSI_LOOP)));
+
+ if (i < NCSI_LOOP) {
+ if (status & LRS) {
+ length = (le32_to_cpu(rx_ring[rx_new].status) & 0x3FFF);
+ memcpy (&NCSI_Respond, (unsigned char *)rx_ring[rx_new].buf, length);
+ }
+ rx_ring[rx_new].status &= cpu_to_le32(0x7FFFFFFF);
+ rx_new = (rx_new + 1) % rxRingSize;
+ }
+}
+
+void DeSelect_Package (struct eth_device* dev, int Package_ID)
+{
+ unsigned long Combined_Channel_ID;
+
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = DESELECT_PACKAGE;
+ Combined_Channel_ID = (Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F, 0x1F means all channel
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = 0;
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (DESELECT_PACKAGE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+int Select_Package (struct eth_device* dev, int Package_ID)
+{
+ unsigned long Combined_Channel_ID, Found = 0;
+
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = SELECT_PACKAGE;
+ Combined_Channel_ID = (Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = (4 << 8);
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ NCSI_Request.Payload_Length = 4;
+ memset ((void *)Payload_Data, 0, 4);
+ Payload_Data[3] = 1; //Arbitration Disable
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (SELECT_PACKAGE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ Found = 0;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ Found = 1;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+
+ return Found;
+}
+
+void DeSelect_Active_Package (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = DESELECT_PACKAGE;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F, 0x1F means all channel
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = 0;
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (DESELECT_PACKAGE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+int Select_Active_Package (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID, Found = 0;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = SELECT_PACKAGE;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = (4 << 8);
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ NCSI_Request.Payload_Length = 4;
+ memset ((void *)Payload_Data, 0, 4);
+ Payload_Data[3] = 1; //Arbitration Disable
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (SELECT_PACKAGE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ Found = 0;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ Found = 1;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+
+ return Found;
+}
+
+int Clear_Initial_State (struct eth_device* dev, int Channel_ID)
+{
+ unsigned long Combined_Channel_ID, Found = 0;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = CLEAR_INITIAL_STATE;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + Channel_ID; //Internal Channel ID = 0
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = 0;
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (CLEAR_INITIAL_STATE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ Found = 0;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ Found = 1;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+
+ return Found;
+}
+
+void Get_Version_ID (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = GET_VERSION_ID;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = 0;
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (GET_VERSION_ID | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+void Get_Capabilities (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = GET_CAPABILITIES;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = 0;
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (GET_CAPABILITIES | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ NCSI_Cap.Capabilities_Flags = NCSI_Respond.Payload_Data[0];
+ NCSI_Cap.Broadcast_Packet_Filter_Capabilities = NCSI_Respond.Payload_Data[1];
+ NCSI_Cap.Multicast_Packet_Filter_Capabilities = NCSI_Respond.Payload_Data[2];
+ NCSI_Cap.Buffering_Capabilities = NCSI_Respond.Payload_Data[3];
+ NCSI_Cap.AEN_Control_Support = NCSI_Respond.Payload_Data[4];
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+void Enable_Set_MAC_Address (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID, i;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = SET_MAC_ADDRESS;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = (8 << 8);
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ NCSI_Request.Payload_Length = 8;
+ for (i = 0; i < 6; i++) {
+ Payload_Data[i] = NCSI_Request.SA[i];
+ }
+ Payload_Data[6] = 1; //MAC Address Num = 1 --> address filter 1, fixed in sample code
+ Payload_Data[7] = UNICAST + 0 + ENABLE_MAC_ADDRESS_FILTER; //AT + Reserved + E
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (SET_MAC_ADDRESS | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+void Enable_Broadcast_Filter (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = ENABLE_BROADCAST_FILTERING;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = (4 << 8);
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ NCSI_Request.Payload_Length = 4;
+ memset ((void *)Payload_Data, 0, 4);
+ Payload_Data[3] = 0xF; //ARP, DHCP, NetBIOS
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (ENABLE_BROADCAST_FILTERING | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+void Enable_AEN (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = AEN_ENABLE;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = (8 << 8);
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ NCSI_Request.Payload_Length = 8;
+ memset ((void *)Payload_Data, 0, 8);
+ Payload_Data[3] = 0x00; //MC ID
+ Payload_Data[7] = 0x01; //Link Status only
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (AEN_ENABLE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+void Enable_Network_TX (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = ENABLE_CHANNEL_NETWORK_TX;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = 0;
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (ENABLE_CHANNEL_NETWORK_TX | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+void Disable_Network_TX (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = DISABLE_CHANNEL_NETWORK_TX;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = 0;
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (DISABLE_CHANNEL_NETWORK_TX | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+void Enable_Channel (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = ENABLE_CHANNEL;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = 0;
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (ENABLE_CHANNEL | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+void Disable_Channel (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = DISABLE_CHANNEL;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = (4 << 8);
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ NCSI_Request.Payload_Length = 4;
+ memset ((void *)Payload_Data, 0, 4);
+ Payload_Data[3] = 0x1; //ALD
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (DISABLE_CHANNEL | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+int Get_Link_Status (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = GET_LINK_STATUS;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = 0;
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (GET_LINK_STATUS | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+ if (NCSI_Respond.Payload_Data[3] & 0x40) {
+ return (NCSI_Respond.Payload_Data[3] & 0x01); //Link Up or Not
+ }
+ else {
+ return 0; //Auto Negotiate did not finish
+ }
+}
+
+void Set_Link (struct eth_device* dev)
+{
+ unsigned long Combined_Channel_ID;
+//TX
+ do {
+ InstanceID++;
+ NCSI_Request.IID = InstanceID;
+ NCSI_Request.Command = SET_LINK;
+ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
+ NCSI_Request.Channel_ID = Combined_Channel_ID;
+ NCSI_Request.Payload_Length = (8 << 8);
+ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
+ NCSI_Request.Payload_Length = 8;
+ memset ((void *)Payload_Data, 0, 8);
+ Payload_Data[2] = 0x02; //full duplex
+ Payload_Data[3] = 0x04; //100M, auto-disable
+ copy_data (NCSI_Request.Payload_Length);
+ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
+//RX
+ NCSI_Rx();
+ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (SET_LINK | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
+ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
+ Retry++;
+ InstanceID--;
+ }
+ else {
+ Retry = 0;
+ }
+ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
+ Retry = 0;
+}
+
+static int aspeednic_init(struct eth_device* dev, bd_t* bis)
+{
+ unsigned long i, Package_Found = 0, Channel_Found = 0, Re_Send = 0, Link_Status;
+
+ RESET_DE4X5(dev);
+ set_mac_address (dev, bis);
+ set_mac_control_register (dev);
+
+ for (i = 0; i < NUM_RX_DESC; i++) {
+ rx_ring[i].status = cpu_to_le32(RXPKT_RDY + RX_BUFF_SZ);
+ rx_ring[i].buf = (u32)(&rx_buffer[i]);
+ rx_ring[i].reserved = 0;
+ }
+
+ for (i=0; i < NUM_TX_DESC; i++) {
+ tx_ring[i].status = 0;
+ tx_ring[i].des1 = 0;
+ tx_ring[i].buf = (u32)(&tx_buffer[i]);
+ tx_ring[i].reserved = 0;
+ }
+
+ rxRingSize = NUM_RX_DESC;
+ txRingSize = NUM_TX_DESC;
+
+ rx_ring[rxRingSize - 1].status |= cpu_to_le32(EDORR);
+ tx_ring[txRingSize - 1].status |= cpu_to_le32(EDOTR);
+
+ OUTL(dev, ((u32) &tx_ring), TXR_BADR_REG);
+ OUTL(dev, ((u32) &rx_ring), RXR_BADR_REG);
+
+ START_MAC(dev);
+
+ tx_new = 0;
+ rx_new = 0;
+
+ if (CONFIG_MAC1_PHY_SETTING >= 1) {
+//NCSI Start
+//DeSelect Package/ Select Package
+ for (i = 0; i < 4; i++) {
+ DeSelect_Package (dev, i);
+ Package_Found = Select_Package (dev, i);
+ if (Package_Found == 1) {
+//AST2100/AST2050/AST1100 supports 1 package only in current firmware version
+ NCSI_Cap.Package_ID = i;
+// Package_Found = 0;
+ break;
+ }
+ }
+ if (Package_Found != 0) {
+//Initiali State
+ for (i = 0; i < 2; i++) { //Suppose 2 channels in current version, You could modify it to 0x1F to support 31 channels
+ Channel_Found = Clear_Initial_State(dev, i);
+ if (Channel_Found == 1) {
+ NCSI_Cap.Channel_ID = i;
+ printf ("Found NCSI Network Controller at (%d, %d)\n", NCSI_Cap.Package_ID, NCSI_Cap.Channel_ID);
+//Get Version and Capabilities
+ Get_Version_ID(dev);
+ Get_Capabilities(dev);
+ Select_Active_Package(dev);
+//Configuration
+ Enable_Set_MAC_Address(dev);
+ Enable_Broadcast_Filter(dev);
+//Enable TX
+ Enable_Network_TX(dev);
+//Enable Channel
+ Enable_Channel(dev);
+//Get Link Status
+ Re_Get_Link_Status:
+ Link_Status = Get_Link_Status(dev);
+ if (Link_Status == LINK_UP) {
+ printf ("Using NCSI Network Controller (%d, %d)\n", NCSI_Cap.Package_ID, NCSI_Cap.Channel_ID);
+ break;
+ }
+ else if ((Link_Status == LINK_DOWN) && (Re_Send < 2)) {
+ Re_Send++;
+ goto Re_Get_Link_Status;
+ }
+//Disable TX
+ Disable_Network_TX(dev);
+//Disable Channel
+// Disable_Channel(dev);
+ Re_Send = 0;
+ Channel_Found = 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+static int aspeednic_send(struct eth_device* dev, volatile void *packet, int length)
+{
+ int status = -1, oldlength = 0, fail = 0;
+ int i;
+
+ if (length <= 0) {
+ printf("%s: bad packet size: %d\n", dev->name, length);
+ goto Done;
+ }
+
+
+ for(i = 0; (tx_ring[tx_new].status & cpu_to_le32(TXDMA_OWN)) == 0x80000000; i++) {
+ if (i >= TOUT_LOOP) {
+ printf("%s: tx error buffer not ready\n", dev->name);
+ fail = 1;
+ goto Done;
+ }
+ }
+
+
+ if (length < 60) {
+ oldlength = length;
+// memset ((void *)cpu_to_le32((u32) (packet + length)), 0, 60 - length);
+ length = 60;
+ }
+ tx_ring[tx_new].buf = cpu_to_le32(((u32) packet));
+ tx_ring[tx_new].status &= (~(0x3FFF));
+ tx_ring[tx_new].status |= cpu_to_le32(LTS | FTS | length);
+ tx_ring[tx_new].status |= cpu_to_le32(TXDMA_OWN);
+
+ OUTL(dev, POLL_DEMAND, TXPD_REG);
+
+ for (i = 0; (tx_ring[tx_new].status & cpu_to_le32(TXDMA_OWN)) == 0x80000000; i++)
+ {
+ if (i >= TOUT_LOOP)
+ {
+ printf(".%s: tx buffer not ready\n", dev->name);
+ fail = 1;
+ goto Done;
+ }
+ }
+
+ if (fail != 1) {
+ status = oldlength;
+ }
+
+ Done:
+ tx_new = (tx_new+1) % NUM_TX_DESC;
+
+ return status;
+}
+
+static int aspeednic_recv(struct eth_device* dev)
+{
+ s32 status;
+ int length = 0;
+
+ for ( ; ; )
+ {
+ status = (s32)le32_to_cpu(rx_ring[rx_new].status);
+
+ if ((status & RXPKT_STATUS) == 0) {
+ break;
+ }
+
+ if (status & LRS) {
+ /* Valid frame status.
+ */
+ if (status & (RX_ERR | CRC_ERR | FTL | RUNT | RX_ODD_NB)) {
+
+ /* There was an error.
+ */
+ printf("RX error status = 0x%08X\n", status);
+ } else {
+ /* A valid frame received.
+ */
+ length = (le32_to_cpu(rx_ring[rx_new].status) & 0x3FFF);
+ debug("%s(): RX buffer %d, %x received\n",
+ __func__, rx_new, length);
+
+
+ /* Pass the packet up to the protocol
+ * layers.
+ */
+ NetReceive(rx_buffer[rx_new], length - 4);
+ }
+
+ /* Change buffer ownership for this frame, back
+ * to the adapter.
+ */
+ rx_ring[rx_new].status &= cpu_to_le32(0x7FFFFFFF);
+// rx_ring[rx_new].status = cpu_to_le32(RXPKT_RDY);
+ }
+
+ /* Update entry information.
+ */
+ rx_new = (rx_new + 1) % rxRingSize;
+ }
+
+ return length;
+}
+
+static void aspeednic_halt(struct eth_device* dev)
+{
+ STOP_MAC(dev);
+}
+
+static void set_mac_address (struct eth_device* dev, bd_t* bis)
+{
+ unsigned char mac_address[6]; // 6 bytes mac address
+ unsigned char ethaddress[20]; // string for setenv function
+ char *s;
+ int i, env; // env variable 0: eeprom, 1: environment parameters
+
+ s = getenv ("eeprom");
+ env = (s && (*s == 'y')) ? 0 : 1;
+
+ if (env == 0) {
+ env = 1;
+ eeprom_init ();
+ eeprom_read (0xA0, 0, mac_address, 6);
+
+ for (i = 0; i < 6; i++) {
+ if (mac_address[i] != 0xFF) {
+ env = 0; //Suppose not all 0xFF is valid
+ }
+ }
+ }
+
+ if (env == 0) { // EEPROM
+ sprintf (ethaddress, "%02X:%02X:%02X:%02X:%02X:%02X", mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]);
+ setenv ("ethaddr", ethaddress);
+ OUTL(dev, ((mac_address[2] << 24) | (mac_address[3] << 16) | (mac_address[4] << 8) | mac_address[5]), MAC_LADR_REG);
+ OUTL(dev, ((mac_address[0] << 8) | mac_address[1]), MAC_MADR_REG);
+ if (CONFIG_MAC1_PHY_SETTING >= 1) {
+ for (i = 0; i < 6; i++) {
+ NCSI_Request.SA[i] = mac_address[i];
+ }
+ }
+ }
+ else { // Environment Parameters
+ OUTL(dev, ((bis->bi_enetaddr[2] << 24) | (bis->bi_enetaddr[3] << 16) | (bis->bi_enetaddr[4] << 8) | bis->bi_enetaddr[5]), MAC_LADR_REG);
+ OUTL(dev, ((bis->bi_enetaddr[0] << 8) | bis->bi_enetaddr[1]), MAC_MADR_REG);
+ if (CONFIG_MAC1_PHY_SETTING >= 1) {
+ for (i = 0; i < 6; i++) {
+ NCSI_Request.SA[i] = bis->bi_enetaddr[i];
+ }
+ }
+ }
+
+}
+
+
+static u16 phy_read_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address)
+{
+ u32 Data, Status = 0, Loop_Count = 0, PHY_Ready = 1;
+ u16 Return_Data;
+
+#ifdef REALTEK_PHY_SUPPORT
+ PHY_Address = 0x01;
+#endif
+//20us * 100 = 2ms > (1 / 2.5Mhz) * 0x34
+ OUTL(dev, (PHY_Register << 21) + (PHY_Address << 16) + MIIRD + MDC_CYCTHR, PHYCR_REG);
+ do {
+ udelay(20);
+ Status = (INL (dev, PHYCR_REG) & MIIRD);
+ Loop_Count++;
+ if (Loop_Count >= 100) {
+ PHY_Ready = 0;
+ break;
+ }
+ } while (Status == MIIRD);
+
+ if (PHY_Ready == 0) {
+ printf ("PHY NOT REDAY ");
+ return 0;
+ }
+ Data = INL (dev, PHYDATA_REG);
+ Return_Data = (Data >> 16);
+
+ return Return_Data;
+}
+
+
+static void phy_write_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address, u16 PHY_Data)
+{
+ u32 Status = 0, Loop_Count = 0, PHY_Ready = 1;
+
+#ifdef REALTEK_PHY_SUPPORT
+ PHY_Address = 0x01;
+#endif
+//20us * 100 = 2ms > (1 / 2.5Mhz) * 0x34
+ OUTL(dev, PHY_Data, PHYDATA_REG);
+ OUTL(dev, (PHY_Register << 21) + (PHY_Address << 16) + MIIWR + MDC_CYCTHR, PHYCR_REG);
+ do {
+ udelay(20);
+ Status = (INL (dev, PHYCR_REG) & MIIWR);
+ Loop_Count++;
+ if (Loop_Count >= 100) {
+ PHY_Ready = 0;
+ break;
+ }
+ } while (Status == MIIWR);
+ if (PHY_Ready == 0) {
+ printf ("PHY NOT REDAY ");
+ }
+}
+
+static void set_mac_control_register (struct eth_device* dev)
+{
+ unsigned long MAC_CR_Register = 0;
+ unsigned long Loop_Count = 0, PHY_Ready = 1, Chip_ID;
+ u16 PHY_Status, PHY_Speed, PHY_Duplex, Resolved_Status = 0, Advertise, Link_Partner;
+
+ if (CONFIG_MAC1_PHY_SETTING >= 1) {
+ MAC_CR_Register = SPEED_100M_MODE_bit | RX_BROADPKT_bit | FULLDUP_bit | RXMAC_EN_bit | RXDMA_EN_bit | TXMAC_EN_bit | TXDMA_EN_bit | CRC_APD_bit;
+ }
+ else {
+ MAC_CR_Register = SPEED_100M_MODE_bit | FULLDUP_bit | RXMAC_EN_bit | RXDMA_EN_bit | TXMAC_EN_bit | TXDMA_EN_bit | CRC_APD_bit;
+ }
+
+ if (CONFIG_MAC1_PHY_SETTING != 2) {
+ Chip_ID = ((phy_read_register (dev, 0x02, 0)) << 16);
+ Chip_ID |= (phy_read_register (dev, 0x03, 0) & 0xffff);
+ if (((Chip_ID & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
+ ((Chip_ID & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
+ Advertise = phy_read_register (dev, 0x04, 0);
+ Link_Partner = phy_read_register (dev, 0x05, 0);
+ Advertise = (Advertise & PHY_SPEED_DUPLEX_MASK);
+ Link_Partner = (Link_Partner & PHY_SPEED_DUPLEX_MASK);
+ if ((Advertise & Link_Partner) & PHY_100M_DUPLEX) {
+ MAC_CR_Register |= SPEED_100M_MODE_bit;
+ MAC_CR_Register |= FULLDUP_bit;
+ }
+ else if ((Advertise & Link_Partner) & PHY_100M_HALF) {
+ MAC_CR_Register |= SPEED_100M_MODE_bit;
+ MAC_CR_Register &= ~FULLDUP_bit;
+ }
+ else if ((Advertise & Link_Partner) & PHY_10M_DUPLEX) {
+ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
+ MAC_CR_Register |= FULLDUP_bit;
+ }
+ else if ((Advertise & Link_Partner) & PHY_10M_HALF) {
+ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
+ MAC_CR_Register &= ~FULLDUP_bit;
+ }
+ }
+ else if (((Chip_ID & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
+ ((Chip_ID & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
+//Max waiting time = (20 + 2)ms * 250(PHY_LOOP) = 5.5s
+ do {
+ udelay (20000);
+ Resolved_Status = (phy_read_register (dev, 0x11, 0) & RESOLVED_BIT);
+ Loop_Count++;
+ if (Loop_Count >= PHY_LOOP) {
+ PHY_Ready = 0;
+ printf ("PHY NOT READY ");
+ break;
+ }
+ } while (Resolved_Status != RESOLVED_BIT);
+
+ if (PHY_Ready == 1) {
+ PHY_Status = phy_read_register (dev, 0x11, 0);
+ PHY_Speed = (PHY_Status & PHY_SPEED_MASK) >> 14;
+ PHY_Duplex = (PHY_Status & PHY_DUPLEX_MASK) >> 13;
+
+ if (PHY_Speed == SPEED_1000M) {
+ MAC_CR_Register |= GMAC_MODE_bit;
+ }
+ else {
+ MAC_CR_Register &= ~GMAC_MODE_bit;
+ if (PHY_Speed == SPEED_10M) {
+ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
+ }
+ }
+ if (PHY_Duplex == DUPLEX_HALF) {
+ MAC_CR_Register &= ~FULLDUP_bit;
+ }
+ }
+//LED Control
+// if (Chip_ID == 0x1C) {
+// PHY_Status = phy_read_register (dev, 0x18, 0);
+// phy_write_register (dev, 0x18, 0, (PHY_Status | 0x09));
+// }
+//LED Control D[0], D[6]
+// if (Chip_ID == 0x141) {
+// PHY_Status = phy_read_register (dev, 0x18, 0);
+// phy_write_register (dev, 0x18, 0, ((PHY_Status & ~(0x41)) | 0x01));
+// }
+ }
+ else if (Chip_ID == PHYID_BCM54612E ) {
+ phy_write_register ( dev, 0x1C, 1, 0x8C00 ); // Disable GTXCLK Clock Delay Enable
+ phy_write_register ( dev, 0x18, 1, 0xF0E7 ); // Disable RGMII RXD to RXC Skew
+
+ Advertise = phy_read_register (dev, 0x04, 1);
+ Link_Partner = phy_read_register (dev, 0x05, 1);
+ Advertise = (Advertise & PHY_SPEED_DUPLEX_MASK);
+ Link_Partner = (Link_Partner & PHY_SPEED_DUPLEX_MASK);
+ if ((Advertise & Link_Partner) & PHY_100M_DUPLEX) {
+ MAC_CR_Register |= SPEED_100M_MODE_bit;
+ MAC_CR_Register |= FULLDUP_bit;
+ }
+ else if ((Advertise & Link_Partner) & PHY_100M_HALF) {
+ MAC_CR_Register |= SPEED_100M_MODE_bit;
+ MAC_CR_Register &= ~FULLDUP_bit;
+ }
+ else if ((Advertise & Link_Partner) & PHY_10M_DUPLEX) {
+ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
+ MAC_CR_Register |= FULLDUP_bit;
+ }
+ else if ((Advertise & Link_Partner) & PHY_10M_HALF) {
+ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
+ MAC_CR_Register &= ~FULLDUP_bit;
+ }
+ }else {
+ printf("Unknow Chip_ID %x\n",Chip_ID);
+ }
+ }
+ OUTL(dev, MAC_CR_Register, MACCR_REG);
+}
+
+#endif /* CFG_CMD_NET && CONFIG_NET_MULTI && CONFIG_ASPEEDMAC */