diff options
Diffstat (limited to 'drivers/net/ethernet/intel')
19 files changed, 419 insertions, 138 deletions
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 7b54d7246150..cf480b554622 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -2894,10 +2894,10 @@ static int e1000_tx_map(struct e1000_adapter *adapter, } for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[f]; - len = frag->size; + len = skb_frag_size(frag); offset = 0; while (len) { @@ -3183,7 +3183,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, nr_frags = skb_shinfo(skb)->nr_frags; for (f = 0; f < nr_frags; f++) - count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, + count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]), max_txd_pwr); if (adapter->pcix_82544) count += nr_frags; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 035ce73c388e..a855db1ad249 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -47,7 +47,7 @@ #include <linux/if_vlan.h> #include <linux/cpu.h> #include <linux/smp.h> -#include <linux/pm_qos_params.h> +#include <linux/pm_qos.h> #include <linux/pm_runtime.h> #include <linux/aer.h> #include <linux/prefetch.h> @@ -4673,10 +4673,10 @@ static int e1000_tx_map(struct e1000_adapter *adapter, } for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[f]; - len = frag->size; + len = skb_frag_size(frag); offset = 0; while (len) { @@ -4943,7 +4943,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, nr_frags = skb_shinfo(skb)->nr_frags; for (f = 0; f < nr_frags; f++) - count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, + count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]), max_txd_pwr); if (adapter->hw.mac.tx_pkt_filtering) diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 6580cea796c5..7881fb95a25b 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 872119d91afd..73aac082c44d 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 4927f61fbbc8..e45996b4ea34 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/e1000_mbx.c b/drivers/net/ethernet/intel/igb/e1000_mbx.c index 74f2f11ac290..469d95eaa154 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mbx.c +++ b/drivers/net/ethernet/intel/igb/e1000_mbx.c @@ -34,7 +34,7 @@ * @size: Length of buffer * @mbx_id: id of mailbox to read * - * returns SUCCESS if it successfuly read message from buffer + * returns SUCCESS if it successfully read message from buffer **/ s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) { diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 4c500a76972e..c69feebf2653 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -72,6 +72,8 @@ struct igb_adapter; #define IGB_MAX_VF_MC_ENTRIES 30 #define IGB_MAX_VF_FUNCTIONS 8 #define IGB_MAX_VFTA_ENTRIES 128 +#define IGB_82576_VF_DEV_ID 0x10CA +#define IGB_I350_VF_DEV_ID 0x1520 struct vf_data_storage { unsigned char vf_mac_addresses[ETH_ALEN]; @@ -83,6 +85,7 @@ struct vf_data_storage { u16 pf_vlan; /* When set, guest VLAN config not allowed. */ u16 pf_qos; u16 tx_rate; + struct pci_dev *vfdev; }; #define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */ @@ -360,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 c10cc716fdec..ced544499f1b 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -163,6 +163,12 @@ static int igb_ndo_get_vf_config(struct net_device *netdev, int vf, struct ifla_vf_info *ivi); static void igb_check_vf_rate_limit(struct igb_adapter *); +#ifdef CONFIG_PCI_IOV +static int igb_vf_configure(struct igb_adapter *adapter, int vf); +static int igb_find_enabled_vfs(struct igb_adapter *adapter); +static int igb_check_vf_assignment(struct igb_adapter *adapter); +#endif + #ifdef CONFIG_PM static int igb_suspend(struct pci_dev *, pm_message_t); static int igb_resume(struct pci_dev *); @@ -198,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, @@ -1722,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); @@ -2232,8 +2184,12 @@ static void __devexit igb_remove(struct pci_dev *pdev) /* reclaim resources allocated to VFs */ if (adapter->vf_data) { /* disable iov and allow time for transactions to clear */ - pci_disable_sriov(pdev); - msleep(500); + if (!igb_check_vf_assignment(adapter)) { + pci_disable_sriov(pdev); + msleep(500); + } else { + dev_info(&pdev->dev, "VF(s) assigned to guests!\n"); + } kfree(adapter->vf_data); adapter->vf_data = NULL; @@ -2250,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); @@ -2270,42 +2227,49 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter) { #ifdef CONFIG_PCI_IOV struct pci_dev *pdev = adapter->pdev; + int old_vfs = igb_find_enabled_vfs(adapter); + int i; - if (adapter->vfs_allocated_count) { - adapter->vf_data = kcalloc(adapter->vfs_allocated_count, - sizeof(struct vf_data_storage), - GFP_KERNEL); - /* if allocation failed then we do not support SR-IOV */ - if (!adapter->vf_data) { - adapter->vfs_allocated_count = 0; - dev_err(&pdev->dev, "Unable to allocate memory for VF " - "Data Storage\n"); - } + if (old_vfs) { + dev_info(&pdev->dev, "%d pre-allocated VFs found - override " + "max_vfs setting of %d\n", old_vfs, max_vfs); + adapter->vfs_allocated_count = old_vfs; } - if (pci_enable_sriov(pdev, adapter->vfs_allocated_count)) { - kfree(adapter->vf_data); - adapter->vf_data = NULL; -#endif /* CONFIG_PCI_IOV */ + if (!adapter->vfs_allocated_count) + return; + + adapter->vf_data = kcalloc(adapter->vfs_allocated_count, + sizeof(struct vf_data_storage), GFP_KERNEL); + /* if allocation failed then we do not support SR-IOV */ + if (!adapter->vf_data) { adapter->vfs_allocated_count = 0; -#ifdef CONFIG_PCI_IOV - } else { - unsigned char mac_addr[ETH_ALEN]; - int i; - dev_info(&pdev->dev, "%d vfs allocated\n", - adapter->vfs_allocated_count); - for (i = 0; i < adapter->vfs_allocated_count; i++) { - random_ether_addr(mac_addr); - igb_set_vf_mac(adapter, i, mac_addr); - } - /* DMA Coalescing is not supported in IOV mode. */ - if (adapter->flags & IGB_FLAG_DMAC) - adapter->flags &= ~IGB_FLAG_DMAC; + dev_err(&pdev->dev, "Unable to allocate memory for VF " + "Data Storage\n"); + goto out; } + + if (!old_vfs) { + if (pci_enable_sriov(pdev, adapter->vfs_allocated_count)) + goto err_out; + } + dev_info(&pdev->dev, "%d VFs allocated\n", + adapter->vfs_allocated_count); + for (i = 0; i < adapter->vfs_allocated_count; i++) + igb_vf_configure(adapter, i); + + /* DMA Coalescing is not supported in IOV mode. */ + adapter->flags &= ~IGB_FLAG_DMAC; + goto out; +err_out: + kfree(adapter->vf_data); + adapter->vf_data = NULL; + adapter->vfs_allocated_count = 0; +out: + return; #endif /* CONFIG_PCI_IOV */ } - /** * igb_init_hw_timer - Initialize hardware timer used with IEEE 1588 timestamp * @adapter: board private structure to initialize @@ -2475,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"); @@ -4254,7 +4223,7 @@ static void igb_tx_map(struct igb_ring *tx_ring, i = 0; } - size = frag->size; + size = skb_frag_size(frag); data_len -= size; dma = skb_frag_dma_map(tx_ring->dev, frag, 0, @@ -4917,6 +4886,109 @@ static int igb_notify_dca(struct notifier_block *nb, unsigned long event, } #endif /* CONFIG_IGB_DCA */ +#ifdef CONFIG_PCI_IOV +static int igb_vf_configure(struct igb_adapter *adapter, int vf) +{ + unsigned char mac_addr[ETH_ALEN]; + struct pci_dev *pdev = adapter->pdev; + struct e1000_hw *hw = &adapter->hw; + struct pci_dev *pvfdev; + unsigned int device_id; + u16 thisvf_devfn; + + random_ether_addr(mac_addr); + igb_set_vf_mac(adapter, vf, mac_addr); + + switch (adapter->hw.mac.type) { + case e1000_82576: + device_id = IGB_82576_VF_DEV_ID; + /* VF Stride for 82576 is 2 */ + thisvf_devfn = (pdev->devfn + 0x80 + (vf << 1)) | + (pdev->devfn & 1); + break; + case e1000_i350: + device_id = IGB_I350_VF_DEV_ID; + /* VF Stride for I350 is 4 */ + thisvf_devfn = (pdev->devfn + 0x80 + (vf << 2)) | + (pdev->devfn & 3); + break; + default: + device_id = 0; + thisvf_devfn = 0; + break; + } + + pvfdev = pci_get_device(hw->vendor_id, device_id, NULL); + while (pvfdev) { + if (pvfdev->devfn == thisvf_devfn) + break; + pvfdev = pci_get_device(hw->vendor_id, + device_id, pvfdev); + } + + if (pvfdev) + adapter->vf_data[vf].vfdev = pvfdev; + else + dev_err(&pdev->dev, + "Couldn't find pci dev ptr for VF %4.4x\n", + thisvf_devfn); + return pvfdev != NULL; +} + +static int igb_find_enabled_vfs(struct igb_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + struct pci_dev *pdev = adapter->pdev; + struct pci_dev *pvfdev; + u16 vf_devfn = 0; + u16 vf_stride; + unsigned int device_id; + int vfs_found = 0; + + switch (adapter->hw.mac.type) { + case e1000_82576: + device_id = IGB_82576_VF_DEV_ID; + /* VF Stride for 82576 is 2 */ + vf_stride = 2; + break; + case e1000_i350: + device_id = IGB_I350_VF_DEV_ID; + /* VF Stride for I350 is 4 */ + vf_stride = 4; + break; + default: + device_id = 0; + vf_stride = 0; + break; + } + + vf_devfn = pdev->devfn + 0x80; + pvfdev = pci_get_device(hw->vendor_id, device_id, NULL); + while (pvfdev) { + if (pvfdev->devfn == vf_devfn) + vfs_found++; + vf_devfn += vf_stride; + pvfdev = pci_get_device(hw->vendor_id, + device_id, pvfdev); + } + + return vfs_found; +} + +static int igb_check_vf_assignment(struct igb_adapter *adapter) +{ + int i; + for (i = 0; i < adapter->vfs_allocated_count; i++) { + if (adapter->vf_data[i].vfdev) { + if (adapter->vf_data[i].vfdev->dev_flags & + PCI_DEV_FLAGS_ASSIGNED) + return true; + } + } + return false; +} + +#endif static void igb_ping_all_vfs(struct igb_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; @@ -6978,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/mbx.c b/drivers/net/ethernet/intel/igbvf/mbx.c index 3d6f4cc3998a..048aae248d06 100644 --- a/drivers/net/ethernet/intel/igbvf/mbx.c +++ b/drivers/net/ethernet/intel/igbvf/mbx.c @@ -288,7 +288,7 @@ out_no_write: * @msg: The message buffer * @size: Length of buffer * - * returns SUCCESS if it successfuly read message from buffer + * returns SUCCESS if it successfully read message from buffer **/ static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size) { diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index 32b3044fa45c..cca78124be31 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 *); @@ -102,8 +102,8 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter, { if (status & E1000_RXD_STAT_VP) { u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; - - __vlan_hwaccel_put_tag(skb, vid); + if (test_bit(vid, adapter->active_vlans)) + __vlan_hwaccel_put_tag(skb, vid); } netif_receive_skb(skb); } @@ -312,7 +312,7 @@ static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter, skb->len += length; skb->data_len += length; - skb->truesize += length; + skb->truesize += PAGE_SIZE / 2; } send_up: i++; @@ -2045,7 +2045,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; count++; i++; @@ -2053,7 +2053,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, i = 0; frag = &skb_shinfo(skb)->frags[f]; - len = frag->size; + len = skb_frag_size(frag); buffer_info = &tx_ring->buffer_info[i]; BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD); @@ -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); diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index 88558b1aac07..e21148f8b160 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -1383,10 +1383,10 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, } for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[f]; - len = frag->size; + len = skb_frag_size(frag); offset = 0; while (len) { diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 6c4d693be08d..a8368d5cf686 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -497,7 +497,8 @@ struct ixgbe_adapter { u64 rsc_total_count; u64 rsc_total_flush; u32 wol; - u16 eeprom_version; + u16 eeprom_verh; + u16 eeprom_verl; u16 eeprom_cap; int node; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c index e02e911057de..ef2afefb0cd4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c @@ -1305,6 +1305,8 @@ static struct ixgbe_mac_operations mac_ops_82598 = { static struct ixgbe_eeprom_operations eeprom_ops_82598 = { .init_params = &ixgbe_init_eeprom_params_generic, .read = &ixgbe_read_eerd_generic, + .write = &ixgbe_write_eeprom_generic, + .write_buffer = &ixgbe_write_eeprom_buffer_bit_bang_generic, .read_buffer = &ixgbe_read_eerd_buffer_generic, .calc_checksum = &ixgbe_calc_eeprom_checksum_generic, .validate_checksum = &ixgbe_validate_eeprom_checksum_generic, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index 35fa444556b3..834f044be4c3 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c @@ -3341,7 +3341,7 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) * Communicates with the manageability block. On success return 0 * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. **/ -static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u8 *buffer, +static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, u32 length) { u32 hicr, i; @@ -3374,7 +3374,7 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u8 *buffer, */ for (i = 0; i < dword_len; i++) IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG, - i, *((u32 *)buffer + i)); + i, cpu_to_le32(buffer[i])); /* Setting this bit tells the ARC that a new command is pending. */ IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); @@ -3398,9 +3398,10 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u8 *buffer, dword_len = hdr_size >> 2; /* first pull in the header so we know the buffer length */ - for (i = 0; i < dword_len; i++) - *((u32 *)buffer + i) = - IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, i); + for (i = 0; i < dword_len; i++) { + buffer[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, i); + le32_to_cpus(&buffer[i]); + } /* If there is any thing in data position pull it in */ buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len; @@ -3418,8 +3419,7 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u8 *buffer, /* Pull in the rest of the buffer (i is where we left off)*/ for (; i < buf_len; i++) - *((u32 *)buffer + i) = - IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, i); + buffer[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, i); out: return ret_val; @@ -3465,7 +3465,7 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, fw_cmd.pad2 = 0; for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { - ret_val = ixgbe_host_interface_command(hw, (u8 *)&fw_cmd, + ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, sizeof(fw_cmd)); if (ret_val != 0) continue; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index e102ff6fb08d..70d58c3849b0 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -814,26 +814,97 @@ static int ixgbe_get_eeprom(struct net_device *netdev, return ret_val; } +static int ixgbe_set_eeprom(struct net_device *netdev, + struct ethtool_eeprom *eeprom, u8 *bytes) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + u16 *eeprom_buff; + void *ptr; + int max_len, first_word, last_word, ret_val = 0; + u16 i; + + if (eeprom->len == 0) + return -EINVAL; + + if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) + return -EINVAL; + + max_len = hw->eeprom.word_size * 2; + + first_word = eeprom->offset >> 1; + last_word = (eeprom->offset + eeprom->len - 1) >> 1; + eeprom_buff = kmalloc(max_len, GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + ptr = eeprom_buff; + + if (eeprom->offset & 1) { + /* + * need read/modify/write of first changed EEPROM word + * only the second byte of the word is being modified + */ + ret_val = hw->eeprom.ops.read(hw, first_word, &eeprom_buff[0]); + if (ret_val) + goto err; + + ptr++; + } + if ((eeprom->offset + eeprom->len) & 1) { + /* + * need read/modify/write of last changed EEPROM word + * only the first byte of the word is being modified + */ + ret_val = hw->eeprom.ops.read(hw, last_word, + &eeprom_buff[last_word - first_word]); + if (ret_val) + goto err; + } + + /* Device's eeprom is always little-endian, word addressable */ + for (i = 0; i < last_word - first_word + 1; i++) + le16_to_cpus(&eeprom_buff[i]); + + memcpy(ptr, bytes, eeprom->len); + + for (i = 0; i < last_word - first_word + 1; i++) + cpu_to_le16s(&eeprom_buff[i]); + + ret_val = hw->eeprom.ops.write_buffer(hw, first_word, + last_word - first_word + 1, + eeprom_buff); + + /* Update the checksum */ + if (ret_val == 0) + hw->eeprom.ops.update_checksum(hw); + +err: + kfree(eeprom_buff); + return ret_val; +} + static void ixgbe_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) { struct ixgbe_adapter *adapter = netdev_priv(netdev); char firmware_version[32]; + u32 nvm_track_id; strncpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver) - 1); strncpy(drvinfo->version, ixgbe_driver_version, sizeof(drvinfo->version) - 1); - snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d", - (adapter->eeprom_version & 0xF000) >> 12, - (adapter->eeprom_version & 0x0FF0) >> 4, - adapter->eeprom_version & 0x000F); + nvm_track_id = (adapter->eeprom_verh << 16) | + adapter->eeprom_verl; + snprintf(firmware_version, sizeof(firmware_version), "0x%08x", + nvm_track_id); strncpy(drvinfo->fw_version, firmware_version, - sizeof(drvinfo->fw_version)); + sizeof(drvinfo->fw_version) - 1); strncpy(drvinfo->bus_info, pci_name(adapter->pdev), - sizeof(drvinfo->bus_info)); + sizeof(drvinfo->bus_info) - 1); drvinfo->n_stats = IXGBE_STATS_LEN; drvinfo->testinfo_len = IXGBE_TEST_LEN; drvinfo->regdump_len = ixgbe_get_regs_len(netdev); @@ -2524,6 +2595,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .get_link = ethtool_op_get_link, .get_eeprom_len = ixgbe_get_eeprom_len, .get_eeprom = ixgbe_get_eeprom, + .set_eeprom = ixgbe_set_eeprom, .get_ringparam = ixgbe_get_ringparam, .set_ringparam = ixgbe_set_ringparam, .get_pauseparam = ixgbe_get_pauseparam, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index fb7d8842a362..09b8e88b2999 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -6545,9 +6545,9 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring, frag = &skb_shinfo(skb)->frags[f]; #ifdef IXGBE_FCOE - size = min_t(unsigned int, data_len, frag->size); + size = min_t(unsigned int, data_len, skb_frag_size(frag)); #else - size = frag->size; + size = skb_frag_size(frag); #endif data_len -= size; f++; @@ -7640,6 +7640,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, } device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); + /* save off EEPROM version number */ + hw->eeprom.ops.read(hw, 0x2e, &adapter->eeprom_verh); + hw->eeprom.ops.read(hw, 0x2d, &adapter->eeprom_verl); + /* pick up the PCI bus settings for reporting later */ hw->mac.ops.get_bus_info(hw); @@ -7672,9 +7676,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, "is required.\n"); } - /* save off EEPROM version number */ - hw->eeprom.ops.read(hw, 0x29, &adapter->eeprom_version); - /* reset the hardware with the new settings */ err = hw->mac.ops.start_hw(hw); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c index 1ff0eefcfd0a..3f725d48336d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c @@ -38,7 +38,7 @@ * @size: Length of buffer * @mbx_id: id of mailbox to read * - * returns SUCCESS if it successfuly read message from buffer + * returns SUCCESS if it successfully read message from buffer **/ s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) { diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 4930c4605493..5e92cc2079bd 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -2912,10 +2912,10 @@ static int ixgbevf_tx_map(struct ixgbevf_adapter *adapter, } for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[f]; - len = min((unsigned int)frag->size, total); + len = min((unsigned int)skb_frag_size(frag), total); offset = 0; while (len) { @@ -3096,7 +3096,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) count += TXD_USE_COUNT(skb_headlen(skb)); for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) - count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); + count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f])); if (ixgbevf_maybe_stop_tx(netdev, tx_ring, count)) { adapter->tx_busy++; diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.c b/drivers/net/ethernet/intel/ixgbevf/mbx.c index 7a8833125770..930fa83f2568 100644 --- a/drivers/net/ethernet/intel/ixgbevf/mbx.c +++ b/drivers/net/ethernet/intel/ixgbevf/mbx.c @@ -276,7 +276,7 @@ out_no_write: * @msg: The message buffer * @size: Length of buffer * - * returns 0 if it successfuly read message from buffer + * returns 0 if it successfully read message from buffer **/ static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size) { |