]> git.sur5r.net Git - u-boot/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-net
authorWolfgang Denk <wd@denx.de>
Fri, 21 Aug 2009 21:03:58 +0000 (23:03 +0200)
committerWolfgang Denk <wd@denx.de>
Fri, 21 Aug 2009 21:03:58 +0000 (23:03 +0200)
drivers/net/e1000.c
drivers/net/kirkwood_egiga.c
drivers/net/kirkwood_egiga.h
drivers/net/tsec.c

index 777783a91bf192664f5180e63ef005a7ce7d4959..b8dd9f2fe4636f0d474b3fb296876de49a76568f 100644 (file)
@@ -46,8 +46,7 @@ tested on both gig copper and gig fiber boards
 
 #define TOUT_LOOP   100000
 
-#undef virt_to_bus
-#define        virt_to_bus(x)  ((unsigned long)x)
+#define virt_to_bus(devno, v)  pci_virt_to_mem(devno, (void *) (v))
 #define bus_to_phys(devno, a)  pci_mem_to_phys(devno, a)
 #define mdelay(n)      udelay((n)*1000)
 
@@ -357,7 +356,7 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
        struct e1000_eeprom_info *eeprom = &hw->eeprom;
        uint32_t eecd, i = 0;
 
-       DEBUGOUT();
+       DEBUGFUNC();
 
        if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
                return -E1000_ERR_SWFW_SYNC;
@@ -418,7 +417,7 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw)
        int32_t ret_val = E1000_SUCCESS;
        uint16_t eeprom_size;
 
-       DEBUGOUT();
+       DEBUGFUNC();
 
        switch (hw->mac_type) {
        case e1000_82542_rev2_0:
@@ -2355,7 +2354,7 @@ e1000_copper_link_igp_setup(struct e1000_hw *hw)
        int32_t ret_val;
        uint16_t phy_data;
 
-       DEBUGOUT();
+       DEBUGFUNC();
 
        if (hw->phy_reset_disable)
                return E1000_SUCCESS;
@@ -5017,7 +5016,7 @@ e1000_transmit(struct eth_device *nic, volatile void *packet, int length)
        txp = tx_base + tx_tail;
        tx_tail = (tx_tail + 1) % 8;
 
-       txp->buffer_addr = cpu_to_le64(virt_to_bus(packet));
+       txp->buffer_addr = cpu_to_le64(virt_to_bus(hw->pdev, packet));
        txp->lower.data = cpu_to_le32(hw->txd_cmd | length);
        txp->upper.data = 0;
        E1000_WRITE_REG(hw, TDT, tx_tail);
@@ -5145,6 +5144,8 @@ e1000_initialize(bd_t * bis)
        int idx = 0;
        u32 PciCommandWord;
 
+       DEBUGFUNC();
+
        while (1) {             /* Find PCI device(s) */
                if ((devno = pci_find_devices(supported, idx++)) < 0) {
                        break;
@@ -5170,7 +5171,6 @@ e1000_initialize(bd_t * bis)
                hw = (struct e1000_hw *) malloc(sizeof (*hw));
                hw->pdev = devno;
                nic->priv = hw;
-               nic->iobase = bus_to_phys(devno, iobase);
 
                sprintf(nic->name, "e1000#%d", card_number);
 
@@ -5180,7 +5180,8 @@ e1000_initialize(bd_t * bis)
                hw->autoneg_failed = 0;
                hw->autoneg = 1;
                hw->get_link_status = TRUE;
-               hw->hw_addr = (typeof(hw->hw_addr)) iobase;
+               hw->hw_addr =
+                       pci_map_bar(devno, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
                hw->mac_type = e1000_undefined;
 
                /* MAC and Phy settings */
index f31fefcb09f7e47441e4b8ed39af52f5be213477..479035d552052b7e8a0e1f168063eb45a6dd2a3b 100644 (file)
@@ -38,6 +38,8 @@
 #include <asm/arch/kirkwood.h>
 #include "kirkwood_egiga.h"
 
+#define KIRKWOOD_PHY_ADR_REQUEST 0xee
+
 /*
  * smi_reg_read - miiphy_read callback function.
  *
@@ -52,7 +54,8 @@ static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
        u32 timeout;
 
        /* Phyadr read request */
-       if (phy_adr == 0xEE && reg_ofs == 0xEE) {
+       if (phy_adr == KIRKWOOD_PHY_ADR_REQUEST &&
+                       reg_ofs == KIRKWOOD_PHY_ADR_REQUEST) {
                /* */
                *data = (u16) (KWGBEREG_RD(regs->phyadr) & PHYADR_MASK);
                return 0;
@@ -127,7 +130,8 @@ static int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
        u32 timeout;
 
        /* Phyadr write request*/
-       if (phy_adr == 0xEE && reg_ofs == 0xEE) {
+       if (phy_adr == KIRKWOOD_PHY_ADR_REQUEST &&
+                       reg_ofs == KIRKWOOD_PHY_ADR_REQUEST) {
                KWGBEREG_WR(regs->phyadr, data);
                return 0;
        }
@@ -396,6 +400,7 @@ static int kwgbe_init(struct eth_device *dev)
 {
        struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
        struct kwgbe_registers *regs = dkwgbe->regs;
+       int i;
 
        /* setup RX rings */
        kwgbe_init_rx_desc_ring(dkwgbe);
@@ -443,12 +448,20 @@ static int kwgbe_init(struct eth_device *dev)
 
 #if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \
         && defined (CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
-       u16 phyadr;
-       miiphy_read(dev->name, 0xEE, 0xEE, &phyadr);
-       if (!miiphy_link(dev->name, phyadr)) {
-               printf("%s: No link on %s\n", __FUNCTION__, dev->name);
-               return -1;
+       /* Wait up to 5s for the link status */
+       for (i = 0; i < 5; i++) {
+               u16 phyadr;
+
+               miiphy_read(dev->name, KIRKWOOD_PHY_ADR_REQUEST,
+                               KIRKWOOD_PHY_ADR_REQUEST, &phyadr);
+               /* Return if we get link up */
+               if (miiphy_link(dev->name, phyadr))
+                       return 0;
+               udelay(1000000);
        }
+
+       printf("No link on %s\n", dev->name);
+       return -1;
 #endif
        return 0;
 }
@@ -487,18 +500,26 @@ static int kwgbe_send(struct eth_device *dev, volatile void *dataptr,
        struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
        struct kwgbe_registers *regs = dkwgbe->regs;
        struct kwgbe_txdesc *p_txdesc = dkwgbe->p_txdesc;
+       void *p = (void *)dataptr;
        u32 cmd_sts;
 
+       /* Copy buffer if it's misaligned */
        if ((u32) dataptr & 0x07) {
-               printf("Err..(%s) xmit dataptr not 64bit aligned\n",
-                       __FUNCTION__);
-               return -1;
+               if (datasize > PKTSIZE_ALIGN) {
+                       printf("Non-aligned data too large (%d)\n",
+                                       datasize);
+                       return -1;
+               }
+
+               memcpy(dkwgbe->p_aligned_txbuf, p, datasize);
+               p = dkwgbe->p_aligned_txbuf;
        }
+
        p_txdesc->cmd_sts = KWGBE_ZERO_PADDING | KWGBE_GEN_CRC;
        p_txdesc->cmd_sts |= KWGBE_TX_FIRST_DESC | KWGBE_TX_LAST_DESC;
        p_txdesc->cmd_sts |= KWGBE_BUFFER_OWNED_BY_DMA;
        p_txdesc->cmd_sts |= KWGBE_TX_EN_INTERRUPT;
-       p_txdesc->buf_ptr = (u8 *) dataptr;
+       p_txdesc->buf_ptr = (u8 *) p;
        p_txdesc->byte_cnt = datasize;
 
        /* Apply send command using zeroth RXUQ */
@@ -615,8 +636,13 @@ int kirkwood_egiga_initialize(bd_t * bis)
                                                        * PKTSIZE_ALIGN + 1)))
                        goto error3;
 
+               if (!(dkwgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN)))
+                       goto error4;
+
                if (!(dkwgbe->p_txdesc = (struct kwgbe_txdesc *)
                      memalign(PKTALIGN, sizeof(struct kwgbe_txdesc) + 1))) {
+                       free(dkwgbe->p_aligned_txbuf);
+                     error4:
                        free(dkwgbe->p_rxbuf);
                      error3:
                        free(dkwgbe->p_rxdesc);
@@ -670,7 +696,8 @@ int kirkwood_egiga_initialize(bd_t * bis)
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
                miiphy_register(dev->name, smi_reg_read, smi_reg_write);
                /* Set phy address of the port */
-               miiphy_write(dev->name, 0xEE, 0xEE, PHY_BASE_ADR + devnum);
+               miiphy_write(dev->name, KIRKWOOD_PHY_ADR_REQUEST,
+                               KIRKWOOD_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum);
 #endif
        }
        return 0;
index 9c893d131831164ae68ce7f92c0bbd69d389cab5..16d52141ed1b35c6cbf5698d6a851369c076334b 100644 (file)
@@ -499,6 +499,7 @@ struct kwgbe_device {
        struct kwgbe_rxdesc *p_rxdesc;
        struct kwgbe_rxdesc *p_rxdesc_curr;
        u8 *p_rxbuf;
+       u8 *p_aligned_txbuf;
 };
 
 #endif /* __EGIGA_H__ */
index a9ba68399a1545a583543d6a48515a99f051a1e4..9c9fd377c94798624b46d7b74c5c47db95848835 100644 (file)
@@ -356,8 +356,8 @@ uint mii_cr_init(uint mii_reg, struct tsec_private * priv)
                return MIIM_CR_INIT;
 }
 
-/* Parse the status register for link, and then do
- * auto-negotiation
+/*
+ * Wait for auto-negotiation to complete, then determine link
  */
 uint mii_parse_sr(uint mii_reg, struct tsec_private * priv)
 {
@@ -366,8 +366,7 @@ uint mii_parse_sr(uint mii_reg, struct tsec_private * priv)
         * (ie - we're capable and it's not done)
         */
        mii_reg = read_phy_reg(priv, MIIM_STATUS);
-       if ((mii_reg & MIIM_STATUS_LINK) && (mii_reg & PHY_BMSR_AUTN_ABLE)
-           && !(mii_reg & PHY_BMSR_AUTN_COMP)) {
+       if ((mii_reg & PHY_BMSR_AUTN_ABLE) && !(mii_reg & PHY_BMSR_AUTN_COMP)) {
                int i = 0;
 
                puts("Waiting for PHY auto negotiation to complete");
@@ -388,15 +387,15 @@ uint mii_parse_sr(uint mii_reg, struct tsec_private * priv)
                        mii_reg = read_phy_reg(priv, MIIM_STATUS);
                }
                puts(" done\n");
-               priv->link = 1;
+
+               /* Link status bit is latched low, read it again */
+               mii_reg = read_phy_reg(priv, MIIM_STATUS);
+
                udelay(500000); /* another 500 ms (results in faster booting) */
-       } else {
-               if (mii_reg & MIIM_STATUS_LINK)
-                       priv->link = 1;
-               else
-                       priv->link = 0;
        }
 
+       priv->link = mii_reg & MIIM_STATUS_LINK ? 1 : 0;
+
        return 0;
 }