diff options
Diffstat (limited to 'drivers/net/ethernet/intel/fm10k')
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_common.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_dcbnl.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c | 95 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_iov.c | 53 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_main.c | 76 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_mbx.c | 52 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 54 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 63 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_pf.c | 33 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_ptp.c | 17 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_tlv.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_type.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_vf.c | 20 |
15 files changed, 301 insertions, 196 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k.h b/drivers/net/ethernet/intel/fm10k/fm10k.h index 42eb4344a9dc..c8c8c5baefda 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k.h +++ b/drivers/net/ethernet/intel/fm10k/fm10k.h @@ -1,5 +1,5 @@ /* Intel Ethernet Switch Host Interface Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -235,6 +235,9 @@ struct fm10k_vxlan_port { __be16 port; }; +/* one work queue for entire driver */ +extern struct workqueue_struct *fm10k_workqueue; + struct fm10k_intfc { unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; struct net_device *netdev; @@ -266,7 +269,6 @@ struct fm10k_intfc { u64 tx_csum_errors; u64 alloc_failed; u64 rx_csum_errors; - u64 rx_errors; u64 tx_bytes_nic; u64 tx_packets_nic; @@ -439,6 +441,7 @@ extern char fm10k_driver_name[]; extern const char fm10k_driver_version[]; int fm10k_init_queueing_scheme(struct fm10k_intfc *interface); void fm10k_clear_queueing_scheme(struct fm10k_intfc *interface); +__be16 fm10k_tx_encap_offload(struct sk_buff *skb); netdev_tx_t fm10k_xmit_frame_ring(struct sk_buff *skb, struct fm10k_ring *tx_ring); void fm10k_tx_timeout_reset(struct fm10k_intfc *interface); @@ -457,6 +460,9 @@ void fm10k_down(struct fm10k_intfc *interface); void fm10k_update_stats(struct fm10k_intfc *interface); void fm10k_service_event_schedule(struct fm10k_intfc *interface); void fm10k_update_rx_drop_en(struct fm10k_intfc *interface); +#ifdef CONFIG_NET_POLL_CONTROLLER +void fm10k_netpoll(struct net_device *netdev); +#endif /* Netdev */ struct net_device *fm10k_alloc_netdev(void); diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_common.c b/drivers/net/ethernet/intel/fm10k/fm10k_common.c index bf19dccd4288..6cfae6ac04ea 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_common.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_common.c @@ -398,7 +398,7 @@ static void fm10k_update_hw_stats_rx_q(struct fm10k_hw *hw, /* Retrieve RX Owner Data */ id_rx = fm10k_read_reg(hw, FM10K_RXQCTL(idx)); - /* Process RX Ring*/ + /* Process RX Ring */ do { rx_drops = fm10k_read_hw_stats_32b(hw, FM10K_QPRDC(idx), &q->rx_drops); @@ -466,7 +466,6 @@ void fm10k_update_hw_stats_q(struct fm10k_hw *hw, struct fm10k_hw_stats_q *q, * Function invalidates the index values for the queues so any updates that * may have happened are ignored and the base for the queue stats is reset. **/ - void fm10k_unbind_hw_stats_q(struct fm10k_hw_stats_q *q, u32 idx, u32 count) { u32 i; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_dcbnl.c b/drivers/net/ethernet/intel/fm10k/fm10k_dcbnl.c index 212a92dad222..5c7a4d7662d8 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_dcbnl.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_dcbnl.c @@ -1,5 +1,5 @@ /* Intel Ethernet Switch Host Interface Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -128,7 +128,7 @@ static int fm10k_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc) * * Returns that we support only IEEE DCB for this interface **/ -static u8 fm10k_dcbnl_getdcbx(struct net_device *dev) +static u8 fm10k_dcbnl_getdcbx(struct net_device __always_unused *dev) { return DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE; } @@ -140,7 +140,7 @@ static u8 fm10k_dcbnl_getdcbx(struct net_device *dev) * * Returns error on attempt to enable anything but IEEE DCB for this interface **/ -static u8 fm10k_dcbnl_setdcbx(struct net_device *dev, u8 mode) +static u8 fm10k_dcbnl_setdcbx(struct net_device __always_unused *dev, u8 mode) { return (mode != (DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE)) ? 1 : 0; } diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c b/drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c index 4327f86218b9..f45b4d71adb8 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c @@ -1,5 +1,5 @@ /* Intel Ethernet Switch Host Interface Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -36,14 +36,16 @@ static void *fm10k_dbg_desc_seq_start(struct seq_file *s, loff_t *pos) return (*pos < ring->count) ? pos : NULL; } -static void *fm10k_dbg_desc_seq_next(struct seq_file *s, void *v, loff_t *pos) +static void *fm10k_dbg_desc_seq_next(struct seq_file *s, + void __always_unused *v, loff_t *pos) { struct fm10k_ring *ring = s->private; return (++(*pos) < ring->count) ? pos : NULL; } -static void fm10k_dbg_desc_seq_stop(struct seq_file *s, void *v) +static void fm10k_dbg_desc_seq_stop(struct seq_file __always_unused *s, + __always_unused void *v) { /* Do nothing. */ } diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c index 651f53bc7376..4b9d9f88af70 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c @@ -1,5 +1,5 @@ /* Intel Ethernet Switch Host Interface Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -57,13 +57,12 @@ static const struct fm10k_stats fm10k_gstrings_net_stats[] = { .stat_offset = offsetof(struct fm10k_intfc, _stat) \ } -static const struct fm10k_stats fm10k_gstrings_stats[] = { +static const struct fm10k_stats fm10k_gstrings_global_stats[] = { FM10K_STAT("tx_restart_queue", restart_queue), FM10K_STAT("tx_busy", tx_busy), FM10K_STAT("tx_csum_errors", tx_csum_errors), FM10K_STAT("rx_alloc_failed", alloc_failed), FM10K_STAT("rx_csum_errors", rx_csum_errors), - FM10K_STAT("rx_errors", rx_errors), FM10K_STAT("tx_packets_nic", tx_packets_nic), FM10K_STAT("tx_bytes_nic", tx_bytes_nic), @@ -73,38 +72,42 @@ static const struct fm10k_stats fm10k_gstrings_stats[] = { FM10K_STAT("rx_overrun_pf", rx_overrun_pf), FM10K_STAT("rx_overrun_vf", rx_overrun_vf), - FM10K_STAT("timeout", stats.timeout.count), - FM10K_STAT("ur", stats.ur.count), - FM10K_STAT("ca", stats.ca.count), - FM10K_STAT("um", stats.um.count), - FM10K_STAT("xec", stats.xec.count), - FM10K_STAT("vlan_drop", stats.vlan_drop.count), - FM10K_STAT("loopback_drop", stats.loopback_drop.count), - FM10K_STAT("nodesc_drop", stats.nodesc_drop.count), - FM10K_STAT("swapi_status", hw.swapi.status), FM10K_STAT("mac_rules_used", hw.swapi.mac.used), FM10K_STAT("mac_rules_avail", hw.swapi.mac.avail), FM10K_STAT("mbx_tx_busy", hw.mbx.tx_busy), - FM10K_STAT("mbx_tx_dropped", hw.mbx.tx_dropped), + FM10K_STAT("mbx_tx_oversized", hw.mbx.tx_dropped), FM10K_STAT("mbx_tx_messages", hw.mbx.tx_messages), FM10K_STAT("mbx_tx_dwords", hw.mbx.tx_dwords), FM10K_STAT("mbx_rx_messages", hw.mbx.rx_messages), FM10K_STAT("mbx_rx_dwords", hw.mbx.rx_dwords), FM10K_STAT("mbx_rx_parse_err", hw.mbx.rx_parse_err), + FM10K_STAT("tx_hang_count", tx_timeout_count), + FM10K_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts), }; -#define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_stats) +static const struct fm10k_stats fm10k_gstrings_pf_stats[] = { + FM10K_STAT("timeout", stats.timeout.count), + FM10K_STAT("ur", stats.ur.count), + FM10K_STAT("ca", stats.ca.count), + FM10K_STAT("um", stats.um.count), + FM10K_STAT("xec", stats.xec.count), + FM10K_STAT("vlan_drop", stats.vlan_drop.count), + FM10K_STAT("loopback_drop", stats.loopback_drop.count), + FM10K_STAT("nodesc_drop", stats.nodesc_drop.count), +}; + +#define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats) +#define FM10K_PF_STATS_LEN ARRAY_SIZE(fm10k_gstrings_pf_stats) -#define FM10K_QUEUE_STATS_LEN \ - (MAX_QUEUES * 2 * (sizeof(struct fm10k_queue_stats) / sizeof(u64))) +#define FM10K_QUEUE_STATS_LEN(_n) \ + ( (_n) * 2 * (sizeof(struct fm10k_queue_stats) / sizeof(u64))) -#define FM10K_STATS_LEN (FM10K_GLOBAL_STATS_LEN + \ - FM10K_NETDEV_STATS_LEN + \ - FM10K_QUEUE_STATS_LEN) +#define FM10K_STATIC_STATS_LEN (FM10K_GLOBAL_STATS_LEN + \ + FM10K_NETDEV_STATS_LEN) static const char fm10k_gstrings_test[][ETH_GSTRING_LEN] = { "Mailbox test (on/offline)" @@ -117,9 +120,9 @@ enum fm10k_self_test_types { FM10K_TEST_MAX = FM10K_TEST_LEN }; -static void fm10k_get_strings(struct net_device *dev, u32 stringset, - u8 *data) +static void fm10k_get_strings(struct net_device *dev, u32 stringset, u8 *data) { + struct fm10k_intfc *interface = netdev_priv(dev); char *p = (char *)data; int i; @@ -135,12 +138,19 @@ static void fm10k_get_strings(struct net_device *dev, u32 stringset, p += ETH_GSTRING_LEN; } for (i = 0; i < FM10K_GLOBAL_STATS_LEN; i++) { - memcpy(p, fm10k_gstrings_stats[i].stat_string, + memcpy(p, fm10k_gstrings_global_stats[i].stat_string, ETH_GSTRING_LEN); p += ETH_GSTRING_LEN; } - for (i = 0; i < MAX_QUEUES; i++) { + if (interface->hw.mac.type != fm10k_mac_vf) + for (i = 0; i < FM10K_PF_STATS_LEN; i++) { + memcpy(p, fm10k_gstrings_pf_stats[i].stat_string, + ETH_GSTRING_LEN); + p += ETH_GSTRING_LEN; + } + + for (i = 0; i < interface->hw.mac.max_queues; i++) { sprintf(p, "tx_queue_%u_packets", i); p += ETH_GSTRING_LEN; sprintf(p, "tx_queue_%u_bytes", i); @@ -156,18 +166,28 @@ static void fm10k_get_strings(struct net_device *dev, u32 stringset, static int fm10k_get_sset_count(struct net_device *dev, int sset) { + struct fm10k_intfc *interface = netdev_priv(dev); + struct fm10k_hw *hw = &interface->hw; + int stats_len = FM10K_STATIC_STATS_LEN; + switch (sset) { case ETH_SS_TEST: return FM10K_TEST_LEN; case ETH_SS_STATS: - return FM10K_STATS_LEN; + stats_len += FM10K_QUEUE_STATS_LEN(hw->mac.max_queues); + + if (hw->mac.type != fm10k_mac_vf) + stats_len += FM10K_PF_STATS_LEN; + + return stats_len; default: return -EOPNOTSUPP; } } static void fm10k_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, u64 *data) + struct ethtool_stats __always_unused *stats, + u64 *data) { const int stat_count = sizeof(struct fm10k_queue_stats) / sizeof(u64); struct fm10k_intfc *interface = netdev_priv(netdev); @@ -184,12 +204,21 @@ static void fm10k_get_ethtool_stats(struct net_device *netdev, } for (i = 0; i < FM10K_GLOBAL_STATS_LEN; i++) { - p = (char *)interface + fm10k_gstrings_stats[i].stat_offset; - *(data++) = (fm10k_gstrings_stats[i].sizeof_stat == + p = (char *)interface + + fm10k_gstrings_global_stats[i].stat_offset; + *(data++) = (fm10k_gstrings_global_stats[i].sizeof_stat == sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } - for (i = 0; i < MAX_QUEUES; i++) { + if (interface->hw.mac.type != fm10k_mac_vf) + for (i = 0; i < FM10K_PF_STATS_LEN; i++) { + p = (char *)interface + + fm10k_gstrings_pf_stats[i].stat_offset; + *(data++) = (fm10k_gstrings_pf_stats[i].sizeof_stat == + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + } + + for (i = 0; i < interface->hw.mac.max_queues; i++) { struct fm10k_ring *ring; u64 *queue_stat; @@ -369,7 +398,7 @@ static void fm10k_get_drvinfo(struct net_device *dev, strncpy(info->bus_info, pci_name(interface->pdev), sizeof(info->bus_info) - 1); - info->n_stats = FM10K_STATS_LEN; + info->n_stats = fm10k_get_sset_count(dev, ETH_SS_STATS); info->regdump_len = fm10k_get_regs_len(dev); } @@ -645,7 +674,7 @@ static int fm10k_get_rss_hash_opts(struct fm10k_intfc *interface, } static int fm10k_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, - u32 *rule_locs) + u32 __always_unused *rule_locs) { struct fm10k_intfc *interface = netdev_priv(dev); int ret = -EOPNOTSUPP; @@ -851,7 +880,7 @@ static void fm10k_self_test(struct net_device *dev, eth_test->flags |= ETH_TEST_FL_FAILED; } -static u32 fm10k_get_reta_size(struct net_device *netdev) +static u32 fm10k_get_reta_size(struct net_device __always_unused *netdev) { return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG; } @@ -911,7 +940,7 @@ static int fm10k_set_reta(struct net_device *netdev, const u32 *indir) return 0; } -static u32 fm10k_get_rssrk_size(struct net_device *netdev) +static u32 fm10k_get_rssrk_size(struct net_device __always_unused *netdev) { return FM10K_RSSRK_SIZE * FM10K_RSSRK_ENTRIES_PER_REG; } @@ -1019,7 +1048,7 @@ static int fm10k_set_channels(struct net_device *dev, } static int fm10k_get_ts_info(struct net_device *dev, - struct ethtool_ts_info *info) + struct ethtool_ts_info *info) { struct fm10k_intfc *interface = netdev_priv(dev); diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c index 060190864238..5b08e6284a3c 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c @@ -1,5 +1,5 @@ /* Intel Ethernet Switch Host Interface Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -47,7 +47,7 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface) { struct fm10k_hw *hw = &interface->hw; struct fm10k_iov_data *iov_data; - s64 mbicr, vflre; + s64 vflre; int i; /* if there is no iov_data then there is no mailboxes to process */ @@ -63,7 +63,7 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface) goto read_unlock; if (!(fm10k_read_reg(hw, FM10K_EICR) & FM10K_EICR_VFLR)) - goto process_mbx; + goto read_unlock; /* read VFLRE to determine if any VFs have been reset */ do { @@ -86,32 +86,6 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface) } } while (i != iov_data->num_vfs); -process_mbx: - /* read MBICR to determine which VFs require attention */ - mbicr = fm10k_read_reg(hw, FM10K_MBICR(1)); - mbicr <<= 32; - mbicr |= fm10k_read_reg(hw, FM10K_MBICR(0)); - - i = iov_data->next_vf_mbx ? : iov_data->num_vfs; - - for (mbicr <<= 64 - i; i--; mbicr += mbicr) { - struct fm10k_mbx_info *mbx = &iov_data->vf_info[i].mbx; - - if (mbicr >= 0) - continue; - - if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU)) - break; - - mbx->ops.process(hw, mbx); - } - - if (i >= 0) { - iov_data->next_vf_mbx = i + 1; - } else if (iov_data->next_vf_mbx) { - iov_data->next_vf_mbx = 0; - goto process_mbx; - } read_unlock: rcu_read_unlock(); @@ -139,6 +113,13 @@ s32 fm10k_iov_mbx(struct fm10k_intfc *interface) /* lock the mailbox for transmit and receive */ fm10k_mbx_lock(interface); + /* Most VF messages sent to the PF cause the PF to respond by + * requesting from the SM mailbox. This means that too many VF + * messages processed at once could cause a mailbox timeout on the PF. + * To prevent this, store a pointer to the next VF mbx to process. Use + * that as the start of the loop so that we don't starve whichever VF + * got ignored on the previous run. + */ process_mbx: for (i = iov_data->next_vf_mbx ? : iov_data->num_vfs; i--;) { struct fm10k_vf_info *vf_info = &iov_data->vf_info[i]; @@ -155,10 +136,6 @@ process_mbx: mbx->ops.connect(hw, mbx); } - /* no work pending, then just continue */ - if (mbx->ops.tx_complete(mbx) && !mbx->ops.rx_ready(mbx)) - continue; - /* guarantee we have free space in the SM mailbox */ if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU)) break; @@ -167,6 +144,10 @@ process_mbx: mbx->ops.process(hw, mbx); } + /* if we stopped processing mailboxes early, update next_vf_mbx. + * Otherwise, reset next_vf_mbx, and restart loop so that we process + * the remaining mailboxes we skipped at the start. + */ if (i >= 0) { iov_data->next_vf_mbx = i + 1; } else if (iov_data->next_vf_mbx) { @@ -275,7 +256,7 @@ s32 fm10k_iov_update_pvid(struct fm10k_intfc *interface, u16 glort, u16 pvid) if (vf_idx >= iov_data->num_vfs) return FM10K_ERR_PARAM; - /* determine if an update has occured and if so notify the VF */ + /* determine if an update has occurred and if so notify the VF */ vf_info = &iov_data->vf_info[vf_idx]; if (vf_info->sw_vid != pvid) { vf_info->sw_vid = pvid; @@ -488,8 +469,8 @@ int fm10k_ndo_set_vf_vlan(struct net_device *netdev, int vf_idx, u16 vid, return 0; } -int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx, int unused, - int rate) +int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx, + int __always_unused unused, int rate) { struct fm10k_intfc *interface = netdev_priv(netdev); struct fm10k_iov_data *iov_data = interface->iov_data; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c index 84ab9eea2768..c754b2027281 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c @@ -28,7 +28,7 @@ #include "fm10k.h" -#define DRV_VERSION "0.12.2-k" +#define DRV_VERSION "0.15.2-k" const char fm10k_driver_version[] = DRV_VERSION; char fm10k_driver_name[] = "fm10k"; static const char fm10k_driver_string[] = @@ -41,6 +41,9 @@ MODULE_DESCRIPTION("Intel(R) Ethernet Switch Host Interface Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +/* single workqueue for entire fm10k driver */ +struct workqueue_struct *fm10k_workqueue = NULL; + /** * fm10k_init_module - Driver Registration Routine * @@ -52,6 +55,10 @@ static int __init fm10k_init_module(void) pr_info("%s - version %s\n", fm10k_driver_string, fm10k_driver_version); pr_info("%s\n", fm10k_copyright); + /* create driver workqueue */ + if (!fm10k_workqueue) + fm10k_workqueue = create_workqueue("fm10k"); + fm10k_dbg_init(); return fm10k_register_pci_driver(); @@ -69,6 +76,11 @@ static void __exit fm10k_exit_module(void) fm10k_unregister_pci_driver(); fm10k_dbg_exit(); + + /* destroy driver workqueue */ + flush_workqueue(fm10k_workqueue); + destroy_workqueue(fm10k_workqueue); + fm10k_workqueue = NULL; } module_exit(fm10k_exit_module); @@ -209,7 +221,7 @@ static inline bool fm10k_page_is_reserved(struct page *page) static bool fm10k_can_reuse_rx_page(struct fm10k_rx_buffer *rx_buffer, struct page *page, - unsigned int truesize) + unsigned int __maybe_unused truesize) { /* avoid re-using remote pages */ if (unlikely(fm10k_page_is_reserved(page))) @@ -240,7 +252,6 @@ static bool fm10k_can_reuse_rx_page(struct fm10k_rx_buffer *rx_buffer, /** * fm10k_add_rx_frag - Add contents of Rx buffer to sk_buff - * @rx_ring: rx descriptor ring to transact packets on * @rx_buffer: buffer containing page to add * @rx_desc: descriptor containing length of buffer written by hardware * @skb: sk_buff to place the data into @@ -253,8 +264,7 @@ static bool fm10k_can_reuse_rx_page(struct fm10k_rx_buffer *rx_buffer, * The function will then update the page offset if necessary and return * true if the buffer can be reused by the interface. **/ -static bool fm10k_add_rx_frag(struct fm10k_ring *rx_ring, - struct fm10k_rx_buffer *rx_buffer, +static bool fm10k_add_rx_frag(struct fm10k_rx_buffer *rx_buffer, union fm10k_rx_desc *rx_desc, struct sk_buff *skb) { @@ -330,7 +340,7 @@ static struct sk_buff *fm10k_fetch_rx_buffer(struct fm10k_ring *rx_ring, DMA_FROM_DEVICE); /* pull page into skb */ - if (fm10k_add_rx_frag(rx_ring, rx_buffer, rx_desc, skb)) { + if (fm10k_add_rx_frag(rx_buffer, rx_desc, skb)) { /* hand second half of page back to the ring */ fm10k_reuse_rx_page(rx_ring, rx_buffer); } else { @@ -412,7 +422,7 @@ static void fm10k_rx_hwtstamp(struct fm10k_ring *rx_ring, } static void fm10k_type_trans(struct fm10k_ring *rx_ring, - union fm10k_rx_desc *rx_desc, + union fm10k_rx_desc __maybe_unused *rx_desc, struct sk_buff *skb) { struct net_device *dev = rx_ring->netdev; @@ -509,8 +519,6 @@ static bool fm10k_is_non_eop(struct fm10k_ring *rx_ring, /** * fm10k_pull_tail - fm10k specific version of skb_pull_tail - * @rx_ring: rx descriptor ring packet is being transacted on - * @rx_desc: pointer to the EOP Rx descriptor * @skb: pointer to current skb being adjusted * * This function is an fm10k specific version of __pskb_pull_tail. The @@ -520,9 +528,7 @@ static bool fm10k_is_non_eop(struct fm10k_ring *rx_ring, * As a result we can do things like drop a frag and maintain an accurate * truesize for the skb. */ -static void fm10k_pull_tail(struct fm10k_ring *rx_ring, - union fm10k_rx_desc *rx_desc, - struct sk_buff *skb) +static void fm10k_pull_tail(struct sk_buff *skb) { struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0]; unsigned char *va; @@ -576,7 +582,7 @@ static bool fm10k_cleanup_headers(struct fm10k_ring *rx_ring, /* place header in linear portion of buffer */ if (skb_is_nonlinear(skb)) - fm10k_pull_tail(rx_ring, rx_desc, skb); + fm10k_pull_tail(skb); /* if eth_skb_pad returns an error the skb was freed */ if (eth_skb_pad(skb)) @@ -604,7 +610,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector, unsigned int total_bytes = 0, total_packets = 0; u16 cleaned_count = fm10k_desc_unused(rx_ring); - do { + while (likely(total_packets < budget)) { union fm10k_rx_desc *rx_desc; /* return some buffers to hardware, one at a time is too slow */ @@ -653,7 +659,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector, /* update budget accounting */ total_packets++; - } while (likely(total_packets < budget)); + } /* place incomplete frames back on ring for completion */ rx_ring->skb = skb; @@ -711,10 +717,6 @@ static struct ethhdr *fm10k_gre_is_nvgre(struct sk_buff *skb) if (nvgre_hdr->flags & FM10K_NVGRE_RESERVED0_FLAGS) return NULL; - /* verify protocol is transparent Ethernet bridging */ - if (nvgre_hdr->proto != htons(ETH_P_TEB)) - return NULL; - /* report start of ethernet header */ if (nvgre_hdr->flags & NVGRE_TNI) return (struct ethhdr *)(nvgre_hdr + 1); @@ -722,15 +724,13 @@ static struct ethhdr *fm10k_gre_is_nvgre(struct sk_buff *skb) return (struct ethhdr *)(&nvgre_hdr->tni); } -static __be16 fm10k_tx_encap_offload(struct sk_buff *skb) +__be16 fm10k_tx_encap_offload(struct sk_buff *skb) { + u8 l4_hdr = 0, inner_l4_hdr = 0, inner_l4_hlen; struct ethhdr *eth_hdr; - u8 l4_hdr = 0; -/* fm10k supports 184 octets of outer+inner headers. Minus 20 for inner L4. */ -#define FM10K_MAX_ENCAP_TRANSPORT_OFFSET 164 - if (skb_inner_transport_header(skb) - skb_mac_header(skb) > - FM10K_MAX_ENCAP_TRANSPORT_OFFSET) + if (skb->inner_protocol_type != ENCAP_TYPE_ETHER || + skb->inner_protocol != htons(ETH_P_TEB)) return 0; switch (vlan_get_protocol(skb)) { @@ -760,12 +760,33 @@ static __be16 fm10k_tx_encap_offload(struct sk_buff *skb) switch (eth_hdr->h_proto) { case htons(ETH_P_IP): + inner_l4_hdr = inner_ip_hdr(skb)->protocol; + break; case htons(ETH_P_IPV6): + inner_l4_hdr = inner_ipv6_hdr(skb)->nexthdr; break; default: return 0; } + switch (inner_l4_hdr) { + case IPPROTO_TCP: + inner_l4_hlen = inner_tcp_hdrlen(skb); + break; + case IPPROTO_UDP: + inner_l4_hlen = 8; + break; + default: + return 0; + } + + /* The hardware allows tunnel offloads only if the combined inner and + * outer header is 184 bytes or less + */ + if (skb_inner_transport_header(skb) + inner_l4_hlen - + skb_mac_header(skb) > FM10K_TUNNEL_HEADER_LENGTH) + return 0; + return eth_hdr->h_proto; } @@ -934,10 +955,10 @@ static int __fm10k_maybe_stop_tx(struct fm10k_ring *tx_ring, u16 size) { netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); + /* Memory barrier before checking head and tail */ smp_mb(); - /* We need to check again in a case another CPU has just - * made room available. */ + /* Check again in a case another CPU has just made room available */ if (likely(fm10k_desc_unused(tx_ring) < size)) return -EBUSY; @@ -1182,7 +1203,6 @@ void fm10k_tx_timeout_reset(struct fm10k_intfc *interface) { /* Do the reset outside of interrupt context */ if (!test_bit(__FM10K_DOWN, &interface->state)) { - netdev_err(interface->netdev, "Reset interface\n"); interface->tx_timeout_count++; interface->flags |= FM10K_FLAG_RESET_REQUESTED; fm10k_service_event_schedule(interface); diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c index 9f5457c9e627..1b2738380518 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c @@ -1,5 +1,5 @@ /* Intel Ethernet Switch Host Interface Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -72,7 +72,7 @@ static bool fm10k_fifo_empty(struct fm10k_mbx_fifo *fifo) * @fifo: pointer to FIFO * @offset: offset to add to head * - * This function returns the indicies into the fifo based on head + offset + * This function returns the indices into the fifo based on head + offset **/ static u16 fm10k_fifo_head_offset(struct fm10k_mbx_fifo *fifo, u16 offset) { @@ -84,7 +84,7 @@ static u16 fm10k_fifo_head_offset(struct fm10k_mbx_fifo *fifo, u16 offset) * @fifo: pointer to FIFO * @offset: offset to add to tail * - * This function returns the indicies into the fifo based on tail + offset + * This function returns the indices into the fifo based on tail + offset **/ static u16 fm10k_fifo_tail_offset(struct fm10k_mbx_fifo *fifo, u16 offset) { @@ -126,6 +126,18 @@ static u16 fm10k_fifo_head_drop(struct fm10k_mbx_fifo *fifo) } /** + * fm10k_fifo_drop_all - Drop all messages in FIFO + * @fifo: pointer to FIFO + * + * This function resets the head pointer to drop all messages in the FIFO, + * and ensure the FIFO is empty. + **/ +static void fm10k_fifo_drop_all(struct fm10k_mbx_fifo *fifo) +{ + fifo->head = fifo->tail; +} + +/** * fm10k_mbx_index_len - Convert a head/tail index into a length value * @mbx: pointer to mailbox * @head: head index @@ -315,7 +327,7 @@ static u16 fm10k_mbx_validate_msg_size(struct fm10k_mbx_info *mbx, u16 len) } while (total_len < len); /* message extends out of pushed section, but fits in FIFO */ - if ((len < total_len) && (msg_len <= mbx->rx.size)) + if ((len < total_len) && (msg_len <= mbx->max_size)) return 0; /* return length of invalid section */ @@ -326,8 +338,7 @@ static u16 fm10k_mbx_validate_msg_size(struct fm10k_mbx_info *mbx, u16 len) * fm10k_mbx_write_copy - pulls data off of Tx FIFO and places it in mbmem * @mbx: pointer to mailbox * - * This function will take a seciton of the Rx FIFO and copy it into the - mbx->tail--; + * This function will take a section of the Tx FIFO and copy it into the * mailbox memory. The offset in mbmem is based on the lower bits of the * tail and len determines the length to copy. **/ @@ -418,7 +429,7 @@ static void fm10k_mbx_pull_head(struct fm10k_hw *hw, * @hw: pointer to hardware structure * @mbx: pointer to mailbox * - * This function will take a seciton of the mailbox memory and copy it + * This function will take a section of the mailbox memory and copy it * into the Rx FIFO. The offset is based on the lower bits of the * head and len determines the length to copy. **/ @@ -464,7 +475,7 @@ static void fm10k_mbx_read_copy(struct fm10k_hw *hw, * @tail: tail index of message * * This function will first validate the tail index and size for the - * incoming message. It then updates the acknowlegment number and + * incoming message. It then updates the acknowledgment number and * copies the data into the FIFO. It will return the number of messages * dequeued on success and a negative value on error. **/ @@ -761,7 +772,7 @@ static s32 fm10k_mbx_enqueue_tx(struct fm10k_hw *hw, err = fm10k_fifo_enqueue(&mbx->tx, msg); } - /* if we failed trhead the error */ + /* if we failed treat the error */ if (err) { mbx->timeout = 0; mbx->tx_busy++; @@ -815,10 +826,10 @@ static void fm10k_mbx_write(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) { u32 mbmem = mbx->mbmem_reg; - /* write new msg header to notify recepient of change */ + /* write new msg header to notify recipient of change */ fm10k_write_reg(hw, mbmem, mbx->mbx_hdr); - /* write mailbox to sent interrupt */ + /* write mailbox to send interrupt */ if (mbx->mbx_lock) fm10k_write_reg(hw, mbx->mbx_reg, mbx->mbx_lock); @@ -1052,8 +1063,11 @@ static void fm10k_mbx_reset_work(struct fm10k_mbx_info *mbx) * @mbx: pointer to mailbox * @size: new value for max_size * - * This function will update the max_size value and drop any outgoing messages - * from the head of the Tx FIFO that are larger than max_size. + * This function updates the max_size value and drops any outgoing messages + * at the head of the Tx FIFO if they are larger than max_size. It does not + * drop all messages, as this is too difficult to parse and remove them from + * the FIFO. Instead, rely on the checking to ensure that messages larger + * than max_size aren't pushed into the memory buffer. **/ static void fm10k_mbx_update_max_size(struct fm10k_mbx_info *mbx, u16 size) { @@ -1251,7 +1265,7 @@ static s32 fm10k_mbx_process_error(struct fm10k_hw *hw, /* we will need to pull all of the fields for verification */ head = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD); - /* we only have lower 10 bits of error number os add upper bits */ + /* we only have lower 10 bits of error number so add upper bits */ err_no = FM10K_MSG_HDR_FIELD_GET(*hdr, ERR_NO); err_no |= ~FM10K_MSG_HDR_MASK(ERR_NO); @@ -1371,9 +1385,11 @@ static void fm10k_mbx_disconnect(struct fm10k_hw *hw, timeout -= FM10K_MBX_POLL_DELAY; } while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED)); - /* in case we didn't close just force the mailbox into shutdown */ + /* in case we didn't close, just force the mailbox into shutdown and + * drop all left over messages in the FIFO. + */ fm10k_mbx_connect_reset(mbx); - fm10k_mbx_update_max_size(mbx, 0); + fm10k_fifo_drop_all(&mbx->tx); fm10k_write_reg(hw, mbx->mbmem_reg, 0); } @@ -1548,7 +1564,7 @@ s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx, mbx->timeout = 0; mbx->udelay = FM10K_MBX_INIT_DELAY; - /* initalize tail and head */ + /* initialize tail and head */ mbx->tail = 1; mbx->head = 1; @@ -1627,7 +1643,7 @@ static void fm10k_sm_mbx_connect_reset(struct fm10k_mbx_info *mbx) mbx->local = FM10K_SM_MBX_VERSION; mbx->remote = 0; - /* initalize tail and head */ + /* initialize tail and head */ mbx->tail = 1; mbx->head = 1; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c index cfde8bac1aeb..2f4f41b7eae7 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c @@ -1,5 +1,5 @@ /* Intel Ethernet Switch Host Interface Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -356,7 +356,7 @@ static void fm10k_free_all_rx_resources(struct fm10k_intfc *interface) * fm10k_request_glort_range - Request GLORTs for use in configuring rules * @interface: board private structure * - * This function allocates a range of glorts for this inteface to use. + * This function allocates a range of glorts for this interface to use. **/ static void fm10k_request_glort_range(struct fm10k_intfc *interface) { @@ -770,18 +770,18 @@ static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set) if (hw->mac.vlan_override) return -EACCES; - /* if default VLAN is already present do nothing */ - if (vid == hw->mac.default_vid) - return -EBUSY; - /* update active_vlans bitmask */ set_bit(vid, interface->active_vlans); if (!set) clear_bit(vid, interface->active_vlans); + /* if default VLAN is already present do nothing */ + if (vid == hw->mac.default_vid) + return 0; + fm10k_mbx_lock(interface); - /* only need to update the VLAN if not in promiscous mode */ + /* only need to update the VLAN if not in promiscuous mode */ if (!(netdev->flags & IFF_PROMISC)) { err = hw->mac.ops.update_vlan(hw, vid, 0, set); if (err) @@ -970,14 +970,7 @@ static void fm10k_set_rx_mode(struct net_device *dev) fm10k_mbx_lock(interface); - /* syncronize all of the addresses */ - if (xcast_mode != FM10K_XCAST_MODE_PROMISC) { - __dev_uc_sync(dev, fm10k_uc_sync, fm10k_uc_unsync); - if (xcast_mode != FM10K_XCAST_MODE_ALLMULTI) - __dev_mc_sync(dev, fm10k_mc_sync, fm10k_mc_unsync); - } - - /* if we aren't changing modes there is nothing to do */ + /* update xcast mode first, but only if it changed */ if (interface->xcast_mode != xcast_mode) { /* update VLAN table */ if (xcast_mode == FM10K_XCAST_MODE_PROMISC) @@ -992,6 +985,13 @@ static void fm10k_set_rx_mode(struct net_device *dev) interface->xcast_mode = xcast_mode; } + /* synchronize all of the addresses */ + if (xcast_mode != FM10K_XCAST_MODE_PROMISC) { + __dev_uc_sync(dev, fm10k_uc_sync, fm10k_uc_unsync); + if (xcast_mode != FM10K_XCAST_MODE_ALLMULTI) + __dev_mc_sync(dev, fm10k_mc_sync, fm10k_mc_unsync); + } + fm10k_mbx_unlock(interface); } @@ -1051,16 +1051,16 @@ void fm10k_restore_rx_state(struct fm10k_intfc *interface) vid, true, 0); } - /* syncronize all of the addresses */ + /* update xcast mode before syncronizing addresses */ + hw->mac.ops.update_xcast_mode(hw, glort, xcast_mode); + + /* synchronize all of the addresses */ if (xcast_mode != FM10K_XCAST_MODE_PROMISC) { __dev_uc_sync(netdev, fm10k_uc_sync, fm10k_uc_unsync); if (xcast_mode != FM10K_XCAST_MODE_ALLMULTI) __dev_mc_sync(netdev, fm10k_mc_sync, fm10k_mc_unsync); } - /* update xcast mode */ - hw->mac.ops.update_xcast_mode(hw, glort, xcast_mode); - fm10k_mbx_unlock(interface); /* record updated xcast mode state */ @@ -1126,7 +1126,7 @@ static struct rtnl_link_stats64 *fm10k_get_stats64(struct net_device *netdev, } for (i = 0; i < interface->num_tx_queues; i++) { - ring = ACCESS_ONCE(interface->rx_ring[i]); + ring = ACCESS_ONCE(interface->tx_ring[i]); if (!ring) continue; @@ -1350,6 +1350,16 @@ static void fm10k_dfwd_del_station(struct net_device *dev, void *priv) } } +static netdev_features_t fm10k_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) +{ + if (!skb->encapsulation || fm10k_tx_encap_offload(skb)) + return features; + + return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); +} + static const struct net_device_ops fm10k_netdev_ops = { .ndo_open = fm10k_open, .ndo_stop = fm10k_close, @@ -1372,6 +1382,10 @@ static const struct net_device_ops fm10k_netdev_ops = { .ndo_do_ioctl = fm10k_ioctl, .ndo_dfwd_add_station = fm10k_dfwd_add_station, .ndo_dfwd_del_station = fm10k_dfwd_del_station, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = fm10k_netpoll, +#endif + .ndo_features_check = fm10k_features_check, }; #define DEFAULT_DEBUG_LEVEL_SHIFT 3 diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c index 4f5892cc32d7..df9fda38bdd1 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c @@ -1,5 +1,5 @@ /* Intel Ethernet Switch Host Interface Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -94,7 +94,7 @@ void fm10k_service_event_schedule(struct fm10k_intfc *interface) { if (!test_bit(__FM10K_SERVICE_DISABLE, &interface->state) && !test_and_set_bit(__FM10K_SERVICE_SCHED, &interface->state)) - schedule_work(&interface->service_task); + queue_work(fm10k_workqueue, &interface->service_task); } static void fm10k_service_event_complete(struct fm10k_intfc *interface) @@ -191,7 +191,6 @@ static void fm10k_reset_subtask(struct fm10k_intfc *interface) interface->flags &= ~FM10K_FLAG_RESET_REQUESTED; netdev_err(interface->netdev, "Reset interface\n"); - interface->tx_timeout_count++; fm10k_reinit(interface); } @@ -357,11 +356,10 @@ void fm10k_update_stats(struct fm10k_intfc *interface) net_stats->rx_packets = pkts; interface->alloc_failed = alloc_failed; interface->rx_csum_errors = rx_csum_errors; - interface->rx_errors = rx_errors; hw->mac.ops.update_hw_stats(hw, &interface->stats); - for (i = 0; i < FM10K_MAX_QUEUES_PF; i++) { + for (i = 0; i < hw->mac.max_queues; i++) { struct fm10k_hw_stats_q *q = &interface->stats.q[i]; tx_bytes_nic += q->tx_bytes.count; @@ -378,7 +376,7 @@ void fm10k_update_stats(struct fm10k_intfc *interface) interface->rx_drops_nic = rx_drops_nic; /* Fill out the OS statistics structure */ - net_stats->rx_errors = interface->stats.xec.count; + net_stats->rx_errors = rx_errors; net_stats->rx_dropped = interface->stats.nodesc_drop.count; } @@ -648,7 +646,7 @@ static void fm10k_configure_rx_ring(struct fm10k_intfc *interface, /* Configure the Rx buffer size for one buff without split */ srrctl |= FM10K_RX_BUFSZ >> FM10K_SRRCTL_BSIZEPKT_SHIFT; - /* Configure the Rx ring to supress loopback packets */ + /* Configure the Rx ring to suppress loopback packets */ srrctl |= FM10K_SRRCTL_LOOPBACK_SUPPRESS; fm10k_write_reg(hw, FM10K_SRRCTL(reg_idx), srrctl); @@ -808,7 +806,7 @@ static void fm10k_napi_enable_all(struct fm10k_intfc *interface) } } -static irqreturn_t fm10k_msix_clean_rings(int irq, void *data) +static irqreturn_t fm10k_msix_clean_rings(int __always_unused irq, void *data) { struct fm10k_q_vector *q_vector = data; @@ -818,7 +816,7 @@ static irqreturn_t fm10k_msix_clean_rings(int irq, void *data) return IRQ_HANDLED; } -static irqreturn_t fm10k_msix_mbx_vf(int irq, void *data) +static irqreturn_t fm10k_msix_mbx_vf(int __always_unused irq, void *data) { struct fm10k_intfc *interface = data; struct fm10k_hw *hw = &interface->hw; @@ -840,6 +838,28 @@ static irqreturn_t fm10k_msix_mbx_vf(int irq, void *data) return IRQ_HANDLED; } +#ifdef CONFIG_NET_POLL_CONTROLLER +/** + * fm10k_netpoll - A Polling 'interrupt' handler + * @netdev: network interface device structure + * + * This is used by netconsole to send skbs without having to re-enable + * interrupts. It's not called while the normal interrupt routine is executing. + **/ +void fm10k_netpoll(struct net_device *netdev) +{ + struct fm10k_intfc *interface = netdev_priv(netdev); + int i; + + /* if interface is down do nothing */ + if (test_bit(__FM10K_DOWN, &interface->state)) + return; + + for (i = 0; i < interface->num_q_vectors; i++) + fm10k_msix_clean_rings(0, interface->q_vector[i]); +} + +#endif #define FM10K_ERR_MSG(type) case (type): error = #type; break static void fm10k_print_fault(struct fm10k_intfc *interface, int type, struct fm10k_fault *fault) @@ -964,7 +984,7 @@ static void fm10k_reset_drop_on_empty(struct fm10k_intfc *interface, u32 eicr) } } -static irqreturn_t fm10k_msix_mbx_pf(int irq, void *data) +static irqreturn_t fm10k_msix_mbx_pf(int __always_unused irq, void *data) { struct fm10k_intfc *interface = data; struct fm10k_hw *hw = &interface->hw; @@ -986,6 +1006,7 @@ static irqreturn_t fm10k_msix_mbx_pf(int irq, void *data) /* service mailboxes */ if (fm10k_mbx_trylock(interface)) { mbx->ops.process(hw, mbx); + /* handle VFLRE events */ fm10k_iov_event(interface); fm10k_mbx_unlock(interface); } @@ -1002,6 +1023,8 @@ static irqreturn_t fm10k_msix_mbx_pf(int irq, void *data) /* we should validate host state after interrupt event */ hw->mac.get_host_state = 1; + + /* validate host state, and handle VF mailboxes in the service task */ fm10k_service_event_schedule(interface); /* re-enable mailbox interrupt and indicate 20us delay */ @@ -1069,7 +1092,7 @@ static s32 fm10k_mbx_mac_addr(struct fm10k_hw *hw, u32 **results, } static s32 fm10k_1588_msg_vf(struct fm10k_hw *hw, u32 **results, - struct fm10k_mbx_info *mbx) + struct fm10k_mbx_info __always_unused *mbx) { struct fm10k_intfc *interface; u64 timestamp; @@ -1089,7 +1112,7 @@ static s32 fm10k_1588_msg_vf(struct fm10k_hw *hw, u32 **results, /* generic error handler for mailbox issues */ static s32 fm10k_mbx_error(struct fm10k_hw *hw, u32 **results, - struct fm10k_mbx_info *mbx) + struct fm10k_mbx_info __always_unused *mbx) { struct fm10k_intfc *interface; struct pci_dev *pdev; @@ -1165,7 +1188,7 @@ static s32 fm10k_lport_map(struct fm10k_hw *hw, u32 **results, } static s32 fm10k_update_pvid(struct fm10k_hw *hw, u32 **results, - struct fm10k_mbx_info *mbx) + struct fm10k_mbx_info __always_unused *mbx) { struct fm10k_intfc *interface; u16 glort, pvid; @@ -1206,7 +1229,7 @@ static s32 fm10k_update_pvid(struct fm10k_hw *hw, u32 **results, } static s32 fm10k_1588_msg_pf(struct fm10k_hw *hw, u32 **results, - struct fm10k_mbx_info *mbx) + struct fm10k_mbx_info __always_unused *mbx) { struct fm10k_swapi_1588_timestamp timestamp; struct fm10k_iov_data *iov_data; @@ -1488,7 +1511,7 @@ void fm10k_up(struct fm10k_intfc *interface) /* enable transmits */ netif_tx_start_all_queues(interface->netdev); - /* kick off the service timer */ + /* kick off the service timer now */ hw->mac.get_host_state = 1; mod_timer(&interface->service_timer, jiffies); } @@ -1528,8 +1551,6 @@ void fm10k_down(struct fm10k_intfc *interface) /* disable polling routines */ fm10k_napi_disable_all(interface); - del_timer_sync(&interface->service_timer); - /* capture stats one last time before stopping interface */ fm10k_update_stats(interface); @@ -1655,6 +1676,9 @@ static int fm10k_sw_init(struct fm10k_intfc *interface, (unsigned long)interface); INIT_WORK(&interface->service_task, fm10k_service_task); + /* kick off service timer now, even when interface is down */ + mod_timer(&interface->service_timer, (HZ * 2) + jiffies); + /* Intitialize timestamp data */ fm10k_ts_init(interface); @@ -1871,6 +1895,8 @@ static void fm10k_remove(struct pci_dev *pdev) struct fm10k_intfc *interface = pci_get_drvdata(pdev); struct net_device *netdev = interface->netdev; + del_timer_sync(&interface->service_timer); + set_bit(__FM10K_SERVICE_DISABLE, &interface->state); cancel_work_sync(&interface->service_task); @@ -1984,7 +2010,8 @@ static int fm10k_resume(struct pci_dev *pdev) * a sleep state. The fm10k hardware does not support wake on lan so the * driver simply needs to shut down the device so it is in a low power state. **/ -static int fm10k_suspend(struct pci_dev *pdev, pm_message_t state) +static int fm10k_suspend(struct pci_dev *pdev, + pm_message_t __always_unused state) { struct fm10k_intfc *interface = pci_get_drvdata(pdev); struct net_device *netdev = interface->netdev; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c index 7e4711958e46..891e21874b2a 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c @@ -234,8 +234,7 @@ static s32 fm10k_update_vlan_pf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set) vid = (vid << 17) >> 17; /* verify the reserved 0 fields are 0 */ - if (len >= FM10K_VLAN_TABLE_VID_MAX || - vid >= FM10K_VLAN_TABLE_VID_MAX) + if (len >= FM10K_VLAN_TABLE_VID_MAX || vid >= FM10K_VLAN_TABLE_VID_MAX) return FM10K_ERR_PARAM; /* Loop through the table updating all required VLANs */ @@ -312,7 +311,7 @@ bool fm10k_glort_valid_pf(struct fm10k_hw *hw, u16 glort) } /** - * fm10k_update_uc_addr_pf - Update device unicast addresss + * fm10k_update_xc_addr_pf - Update device addresses * @hw: pointer to the HW structure * @glort: base resource tag for this request * @mac: MAC address to add/remove from table @@ -330,6 +329,9 @@ static s32 fm10k_update_xc_addr_pf(struct fm10k_hw *hw, u16 glort, struct fm10k_mac_update mac_update; u32 msg[5]; + /* clear set bit from VLAN ID */ + vid &= ~FM10K_VLAN_CLEAR; + /* if glort or vlan are not valid return error */ if (!fm10k_glort_valid_pf(hw, glort) || vid >= FM10K_VLAN_TABLE_VID_MAX) return FM10K_ERR_PARAM; @@ -356,7 +358,7 @@ static s32 fm10k_update_xc_addr_pf(struct fm10k_hw *hw, u16 glort, } /** - * fm10k_update_uc_addr_pf - Update device unicast addresss + * fm10k_update_uc_addr_pf - Update device unicast addresses * @hw: pointer to the HW structure * @glort: base resource tag for this request * @mac: MAC address to add/remove from table @@ -454,7 +456,7 @@ static void fm10k_update_int_moderator_pf(struct fm10k_hw *hw) break; } - /* always reset VFITR2[0] to point to last enabled PF vector*/ + /* always reset VFITR2[0] to point to last enabled PF vector */ fm10k_write_reg(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), i); /* reset ITR2[0] to point to last enabled PF vector */ @@ -677,7 +679,8 @@ static s32 fm10k_iov_assign_resources_pf(struct fm10k_hw *hw, u16 num_vfs, /* loop through unallocated rings assigning them back to PF */ for (i = FM10K_MAX_QUEUES_PF; i < vf_q_idx; i++) { fm10k_write_reg(hw, FM10K_TXDCTL(i), 0); - fm10k_write_reg(hw, FM10K_TXQCTL(i), FM10K_TXQCTL_PF | vid); + fm10k_write_reg(hw, FM10K_TXQCTL(i), FM10K_TXQCTL_PF | + FM10K_TXQCTL_UNLIMITED_BW | vid); fm10k_write_reg(hw, FM10K_RXQCTL(i), FM10K_RXQCTL_PF); } @@ -812,7 +815,7 @@ static s32 fm10k_iov_assign_int_moderator_pf(struct fm10k_hw *hw, u16 vf_idx) if (vf_idx >= hw->iov.num_vfs) return FM10K_ERR_PARAM; - /* determine vector offset and count*/ + /* determine vector offset and count */ vf_v_idx = fm10k_vf_vector_index(hw, vf_idx); vf_v_limit = vf_v_idx + fm10k_vectors_per_pool(hw); @@ -951,7 +954,7 @@ static s32 fm10k_iov_reset_resources_pf(struct fm10k_hw *hw, if (vf_info->mbx.ops.disconnect) vf_info->mbx.ops.disconnect(hw, &vf_info->mbx); - /* determine vector offset and count*/ + /* determine vector offset and count */ vf_v_idx = fm10k_vf_vector_index(hw, vf_idx); vf_v_limit = vf_v_idx + fm10k_vectors_per_pool(hw); @@ -1035,7 +1038,7 @@ static s32 fm10k_iov_reset_resources_pf(struct fm10k_hw *hw, ((u32)vf_info->mac[2]); } - /* map queue pairs back to VF from last to first*/ + /* map queue pairs back to VF from last to first */ for (i = queues_per_pool; i--;) { fm10k_write_reg(hw, FM10K_TDBAL(vf_q_idx + i), tdbal); fm10k_write_reg(hw, FM10K_TDBAH(vf_q_idx + i), tdbah); @@ -1141,7 +1144,7 @@ static s32 fm10k_iov_report_timestamp_pf(struct fm10k_hw *hw, * * This function is a default handler for MSI-X requests from the VF. The * assumption is that in this case it is acceptable to just directly - * hand off the message form the VF to the underlying shared code. + * hand off the message from the VF to the underlying shared code. **/ s32 fm10k_iov_msg_msix_pf(struct fm10k_hw *hw, u32 **results, struct fm10k_mbx_info *mbx) @@ -1160,7 +1163,7 @@ s32 fm10k_iov_msg_msix_pf(struct fm10k_hw *hw, u32 **results, * * This function is a default handler for MAC/VLAN requests from the VF. * The assumption is that in this case it is acceptable to just directly - * hand off the message form the VF to the underlying shared code. + * hand off the message from the VF to the underlying shared code. **/ s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results, struct fm10k_mbx_info *mbx) @@ -1250,8 +1253,8 @@ s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results, } /* notify switch of request for new multicast address */ - err = hw->mac.ops.update_mc_addr(hw, vf_info->glort, mac, - !(vlan & FM10K_VLAN_CLEAR), 0); + err = hw->mac.ops.update_mc_addr(hw, vf_info->glort, mac, vlan, + !(vlan & FM10K_VLAN_CLEAR)); } return err; @@ -1404,7 +1407,7 @@ static void fm10k_update_hw_stats_pf(struct fm10k_hw *hw, &stats->vlan_drop); loopback_drop = fm10k_read_hw_stats_32b(hw, FM10K_STATS_LOOPBACK_DROP, - &stats->loopback_drop); + &stats->loopback_drop); nodesc_drop = fm10k_read_hw_stats_32b(hw, FM10K_STATS_NODESC_DROP, &stats->nodesc_drop); @@ -1573,7 +1576,7 @@ static s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready) s32 ret_val = 0; u32 dma_ctrl2; - /* verify the switch is ready for interraction */ + /* verify the switch is ready for interaction */ dma_ctrl2 = fm10k_read_reg(hw, FM10K_DMA_CTRL2); if (!(dma_ctrl2 & FM10K_DMA_CTRL2_SWITCH_READY)) goto out; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c b/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c index d966044e017a..9043633c3e50 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_ptp.c @@ -1,5 +1,5 @@ /* Intel Ethernet Switch Host Interface Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -285,7 +285,7 @@ static int fm10k_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) return 0; } -static int fm10k_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) +static int fm10k_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) { struct fm10k_intfc *interface; unsigned long flags; @@ -297,17 +297,17 @@ static int fm10k_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) now = fm10k_systime_read(interface) + interface->ptp_adjust; read_unlock_irqrestore(&interface->systime_lock, flags); - *ts = ns_to_timespec(now); + *ts = ns_to_timespec64(now); return 0; } static int fm10k_ptp_settime(struct ptp_clock_info *ptp, - const struct timespec *ts) + const struct timespec64 *ts) { struct fm10k_intfc *interface; unsigned long flags; - u64 ns = timespec_to_ns(ts); + u64 ns = timespec64_to_ns(ts); interface = container_of(ptp, struct fm10k_intfc, ptp_caps); @@ -319,7 +319,8 @@ static int fm10k_ptp_settime(struct ptp_clock_info *ptp, } static int fm10k_ptp_enable(struct ptp_clock_info *ptp, - struct ptp_clock_request *rq, int on) + struct ptp_clock_request *rq, + int __always_unused on) { struct ptp_clock_time *t = &rq->perout.period; struct fm10k_intfc *interface; @@ -419,8 +420,8 @@ void fm10k_ptp_register(struct fm10k_intfc *interface) ptp_caps->max_adj = 976562; ptp_caps->adjfreq = fm10k_ptp_adjfreq; ptp_caps->adjtime = fm10k_ptp_adjtime; - ptp_caps->gettime = fm10k_ptp_gettime; - ptp_caps->settime = fm10k_ptp_settime; + ptp_caps->gettime64 = fm10k_ptp_gettime; + ptp_caps->settime64 = fm10k_ptp_settime; /* provide pins if BAR4 is accessible */ if (interface->sw_addr) { diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c b/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c index fd0a05f011a8..9b29d7b0377a 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c @@ -710,7 +710,7 @@ void fm10k_tlv_msg_test_create(u32 *msg, u32 attr_flags) /** * fm10k_tlv_msg_test - Validate all results on test message receive * @hw: Pointer to hardware structure - * @results: Pointer array to attributes in the mesage + * @results: Pointer array to attributes in the message * @mbx: Pointer to mailbox information structure * * This function does a check to verify all attributes match what the test diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_type.h b/drivers/net/ethernet/intel/fm10k/fm10k_type.h index 7c6d9d5a8ae5..4af96686c584 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_type.h +++ b/drivers/net/ethernet/intel/fm10k/fm10k_type.h @@ -356,6 +356,9 @@ struct fm10k_hw; #define FM10K_QUEUE_DISABLE_TIMEOUT 100 #define FM10K_RESET_TIMEOUT 150 +/* Maximum supported combined inner and outer header length for encapsulation */ +#define FM10K_TUNNEL_HEADER_LENGTH 184 + /* VF registers */ #define FM10K_VFCTRL 0x00000 #define FM10K_VFCTRL_RST 0x00000008 @@ -593,7 +596,7 @@ struct fm10k_vf_info { u16 sw_vid; /* Switch API assigned VLAN */ u16 pf_vid; /* PF assigned Default VLAN */ u8 mac[ETH_ALEN]; /* PF Default MAC address */ - u8 vsi; /* VSI idenfifier */ + u8 vsi; /* VSI identifier */ u8 vf_idx; /* which VF this is */ u8 vf_flags; /* flags indicating what modes * are supported for the port diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_vf.c b/drivers/net/ethernet/intel/fm10k/fm10k_vf.c index f0aa0f97b4a9..94f0f6a146d9 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_vf.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_vf.c @@ -1,5 +1,5 @@ /* Intel Ethernet Switch Host Interface Driver - * Copyright(c) 2013 - 2014 Intel Corporation. + * Copyright(c) 2013 - 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -37,7 +37,7 @@ static s32 fm10k_stop_hw_vf(struct fm10k_hw *hw) if (err) return err; - /* If permenant address is set then we need to restore it */ + /* If permanent address is set then we need to restore it */ if (is_valid_ether_addr(perm_addr)) { bal = (((u32)perm_addr[3]) << 24) | (((u32)perm_addr[4]) << 16) | @@ -65,7 +65,7 @@ static s32 fm10k_stop_hw_vf(struct fm10k_hw *hw) * fm10k_reset_hw_vf - VF hardware reset * @hw: pointer to hardware structure * - * This function should return the hardare to a state similar to the + * This function should return the hardware to a state similar to the * one it is in after just being initialized. **/ static s32 fm10k_reset_hw_vf(struct fm10k_hw *hw) @@ -124,6 +124,10 @@ static s32 fm10k_init_hw_vf(struct fm10k_hw *hw) /* record maximum queue count */ hw->mac.max_queues = i; + /* fetch default VLAN */ + hw->mac.default_vid = (fm10k_read_reg(hw, FM10K_TXQCTL(0)) & + FM10K_TXQCTL_VID_MASK) >> FM10K_TXQCTL_VID_SHIFT; + return 0; } @@ -252,7 +256,7 @@ static s32 fm10k_read_mac_addr_vf(struct fm10k_hw *hw) } /** - * fm10k_update_uc_addr_vf - Update device unicast address + * fm10k_update_uc_addr_vf - Update device unicast addresses * @hw: pointer to the HW structure * @glort: unused * @mac: MAC address to add/remove from table @@ -282,7 +286,7 @@ static s32 fm10k_update_uc_addr_vf(struct fm10k_hw *hw, u16 glort, memcmp(hw->mac.perm_addr, mac, ETH_ALEN)) return FM10K_ERR_PARAM; - /* add bit to notify us if this is a set of clear operation */ + /* add bit to notify us if this is a set or clear operation */ if (!add) vid |= FM10K_VLAN_CLEAR; @@ -295,7 +299,7 @@ static s32 fm10k_update_uc_addr_vf(struct fm10k_hw *hw, u16 glort, } /** - * fm10k_update_mc_addr_vf - Update device multicast address + * fm10k_update_mc_addr_vf - Update device multicast addresses * @hw: pointer to the HW structure * @glort: unused * @mac: MAC address to add/remove from table @@ -319,7 +323,7 @@ static s32 fm10k_update_mc_addr_vf(struct fm10k_hw *hw, u16 glort, if (!is_multicast_ether_addr(mac)) return FM10K_ERR_PARAM; - /* add bit to notify us if this is a set of clear operation */ + /* add bit to notify us if this is a set or clear operation */ if (!add) vid |= FM10K_VLAN_CLEAR; @@ -515,7 +519,7 @@ static s32 fm10k_adjust_systime_vf(struct fm10k_hw *hw, s32 ppb) * @hw: pointer to the hardware structure * * Function reads the content of 2 registers, combined to represent a 64 bit - * value measured in nanosecods. In order to guarantee the value is accurate + * value measured in nanoseconds. In order to guarantee the value is accurate * we check the 32 most significant bits both before and after reading the * 32 least significant bits to verify they didn't change as we were reading * the registers. |