diff options
Diffstat (limited to 'drivers/net/inca-ip_sw.c')
-rw-r--r-- | drivers/net/inca-ip_sw.c | 793 |
1 files changed, 0 insertions, 793 deletions
diff --git a/drivers/net/inca-ip_sw.c b/drivers/net/inca-ip_sw.c deleted file mode 100644 index cdfbfa67d8..0000000000 --- a/drivers/net/inca-ip_sw.c +++ /dev/null @@ -1,793 +0,0 @@ -/* - * INCA-IP internal switch ethernet driver. - * - * (C) Copyright 2003-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - - -#include <common.h> - -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/inca-ip.h> -#include <asm/addrspace.h> - - -#define NUM_RX_DESC PKTBUFSRX -#define NUM_TX_DESC 3 -#define TOUT_LOOP 1000000 - - -#define DELAY udelay(10000) - /* Sometimes the store word instruction hangs while writing to one - * of the Switch registers. Moving the instruction into a separate - * function somehow makes the problem go away. - */ -static void SWORD(volatile u32 * reg, u32 value) -{ - *reg = value; -} - -#define DMA_WRITE_REG(reg, value) *((volatile u32 *)reg) = (u32)value; -#define DMA_READ_REG(reg, value) value = (u32)*((volatile u32*)reg) -#define SW_WRITE_REG(reg, value) \ - SWORD(reg, value);\ - DELAY;\ - SWORD(reg, value); - -#define SW_READ_REG(reg, value) \ - value = (u32)*((volatile u32*)reg);\ - DELAY;\ - value = (u32)*((volatile u32*)reg); - -#define INCA_DMA_TX_POLLING_TIME 0x07 -#define INCA_DMA_RX_POLLING_TIME 0x07 - -#define INCA_DMA_TX_HOLD 0x80000000 -#define INCA_DMA_TX_EOP 0x40000000 -#define INCA_DMA_TX_SOP 0x20000000 -#define INCA_DMA_TX_ICPT 0x10000000 -#define INCA_DMA_TX_IEOP 0x08000000 - -#define INCA_DMA_RX_C 0x80000000 -#define INCA_DMA_RX_SOP 0x40000000 -#define INCA_DMA_RX_EOP 0x20000000 - -#define INCA_SWITCH_PHY_SPEED_10H 0x1 -#define INCA_SWITCH_PHY_SPEED_10F 0x5 -#define INCA_SWITCH_PHY_SPEED_100H 0x2 -#define INCA_SWITCH_PHY_SPEED_100F 0x6 - -/************************ Auto MDIX settings ************************/ -#define INCA_IP_AUTO_MDIX_LAN_PORTS_DIR INCA_IP_Ports_P1_DIR -#define INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL INCA_IP_Ports_P1_ALTSEL -#define INCA_IP_AUTO_MDIX_LAN_PORTS_OUT INCA_IP_Ports_P1_OUT -#define INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX 16 - -#define WAIT_SIGNAL_RETRIES 100 -#define WAIT_LINK_RETRIES 100 -#define LINK_RETRY_DELAY 2000 /* ms */ -/********************************************************************/ - -typedef struct -{ - union { - struct { - volatile u32 HOLD :1; - volatile u32 ICpt :1; - volatile u32 IEop :1; - volatile u32 offset :3; - volatile u32 reserved0 :4; - volatile u32 NFB :22; - }field; - - volatile u32 word; - }params; - - volatile u32 nextRxDescPtr; - - volatile u32 RxDataPtr; - - union { - struct { - volatile u32 C :1; - volatile u32 Sop :1; - volatile u32 Eop :1; - volatile u32 reserved3 :12; - volatile u32 NBT :17; - }field; - - volatile u32 word; - }status; - -} inca_rx_descriptor_t; - - -typedef struct -{ - union { - struct { - volatile u32 HOLD :1; - volatile u32 Eop :1; - volatile u32 Sop :1; - volatile u32 ICpt :1; - volatile u32 IEop :1; - volatile u32 reserved0 :5; - volatile u32 NBA :22; - }field; - - volatile u32 word; - }params; - - volatile u32 nextTxDescPtr; - - volatile u32 TxDataPtr; - - volatile u32 C :1; - volatile u32 reserved3 :31; - -} inca_tx_descriptor_t; - - -static inca_rx_descriptor_t rx_ring[NUM_RX_DESC] __attribute__ ((aligned(16))); -static inca_tx_descriptor_t tx_ring[NUM_TX_DESC] __attribute__ ((aligned(16))); - -static int tx_new, rx_new, tx_hold, rx_hold; -static int tx_old_hold = -1; -static int initialized = 0; - - -static int inca_switch_init(struct eth_device *dev, bd_t * bis); -static int inca_switch_send(struct eth_device *dev, void *packet, int length); -static int inca_switch_recv(struct eth_device *dev); -static void inca_switch_halt(struct eth_device *dev); -static void inca_init_switch_chip(void); -static void inca_dma_init(void); -static int inca_amdix(void); - - -int inca_switch_initialize(bd_t * bis) -{ - struct eth_device *dev; - -#if 0 - printf("Entered inca_switch_initialize()\n"); -#endif - - if (!(dev = (struct eth_device *) malloc (sizeof *dev))) { - printf("Failed to allocate memory\n"); - return 0; - } - memset(dev, 0, sizeof(*dev)); - - inca_dma_init(); - - inca_init_switch_chip(); - -#if defined(CONFIG_INCA_IP_SWITCH_AMDIX) - inca_amdix(); -#endif - - sprintf(dev->name, "INCA-IP Switch"); - dev->init = inca_switch_init; - dev->halt = inca_switch_halt; - dev->send = inca_switch_send; - dev->recv = inca_switch_recv; - - eth_register(dev); - -#if 0 - printf("Leaving inca_switch_initialize()\n"); -#endif - - return 0; -} - - -static int inca_switch_init(struct eth_device *dev, bd_t * bis) -{ - int i; - u32 v, regValue; - u16 wTmp; - -#if 0 - printf("Entering inca_switch_init()\n"); -#endif - - /* Set MAC address. - */ - wTmp = (u16)dev->enetaddr[0]; - regValue = (wTmp << 8) | dev->enetaddr[1]; - - SW_WRITE_REG(INCA_IP_Switch_PMAC_SA1, regValue); - - wTmp = (u16)dev->enetaddr[2]; - regValue = (wTmp << 8) | dev->enetaddr[3]; - regValue = regValue << 16; - wTmp = (u16)dev->enetaddr[4]; - regValue |= (wTmp<<8) | dev->enetaddr[5]; - - SW_WRITE_REG(INCA_IP_Switch_PMAC_SA2, regValue); - - /* Initialize the descriptor rings. - */ - for (i = 0; i < NUM_RX_DESC; i++) { - inca_rx_descriptor_t * rx_desc = (inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[i]); - memset(rx_desc, 0, sizeof(rx_ring[i])); - - /* Set maximum size of receive buffer. - */ - rx_desc->params.field.NFB = PKTSIZE_ALIGN; - - /* Set the offset of the receive buffer. Zero means - * that the offset mechanism is not used. - */ - rx_desc->params.field.offset = 0; - - /* Check if it is the last descriptor. - */ - if (i == (NUM_RX_DESC - 1)) { - /* Let the last descriptor point to the first - * one. - */ - rx_desc->nextRxDescPtr = (u32)CKSEG1ADDR(rx_ring); - } else { - /* Set the address of the next descriptor. - */ - rx_desc->nextRxDescPtr = (u32)CKSEG1ADDR(&rx_ring[i+1]); - } - - rx_desc->RxDataPtr = (u32)CKSEG1ADDR(NetRxPackets[i]); - } - -#if 0 - printf("rx_ring = 0x%08X 0x%08X\n", (u32)rx_ring, (u32)&rx_ring[0]); - printf("tx_ring = 0x%08X 0x%08X\n", (u32)tx_ring, (u32)&tx_ring[0]); -#endif - - for (i = 0; i < NUM_TX_DESC; i++) { - inca_tx_descriptor_t * tx_desc = (inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[i]); - - memset(tx_desc, 0, sizeof(tx_ring[i])); - - tx_desc->params.word = 0; - tx_desc->params.field.HOLD = 1; - tx_desc->C = 1; - - /* Check if it is the last descriptor. - */ - if (i == (NUM_TX_DESC - 1)) { - /* Let the last descriptor point to the - * first one. - */ - tx_desc->nextTxDescPtr = (u32)CKSEG1ADDR(tx_ring); - } else { - /* Set the address of the next descriptor. - */ - tx_desc->nextTxDescPtr = (u32)CKSEG1ADDR(&tx_ring[i+1]); - } - } - - /* Initialize RxDMA. - */ - DMA_READ_REG(INCA_IP_DMA_DMA_RXISR, v); - debug("RX status = 0x%08X\n", v); - - /* Writing to the FRDA of CHANNEL. - */ - DMA_WRITE_REG(INCA_IP_DMA_DMA_RXFRDA0, (u32)rx_ring); - - /* Writing to the COMMAND REG. - */ - DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_INIT); - - /* Initialize TxDMA. - */ - DMA_READ_REG(INCA_IP_DMA_DMA_TXISR, v); - debug("TX status = 0x%08X\n", v); - - /* Writing to the FRDA of CHANNEL. - */ - DMA_WRITE_REG(INCA_IP_DMA_DMA_TXFRDA0, (u32)tx_ring); - - tx_new = rx_new = 0; - - tx_hold = NUM_TX_DESC - 1; - rx_hold = NUM_RX_DESC - 1; - -#if 0 - rx_ring[rx_hold].params.field.HOLD = 1; -#endif - /* enable spanning tree forwarding, enable the CPU port */ - /* ST_PT: - * CPS (CPU port status) 0x3 (forwarding) - * LPS (LAN port status) 0x3 (forwarding) - * PPS (PC port status) 0x3 (forwarding) - */ - SW_WRITE_REG(INCA_IP_Switch_ST_PT,0x3f); - -#if 0 - printf("Leaving inca_switch_init()\n"); -#endif - - return 0; -} - - -static int inca_switch_send(struct eth_device *dev, void *packet, int length) -{ - int i; - int res = -1; - u32 command; - u32 regValue; - inca_tx_descriptor_t * tx_desc = (inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_new]); - -#if 0 - printf("Entered inca_switch_send()\n"); -#endif - - if (length <= 0) { - printf ("%s: bad packet size: %d\n", dev->name, length); - goto Done; - } - - for(i = 0; tx_desc->C == 0; i++) { - if (i >= TOUT_LOOP) { - printf("%s: tx error buffer not ready\n", dev->name); - goto Done; - } - } - - if (tx_old_hold >= 0) { - ((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_old_hold]))->params.field.HOLD = 1; - } - tx_old_hold = tx_hold; - - tx_desc->params.word = - (INCA_DMA_TX_SOP | INCA_DMA_TX_EOP | INCA_DMA_TX_HOLD); - - tx_desc->C = 0; - tx_desc->TxDataPtr = (u32)packet; - tx_desc->params.field.NBA = length; - - ((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_hold]))->params.field.HOLD = 0; - - tx_hold = tx_new; - tx_new = (tx_new + 1) % NUM_TX_DESC; - - - if (! initialized) { - command = INCA_IP_DMA_DMA_TXCCR0_INIT; - initialized = 1; - } else { - command = INCA_IP_DMA_DMA_TXCCR0_HR; - } - - DMA_READ_REG(INCA_IP_DMA_DMA_TXCCR0, regValue); - regValue |= command; -#if 0 - printf("regValue = 0x%x\n", regValue); -#endif - DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, regValue); - -#if 1 - for(i = 0; ((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_hold]))->C == 0; i++) { - if (i >= TOUT_LOOP) { - printf("%s: tx buffer not ready\n", dev->name); - goto Done; - } - } -#endif - res = length; -Done: -#if 0 - printf("Leaving inca_switch_send()\n"); -#endif - return res; -} - - -static int inca_switch_recv(struct eth_device *dev) -{ - int length = 0; - inca_rx_descriptor_t * rx_desc; - -#if 0 - printf("Entered inca_switch_recv()\n"); -#endif - - for (;;) { - rx_desc = (inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[rx_new]); - - if (rx_desc->status.field.C == 0) { - break; - } - -#if 0 - rx_ring[rx_new].params.field.HOLD = 1; -#endif - - if (! rx_desc->status.field.Eop) { - printf("Partly received packet!!!\n"); - break; - } - - length = rx_desc->status.field.NBT; - rx_desc->status.word &= - ~(INCA_DMA_RX_EOP | INCA_DMA_RX_SOP | INCA_DMA_RX_C); -#if 0 -{ - int i; - for (i=0;i<length - 4;i++) { - if (i % 16 == 0) printf("\n%04x: ", i); - printf("%02X ", NetRxPackets[rx_new][i]); - } - printf("\n"); -} -#endif - - if (length) { -#if 0 - printf("Received %d bytes\n", length); -#endif - NetReceive((void*)CKSEG1ADDR(NetRxPackets[rx_new]), length - 4); - } else { -#if 1 - printf("Zero length!!!\n"); -#endif - } - - - ((inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[rx_hold]))->params.field.HOLD = 0; - - rx_hold = rx_new; - - rx_new = (rx_new + 1) % NUM_RX_DESC; - } - -#if 0 - printf("Leaving inca_switch_recv()\n"); -#endif - - return length; -} - - -static void inca_switch_halt(struct eth_device *dev) -{ -#if 0 - printf("Entered inca_switch_halt()\n"); -#endif - -#if 1 - initialized = 0; -#endif -#if 1 - /* Disable forwarding to the CPU port. - */ - SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf); - - /* Close RxDMA channel. - */ - DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF); - - /* Close TxDMA channel. - */ - DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_TXCCR0_OFF); - - -#endif -#if 0 - printf("Leaving inca_switch_halt()\n"); -#endif -} - - -static void inca_init_switch_chip(void) -{ - u32 regValue; - - /* To workaround a problem with collision counter - * (see Errata sheet). - */ - SW_WRITE_REG(INCA_IP_Switch_PC_TX_CTL, 0x00000001); - SW_WRITE_REG(INCA_IP_Switch_LAN_TX_CTL, 0x00000001); - -#if 1 - /* init MDIO configuration: - * MDS (Poll speed): 0x01 (4ms) - * PHY_LAN_ADDR: 0x06 - * PHY_PC_ADDR: 0x05 - * UEP (Use External PHY): 0x00 (Internal PHY is used) - * PS (Port Select): 0x00 (PT/UMM for LAN) - * PT (PHY Test): 0x00 (no test mode) - * UMM (Use MDIO Mode): 0x00 (state machine is disabled) - */ - SW_WRITE_REG(INCA_IP_Switch_MDIO_CFG, 0x4c50); - - /* init PHY: - * SL (Auto Neg. Speed for LAN) - * SP (Auto Neg. Speed for PC) - * LL (Link Status for LAN) - * LP (Link Status for PC) - * DL (Duplex Status for LAN) - * DP (Duplex Status for PC) - * PL (Auto Neg. Pause Status for LAN) - * PP (Auto Neg. Pause Status for PC) - */ - SW_WRITE_REG (INCA_IP_Switch_EPHY, 0xff); - - /* MDIO_ACC: - * RA (Request/Ack) 0x01 (Request) - * RW (Read/Write) 0x01 (Write) - * PHY_ADDR 0x05 (PC) - * REG_ADDR 0x00 (PHY_BCR: basic control register) - * PHY_DATA 0x8000 - * Reset - software reset - * LB (loop back) - normal - * SS (speed select) - 10 Mbit/s - * ANE (auto neg. enable) - enable - * PD (power down) - normal - * ISO (isolate) - normal - * RAN (restart auto neg.) - normal - * DM (duplex mode) - half duplex - * CT (collision test) - enable - */ - SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0a09000); - - /* MDIO_ACC: - * RA (Request/Ack) 0x01 (Request) - * RW (Read/Write) 0x01 (Write) - * PHY_ADDR 0x06 (LAN) - * REG_ADDR 0x00 (PHY_BCR: basic control register) - * PHY_DATA 0x8000 - * Reset - software reset - * LB (loop back) - normal - * SS (speed select) - 10 Mbit/s - * ANE (auto neg. enable) - enable - * PD (power down) - normal - * ISO (isolate) - normal - * RAN (restart auto neg.) - normal - * DM (duplex mode) - half duplex - * CT (collision test) - enable - */ - SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0c09000); - -#endif - - /* Make sure the CPU port is disabled for now. We - * don't want packets to get stacked for us until - * we enable DMA and are prepared to receive them. - */ - SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf); - - SW_READ_REG(INCA_IP_Switch_ARL_CTL, regValue); - - /* CRC GEN is enabled. - */ - regValue |= 0x00000200; - SW_WRITE_REG(INCA_IP_Switch_ARL_CTL, regValue); - - /* ADD TAG is disabled. - */ - SW_READ_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue); - regValue &= ~0x00000002; - SW_WRITE_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue); -} - - -static void inca_dma_init(void) -{ - /* Switch off all DMA channels. - */ - DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF); - DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR1, INCA_IP_DMA_DMA_RXCCR1_OFF); - - DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF); - DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR1, INCA_IP_DMA_DMA_TXCCR1_OFF); - DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR2, INCA_IP_DMA_DMA_TXCCR2_OFF); - - /* Setup TX channel polling time. - */ - DMA_WRITE_REG(INCA_IP_DMA_DMA_TXPOLL, INCA_DMA_TX_POLLING_TIME); - - /* Setup RX channel polling time. - */ - DMA_WRITE_REG(INCA_IP_DMA_DMA_RXPOLL, INCA_DMA_RX_POLLING_TIME); - - /* ERRATA: write reset value into the DMA RX IMR register. - */ - DMA_WRITE_REG(INCA_IP_DMA_DMA_RXIMR, 0xFFFFFFFF); - - /* Just in case: disable all transmit interrupts also. - */ - DMA_WRITE_REG(INCA_IP_DMA_DMA_TXIMR, 0xFFFFFFFF); - - DMA_WRITE_REG(INCA_IP_DMA_DMA_TXISR, 0xFFFFFFFF); - DMA_WRITE_REG(INCA_IP_DMA_DMA_RXISR, 0xFFFFFFFF); -} - -#if defined(CONFIG_INCA_IP_SWITCH_AMDIX) -static int inca_amdix(void) -{ - u32 phyReg1 = 0; - u32 phyReg4 = 0; - u32 phyReg5 = 0; - u32 phyReg6 = 0; - u32 phyReg31 = 0; - u32 regEphy = 0; - int mdi_flag; - int retries; - - /* Setup GPIO pins. - */ - *INCA_IP_AUTO_MDIX_LAN_PORTS_DIR |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX); - *INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX); - -#if 0 - /* Wait for signal. - */ - retries = WAIT_SIGNAL_RETRIES; - while (--retries) { - SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, - (0x1 << 31) | /* RA */ - (0x0 << 30) | /* Read */ - (0x6 << 21) | /* LAN */ - (17 << 16)); /* PHY_MCSR */ - do { - SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1); - } while (phyReg1 & (1 << 31)); - - if (phyReg1 & (1 << 1)) { - /* Signal detected */ - break; - } - } - - if (!retries) - goto Fail; -#endif - - /* Set MDI mode. - */ - *INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX); - mdi_flag = 1; - - /* Wait for link. - */ - retries = WAIT_LINK_RETRIES; - while (--retries) { - udelay(LINK_RETRY_DELAY * 1000); - SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, - (0x1 << 31) | /* RA */ - (0x0 << 30) | /* Read */ - (0x6 << 21) | /* LAN */ - (1 << 16)); /* PHY_BSR */ - do { - SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1); - } while (phyReg1 & (1 << 31)); - - if (phyReg1 & (1 << 2)) { - /* Link is up */ - break; - } else if (mdi_flag) { - /* Set MDIX mode */ - *INCA_IP_AUTO_MDIX_LAN_PORTS_OUT |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX); - mdi_flag = 0; - } else { - /* Set MDI mode */ - *INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX); - mdi_flag = 1; - } - } - - if (!retries) { - goto Fail; - } else { - SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, - (0x1 << 31) | /* RA */ - (0x0 << 30) | /* Read */ - (0x6 << 21) | /* LAN */ - (1 << 16)); /* PHY_BSR */ - do { - SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1); - } while (phyReg1 & (1 << 31)); - - /* Auto-negotiation / Parallel detection complete - */ - if (phyReg1 & (1 << 5)) { - SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, - (0x1 << 31) | /* RA */ - (0x0 << 30) | /* Read */ - (0x6 << 21) | /* LAN */ - (31 << 16)); /* PHY_SCSR */ - do { - SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg31); - } while (phyReg31 & (1 << 31)); - - switch ((phyReg31 >> 2) & 0x7) { - case INCA_SWITCH_PHY_SPEED_10H: - /* 10Base-T Half-duplex */ - regEphy = 0; - break; - case INCA_SWITCH_PHY_SPEED_10F: - /* 10Base-T Full-duplex */ - regEphy = INCA_IP_Switch_EPHY_DL; - break; - case INCA_SWITCH_PHY_SPEED_100H: - /* 100Base-TX Half-duplex */ - regEphy = INCA_IP_Switch_EPHY_SL; - break; - case INCA_SWITCH_PHY_SPEED_100F: - /* 100Base-TX Full-duplex */ - regEphy = INCA_IP_Switch_EPHY_SL | INCA_IP_Switch_EPHY_DL; - break; - } - - /* In case of Auto-negotiation, - * update the negotiated PAUSE support status - */ - if (phyReg1 & (1 << 3)) { - SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, - (0x1 << 31) | /* RA */ - (0x0 << 30) | /* Read */ - (0x6 << 21) | /* LAN */ - (6 << 16)); /* MII_EXPANSION */ - do { - SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg6); - } while (phyReg6 & (1 << 31)); - - /* We are Autoneg-able. - * Is Link partner also able to autoneg? - */ - if (phyReg6 & (1 << 0)) { - SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, - (0x1 << 31) | /* RA */ - (0x0 << 30) | /* Read */ - (0x6 << 21) | /* LAN */ - (4 << 16)); /* MII_ADVERTISE */ - do { - SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg4); - } while (phyReg4 & (1 << 31)); - - /* We advertise PAUSE capab. - * Does link partner also advertise it? - */ - if (phyReg4 & (1 << 10)) { - SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, - (0x1 << 31) | /* RA */ - (0x0 << 30) | /* Read */ - (0x6 << 21) | /* LAN */ - (5 << 16)); /* MII_LPA */ - do { - SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg5); - } while (phyReg5 & (1 << 31)); - - /* Link partner is PAUSE capab. - */ - if (phyReg5 & (1 << 10)) { - regEphy |= INCA_IP_Switch_EPHY_PL; - } - } - } - - } - - /* Link is up */ - regEphy |= INCA_IP_Switch_EPHY_LL; - - SW_WRITE_REG(INCA_IP_Switch_EPHY, regEphy); - } - } - - return 0; - -Fail: - printf("No Link on LAN port\n"); - return -1; -} -#endif /* CONFIG_INCA_IP_SWITCH_AMDIX */ |