vserver 1.9.5.x5
[linux-2.6.git] / drivers / net / e1000 / e1000_ethtool.c
index 2e4544e..e4061ff 100644 (file)
@@ -249,7 +249,8 @@ e1000_set_pauseparam(struct net_device *netdev,
                        e1000_reset(adapter);
        }
        else
-               return e1000_force_mac_fc(hw);
+               return ((hw->media_type == e1000_media_type_fiber) ?
+                       e1000_setup_link(hw) : e1000_force_mac_fc(hw));
        
        return 0;
 }
@@ -592,6 +593,9 @@ e1000_set_ringparam(struct net_device *netdev,
        tx_old = adapter->tx_ring;
        rx_old = adapter->rx_ring;
 
+       if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+               return -EINVAL;
+
        if(netif_running(adapter->netdev))
                e1000_down(adapter);
 
@@ -637,7 +641,6 @@ err_setup_rx:
        return err;
 }
 
-
 #define REG_PATTERN_TEST(R, M, W)                                              \
 {                                                                              \
        uint32_t pat, value;                                                   \
@@ -773,7 +776,7 @@ static int
 e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
 {
        struct net_device *netdev = adapter->netdev;
-       uint32_t icr, mask, i=0, shared_int = TRUE;
+       uint32_t mask, i=0, shared_int = TRUE;
        uint32_t irq = adapter->pdev->irq;
 
        *data = 0;
@@ -781,7 +784,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
        /* Hook up test interrupt handler just for this test */
        if(!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) {
                shared_int = FALSE;
-       } else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ, netdev->name, netdev)){
+       } else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ, 
+                       netdev->name, netdev)){
                *data = 1;
                return -1;
        }
@@ -790,21 +794,6 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
        E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF);
        msec_delay(10);
 
-       /* Interrupts are disabled, so read interrupt cause
-        * register (icr) twice to verify that there are no interrupts
-        * pending.  icr is clear on read.
-        */
-       icr = E1000_READ_REG(&adapter->hw, ICR);
-       icr = E1000_READ_REG(&adapter->hw, ICR);
-
-       if(icr != 0) {
-               /* if icr is non-zero, there is no point
-                * running other interrupt tests.
-                */
-               *data = 2;
-               i = 10;
-       }
-
        /* Test each interrupt */
        for(; i < 10; i++) {
 
@@ -853,8 +842,10 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
                         * test failed.
                         */
                        adapter->test_icr = 0;
-                       E1000_WRITE_REG(&adapter->hw, IMC, ~mask);
-                       E1000_WRITE_REG(&adapter->hw, ICS, ~mask);
+                       E1000_WRITE_REG(&adapter->hw, IMC, 
+                                       (~mask & 0x00007FFF));
+                       E1000_WRITE_REG(&adapter->hw, ICS, 
+                                       (~mask & 0x00007FFF));
                        msec_delay(10);
 
                        if(adapter->test_icr) {
@@ -1017,8 +1008,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter)
                struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
                struct sk_buff *skb;
 
-               if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
-                                    GFP_KERNEL))) {
+               if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, 
+                               GFP_KERNEL))) {
                        ret_val = 6;
                        goto err_nomem;
                }
@@ -1333,10 +1324,17 @@ e1000_run_loopback_test(struct e1000_adapter *adapter)
 
        msec_delay(200);
 
-       pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[0].dma,
-                           rxdr->buffer_info[0].length, PCI_DMA_FROMDEVICE);
+       i = 0;
+       do {
+               pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[i].dma,
+                                           rxdr->buffer_info[i].length,
+                                           PCI_DMA_FROMDEVICE);
+
+               if (!e1000_check_lbtest_frame(rxdr->buffer_info[i++].skb, 1024))
+                       return 0;
+       } while (i < 64);
 
-       return e1000_check_lbtest_frame(rxdr->buffer_info[0].skb, 1024);
+       return 13;
 }
 
 static int
@@ -1355,10 +1353,27 @@ static int
 e1000_link_test(struct e1000_adapter *adapter, uint64_t *data)
 {
        *data = 0;
-       e1000_check_for_link(&adapter->hw);
 
-       if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
-               *data = 1;
+       if (adapter->hw.media_type == e1000_media_type_internal_serdes) {
+               int i = 0;
+               adapter->hw.serdes_link_down = TRUE;
+
+               /* on some blade server designs link establishment */
+               /* could take as long as 2-3 minutes.              */
+               do {
+                       e1000_check_for_link(&adapter->hw);
+                       if (adapter->hw.serdes_link_down == FALSE)
+                               return *data;
+                       msec_delay(20);
+               } while (i++ < 3750);
+
+               *data = 1; 
+       } else {
+               e1000_check_for_link(&adapter->hw);
+
+               if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
+                       *data = 1;
+               }
        }
        return *data;
 }
@@ -1442,6 +1457,8 @@ e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
        case E1000_DEV_ID_82543GC_COPPER:
        case E1000_DEV_ID_82544EI_FIBER:
        case E1000_DEV_ID_82546EB_QUAD_COPPER:
+       case E1000_DEV_ID_82545EM_FIBER:
+       case E1000_DEV_ID_82545EM_COPPER:
                wol->supported = 0;
                wol->wolopts   = 0;
                return;
@@ -1485,6 +1502,8 @@ e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
        case E1000_DEV_ID_82543GC_COPPER:
        case E1000_DEV_ID_82544EI_FIBER:
        case E1000_DEV_ID_82546EB_QUAD_COPPER:
+       case E1000_DEV_ID_82545EM_FIBER:
+       case E1000_DEV_ID_82545EM_COPPER:
                return wol->wolopts ? -EOPNOTSUPP : 0;
 
        case E1000_DEV_ID_82546EB_FIBER:
@@ -1549,9 +1568,7 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
        e1000_setup_led(&adapter->hw);
        mod_timer(&adapter->blink_timer, jiffies);
 
-       set_current_state(TASK_INTERRUPTIBLE);
-
-       schedule_timeout(data * HZ);
+       msleep_interruptible(data * 1000);
        del_timer_sync(&adapter->blink_timer);
        e1000_led_off(&adapter->hw);
        clear_bit(E1000_LED_ON, &adapter->led_status);
@@ -1649,7 +1666,7 @@ struct ethtool_ops e1000_ethtool_ops = {
        .get_ethtool_stats      = e1000_get_ethtool_stats,
 };
 
-void set_ethtool_ops(struct net_device *netdev)
+void e1000_set_ethtool_ops(struct net_device *netdev)
 {
        SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
 }