OSDN Git Service

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net...
authorDavid S. Miller <davem@davemloft.net>
Wed, 22 Aug 2012 21:23:43 +0000 (14:23 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 22 Aug 2012 21:23:43 +0000 (14:23 -0700)
Jeff Kirsher says:

====================
This series contains updates to ethtool.h, e1000, e1000e, and igb to
implement MDI/MDIx control.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
1  2 
drivers/net/ethernet/intel/igb/igb_ethtool.c
drivers/net/ethernet/intel/igb/igb_main.c

@@@ -198,6 -198,19 +198,19 @@@ static int igb_get_settings(struct net_
        }
  
        ecmd->autoneg = hw->mac.autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+       /* MDI-X => 2; MDI =>1; Invalid =>0 */
+       if (hw->phy.media_type == e1000_media_type_copper)
+               ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X :
+                                                     ETH_TP_MDI;
+       else
+               ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
+       if (hw->phy.mdix == AUTO_ALL_MODES)
+               ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
+       else
+               ecmd->eth_tp_mdix_ctrl = hw->phy.mdix;
        return 0;
  }
  
@@@ -209,11 -222,27 +222,27 @@@ static int igb_set_settings(struct net_
        /* When SoL/IDER sessions are active, autoneg/speed/duplex
         * cannot be changed */
        if (igb_check_reset_block(hw)) {
 -              dev_err(&adapter->pdev->dev, "Cannot change link "
 -                      "characteristics when SoL/IDER is active.\n");
 +              dev_err(&adapter->pdev->dev,
 +                      "Cannot change link characteristics when SoL/IDER is active.\n");
                return -EINVAL;
        }
  
+       /*
+        * MDI setting is only allowed when autoneg enabled because
+        * some hardware doesn't allow MDI setting when speed or
+        * duplex is forced.
+        */
+       if (ecmd->eth_tp_mdix_ctrl) {
+               if (hw->phy.media_type != e1000_media_type_copper)
+                       return -EOPNOTSUPP;
+               if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
+                   (ecmd->autoneg != AUTONEG_ENABLE)) {
+                       dev_err(&adapter->pdev->dev, "forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
+                       return -EINVAL;
+               }
+       }
        while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
                msleep(1);
  
                        hw->fc.requested_mode = e1000_fc_default;
        } else {
                u32 speed = ethtool_cmd_speed(ecmd);
+               /* calling this overrides forced MDI setting */
                if (igb_set_spd_dplx(adapter, speed, ecmd->duplex)) {
                        clear_bit(__IGB_RESETTING, &adapter->state);
                        return -EINVAL;
                }
        }
  
