X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fe1000%2Fe1000_ethtool.c;h=e4061ffc48aaf21016abc71fe0b2a600e472e2eb;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=2e4544eca333c4be4281285717ccd96c6198a6f7;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 2e4544eca..e4061ffc4 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -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); }