Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / net / e1000e / lib.c
index 5f6b171..b0d2a60 100644 (file)
@@ -340,62 +340,34 @@ static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
  *  @hw: pointer to the HW structure
  *  @mc_addr_list: array of multicast addresses to program
  *  @mc_addr_count: number of multicast addresses to program
- *  @rar_used_count: the first RAR register free to program
- *  @rar_count: total number of supported Receive Address Registers
  *
- *  Updates the Receive Address Registers and Multicast Table Array.
+ *  Updates entire Multicast Table Array.
  *  The caller must have a packed mc_addr_list of multicast addresses.
- *  The parameter rar_count will usually be hw->mac.rar_entry_count
- *  unless there are workarounds that change this.
  **/
 void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
-                                       u8 *mc_addr_list, u32 mc_addr_count,
-                                       u32 rar_used_count, u32 rar_count)
+                                       u8 *mc_addr_list, u32 mc_addr_count)
 {
-       u32 i;
-       u32 *mcarray = kzalloc(hw->mac.mta_reg_count * sizeof(u32), GFP_ATOMIC);
+       u32 hash_value, hash_bit, hash_reg;
+       int i;
 
-       if (!mcarray) {
-               printk(KERN_ERR "multicast array memory allocation failed\n");
-               return;
-       }
+       /* clear mta_shadow */
+       memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
 
-       /*
-        * Load the first set of multicast addresses into the exact
-        * filters (RAR).  If there are not enough to fill the RAR
-        * array, clear the filters.
-        */
-       for (i = rar_used_count; i < rar_count; i++) {
-               if (mc_addr_count) {
-                       e1000e_rar_set(hw, mc_addr_list, i);
-                       mc_addr_count--;
-                       mc_addr_list += ETH_ALEN;
-               } else {
-                       E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0);
-                       e1e_flush();
-                       E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0);
-                       e1e_flush();
-               }
-       }
-
-       /* Load any remaining multicast addresses into the hash table. */
-       for (; mc_addr_count > 0; mc_addr_count--) {
-               u32 hash_value, hash_reg, hash_bit, mta;
+       /* update mta_shadow from mc_addr_list */
+       for (i = 0; (u32) i < mc_addr_count; i++) {
                hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
-               e_dbg("Hash value = 0x%03X\n", hash_value);
+
                hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
                hash_bit = hash_value & 0x1F;
-               mta = (1 << hash_bit);
-               mcarray[hash_reg] |= mta;
-               mc_addr_list += ETH_ALEN;
-       }
 
-       /* write the hash table completely */
-       for (i = 0; i < hw->mac.mta_reg_count; i++)
-               E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, mcarray[i]);
+               hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
+               mc_addr_list += (ETH_ALEN);
+       }
 
+       /* replace the entire MTA table */
+       for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
+               E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
        e1e_flush();
-       kfree(mcarray);
 }
 
 /**
@@ -675,7 +647,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
                                if (!(rxcw & E1000_RXCW_IV)) {
                                        mac->serdes_has_link = true;
                                        e_dbg("SERDES: Link up - autoneg "
-                                          "completed sucessfully.\n");
+                                          "completed successfully.\n");
                                } else {
                                        mac->serdes_has_link = false;
                                        e_dbg("SERDES: Link down - invalid"
@@ -1290,24 +1262,21 @@ s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *dup
        u32 status;
 
        status = er32(STATUS);
-       if (status & E1000_STATUS_SPEED_1000) {
+       if (status & E1000_STATUS_SPEED_1000)
                *speed = SPEED_1000;
-               e_dbg("1000 Mbs, ");
-       } else if (status & E1000_STATUS_SPEED_100) {
+       else if (status & E1000_STATUS_SPEED_100)
                *speed = SPEED_100;
-               e_dbg("100 Mbs, ");
-       } else {
+       else
                *speed = SPEED_10;
-               e_dbg("10 Mbs, ");
-       }
 
-       if (status & E1000_STATUS_FD) {
+       if (status & E1000_STATUS_FD)
                *duplex = FULL_DUPLEX;
-               e_dbg("Full Duplex\n");
-       } else {
+       else
                *duplex = HALF_DUPLEX;
-               e_dbg("Half Duplex\n");
-       }
+
+       e_dbg("%u Mbps, %s Duplex\n",
+             *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10,
+             *duplex == FULL_DUPLEX ? "Full" : "Half");
 
        return 0;
 }