+       /* MDI-X => 2; MDI => 1; Auto => 3 */
+       if (ecmd->eth_tp_mdix_ctrl) {
+               /*
+                * fix up the value for auto (3 => 0) as zero is mapped
+                * internally to auto
+                */
+               if (ecmd->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
+                       hw->phy.mdix = AUTO_ALL_MODES;
+               else
+                       hw->phy.mdix = ecmd->eth_tp_mdix_ctrl;
+       }
        /* reset the link */
        if (netif_running(adapter->netdev)) {
                igb_down(adapter);
@@@ -1089,8 -1131,8 +1131,8 @@@ static bool reg_pattern_test(struct igb
                wr32(reg, (_test[pat] & write));
                val = rd32(reg) & mask;
                if (val != (_test[pat] & write & mask)) {
 -                      dev_err(&adapter->pdev->dev, "pattern test reg %04X "
 -                              "failed: got 0x%08X expected 0x%08X\n",
 +                      dev_err(&adapter->pdev->dev,
 +                              "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n",
                                reg, val, (_test[pat] & write & mask));
                        *data = reg;
                        return 1;
@@@ -1108,8 -1150,8 +1150,8 @@@ static bool reg_set_and_check(struct ig
        wr32(reg, write & mask);
        val = rd32(reg);
        if ((write & mask) != (val & mask)) {
 -              dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:"
 -                      " got 0x%08X expected 0x%08X\n", reg,
 +              dev_err(&adapter->pdev->dev,
 +                      "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg,
                        (val & mask), (write & mask));
                *data = reg;
                return 1;
@@@ -1171,9 -1213,8 +1213,9 @@@ static int igb_reg_test(struct igb_adap
        wr32(E1000_STATUS, toggle);
        after = rd32(E1000_STATUS) & toggle;
        if (value != after) {
 -              dev_err(&adapter->pdev->dev, "failed STATUS register test "
 -                      "got: 0x%08X expected: 0x%08X\n", after, value);
 +              dev_err(&adapter->pdev->dev,
 +                      "failed STATUS register test got: 0x%08X expected: 0x%08X\n",
 +                      after, value);
                *data = 1;
                return 1;
        }
@@@ -1498,9 -1539,6 +1540,9 @@@ static int igb_integrated_phy_loopback(
                break;
        }
  
 +      /* add small delay to avoid loopback test failure */
 +      msleep(50);
 +
        /* force 1000, set loopback */
        igb_write_phy_reg(hw, PHY_CONTROL, 0x4140);
  
@@@ -1781,14 -1819,16 +1823,14 @@@ static int igb_loopback_test(struct igb
         * sessions are active */
        if (igb_check_reset_block(&adapter->hw)) {
                dev_err(&adapter->pdev->dev,
 -                      "Cannot do PHY loopback test "
 -                      "when SoL/IDER is active.\n");
 +                      "Cannot do PHY loopback test when SoL/IDER is active.\n");
                *data = 0;
                goto out;
        }
        if ((adapter->hw.mac.type == e1000_i210)
 -              || (adapter->hw.mac.type == e1000_i210)) {
 +              || (adapter->hw.mac.type == e1000_i211)) {
                dev_err(&adapter->pdev->dev,
 -                      "Loopback test not supported "
 -                      "on this part at this time.\n");
 +                      "Loopback test not supported on this part at this time.\n");
                *data = 0;
                goto out;
        }
@@@ -462,10 -462,10 +462,10 @@@ static void igb_dump(struct igb_adapte
                                (u64)buffer_info->time_stamp,
                                buffer_info->skb, next_desc);
  
 -                      if (netif_msg_pktdata(adapter) && buffer_info->dma != 0)
 +                      if (netif_msg_pktdata(adapter) && buffer_info->skb)
                                print_hex_dump(KERN_INFO, "",
                                        DUMP_PREFIX_ADDRESS,
 -                                      16, 1, phys_to_virt(buffer_info->dma),
 +                                      16, 1, buffer_info->skb->data,
                                        buffer_info->length, true);
                }
        }
@@@ -547,17 -547,18 +547,17 @@@ rx_ring_summary
                                        (u64)buffer_info->dma,
                                        buffer_info->skb, next_desc);
  
 -                              if (netif_msg_pktdata(adapter)) {
 +                              if (netif_msg_pktdata(adapter) &&
 +                                  buffer_info->dma && buffer_info->skb) {
                                        print_hex_dump(KERN_INFO, "",
 -                                              DUMP_PREFIX_ADDRESS,
 -                                              16, 1,
 -                                              phys_to_virt(buffer_info->dma),
 -                                              IGB_RX_HDR_LEN, true);
 +                                                DUMP_PREFIX_ADDRESS,
 +                                                16, 1, buffer_info->skb->data,
 +                                                IGB_RX_HDR_LEN, true);
                                        print_hex_dump(KERN_INFO, "",
                                          DUMP_PREFIX_ADDRESS,
                                          16, 1,
 -                                        phys_to_virt(
 -                                          buffer_info->page_dma +
 -                                          buffer_info->page_offset),
 +                                        page_address(buffer_info->page) +
 +                                                    buffer_info->page_offset,
                                          PAGE_SIZE/2, true);
                                }
                        }
@@@ -6675,6 -6676,10 +6675,10 @@@ int igb_set_spd_dplx(struct igb_adapte
        default:
                goto err_inval;
        }
+       /* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
+       adapter->hw.phy.mdix = AUTO_ALL_MODES;
        return 0;
  
  err_inval: