]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/atl1/atl1_hw.c
Merge branches 'omap1-upstream' and 'omap2-upstream' into devel
[linux-2.6-omap-h63xx.git] / drivers / net / atl1 / atl1_hw.c
index 08b2d785469d13ae524b60d3092b676900980da5..9d3bd22e3a82f96f289a462b60a9503954cb49a8 100644 (file)
@@ -2,20 +2,20 @@
  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
  * Copyright(c) 2006 Chris Snook <csnook@redhat.com>
  * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
- * 
+ *
  * Derived from Intel e1000 driver
  * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- * 
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
  * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
- * 
+ *
  * 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.
  */
 s32 atl1_reset_hw(struct atl1_hw *hw)
 {
+       struct pci_dev *pdev = hw->back->pdev;
        u32 icr;
        int i;
 
-       /* 
+       /*
         * Clear Interrupt mask to stop board from generating
-        * interrupts & Clear any pending interrupt events 
+        * interrupts & Clear any pending interrupt events
         */
        /*
         * iowrite32(0, hw->hw_addr + REG_IMR);
@@ -74,7 +75,7 @@ s32 atl1_reset_hw(struct atl1_hw *hw)
        }
 
        if (icr) {
-               printk (KERN_DEBUG "icr = %x\n", icr); 
+               dev_dbg(&pdev->dev, "ICR = 0x%x\n", icr);
                return icr;
        }
 
@@ -136,8 +137,8 @@ s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
        int i;
 
        val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
-               MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
-               MDIO_CLK_SEL_SHIFT;
+               MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
+               MDIO_CLK_SEL_SHIFT;
        iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
        ioread32(hw->hw_addr + REG_MDIO_CTRL);
 
@@ -204,7 +205,7 @@ static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
 
 /*
  * get_permanent_address
- * return 0 if get valid mac address, 
+ * return 0 if get valid mac address,
  */
 static int atl1_get_permanent_address(struct atl1_hw *hw)
 {
@@ -243,14 +244,8 @@ static int atl1_get_permanent_address(struct atl1_hw *hw)
                        i += 4;
                }
 
-/*
- * The following 2 lines are the Attansic originals.  Saving for posterity.
- *             *(u32 *) & eth_addr[2] = LONGSWAP(addr[0]);
- *             *(u16 *) & eth_addr[0] = SHORTSWAP(*(u16 *) & addr[1]);
- */
-               *(u32 *) & eth_addr[2] = swab32(addr[0]);
-               *(u16 *) & eth_addr[0] = swab16(*(u16 *) & addr[1]);
-
+               *(u32 *) &eth_addr[2] = swab32(addr[0]);
+               *(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
                if (is_valid_ether_addr(eth_addr)) {
                        memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
                        return 0;
@@ -281,22 +276,33 @@ static int atl1_get_permanent_address(struct atl1_hw *hw)
                i += 4;
        }
 
-/*
- * The following 2 lines are the Attansic originals.  Saving for posterity.
- *     *(u32 *) & eth_addr[2] = LONGSWAP(addr[0]);
- *     *(u16 *) & eth_addr[0] = SHORTSWAP(*(u16 *) & addr[1]);
- */
-       *(u32 *) & eth_addr[2] = swab32(addr[0]);
-       *(u16 *) & eth_addr[0] = swab16(*(u16 *) & addr[1]);
+       *(u32 *) &eth_addr[2] = swab32(addr[0]);
+       *(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
        if (is_valid_ether_addr(eth_addr)) {
                memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
                return 0;
        }
+
+       /*
+        * On some motherboards, the MAC address is written by the
+        * BIOS directly to the MAC register during POST, and is
+        * not stored in eeprom.  If all else thus far has failed
+        * to fetch the permanent MAC address, try reading it directly.
+        */
+       addr[0] = ioread32(hw->hw_addr + REG_MAC_STA_ADDR);
+       addr[1] = ioread16(hw->hw_addr + (REG_MAC_STA_ADDR + 4));
+       *(u32 *) &eth_addr[2] = swab32(addr[0]);
+       *(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
+       if (is_valid_ether_addr(eth_addr)) {
+               memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
+               return 0;
+       }
+
        return 1;
 }
 
 /*
- * Reads the adapter's MAC address from the EEPROM 
+ * Reads the adapter's MAC address from the EEPROM
  * hw - Struct containing variables accessed by shared code
  */
 s32 atl1_read_mac_addr(struct atl1_hw *hw)
@@ -329,7 +335,6 @@ u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
        int i;
 
        crc32 = ether_crc_le(6, mc_addr);
-       crc32 = ~crc32;
        for (i = 0; i < 32; i++)
                value |= (((crc32 >> i) & 1) << (31 - i));
 
@@ -357,7 +362,7 @@ void atl1_hash_set(struct atl1_hw *hw, u32 hash_value)
         */
        hash_reg = (hash_value >> 31) & 0x1;
        hash_bit = (hash_value >> 26) & 0x1F;
-       mta = ioread32((hw + REG_RX_HASH_TABLE) + (hash_reg << 2));
+       mta = ioread32((hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
        mta |= (1 << hash_bit);
        iowrite32(mta, (hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
 }
@@ -433,6 +438,7 @@ s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
  */
 static s32 atl1_phy_reset(struct atl1_hw *hw)
 {
+       struct pci_dev *pdev = hw->back->pdev;
        s32 ret_val;
        u16 phy_data;
 
@@ -464,8 +470,7 @@ static s32 atl1_phy_reset(struct atl1_hw *hw)
                u32 val;
                int i;
                /* pcie serdes link may be down! */
-               printk(KERN_DEBUG "%s: autoneg caused pcie phy link down\n", 
-                       atl1_driver_name);
+               dev_dbg(&pdev->dev, "pcie phy link down\n");
 
                for (i = 0; i < 25; i++) {
                        msleep(1);
@@ -475,9 +480,7 @@ static s32 atl1_phy_reset(struct atl1_hw *hw)
                }
 
                if ((val & (MDIO_START | MDIO_BUSY)) != 0) {
-                       printk(KERN_WARNING 
-                               "%s: pcie link down at least for 25ms\n", 
-                               atl1_driver_name);
+                       dev_warn(&pdev->dev, "pcie link down at least 25ms\n");
                        return ret_val;
                }
        }
@@ -567,6 +570,7 @@ s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw)
  */
 static s32 atl1_setup_link(struct atl1_hw *hw)
 {
+       struct pci_dev *pdev = hw->back->pdev;
        s32 ret_val;
 
        /*
@@ -577,15 +581,13 @@ static s32 atl1_setup_link(struct atl1_hw *hw)
         */
        ret_val = atl1_phy_setup_autoneg_adv(hw);
        if (ret_val) {
-               printk(KERN_DEBUG "%s: error setting up autonegotiation\n", 
-                       atl1_driver_name);
+               dev_dbg(&pdev->dev, "error setting up autonegotiation\n");
                return ret_val;
        }
        /* SW.Reset , En-Auto-Neg if needed */
        ret_val = atl1_phy_reset(hw);
        if (ret_val) {
-               printk(KERN_DEBUG "%s: error resetting the phy\n", 
-                       atl1_driver_name);
+               dev_dbg(&pdev->dev, "error resetting phy\n");
                return ret_val;
        }
        hw->phy_configured = true;
@@ -601,7 +603,7 @@ static struct atl1_spi_flash_dev flash_table[] = {
 
 static void atl1_init_flash_opcode(struct atl1_hw *hw)
 {
-       if (hw->flash_vendor >= sizeof(flash_table) / sizeof(flash_table[0]))
+       if (hw->flash_vendor >= ARRAY_SIZE(flash_table))
                hw->flash_vendor = 0;   /* ATMEL */
 
        /* Init OP table */
@@ -627,7 +629,7 @@ static void atl1_init_flash_opcode(struct atl1_hw *hw)
  * Performs basic configuration of the adapter.
  * hw - Struct containing variables accessed by shared code
  * Assumes that the controller has previously been reset and is in a
- * post-reset uninitialized state. Initializes multicast table, 
+ * post-reset uninitialized state. Initializes multicast table,
  * and  Calls routines to setup link
  * Leaves the transmit and receive units disabled and uninitialized.
  */
@@ -665,6 +667,7 @@ s32 atl1_init_hw(struct atl1_hw *hw)
  */
 s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
 {
+       struct pci_dev *pdev = hw->back->pdev;
        s32 ret_val;
        u16 phy_data;
 
@@ -687,8 +690,7 @@ s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
                *speed = SPEED_10;
                break;
        default:
-               printk(KERN_DEBUG "%s: error getting speed\n", 
-                       atl1_driver_name);
+               dev_dbg(&pdev->dev, "error getting speed\n");
                return ATL1_ERR_PHY_SPEED;
                break;
        }