diff options
author | David S. Miller <davem@davemloft.net> | 2011-10-24 03:12:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-10-24 03:12:49 -0400 |
commit | 8b1857357acd919b9a7fa391afbea30123fdfaec (patch) | |
tree | 439493abe674452e72985f2806c0cd8cd7e2db28 | |
parent | 66b13d99d96a1a69f47a6bc3dc47f45955967377 (diff) | |
parent | 1128c756bef8285db3bbde5b26d4a6b4c7e2e613 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_82575.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_mac.c | 63 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_mac.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 130 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igbvf/netdev.c | 14 |
6 files changed, 148 insertions, 66 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 6580cea796c..7881fb95a25 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -1051,7 +1051,10 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw) /* Disabling VLAN filtering */ hw_dbg("Initializing the IEEE VLAN\n"); - igb_clear_vfta(hw); + if (hw->mac.type == e1000_i350) + igb_clear_vfta_i350(hw); + else + igb_clear_vfta(hw); /* Setup the receive address */ igb_init_rx_addrs(hw, rar_count); diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c index 872119d91af..73aac082c44 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mac.c +++ b/drivers/net/ethernet/intel/igb/e1000_mac.c @@ -117,6 +117,50 @@ static void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) wrfl(); } +/* Due to a hw errata, if the host tries to configure the VFTA register + * while performing queries from the BMC or DMA, then the VFTA in some + * cases won't be written. + */ + +/** + * igb_clear_vfta_i350 - Clear VLAN filter table + * @hw: pointer to the HW structure + * + * Clears the register array which contains the VLAN filter table by + * setting all the values to 0. + **/ +void igb_clear_vfta_i350(struct e1000_hw *hw) +{ + u32 offset; + int i; + + for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { + for (i = 0; i < 10; i++) + array_wr32(E1000_VFTA, offset, 0); + + wrfl(); + } +} + +/** + * igb_write_vfta_i350 - Write value to VLAN filter table + * @hw: pointer to the HW structure + * @offset: register offset in VLAN filter table + * @value: register value written to VLAN filter table + * + * Writes value at the given offset in the register array which stores + * the VLAN filter table. + **/ +void igb_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value) +{ + int i; + + for (i = 0; i < 10; i++) + array_wr32(E1000_VFTA, offset, value); + + wrfl(); +} + /** * igb_init_rx_addrs - Initialize receive address's * @hw: pointer to the HW structure @@ -155,9 +199,12 @@ s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add) { u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK; u32 mask = 1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK); - u32 vfta = array_rd32(E1000_VFTA, index); + u32 vfta; + struct igb_adapter *adapter = hw->back; s32 ret_val = 0; + vfta = adapter->shadow_vfta[index]; + /* bit was set/cleared before we started */ if ((!!(vfta & mask)) == add) { ret_val = -E1000_ERR_CONFIG; @@ -167,8 +214,11 @@ s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add) else vfta &= ~mask; } - - igb_write_vfta(hw, index, vfta); + if (hw->mac.type == e1000_i350) + igb_write_vfta_i350(hw, index, vfta); + else + igb_write_vfta(hw, index, vfta); + adapter->shadow_vfta[index] = vfta; return ret_val; } @@ -191,6 +241,13 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw) u16 offset, nvm_alt_mac_addr_offset, nvm_data; u8 alt_mac_addr[ETH_ALEN]; + /* + * Alternate MAC address is handled by the option ROM for 82580 + * and newer. SW support not required. + */ + if (hw->mac.type >= e1000_82580) + goto out; + ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1, &nvm_alt_mac_addr_offset); if (ret_val) { diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.h b/drivers/net/ethernet/intel/igb/e1000_mac.h index 4927f61fbbc..e45996b4ea3 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mac.h +++ b/drivers/net/ethernet/intel/igb/e1000_mac.h @@ -60,6 +60,7 @@ s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, void igb_clear_hw_cntrs_base(struct e1000_hw *hw); void igb_clear_vfta(struct e1000_hw *hw); +void igb_clear_vfta_i350(struct e1000_hw *hw); s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add); void igb_config_collision_dist(struct e1000_hw *hw); void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count); diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 559443015cc..c69feebf265 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -363,6 +363,7 @@ struct igb_adapter { u32 rss_queues; u32 wvbr; int node; + u32 *shadow_vfta; }; #define IGB_FLAG_HAS_MSI (1 << 0) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index f689aa1b5a3..ced544499f1 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -204,6 +204,7 @@ static struct pci_error_handlers igb_err_handler = { .resume = igb_io_resume, }; +static void igb_init_dmac(struct igb_adapter *adapter, u32 pba); static struct pci_driver igb_driver = { .name = igb_driver_name, @@ -1728,63 +1729,8 @@ void igb_reset(struct igb_adapter *adapter) if (hw->mac.ops.init_hw(hw)) dev_err(&pdev->dev, "Hardware Error\n"); - if (hw->mac.type > e1000_82580) { - if (adapter->flags & IGB_FLAG_DMAC) { - u32 reg; - - /* - * DMA Coalescing high water mark needs to be higher - * than * the * Rx threshold. The Rx threshold is - * currently * pba - 6, so we * should use a high water - * mark of pba * - 4. */ - hwm = (pba - 4) << 10; - - reg = (((pba-6) << E1000_DMACR_DMACTHR_SHIFT) - & E1000_DMACR_DMACTHR_MASK); - - /* transition to L0x or L1 if available..*/ - reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK); - - /* watchdog timer= +-1000 usec in 32usec intervals */ - reg |= (1000 >> 5); - wr32(E1000_DMACR, reg); - - /* no lower threshold to disable coalescing(smart fifb) - * -UTRESH=0*/ - wr32(E1000_DMCRTRH, 0); - - /* set hwm to PBA - 2 * max frame size */ - wr32(E1000_FCRTC, hwm); - /* - * This sets the time to wait before requesting tran- - * sition to * low power state to number of usecs needed - * to receive 1 512 * byte frame at gigabit line rate - */ - reg = rd32(E1000_DMCTLX); - reg |= IGB_DMCTLX_DCFLUSH_DIS; - - /* Delay 255 usec before entering Lx state. */ - reg |= 0xFF; - wr32(E1000_DMCTLX, reg); - - /* free space in Tx packet buffer to wake from DMAC */ - wr32(E1000_DMCTXTH, - (IGB_MIN_TXPBSIZE - - (IGB_TX_BUF_4096 + adapter->max_frame_size)) - >> 6); - - /* make low power state decision controlled by DMAC */ - reg = rd32(E1000_PCIEMISC); - reg |= E1000_PCIEMISC_LX_DECISION; - wr32(E1000_PCIEMISC, reg); - } /* end if IGB_FLAG_DMAC set */ - } - if (hw->mac.type == e1000_82580) { - u32 reg = rd32(E1000_PCIEMISC); - wr32(E1000_PCIEMISC, - reg & ~E1000_PCIEMISC_LX_DECISION); - } + igb_init_dmac(adapter, pba); if (!netif_running(adapter->netdev)) igb_power_down_link(adapter); @@ -2260,6 +2206,7 @@ static void __devexit igb_remove(struct pci_dev *pdev) pci_release_selected_regions(pdev, pci_select_bars(pdev, IORESOURCE_MEM)); + kfree(adapter->shadow_vfta); free_netdev(netdev); pci_disable_pcie_error_reporting(pdev); @@ -2492,6 +2439,11 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) ((adapter->rss_queues > 1) && (adapter->vfs_allocated_count > 6))) adapter->flags |= IGB_FLAG_QUEUE_PAIRS; + /* Setup and initialize a copy of the hw vlan table array */ + adapter->shadow_vfta = kzalloc(sizeof(u32) * + E1000_VLAN_FILTER_TBL_SIZE, + GFP_ATOMIC); + /* This call may decrease the number of queues */ if (igb_init_interrupt_scheme(adapter)) { dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); @@ -7098,4 +7050,70 @@ static void igb_vmm_control(struct igb_adapter *adapter) } } +static void igb_init_dmac(struct igb_adapter *adapter, u32 pba) +{ + struct e1000_hw *hw = &adapter->hw; + u32 dmac_thr; + u16 hwm; + + if (hw->mac.type > e1000_82580) { + if (adapter->flags & IGB_FLAG_DMAC) { + u32 reg; + + /* force threshold to 0. */ + wr32(E1000_DMCTXTH, 0); + + /* + * DMA Coalescing high water mark needs to be higher + * than the RX threshold. set hwm to PBA - 2 * max + * frame size + */ + hwm = pba - (2 * adapter->max_frame_size); + reg = rd32(E1000_DMACR); + reg &= ~E1000_DMACR_DMACTHR_MASK; + dmac_thr = pba - 4; + + reg |= ((dmac_thr << E1000_DMACR_DMACTHR_SHIFT) + & E1000_DMACR_DMACTHR_MASK); + + /* transition to L0x or L1 if available..*/ + reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK); + + /* watchdog timer= +-1000 usec in 32usec intervals */ + reg |= (1000 >> 5); + wr32(E1000_DMACR, reg); + + /* + * no lower threshold to disable + * coalescing(smart fifb)-UTRESH=0 + */ + wr32(E1000_DMCRTRH, 0); + wr32(E1000_FCRTC, hwm); + + reg = (IGB_DMCTLX_DCFLUSH_DIS | 0x4); + + wr32(E1000_DMCTLX, reg); + + /* + * free space in tx packet buffer to wake from + * DMA coal + */ + wr32(E1000_DMCTXTH, (IGB_MIN_TXPBSIZE - + (IGB_TX_BUF_4096 + adapter->max_frame_size)) >> 6); + + /* + * make low power state decision controlled + * by DMA coal + */ + reg = rd32(E1000_PCIEMISC); + reg &= ~E1000_PCIEMISC_LX_DECISION; + wr32(E1000_PCIEMISC, reg); + } /* endif adapter->dmac is not disabled */ + } else if (hw->mac.type == e1000_82580) { + u32 reg = rd32(E1000_PCIEMISC); + wr32(E1000_PCIEMISC, reg & ~E1000_PCIEMISC_LX_DECISION); + wr32(E1000_DMACR, 0); + } +} + /* igb_main.c */ diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index db298174801..cca78124be3 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -45,13 +45,13 @@ #include "igbvf.h" -#define DRV_VERSION "2.0.0-k" +#define DRV_VERSION "2.0.1-k" char igbvf_driver_name[] = "igbvf"; const char igbvf_driver_version[] = DRV_VERSION; static const char igbvf_driver_string[] = - "Intel(R) Virtual Function Network Driver"; + "Intel(R) Gigabit Virtual Function Network Driver"; static const char igbvf_copyright[] = - "Copyright (c) 2009 - 2010 Intel Corporation."; + "Copyright (c) 2009 - 2011 Intel Corporation."; static int igbvf_poll(struct napi_struct *napi, int budget); static void igbvf_reset(struct igbvf_adapter *); @@ -2525,9 +2525,11 @@ static void igbvf_print_device_info(struct igbvf_adapter *adapter) struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; - dev_info(&pdev->dev, "Intel(R) 82576 Virtual Function\n"); + if (hw->mac.type == e1000_vfadapt_i350) + dev_info(&pdev->dev, "Intel(R) I350 Virtual Function\n"); + else + dev_info(&pdev->dev, "Intel(R) 82576 Virtual Function\n"); dev_info(&pdev->dev, "Address: %pM\n", netdev->dev_addr); - dev_info(&pdev->dev, "MAC: %d\n", hw->mac.type); } static int igbvf_set_features(struct net_device *netdev, u32 features) @@ -2864,7 +2866,7 @@ module_exit(igbvf_exit_module); MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>"); -MODULE_DESCRIPTION("Intel(R) 82576 Virtual Function Network Driver"); +MODULE_DESCRIPTION("Intel(R) Gigabit Virtual Function Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); |