diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/cpsw.c | 19 | ||||
-rw-r--r-- | drivers/net/e1000.c | 266 | ||||
-rw-r--r-- | drivers/net/e1000.h | 12 | ||||
-rw-r--r-- | drivers/net/fm/t4240.c | 5 | ||||
-rw-r--r-- | drivers/net/phy/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/phy/icplus.c | 80 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 3 | ||||
-rw-r--r-- | drivers/net/phy/vitesse.c | 1 | ||||
-rw-r--r-- | drivers/net/plb2800_eth.c | 373 |
10 files changed, 235 insertions, 527 deletions
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 7cc6b6fc086..84b8ec4a314 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -30,7 +30,6 @@ obj-$(CONFIG_FTGMAC100) += ftgmac100.o obj-$(CONFIG_FTMAC110) += ftmac110.o obj-$(CONFIG_FTMAC100) += ftmac100.o obj-$(CONFIG_GRETH) += greth.o -obj-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o obj-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o @@ -46,7 +45,6 @@ obj-$(CONFIG_DRIVER_AX88796L) += ax88796.o ne2000_base.o obj-$(CONFIG_NETCONSOLE) += netconsole.o obj-$(CONFIG_NS8382X) += ns8382x.o obj-$(CONFIG_PCNET) += pcnet.o -obj-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o obj-$(CONFIG_RTL8139) += rtl8139.o obj-$(CONFIG_RTL8169) += rtl8169.o obj-$(CONFIG_SH_ETHER) += sh_eth.o diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index 8ec5161ec61..52f8da67e1d 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -235,7 +235,6 @@ struct cpsw_priv { struct phy_device *phydev; struct mii_dev *bus; - u32 mdio_link; u32 phy_mask; }; @@ -613,19 +612,8 @@ static int cpsw_update_link(struct cpsw_priv *priv) for_active_slave(slave, priv) cpsw_slave_update_link(slave, priv, &link); - priv->mdio_link = readl(&mdio_regs->link); - return link; -} - -static int cpsw_check_link(struct cpsw_priv *priv) -{ - u32 link = 0; - link = __raw_readl(&mdio_regs->link) & priv->phy_mask; - if ((link) && (link == priv->mdio_link)) - return 1; - - return cpsw_update_link(priv); + return link; } static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num) @@ -891,9 +879,6 @@ static int cpsw_send(struct eth_device *dev, void *packet, int length) int len; int timeout = CPDMA_TIMEOUT; - if (!cpsw_check_link(priv)) - return -EIO; - flush_dcache_range((unsigned long)packet, (unsigned long)packet + length); @@ -916,8 +901,6 @@ static int cpsw_recv(struct eth_device *dev) void *buffer; int len; - cpsw_check_link(priv); - while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) { invalidate_dcache_range((unsigned long)buffer, (unsigned long)buffer + PKTSIZE_ALIGN); diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 9d9b259d644..0eba57cf0ce 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -41,12 +41,12 @@ tested on both gig copper and gig fiber boards /* NIC specific static variables go here */ -static char tx_pool[128 + 16]; -static char rx_pool[128 + 16]; -static char packet[2096]; +/* Intel i210 needs the DMA descriptor rings aligned to 128b */ +#define E1000_BUFFER_ALIGN 128 -static struct e1000_tx_desc *tx_base; -static struct e1000_rx_desc *rx_base; +DEFINE_ALIGN_BUFFER(struct e1000_tx_desc, tx_base, 16, E1000_BUFFER_ALIGN); +DEFINE_ALIGN_BUFFER(struct e1000_rx_desc, rx_base, 16, E1000_BUFFER_ALIGN); +DEFINE_ALIGN_BUFFER(unsigned char, packet, 4096, E1000_BUFFER_ALIGN); static int tx_tail; static int rx_tail, rx_last; @@ -92,6 +92,12 @@ static struct pci_device_id e1000_supported[] = { {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_DPT}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_SPT}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_SPT}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_COPPER}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_COPPER_FLASHLESS}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_SERDES}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_SERDES_FLASHLESS}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I210_1000BASEKX}, + {} }; @@ -340,7 +346,7 @@ int32_t e1000_acquire_eeprom(struct e1000_hw *hw) return -E1000_ERR_SWFW_SYNC; eecd = E1000_READ_REG(hw, EECD); - if (hw->mac_type != e1000_82573 || hw->mac_type != e1000_82574) { + if (hw->mac_type != e1000_82573 && hw->mac_type != e1000_82574) { /* Request EEPROM Access */ if (hw->mac_type > e1000_82544) { eecd |= E1000_EECD_REQ; @@ -391,10 +397,15 @@ int32_t e1000_acquire_eeprom(struct e1000_hw *hw) static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) { struct e1000_eeprom_info *eeprom = &hw->eeprom; - uint32_t eecd = E1000_READ_REG(hw, EECD); + uint32_t eecd; int32_t ret_val = E1000_SUCCESS; uint16_t eeprom_size; + if (hw->mac_type == e1000_igb) + eecd = E1000_READ_REG(hw, I210_EECD); + else + eecd = E1000_READ_REG(hw, EECD); + DEBUGFUNC(); switch (hw->mac_type) { @@ -485,9 +496,10 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->page_size = 8; eeprom->address_bits = 8; } - eeprom->use_eerd = true; - eeprom->use_eewr = true; if (e1000_is_onboard_nvm_eeprom(hw) == false) { + eeprom->use_eerd = true; + eeprom->use_eewr = true; + eeprom->type = e1000_eeprom_flash; eeprom->word_size = 2048; @@ -511,6 +523,16 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->use_eerd = true; eeprom->use_eewr = false; break; + case e1000_igb: + /* i210 has 4k of iNVM mapped as EEPROM */ + eeprom->type = e1000_eeprom_invm; + eeprom->opcode_bits = 8; + eeprom->delay_usec = 1; + eeprom->page_size = 32; + eeprom->address_bits = 16; + eeprom->use_eerd = true; + eeprom->use_eewr = false; + break; /* ich8lan does not support currently. if needed, please * add corresponding code and functions. @@ -552,7 +574,8 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) break; } - if (eeprom->type == e1000_eeprom_spi) { + if (eeprom->type == e1000_eeprom_spi || + eeprom->type == e1000_eeprom_invm) { /* eeprom_size will be an enum [0..8] that maps * to eeprom sizes 128B to * 32KB (incremented by powers of 2). @@ -596,10 +619,17 @@ e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd) int32_t done = E1000_ERR_EEPROM; for (i = 0; i < attempts; i++) { - if (eerd == E1000_EEPROM_POLL_READ) - reg = E1000_READ_REG(hw, EERD); - else - reg = E1000_READ_REG(hw, EEWR); + if (eerd == E1000_EEPROM_POLL_READ) { + if (hw->mac_type == e1000_igb) + reg = E1000_READ_REG(hw, I210_EERD); + else + reg = E1000_READ_REG(hw, EERD); + } else { + if (hw->mac_type == e1000_igb) + reg = E1000_READ_REG(hw, I210_EEWR); + else + reg = E1000_READ_REG(hw, EEWR); + } if (reg & E1000_EEPROM_RW_REG_DONE) { done = E1000_SUCCESS; @@ -632,13 +662,23 @@ e1000_read_eeprom_eerd(struct e1000_hw *hw, eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) + E1000_EEPROM_RW_REG_START; - E1000_WRITE_REG(hw, EERD, eerd); + if (hw->mac_type == e1000_igb) + E1000_WRITE_REG(hw, I210_EERD, eerd); + else + E1000_WRITE_REG(hw, EERD, eerd); + error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ); if (error) break; - data[i] = (E1000_READ_REG(hw, EERD) >> + + if (hw->mac_type == e1000_igb) { + data[i] = (E1000_READ_REG(hw, I210_EERD) >> + E1000_EEPROM_RW_REG_DATA); + } else { + data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA); + } } @@ -949,6 +989,10 @@ e1000_get_software_semaphore(struct e1000_hw *hw) DEBUGFUNC(); + swsm = E1000_READ_REG(hw, SWSM); + swsm &= ~E1000_SWSM_SMBI; + E1000_WRITE_REG(hw, SWSM, swsm); + if (hw->mac_type != e1000_80003es2lan) return E1000_SUCCESS; @@ -1069,7 +1113,7 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) return -E1000_ERR_SWFW_SYNC; swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC); - if (!(swfw_sync & (fwmask | swmask))) + if ((swfw_sync & swmask) && !(swfw_sync & fwmask)) break; /* firmware currently using resource (fwmask) */ @@ -1118,13 +1162,23 @@ e1000_read_mac_addr(struct eth_device *nic) struct e1000_hw *hw = nic->priv; uint16_t offset; uint16_t eeprom_data; + uint32_t reg_data = 0; int i; DEBUGFUNC(); for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) { offset = i >> 1; - if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) { + if (hw->mac_type == e1000_igb) { + /* i210 preloads MAC address into RAL/RAH registers */ + if (offset == 0) + reg_data = E1000_READ_REG_ARRAY(hw, RA, 0); + else if (offset == 1) + reg_data >>= 16; + else if (offset == 2) + reg_data = E1000_READ_REG_ARRAY(hw, RA, 1); + eeprom_data = reg_data & 0xffff; + } else if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) { DEBUGOUT("EEPROM Read Error\n"); return -E1000_ERR_EEPROM; } @@ -1320,6 +1374,13 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_ICH8_IGP_M: hw->mac_type = e1000_ich8lan; break; + case PCI_DEVICE_ID_INTEL_I210_COPPER: + case PCI_DEVICE_ID_INTEL_I210_COPPER_FLASHLESS: + case PCI_DEVICE_ID_INTEL_I210_SERDES: + case PCI_DEVICE_ID_INTEL_I210_SERDES_FLASHLESS: + case PCI_DEVICE_ID_INTEL_I210_1000BASEKX: + hw->mac_type = e1000_igb; + break; default: /* Should never have loaded on this device */ return -E1000_ERR_MAC_TYPE; @@ -1339,6 +1400,7 @@ e1000_reset_hw(struct e1000_hw *hw) uint32_t ctrl_ext; uint32_t manc; uint32_t pba = 0; + uint32_t reg; DEBUGFUNC(); @@ -1357,6 +1419,8 @@ e1000_reset_hw(struct e1000_hw *hw) /* Clear interrupt mask to stop board from generating interrupts */ DEBUGOUT("Masking off all interrupts\n"); + if (hw->mac_type == e1000_igb) + E1000_WRITE_REG(hw, I210_IAM, 0); E1000_WRITE_REG(hw, IMC, 0xffffffff); /* Disable the Transmit and Receive units. Then delay to allow @@ -1386,7 +1450,15 @@ e1000_reset_hw(struct e1000_hw *hw) E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); /* Force a reload from the EEPROM if necessary */ - if (hw->mac_type < e1000_82540) { + if (hw->mac_type == e1000_igb) { + mdelay(20); + reg = E1000_READ_REG(hw, STATUS); + if (reg & E1000_STATUS_PF_RST_DONE) + DEBUGOUT("PF OK\n"); + reg = E1000_READ_REG(hw, I210_EECD); + if (reg & E1000_EECD_AUTO_RD) + DEBUGOUT("EEC OK\n"); + } else if (hw->mac_type < e1000_82540) { /* Wait for reset to complete */ udelay(10); ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); @@ -1406,6 +1478,8 @@ e1000_reset_hw(struct e1000_hw *hw) /* Clear interrupt mask to stop board from generating interrupts */ DEBUGOUT("Masking off all interrupts\n"); + if (hw->mac_type == e1000_igb) + E1000_WRITE_REG(hw, I210_IAM, 0); E1000_WRITE_REG(hw, IMC, 0xffffffff); /* Clear any pending interrupt events. */ @@ -1415,7 +1489,8 @@ e1000_reset_hw(struct e1000_hw *hw) if (hw->mac_type == e1000_82542_rev2_0) { pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word); } - E1000_WRITE_REG(hw, PBA, pba); + if (hw->mac_type != e1000_igb) + E1000_WRITE_REG(hw, PBA, pba); } /****************************************************************************** @@ -1451,6 +1526,10 @@ e1000_initialize_hardware_bits(struct e1000_hw *hw) reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC; E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1); + /* IGB is cool */ + if (hw->mac_type == e1000_igb) + return; + switch (hw->mac_type) { case e1000_82571: case e1000_82572: @@ -1641,6 +1720,7 @@ e1000_init_hw(struct eth_device *nic) switch (hw->mac_type) { case e1000_82545_rev_3: case e1000_82546_rev_3: + case e1000_igb: break; default: /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */ @@ -1670,6 +1750,8 @@ e1000_init_hw(struct eth_device *nic) /* More time needed for PHY to initialize */ if (hw->mac_type == e1000_ich8lan) mdelay(15); + if (hw->mac_type == e1000_igb) + mdelay(15); /* Call a subroutine to configure the link and setup flow control. */ ret_val = e1000_setup_link(nic); @@ -1684,7 +1766,6 @@ e1000_init_hw(struct eth_device *nic) } /* Set the receive descriptor write back policy */ - if (hw->mac_type >= e1000_82571) { ctrl = E1000_READ_REG(hw, RXDCTL); ctrl = @@ -1731,6 +1812,8 @@ e1000_init_hw(struct eth_device *nic) reg_data = E1000_READ_REG(hw, GCR); reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; E1000_WRITE_REG(hw, GCR, reg_data); + case e1000_igb: + break; } #if 0 @@ -1807,6 +1890,7 @@ e1000_setup_link(struct eth_device *nic) case e1000_ich8lan: case e1000_82573: case e1000_82574: + case e1000_igb: hw->fc = e1000_fc_full; break; default: @@ -2267,6 +2351,8 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) if (hw->mac_type == e1000_ich8lan) { phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); + } else if (hw->mac_type == e1000_igb) { + phy_ctrl = E1000_READ_REG(hw, I210_PHY_CTRL); } else { ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); @@ -2278,6 +2364,9 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) if (hw->mac_type == e1000_ich8lan) { phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); + } else if (hw->mac_type == e1000_igb) { + phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; + E1000_WRITE_REG(hw, I210_PHY_CTRL, phy_ctrl); } else { phy_data &= ~IGP02E1000_PM_D0_LPLU; ret_val = e1000_write_phy_reg(hw, @@ -2286,6 +2375,9 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) return ret_val; } + if (hw->mac_type == e1000_igb) + return E1000_SUCCESS; + /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during * Dx states where the power conservation is most important. During * driver activity we should enable SmartSpeed, so performance is @@ -2320,6 +2412,9 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) if (hw->mac_type == e1000_ich8lan) { phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); + } else if (hw->mac_type == e1000_igb) { + phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; + E1000_WRITE_REG(hw, I210_PHY_CTRL, phy_ctrl); } else { phy_data |= IGP02E1000_PM_D0_LPLU; ret_val = e1000_write_phy_reg(hw, @@ -2328,6 +2423,9 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) return ret_val; } + if (hw->mac_type == e1000_igb) + return E1000_SUCCESS; + /* When LPLU is enabled we should disable SmartSpeed */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); @@ -2549,8 +2647,10 @@ e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data) if (e1000_is_second_port(hw)) swfw = E1000_SWFW_PHY1_SM; - if (e1000_swfw_sync_acquire(hw, swfw)) + if (e1000_swfw_sync_acquire(hw, swfw)) { + debug("%s[%i]\n", __func__, __LINE__); return -E1000_ERR_SWFW_SYNC; + } /* Write register address */ reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) & @@ -2985,7 +3085,8 @@ e1000_setup_copper_link(struct eth_device *nic) ret_val = e1000_copper_link_igp_setup(hw); if (ret_val) return ret_val; - } else if (hw->phy_type == e1000_phy_m88) { + } else if (hw->phy_type == e1000_phy_m88 || + hw->phy_type == e1000_phy_igb) { ret_val = e1000_copper_link_mgp_setup(hw); if (ret_val) return ret_val; @@ -3229,7 +3330,8 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) */ ctrl = E1000_READ_REG(hw, CTRL); ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); - ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS); + ctrl &= ~(E1000_CTRL_ILOS); + ctrl |= (E1000_CTRL_SPD_SEL); /* Set up duplex in the Device Control and Transmit Control * registers depending on negotiated values. @@ -4255,11 +4357,16 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw) case e1000_82571: case e1000_82572: + case e1000_igb: while (timeout) { - if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask) - break; - else - mdelay(1); + if (hw->mac_type == e1000_igb) { + if (E1000_READ_REG(hw, I210_EEMNGCTL) & cfg_mask) + break; + } else { + if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask) + break; + } + mdelay(1); timeout--; } if (!timeout) { @@ -4488,6 +4595,7 @@ e1000_phy_reset(struct e1000_hw *hw) case e1000_phy_igp_2: case e1000_phy_igp_3: case e1000_phy_ife: + case e1000_phy_igb: ret_val = e1000_phy_hw_reset(hw); if (ret_val) return ret_val; @@ -4550,6 +4658,9 @@ static int e1000_set_phy_type (struct e1000_hw *hw) case BME1000_E_PHY_ID: hw->phy_type = e1000_phy_bm; break; + case I210_I_PHY_ID: + hw->phy_type = e1000_phy_igb; + break; /* Fall Through */ default: /* Should never have loaded on this device */ @@ -4654,6 +4765,10 @@ e1000_detect_gig_phy(struct e1000_hw *hw) if (hw->phy_id == IFE_C_E_PHY_ID) match = true; break; + case e1000_igb: + if (hw->phy_id == I210_I_PHY_ID) + match = true; + break; default: DEBUGOUT("Invalid MAC type %d\n", hw->mac_type); return -E1000_ERR_CONFIG; @@ -4705,6 +4820,7 @@ e1000_set_media_type(struct e1000_hw *hw) case e1000_ich8lan: case e1000_82573: case e1000_82574: + case e1000_igb: /* The STATUS_TBIMODE bit is reserved or reused * for the this device. */ @@ -4773,6 +4889,7 @@ e1000_sw_init(struct eth_device *nic) hw->fc_send_xon = 1; /* Media type - copper or fiber */ + hw->tbi_compatibility_en = true; e1000_set_media_type(hw); if (hw->mac_type >= e1000_82543) { @@ -4789,7 +4906,6 @@ e1000_sw_init(struct eth_device *nic) hw->media_type = e1000_media_type_fiber; } - hw->tbi_compatibility_en = true; hw->wait_autoneg_complete = true; if (hw->mac_type < e1000_82543) hw->report_tx_early = 0; @@ -4803,12 +4919,25 @@ void fill_rx(struct e1000_hw *hw) { struct e1000_rx_desc *rd; + uint32_t flush_start, flush_end; rx_last = rx_tail; rd = rx_base + rx_tail; rx_tail = (rx_tail + 1) % 8; memset(rd, 0, 16); - rd->buffer_addr = cpu_to_le64((u32) & packet); + rd->buffer_addr = cpu_to_le64((u32)packet); + + /* + * Make sure there are no stale data in WB over this area, which + * might get written into the memory while the e1000 also writes + * into the same memory area. + */ + invalidate_dcache_range((u32)packet, (u32)packet + 4096); + /* Dump the DMA descriptor into RAM. */ + flush_start = ((u32)rd) & ~(ARCH_DMA_MINALIGN - 1); + flush_end = flush_start + roundup(sizeof(*rd), ARCH_DMA_MINALIGN); + flush_dcache_range(flush_start, flush_end); + E1000_WRITE_REG(hw, RDT, rx_tail); } @@ -4822,17 +4951,10 @@ fill_rx(struct e1000_hw *hw) static void e1000_configure_tx(struct e1000_hw *hw) { - unsigned long ptr; unsigned long tctl; unsigned long tipg, tarc; uint32_t ipgr1, ipgr2; - ptr = (u32) tx_pool; - if (ptr & 0xf) - ptr = (ptr + 0x10) & (~0xf); - - tx_base = (typeof(tx_base)) ptr; - E1000_WRITE_REG(hw, TDBAL, (u32) tx_base); E1000_WRITE_REG(hw, TDBAH, 0); @@ -4901,7 +5023,22 @@ e1000_configure_tx(struct e1000_hw *hw) hw->txd_cmd |= E1000_TXD_CMD_RPS; else hw->txd_cmd |= E1000_TXD_CMD_RS; + + + if (hw->mac_type == e1000_igb) { + E1000_WRITE_REG(hw, TCTL_EXT, 0x42 << 10); + + uint32_t reg_txdctl = E1000_READ_REG(hw, TXDCTL); + reg_txdctl |= 1 << 25; + E1000_WRITE_REG(hw, TXDCTL, reg_txdctl); + mdelay(20); + } + + + E1000_WRITE_REG(hw, TCTL, tctl); + + } /** @@ -4941,7 +5078,6 @@ e1000_setup_rctl(struct e1000_hw *hw) static void e1000_configure_rx(struct e1000_hw *hw) { - unsigned long ptr; unsigned long rctl, ctrl_ext; rx_tail = 0; /* make sure receives are disabled while setting up the descriptors */ @@ -4963,10 +5099,6 @@ e1000_configure_rx(struct e1000_hw *hw) E1000_WRITE_FLUSH(hw); } /* Setup the Base and Length of the Rx Descriptor Ring */ - ptr = (u32) rx_pool; - if (ptr & 0xf) - ptr = (ptr + 0x10) & (~0xf); - rx_base = (typeof(rx_base)) ptr; E1000_WRITE_REG(hw, RDBAL, (u32) rx_base); E1000_WRITE_REG(hw, RDBAH, 0); @@ -4977,7 +5109,16 @@ e1000_configure_rx(struct e1000_hw *hw) E1000_WRITE_REG(hw, RDT, 0); /* Enable Receives */ + if (hw->mac_type == e1000_igb) { + + uint32_t reg_rxdctl = E1000_READ_REG(hw, RXDCTL); + reg_rxdctl |= 1 << 25; + E1000_WRITE_REG(hw, RXDCTL, reg_rxdctl); + mdelay(20); + } + E1000_WRITE_REG(hw, RCTL, rctl); + fill_rx(hw); } @@ -4989,12 +5130,25 @@ e1000_poll(struct eth_device *nic) { struct e1000_hw *hw = nic->priv; struct e1000_rx_desc *rd; + uint32_t inval_start, inval_end; + uint32_t len; + /* return true if there's an ethernet packet ready to read */ rd = rx_base + rx_last; + + /* Re-load the descriptor from RAM. */ + inval_start = ((u32)rd) & ~(ARCH_DMA_MINALIGN - 1); + inval_end = inval_start + roundup(sizeof(*rd), ARCH_DMA_MINALIGN); + invalidate_dcache_range(inval_start, inval_end); + if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD) return 0; /*DEBUGOUT("recv: packet len=%d \n", rd->length); */ - NetReceive((uchar *)packet, le32_to_cpu(rd->length)); + /* Packet received, make sure the data are re-loaded from RAM. */ + len = le32_to_cpu(rd->length); + invalidate_dcache_range((u32)packet, + (u32)packet + roundup(len, ARCH_DMA_MINALIGN)); + NetReceive((uchar *)packet, len); fill_rx(hw); return 1; } @@ -5002,12 +5156,13 @@ e1000_poll(struct eth_device *nic) /************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ -static int e1000_transmit(struct eth_device *nic, void *packet, int length) +static int e1000_transmit(struct eth_device *nic, void *txpacket, int length) { - void *nv_packet = (void *)packet; + void *nv_packet = (void *)txpacket; struct e1000_hw *hw = nic->priv; struct e1000_tx_desc *txp; int i = 0; + uint32_t flush_start, flush_end; txp = tx_base + tx_tail; tx_tail = (tx_tail + 1) % 8; @@ -5015,10 +5170,22 @@ static int e1000_transmit(struct eth_device *nic, void *packet, int length) txp->buffer_addr = cpu_to_le64(virt_to_bus(hw->pdev, nv_packet)); txp->lower.data = cpu_to_le32(hw->txd_cmd | length); txp->upper.data = 0; + + /* Dump the packet into RAM so e1000 can pick them. */ + flush_dcache_range((u32)nv_packet, + (u32)nv_packet + roundup(length, ARCH_DMA_MINALIGN)); + /* Dump the descriptor into RAM as well. */ + flush_start = ((u32)txp) & ~(ARCH_DMA_MINALIGN - 1); + flush_end = flush_start + roundup(sizeof(*txp), ARCH_DMA_MINALIGN); + flush_dcache_range(flush_start, flush_end); + E1000_WRITE_REG(hw, TDT, tx_tail); E1000_WRITE_FLUSH(hw); - while (!(le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD)) { + while (1) { + invalidate_dcache_range(flush_start, flush_end); + if (le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD) + break; if (i++ > TOUT_LOOP) { DEBUGOUT("e1000: tx timeout\n"); return 0; @@ -5113,9 +5280,8 @@ void e1000_get_bus_type(struct e1000_hw *hw) case e1000_82573: case e1000_82574: case e1000_80003es2lan: - hw->bus_type = e1000_bus_type_pci_express; - break; case e1000_ich8lan: + case e1000_igb: hw->bus_type = e1000_bus_type_pci_express; break; default: @@ -5196,6 +5362,7 @@ e1000_initialize(bd_t * bis) hw->autoneg_failed = 0; hw->autoneg = 1; hw->get_link_status = true; + hw->eeprom_semaphore_present = true; hw->hw_addr = pci_map_bar(devno, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); hw->mac_type = e1000_undefined; @@ -5219,7 +5386,8 @@ e1000_initialize(bd_t * bis) E1000_ERR(nic, "EEPROM is invalid!\n"); continue; } - if (e1000_validate_eeprom_checksum(hw)) + if ((E1000_READ_REG(hw, I210_EECD) & E1000_EECD_FLUPD) && + e1000_validate_eeprom_checksum(hw)) continue; #endif e1000_read_mac_addr(nic); diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index ff87af2ef8a..b025ecc4fc5 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -100,6 +100,7 @@ typedef enum { e1000_82574, e1000_80003es2lan, e1000_ich8lan, + e1000_igb, e1000_num_macs } e1000_mac_type; @@ -118,6 +119,7 @@ typedef enum { e1000_eeprom_flash, e1000_eeprom_ich8, e1000_eeprom_none, /* No NVM support */ + e1000_eeprom_invm, e1000_num_eeprom_types } e1000_eeprom_type; @@ -212,6 +214,7 @@ typedef enum { e1000_phy_gg82563, e1000_phy_igp_3, e1000_phy_ife, + e1000_phy_igb, e1000_phy_bm, e1000_phy_undefined = 0xFF } e1000_phy_type; @@ -686,7 +689,9 @@ struct e1000_ffvt_entry { #define E1000_CTRL 0x00000 /* Device Control - RW */ #define E1000_STATUS 0x00008 /* Device Status - RO */ #define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ +#define E1000_I210_EECD 0x12010 /* EEPROM/Flash Control - RW */ #define E1000_EERD 0x00014 /* EEPROM Read - RW */ +#define E1000_I210_EERD 0x12014 /* EEPROM Read - RW */ #define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ #define E1000_MDIC 0x00020 /* MDI Control - RW */ #define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ @@ -698,6 +703,7 @@ struct e1000_ffvt_entry { #define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ #define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ #define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ +#define E1000_I210_IAM 0x000E0 /* Interrupt Ack Auto Mask - RW */ #define E1000_RCTL 0x00100 /* RX Control - RW */ #define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ #define E1000_TXCW 0x00178 /* TX Configuration Word - RW */ @@ -711,14 +717,17 @@ struct e1000_ffvt_entry { #define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */ #define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */ #define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */ +#define E1000_I210_PHY_CTRL 0x00E14 /* PHY Control Register in CSR */ #define FEXTNVM_SW_CONFIG 0x0001 #define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ #define E1000_PBS 0x01008 /* Packet Buffer Size */ #define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ +#define E1000_I210_EEMNGCTL 0x12030 /* MNG EEprom Control */ #define E1000_FLASH_UPDATES 1000 #define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ #define E1000_FLASHT 0x01028 /* FLASH Timer Register */ #define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */ +#define E1000_I210_EEWR 0x12018 /* EEPROM Write Register - RW */ #define E1000_FLSWCTL 0x01030 /* FLASH control register */ #define E1000_FLSWDATA 0x01034 /* FLASH data register */ #define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */ @@ -1222,6 +1231,7 @@ struct e1000_hw { #define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ #define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */ #define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */ +#define E1000_STATUS_PF_RST_DONE 0x00200000 /* PCI-X bus speed */ /* Constants used to intrepret the masked PCI-X bus speed. */ #define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */ @@ -2438,6 +2448,8 @@ struct e1000_hw { #define BME1000_E_PHY_ID 0x01410CB0 +#define I210_I_PHY_ID 0x01410C00 + /* Miscellaneous PHY bit definitions. */ #define PHY_PREAMBLE 0xFFFFFFFF #define PHY_SOF 0x01 diff --git a/drivers/net/fm/t4240.c b/drivers/net/fm/t4240.c index 1eacb22841e..ae5aca4bb42 100644 --- a/drivers/net/fm/t4240.c +++ b/drivers/net/fm/t4240.c @@ -71,6 +71,11 @@ phy_interface_t fman_port_enet_if(enum fm_port port) (is_serdes_configured(XFI_FM1_MAC10)))) return PHY_INTERFACE_MODE_XGMII; + if ((port == FM1_DTSEC9 || port == FM1_DTSEC10) && + ((is_serdes_configured(XFI_FM1_MAC9)) || + (is_serdes_configured(XFI_FM1_MAC10)))) + return PHY_INTERFACE_MODE_XGMII; + if ((port == FM2_10GEC1 || port == FM2_10GEC2) && ((is_serdes_configured(XAUI_FM2_MAC9)) || (is_serdes_configured(XAUI_FM2_MAC10)) || diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index dbf7bf70585..9556536b77b 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_PHY_ATHEROS) += atheros.o obj-$(CONFIG_PHY_BROADCOM) += broadcom.o obj-$(CONFIG_PHY_DAVICOM) += davicom.o obj-$(CONFIG_PHY_ET1011C) += et1011c.o -obj-$(CONFIG_PHY_ICPLUS) += icplus.o obj-$(CONFIG_PHY_LXT) += lxt.o obj-$(CONFIG_PHY_MARVELL) += marvell.o obj-$(CONFIG_PHY_MICREL) += micrel.o diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c deleted file mode 100644 index 597195580b2..00000000000 --- a/drivers/net/phy/icplus.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * ICPlus PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright (c) 2007 Freescale Semiconductor, Inc. - */ -#include <phy.h> - -/* IP101A/G - IP1001 */ -#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ -#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ -#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ -#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ -#define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ -#define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ -#define IP101A_G_IRQ_PIN_USED (1<<15) /* INTR pin used */ -#define IP101A_G_IRQ_DEFAULT IP101A_G_IRQ_PIN_USED - -static int ip1001_config(struct phy_device *phydev) -{ - int c; - - /* Enable Auto Power Saving mode */ - c = phy_read(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2); - if (c < 0) - return c; - c |= IP1001_APS_ON; - c = phy_write(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2, c); - if (c < 0) - return c; - - /* INTR pin used: speed/link/duplex will cause an interrupt */ - c = phy_write(phydev, MDIO_DEVAD_NONE, IP101A_G_IRQ_CONF_STATUS, - IP101A_G_IRQ_DEFAULT); - if (c < 0) - return c; - - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { - /* - * Additional delay (2ns) used to adjust RX clock phase - * at RGMII interface - */ - c = phy_read(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS); - if (c < 0) - return c; - - c |= IP1001_PHASE_SEL_MASK; - c = phy_write(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS, - c); - if (c < 0) - return c; - } - - return 0; -} - -static int ip1001_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - genphy_parse_link(phydev); - - return 0; -} -static struct phy_driver IP1001_driver = { - .name = "ICPlus IP1001", - .uid = 0x02430d90, - .mask = 0x0ffffff0, - .features = PHY_GBIT_FEATURES, - .config = &ip1001_config, - .startup = &ip1001_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_icplus_init(void) -{ - phy_register(&IP1001_driver); - - return 0; -} diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index aac85c4d092..1d6c14f2ade 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -454,9 +454,6 @@ int phy_init(void) #ifdef CONFIG_PHY_ET1011C phy_et1011c_init(); #endif -#ifdef CONFIG_PHY_ICPLUS - phy_icplus_init(); -#endif #ifdef CONFIG_PHY_LXT phy_lxt_init(); #endif diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index c58fe50b720..2b29cd89f84 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -126,7 +126,6 @@ static int cis8204_config(struct phy_device *phydev) genphy_config_aneg(phydev); if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII) || (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) || (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)) phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON, diff --git a/drivers/net/plb2800_eth.c b/drivers/net/plb2800_eth.c deleted file mode 100644 index f869514f295..00000000000 --- a/drivers/net/plb2800_eth.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * PLB2800 internal switch ethernet driver. - * - * (C) Copyright 2003 - * 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/addrspace.h> - - -#define NUM_RX_DESC PKTBUFSRX -#define TOUT_LOOP 1000000 - -#define LONG_REF(addr) (*((volatile unsigned long*)addr)) - -#define CMAC_CRX_CTRL LONG_REF(0xb800c870) -#define CMAC_CTX_CTRL LONG_REF(0xb800c874) -#define SYS_MAC_ADDR_0 LONG_REF(0xb800c878) -#define SYS_MAC_ADDR_1 LONG_REF(0xb800c87c) -#define MIPS_H_MASK LONG_REF(0xB800C810) - -#define MA_LEARN LONG_REF(0xb8008004) -#define DA_LOOKUP LONG_REF(0xb8008008) - -#define CMAC_CRX_CTRL_PD 0x00000001 -#define CMAC_CRX_CTRL_CG 0x00000002 -#define CMAC_CRX_CTRL_PL_SHIFT 2 -#define CMAC_CRIT 0x0 -#define CMAC_NON_CRIT 0x1 -#define MBOX_STAT_ID_SHF 28 -#define MBOX_STAT_CP 0x80000000 -#define MBOX_STAT_MB 0x00000001 -#define EN_MA_LEARN 0x02000000 -#define EN_DA_LKUP 0x01000000 -#define MA_DEST_SHF 11 -#define DA_DEST_SHF 11 -#define DA_STATE_SHF 19 -#define TSTAMP_MS 0x00000000 -#define SW_H_MBOX4_MASK 0x08000000 -#define SW_H_MBOX3_MASK 0x04000000 -#define SW_H_MBOX2_MASK 0x02000000 -#define SW_H_MBOX1_MASK 0x01000000 - -typedef volatile struct { - unsigned int stat; - unsigned int cmd; - unsigned int cnt; - unsigned int adr; -} mailbox_t; - -#define MBOX_REG(mb) ((mailbox_t*)(0xb800c830+(mb<<4))) - -typedef volatile struct { - unsigned int word0; - unsigned int word1; - unsigned int word2; -} mbhdr_t; - -#define MBOX_MEM(mb) ((void*)(0xb800a000+((3-mb)<<11))) - - -static int plb2800_eth_init(struct eth_device *dev, bd_t * bis); -static int plb2800_eth_send(struct eth_device *dev, void *packet, int length); -static int plb2800_eth_recv(struct eth_device *dev); -static void plb2800_eth_halt(struct eth_device *dev); - -static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr); -static unsigned char * plb2800_get_mac_addr(void); - -static int rx_new; -static int mac_addr_set = 0; - - -int plb2800_eth_initialize(bd_t * bis) -{ - struct eth_device *dev; - ulong temp; - -#ifdef DEBUG - printf("Entered plb2800_eth_initialize()\n"); -#endif - - if (!(dev = (struct eth_device *) malloc (sizeof *dev))) - { - printf("Failed to allocate memory\n"); - return -1; - } - memset(dev, 0, sizeof(*dev)); - - sprintf(dev->name, "PLB2800 Switch"); - dev->init = plb2800_eth_init; - dev->halt = plb2800_eth_halt; - dev->send = plb2800_eth_send; - dev->recv = plb2800_eth_recv; - - eth_register(dev); - - /* bug fix */ - *(ulong *)0xb800e800 = 0x838; - - /* Set MBOX ownership */ - temp = CMAC_CRIT << MBOX_STAT_ID_SHF; - MBOX_REG(0)->stat = temp; - MBOX_REG(1)->stat = temp; - - temp = CMAC_NON_CRIT << MBOX_STAT_ID_SHF; - MBOX_REG(2)->stat = temp; - MBOX_REG(3)->stat = temp; - - plb2800_set_mac_addr(dev, plb2800_get_mac_addr()); - - /* Disable all Mbox interrupt */ - temp = MIPS_H_MASK; - temp &= ~ (SW_H_MBOX1_MASK | SW_H_MBOX2_MASK | SW_H_MBOX3_MASK | SW_H_MBOX4_MASK) ; - MIPS_H_MASK = temp; - -#ifdef DEBUG - printf("Leaving plb2800_eth_initialize()\n"); -#endif - - return 0; -} - -static int plb2800_eth_init(struct eth_device *dev, bd_t * bis) -{ -#ifdef DEBUG - printf("Entering plb2800_eth_init()\n"); -#endif - - plb2800_set_mac_addr(dev, dev->enetaddr); - - rx_new = 0; - -#ifdef DEBUG - printf("Leaving plb2800_eth_init()\n"); -#endif - - return 0; -} - - -static int plb2800_eth_send(struct eth_device *dev, void *packet, int length) -{ - int i; - int res = -1; - u32 temp; - mailbox_t * mb = MBOX_REG(0); - char * mem = MBOX_MEM(0); - -#ifdef DEBUG - printf("Entered plb2800_eth_send()\n"); -#endif - - if (length <= 0) - { - printf ("%s: bad packet size: %d\n", dev->name, length); - goto Done; - } - - if (length < 64) - { - length = 64; - } - - temp = CMAC_CRX_CTRL_CG | ((length + 4) << CMAC_CRX_CTRL_PL_SHIFT); - -#ifdef DEBUG - printf("0 mb->stat = 0x%x\n", mb->stat); -#endif - - for(i = 0; mb->stat & (MBOX_STAT_CP | MBOX_STAT_MB); i++) - { - if (i >= TOUT_LOOP) - { - printf("%s: tx buffer not ready\n", dev->name); - printf("1 mb->stat = 0x%x\n", mb->stat); - goto Done; - } - } - - /* For some strange reason, memcpy doesn't work, here! - */ - do - { - int words = (length >> 2) + 1; - unsigned int* dst = (unsigned int*)(mem); - unsigned int* src = (unsigned int*)(packet); - for (i = 0; i < words; i++) - { - *dst = *src; - dst++; - src++; - }; - } while(0); - - CMAC_CRX_CTRL = temp; - mb->cmd = MBOX_STAT_CP; - -#ifdef DEBUG - printf("2 mb->stat = 0x%x\n", mb->stat); -#endif - - res = length; -Done: - -#ifdef DEBUG - printf("Leaving plb2800_eth_send()\n"); -#endif - - return res; -} - - -static int plb2800_eth_recv(struct eth_device *dev) -{ - int length = 0; - mailbox_t * mbox = MBOX_REG(3); - unsigned char * hdr = MBOX_MEM(3); - unsigned int stat; - -#ifdef DEBUG - printf("Entered plb2800_eth_recv()\n"); -#endif - - for (;;) - { - stat = mbox->stat; - - if (!(stat & MBOX_STAT_CP)) - { - break; - } - - length = ((*(hdr + 6) & 0x3f) << 8) + *(hdr + 7); - memcpy((void *)NetRxPackets[rx_new], hdr + 12, length); - - stat &= ~MBOX_STAT_CP; - mbox->stat = stat; -#ifdef DEBUG - { - 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) - { -#ifdef DEBUG - printf("Received %d bytes\n", length); -#endif - NetReceive((void*)(NetRxPackets[rx_new]), - length - 4); - } - else - { -#if 1 - printf("Zero length!!!\n"); -#endif - } - - rx_new = (rx_new + 1) % NUM_RX_DESC; - } - -#ifdef DEBUG - printf("Leaving plb2800_eth_recv()\n"); -#endif - - return length; -} - - -static void plb2800_eth_halt(struct eth_device *dev) -{ -#ifdef DEBUG - printf("Entered plb2800_eth_halt()\n"); -#endif - -#ifdef DEBUG - printf("Leaving plb2800_eth_halt()\n"); -#endif -} - -static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr) -{ - char packet[60]; - ulong temp; - int ix; - - if (mac_addr_set || - NULL == addr || memcmp(addr, "\0\0\0\0\0\0", 6) == 0) - { - return; - } - - /* send one packet through CPU port - * in order to learn system MAC address - */ - - /* Set DA_LOOKUP register */ - temp = EN_MA_LEARN | (0 << DA_STATE_SHF) | (63 << DA_DEST_SHF); - DA_LOOKUP = temp; - - /* Set MA_LEARN register */ - temp = 50 << MA_DEST_SHF; /* static entry */ - MA_LEARN = temp; - - /* set destination address */ - for (ix=0;ix<6;ix++) - packet[ix] = 0xff; - - /* set source address = system MAC address */ - for (ix=0;ix<6;ix++) - packet[6+ix] = addr[ix]; - - /* set type field */ - packet[12]=0xaa; - packet[13]=0x55; - - /* set data field */ - for(ix=14;ix<60;ix++) - packet[ix] = 0x00; - -#ifdef DEBUG - for (ix=0;ix<6;ix++) - printf("mac_addr[%d]=%02X\n", ix, (unsigned char)packet[6+ix]); -#endif - - /* set one packet */ - plb2800_eth_send(dev, packet, sizeof(packet)); - - /* delay for a while */ - for(ix=0;ix<65535;ix++) - temp = ~temp; - - /* Set CMAC_CTX_CTRL register */ - temp = TSTAMP_MS; /* no autocast */ - CMAC_CTX_CTRL = temp; - - /* Set DA_LOOKUP register */ - temp = EN_DA_LKUP; - DA_LOOKUP = temp; - - mac_addr_set = 1; -} - -static unsigned char * plb2800_get_mac_addr(void) -{ - static unsigned char addr[6]; - char *tmp, *end; - int i; - - tmp = getenv ("ethaddr"); - if (NULL == tmp) return NULL; - - for (i=0; i<6; i++) { - addr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0; - if (tmp) - tmp = (*end) ? end+1 : end; - } - - return addr; -} |