* [net-next 10/14] i40e: Fix for supported link modes in 10GBaseT PHY's
From: Jeff Kirsher @ 2016-04-06 3:36 UTC (permalink / raw)
To: davem; +Cc: Avinash Dayanand, netdev, nhorman, sassmann, jogreene,
Jeff Kirsher
In-Reply-To: <1459913769-56510-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Avinash Dayanand <avinash.dayanand@intel.com>
100baseT/Full is now listed and supported link mode for 10GBaseT PHY.
This is a fix to list all the supported link modes of 10GBaseT PHY.
Change-ID: If2be3212ef0fef85fd5d6e4550c7783de2f915e9
Signed-off-by: Avinash Dayanand <avinash.dayanand@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 410d237..8a83d45 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -313,6 +313,13 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
ecmd->advertising |= ADVERTISED_10000baseT_Full;
if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
ecmd->advertising |= ADVERTISED_1000baseT_Full;
+ /* adding 100baseT support for 10GBASET_PHY */
+ if (pf->flags & I40E_FLAG_HAVE_10GBASET_PHY) {
+ ecmd->supported |= SUPPORTED_100baseT_Full;
+ ecmd->advertising |= ADVERTISED_100baseT_Full |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_10000baseT_Full;
+ }
break;
case I40E_PHY_TYPE_1000BASE_T_OPTICAL:
ecmd->supported = SUPPORTED_Autoneg |
@@ -325,6 +332,15 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
SUPPORTED_100baseT_Full;
if (hw_link_info->requested_speeds & I40E_LINK_SPEED_100MB)
ecmd->advertising |= ADVERTISED_100baseT_Full;
+ /* firmware detects 10G phy as 100M phy at 100M speed */
+ if (pf->flags & I40E_FLAG_HAVE_10GBASET_PHY) {
+ ecmd->supported |= SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full;
+ ecmd->advertising |= ADVERTISED_Autoneg |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_10000baseT_Full;
+ }
break;
case I40E_PHY_TYPE_10GBASE_CR1_CU:
case I40E_PHY_TYPE_10GBASE_CR1:
--
2.5.5
^ permalink raw reply related
* [net-next 09/14] i40evf: Fix get_rss_aq
From: Jeff Kirsher @ 2016-04-06 3:36 UTC (permalink / raw)
To: davem; +Cc: Catherine Sullivan, netdev, nhorman, sassmann, jogreene,
Jeff Kirsher
In-Reply-To: <1459913769-56510-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Catherine Sullivan <catherine.sullivan@intel.com>
We were passing in the seed where we should just be passing false
because we want the VSI table not the pf table.
Change-ID: I9b633ab06eb59468087f0c0af8539857e99f9495
Signed-off-by: Catherine Sullivan <catherine.sullivan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 6561a33..2d1fe56 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -1341,7 +1341,7 @@ static int i40evf_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
}
if (lut) {
- ret = i40evf_aq_get_rss_lut(hw, vsi->id, seed, lut, lut_size);
+ ret = i40evf_aq_get_rss_lut(hw, vsi->id, false, lut, lut_size);
if (ret) {
dev_err(&adapter->pdev->dev,
"Cannot get RSS lut, err %s aq_err %s\n",
--
2.5.5
^ permalink raw reply related
* [net-next 08/14] i40e: Disable link polling
From: Jeff Kirsher @ 2016-04-06 3:36 UTC (permalink / raw)
To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1459913769-56510-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Shannon Nelson <shannon.nelson@intel.com>
Periodic link polling was added when the link events were found not to be
trustworthy. This was the case early on, but was likely because the link
event mask was being used incorrectly. As this has been fixed in recent
code, we can disable the link polling to lessen the AQ traffic.
Change-ID: Id890b5ee3c2d04381fc76ffa434777644f5d8eb0
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 73d4bea..184f3f9 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -8448,7 +8448,6 @@ static int i40e_sw_init(struct i40e_pf *pf)
/* Set default capability flags */
pf->flags = I40E_FLAG_RX_CSUM_ENABLED |
I40E_FLAG_MSI_ENABLED |
- I40E_FLAG_LINK_POLLING_ENABLED |
I40E_FLAG_MSIX_ENABLED;
if (iommu_present(&pci_bus_type))
--
2.5.5
^ permalink raw reply related
* [net-next 07/14] i40evf: Add longer wait after remove module
From: Jeff Kirsher @ 2016-04-06 3:36 UTC (permalink / raw)
To: davem; +Cc: Mitch Williams, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1459913769-56510-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Mitch Williams <mitch.a.williams@intel.com>
Upon module remove, wait a little longer after requesting a reset before
checking to see if the firmware responded. This change prevents double
resets when the firmware is busy.
Change-ID: Ieedc988ee82fac1f32a074bf4d9e4dba426bfa58
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 2d018b4..6561a33 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -2854,11 +2854,11 @@ static void i40evf_remove(struct pci_dev *pdev)
adapter->state = __I40EVF_REMOVE;
adapter->aq_required = 0;
i40evf_request_reset(adapter);
- msleep(20);
+ msleep(50);
/* If the FW isn't responding, kick it once, but only once. */
if (!i40evf_asq_done(hw)) {
i40evf_request_reset(adapter);
- msleep(20);
+ msleep(50);
}
if (adapter->msix_entries) {
--
2.5.5
^ permalink raw reply related
* [net-next 05/14] i40e: Add new device ID for X722
From: Jeff Kirsher @ 2016-04-06 3:36 UTC (permalink / raw)
To: davem; +Cc: Catherine Sullivan, netdev, nhorman, sassmann, jogreene,
Jeff Kirsher
In-Reply-To: <1459913769-56510-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Catherine Sullivan <catherine.sullivan@intel.com>
The new device ID is 0x37D3 and it should follow the same flows and
branding string as for 0x37D0.
Change-ID: Ia5ad4a1910268c4666a3fd46a7afffbec55b4fc2
Signed-off-by: Catherine Sullivan <catherine.sullivan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_common.c | 1 +
drivers/net/ethernet/intel/i40e/i40e_devids.h | 1 +
drivers/net/ethernet/intel/i40e/i40e_main.c | 1 +
drivers/net/ethernet/intel/i40evf/i40e_common.c | 1 +
drivers/net/ethernet/intel/i40evf/i40e_devids.h | 1 +
5 files changed, 5 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 8276a13..ebcc0d3 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -60,6 +60,7 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw)
case I40E_DEV_ID_SFP_X722:
case I40E_DEV_ID_1G_BASE_T_X722:
case I40E_DEV_ID_10G_BASE_T_X722:
+ case I40E_DEV_ID_SFP_I_X722:
hw->mac.type = I40E_MAC_X722;
break;
default:
diff --git a/drivers/net/ethernet/intel/i40e/i40e_devids.h b/drivers/net/ethernet/intel/i40e/i40e_devids.h
index 99257fc..dd4457d 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_devids.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_devids.h
@@ -44,6 +44,7 @@
#define I40E_DEV_ID_SFP_X722 0x37D0
#define I40E_DEV_ID_1G_BASE_T_X722 0x37D1
#define I40E_DEV_ID_10G_BASE_T_X722 0x37D2
+#define I40E_DEV_ID_SFP_I_X722 0x37D3
#define i40e_is_40G_device(d) ((d) == I40E_DEV_ID_QSFP_A || \
(d) == I40E_DEV_ID_QSFP_B || \
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index fdcb50a..73d4bea 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -90,6 +90,7 @@ static const struct pci_device_id i40e_pci_tbl[] = {
{PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_X722), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_1G_BASE_T_X722), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T_X722), 0},
+ {PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_I_X722), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2_A), 0},
/* required last entry */
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_common.c b/drivers/net/ethernet/intel/i40evf/i40e_common.c
index 771ac6a..4db0c03 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_common.c
@@ -58,6 +58,7 @@ i40e_status i40e_set_mac_type(struct i40e_hw *hw)
case I40E_DEV_ID_SFP_X722:
case I40E_DEV_ID_1G_BASE_T_X722:
case I40E_DEV_ID_10G_BASE_T_X722:
+ case I40E_DEV_ID_SFP_I_X722:
hw->mac.type = I40E_MAC_X722;
break;
case I40E_DEV_ID_X722_VF:
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_devids.h b/drivers/net/ethernet/intel/i40evf/i40e_devids.h
index ca8b58c..7023570 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_devids.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_devids.h
@@ -44,6 +44,7 @@
#define I40E_DEV_ID_SFP_X722 0x37D0
#define I40E_DEV_ID_1G_BASE_T_X722 0x37D1
#define I40E_DEV_ID_10G_BASE_T_X722 0x37D2
+#define I40E_DEV_ID_SFP_I_X722 0x37D3
#define I40E_DEV_ID_X722_VF 0x37CD
#define I40E_DEV_ID_X722_VF_HV 0x37D9
--
2.5.5
^ permalink raw reply related
* [net-next 04/14] i40evf: Fix VLAN features
From: Jeff Kirsher @ 2016-04-06 3:35 UTC (permalink / raw)
To: davem; +Cc: Mitch Williams, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1459913769-56510-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Mitch Williams <mitch.a.williams@intel.com>
Users of ethtool were being given the mistaken impression that this
driver was able to change its VLAN tagging features, and were
disappointed that this was not actually the case. Implement
ndo_fix_features method so that we can adjust these flags as needed to
avoid false impressions.
Change-ID: I08584f103a4fa73d6a4128d472e4ef44dcfda57f
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index e397368..2d018b4 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -2252,6 +2252,28 @@ static int i40evf_change_mtu(struct net_device *netdev, int new_mtu)
return 0;
}
+#define I40EVF_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_TX |\
+ NETIF_F_HW_VLAN_CTAG_RX |\
+ NETIF_F_HW_VLAN_CTAG_FILTER)
+
+/**
+ * i40evf_fix_features - fix up the netdev feature bits
+ * @netdev: our net device
+ * @features: desired feature bits
+ *
+ * Returns fixed-up features bits
+ **/
+static netdev_features_t i40evf_fix_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ struct i40evf_adapter *adapter = netdev_priv(netdev);
+
+ features &= ~I40EVF_VLAN_FEATURES;
+ if (adapter->vf_res->vf_offload_flags & I40E_VIRTCHNL_VF_OFFLOAD_VLAN)
+ features |= I40EVF_VLAN_FEATURES;
+ return features;
+}
+
static const struct net_device_ops i40evf_netdev_ops = {
.ndo_open = i40evf_open,
.ndo_stop = i40evf_close,
@@ -2264,6 +2286,7 @@ static const struct net_device_ops i40evf_netdev_ops = {
.ndo_tx_timeout = i40evf_tx_timeout,
.ndo_vlan_rx_add_vid = i40evf_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = i40evf_vlan_rx_kill_vid,
+ .ndo_fix_features = i40evf_fix_features,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = i40evf_netpoll,
#endif
--
2.5.5
^ permalink raw reply related
* [net-next 01/14] i40e: remove redundant check on vsi->active_vlans
From: Jeff Kirsher @ 2016-04-06 3:35 UTC (permalink / raw)
To: davem; +Cc: Colin King, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1459913769-56510-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Colin King <colin.king@canonical.com>
active_vlans is an unsigned long array, hence a null check on this
array is superfluous and can be removed.
Detected with static analysis by smatch:
drivers/net/ethernet/intel/i40e/i40e_debugfs.c:386
i40e_dbg_dump_vsi_seid() warn: this array is probably
non-NULL. 'vsi->active_vlans'
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Acked-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
index 0c97733..83dccf1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -147,9 +147,8 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
dev_info(&pf->pdev->dev, " vlan_features = 0x%08lx\n",
(unsigned long int)nd->vlan_features);
}
- if (vsi->active_vlans)
- dev_info(&pf->pdev->dev,
- " vlgrp: & = %p\n", vsi->active_vlans);
+ dev_info(&pf->pdev->dev,
+ " vlgrp: & = %p\n", vsi->active_vlans);
dev_info(&pf->pdev->dev,
" state = %li flags = 0x%08lx, netdev_registered = %i, current_netdev_flags = 0x%04x\n",
vsi->state, vsi->flags,
--
2.5.5
^ permalink raw reply related
* [net-next 02/14] i40e: Enable Geneve offload for FW API ver > 1.4 for XL710/X710 devices
From: Jeff Kirsher @ 2016-04-06 3:35 UTC (permalink / raw)
To: davem
Cc: Anjali Singhai Jain, netdev, nhorman, sassmann, jogreene,
Jeff Kirsher
In-Reply-To: <1459913769-56510-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Anjali Singhai Jain <anjali.singhai@intel.com>
This patch enables the Capability for XL710/X710 devices with FW API
version higher than 1.4 to do geneve Rx offload.
Change-ID: I9a8f87772c48d7d67dc85e3701d2e0b845034c0b
Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 297fd39..fdcb50a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -9158,6 +9158,12 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
I40E_VLAN_ANY, false, true);
spin_unlock_bh(&vsi->mac_filter_list_lock);
}
+ } else if ((pf->hw.aq.api_maj_ver > 1) ||
+ ((pf->hw.aq.api_maj_ver == 1) &&
+ (pf->hw.aq.api_min_ver > 4))) {
+ /* Supported in FW API version higher than 1.4 */
+ pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
+ pf->auto_disable_flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
} else {
/* relate the VSI_VMDQ name to the VSI_MAIN name */
snprintf(netdev->name, IFNAMSIZ, "%sv%%d",
--
2.5.5
^ permalink raw reply related
* [net-next 03/14] i40e: Remove unused variable
From: Jeff Kirsher @ 2016-04-06 3:35 UTC (permalink / raw)
To: davem; +Cc: Mitch Williams, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1459913769-56510-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Mitch Williams <mitch.a.williams@intel.com>
This variable is vestigial, a remnant of the primordial code from which
this driver spawned. We can safely remove it.
Change-ID: I24e0fe338e7c7c50d27dc5515564f33caefbb93a
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 47b9e62..150002e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -1311,8 +1311,8 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
struct i40e_pf *pf = vf->pf;
i40e_status aq_ret = 0;
struct i40e_vsi *vsi;
- int i = 0, len = 0;
int num_vsis = 1;
+ int len = 0;
int ret;
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
@@ -1374,15 +1374,14 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
vfres->num_queue_pairs = vf->num_queue_pairs;
vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf;
if (vf->lan_vsi_idx) {
- vfres->vsi_res[i].vsi_id = vf->lan_vsi_id;
- vfres->vsi_res[i].vsi_type = I40E_VSI_SRIOV;
- vfres->vsi_res[i].num_queue_pairs = vsi->alloc_queue_pairs;
+ vfres->vsi_res[0].vsi_id = vf->lan_vsi_id;
+ vfres->vsi_res[0].vsi_type = I40E_VSI_SRIOV;
+ vfres->vsi_res[0].num_queue_pairs = vsi->alloc_queue_pairs;
/* VFs only use TC 0 */
- vfres->vsi_res[i].qset_handle
+ vfres->vsi_res[0].qset_handle
= le16_to_cpu(vsi->info.qs_handle[0]);
- ether_addr_copy(vfres->vsi_res[i].default_mac_addr,
+ ether_addr_copy(vfres->vsi_res[0].default_mac_addr,
vf->default_lan_addr.addr);
- i++;
}
set_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states);
--
2.5.5
^ permalink raw reply related
* [net-next 00/14][pull request] 40GbE Intel Wired LAN Driver Updates 2016-04-05
From: Jeff Kirsher @ 2016-04-06 3:35 UTC (permalink / raw)
To: davem; +Cc: Jeff Kirsher, netdev, nhorman, sassmann, jogreene, john.ronciak
This series contains updates to i40e and i40evf only.
Colin Ian King cleaned up a redundant NULL check which was found by static
analysis.
Anjali enables geneve receive offload for XL710/X710 devices.
Mitch cleans up unused variable in i40e_vc_get_vf_resources_msg().
Fixed the driver to actually be able to adjust VLAN tagging features
through ethtool, as expected. Fixed a problem where VF resets would
get lost by the PF preventing the VF driver from initializing. Also
put users mind at ease by lowering some message levels since many of
these conditions can happen any time VFs are enabled or disabled and
are not really indicative a fatal problems, unless they happen
continuously.
Shannon disables the link polling to lessen the admin queue traffic
especially since the link event mask usage has been fixed recently.
Alex Duyck fixes the i40e and i40evf drivers to correctly update
checksums for frames up to 16776960 in length which should be more than
large enough for all possible TSO frames in the near future.
The following are changes since commit 4da46cebbd3b4dc445195a9672c99c1353af5695:
net/core/dev: Warn on a too-short GRO frame
and are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue 40GbE
Alexander Duyck (1):
i40e/i40evf: Fix TSO checksum pseudo-header adjustment
Anjali Singhai Jain (1):
i40e: Enable Geneve offload for FW API ver > 1.4 for XL710/X710
devices
Avinash Dayanand (2):
i40e: Fix for supported link modes in 10GBaseT PHY's
i40e/i40evf: Bump patch from 1.5.1 to 1.5.2
Catherine Sullivan (2):
i40e: Add new device ID for X722
i40evf: Fix get_rss_aq
Colin King (1):
i40e: remove redundant check on vsi->active_vlans
Mitch Williams (5):
i40e: Remove unused variable
i40evf: Fix VLAN features
i40e: Make VF resets more reliable
i40evf: Add longer wait after remove module
i40e: Lower some message levels
Shannon Nelson (2):
i40e: Disable link polling
i40e: Request phy media event at reset time
drivers/net/ethernet/intel/i40e/i40e_common.c | 1 +
drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 5 ++-
drivers/net/ethernet/intel/i40e/i40e_devids.h | 1 +
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 16 ++++++++++
drivers/net/ethernet/intel/i40e/i40e_main.c | 12 +++++--
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 11 +++----
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 37 ++++++++++------------
drivers/net/ethernet/intel/i40evf/i40e_common.c | 1 +
drivers/net/ethernet/intel/i40evf/i40e_devids.h | 1 +
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 11 +++----
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 31 +++++++++++++++---
11 files changed, 84 insertions(+), 43 deletions(-)
--
2.5.5
^ permalink raw reply
* Re: [PATCH net-next 1/3] net: dsa: make the STP state function return void
From: Vivien Didelot @ 2016-04-06 3:16 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli,
Jiri Pirko, Scott Feldman
In-Reply-To: <20160405234714.GB19409@lunn.ch>
Hi Andrew,
Andrew Lunn <andrew@lunn.ch> writes:
>> -- port_stp_update: bridge layer function invoked when a given switch port STP
>> +- port_stp_state: bridge layer function invoked when a given switch port STP
>
> port_stp_state_set might be a better name, to make it clear it is
> setting the state, not getting the current state, etc. Most of the
> other functions are _add, _prepare, _join, _leave, so _set would fit
> the pattern.
I agree, I'm changing that.
> Changing to a void makes sense.
Thanks,
Vivien
^ permalink raw reply
* Re: [PATCH net-next 2/3] net: dsa: make the FDB add function return void
From: Vivien Didelot @ 2016-04-06 3:14 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli,
Jiri Pirko, Scott Feldman
In-Reply-To: <20160405235119.GC19409@lunn.ch>
Hi Andrew,
Andrew Lunn <andrew@lunn.ch> writes:
>> mutex_lock(&ps->smi_mutex);
>> - ret = _mv88e6xxx_port_fdb_load(ds, port, fdb->addr, fdb->vid, state);
>> + if (_mv88e6xxx_port_fdb_load(ds, port, fdb->addr, fdb->vid, state))
>> + netdev_warn(ds->ports[port], "cannot load address\n");
>
> In the SF2 driver you use pr_err, but here netdev_warn. We probably
> should be consistent if we error or warn. I would use netdev_error,
> since if this fails we probably have a real hardware problem.
I used pr_err in the SF2 driver to be consistent with the rest of the
code which only uses pr_err and pr_info.
I was thinking about adding ds_err and ds_port_err to print errors for
ds->master_dev and ds->ports[port], but that might be overkill. What do
you think? Or local to the driver for the moment, like mvsw_err maybe?
I tend to use warn for cases where the user cannot really do something
about the situation, but an hardware problem is indeed critical, so I
agree with you to use error over warn here.
Thanks,
Vivien
^ permalink raw reply
* [PATCH net-next V3 14/16] net: fec: create subroutine reset_tx_queue
From: Troy Kisky @ 2016-04-06 2:26 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
Create subroutine reset_tx_queue to have one place
to release any queued tx skbs.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: change commit message
---
drivers/net/ethernet/freescale/fec_main.c | 50 +++++++++++++++----------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 445443d..a38acf2 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -752,12 +752,33 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_OK;
}
+static void reset_tx_queue(struct fec_enet_private *fep,
+ struct fec_enet_priv_tx_q *txq)
+{
+ struct bufdesc *bdp = txq->bd.base;
+ unsigned int i;
+
+ txq->bd.cur = bdp;
+ for (i = 0; i < txq->bd.ring_size; i++) {
+ /* Initialize the BD for every fragment in the page. */
+ if (txq->tx_skbuff[i]) {
+ dev_kfree_skb_any(txq->tx_skbuff[i]);
+ txq->tx_skbuff[i] = NULL;
+ }
+ bdp->cbd_bufaddr = cpu_to_fec32(0);
+ bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+ BD_SC_WRAP : 0);
+ bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+ }
+ bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
+ txq->dirty_tx = bdp;
+}
+
/* Init RX & TX buffer descriptors
*/
static void fec_enet_bd_init(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
- struct fec_enet_priv_tx_q *txq;
struct fec_enet_priv_rx_q *rxq;
struct bufdesc *bdp;
unsigned int i;
@@ -780,26 +801,8 @@ static void fec_enet_bd_init(struct net_device *dev)
rxq->bd.cur = rxq->bd.base;
}
- for (q = 0; q < fep->num_tx_queues; q++) {
- /* ...and the same for transmit */
- txq = fep->tx_queue[q];
- bdp = txq->bd.base;
- txq->bd.cur = bdp;
-
- for (i = 0; i < txq->bd.ring_size; i++) {
- /* Initialize the BD for every fragment in the page. */
- if (txq->tx_skbuff[i]) {
- dev_kfree_skb_any(txq->tx_skbuff[i]);
- txq->tx_skbuff[i] = NULL;
- }
- bdp->cbd_bufaddr = cpu_to_fec32(0);
- bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
- BD_SC_WRAP : 0);
- bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
- }
- bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
- txq->dirty_tx = bdp;
- }
+ for (q = 0; q < fep->num_tx_queues; q++)
+ reset_tx_queue(fep, fep->tx_queue[q]);
}
static void fec_enet_active_rxring(struct net_device *ndev)
@@ -2648,13 +2651,10 @@ static void fec_enet_free_buffers(struct net_device *ndev)
for (q = 0; q < fep->num_tx_queues; q++) {
txq = fep->tx_queue[q];
- bdp = txq->bd.base;
+ reset_tx_queue(fep, txq);
for (i = 0; i < txq->bd.ring_size; i++) {
kfree(txq->tx_bounce[i]);
txq->tx_bounce[i] = NULL;
- skb = txq->tx_skbuff[i];
- txq->tx_skbuff[i] = NULL;
- dev_kfree_skb(skb);
}
}
}
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 16/16] net: fec: don't set cbd_bufaddr unless no mapping error
From: Troy Kisky @ 2016-04-06 2:26 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
Not assigning cbd_bufaddr on error will prevent trying to
unmap the error in case the FEC is reset.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: no change
---
drivers/net/ethernet/freescale/fec_main.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 101d820..c2ed8be 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -600,7 +600,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
void *bufaddr;
- unsigned long dmabuf;
+ dma_addr_t dmabuf;
unsigned int estatus = 0;
bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
@@ -1295,17 +1295,21 @@ fec_enet_new_rxbdp(struct net_device *ndev, struct bufdesc *bdp, struct sk_buff
{
struct fec_enet_private *fep = netdev_priv(ndev);
int off;
+ dma_addr_t dmabuf;
off = ((unsigned long)skb->data) & fep->rx_align;
if (off)
skb_reserve(skb, fep->rx_align + 1 - off);
- bdp->cbd_bufaddr = cpu_to_fec32(dma_map_single(&fep->pdev->dev, skb->data, FEC_ENET_RX_FRSIZE - fep->rx_align, DMA_FROM_DEVICE));
- if (dma_mapping_error(&fep->pdev->dev, fec32_to_cpu(bdp->cbd_bufaddr))) {
+ dmabuf = dma_map_single(&fep->pdev->dev, skb->data,
+ FEC_ENET_RX_FRSIZE - fep->rx_align,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&fep->pdev->dev, dmabuf)) {
if (net_ratelimit())
netdev_err(ndev, "Rx DMA memory map failed\n");
return -ENOMEM;
}
+ bdp->cbd_bufaddr = cpu_to_fec32(dmabuf);
return 0;
}
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 12/16] net: fec: dump all tx queues in fec_dump
From: Troy Kisky @ 2016-04-06 2:25 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
Dump all tx queues, not just queue 0.
Also, disable fec interrupts first.
The interrupts will be reenabled in fec_restart.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: no change
---
drivers/net/ethernet/freescale/fec_main.c | 40 +++++++++++++++++--------------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index f96ea97..be875fd 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -271,28 +271,32 @@ static void swap_buffer2(void *dst_buf, void *src_buf, int len)
static void fec_dump(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
- struct bufdesc *bdp;
- struct fec_enet_priv_tx_q *txq;
- int index = 0;
+ int i;
+ /* Disable all FEC interrupts */
+ writel(0, fep->hwp + FEC_IMASK);
netdev_info(ndev, "TX ring dump\n");
pr_info("Nr SC addr len SKB\n");
- txq = fep->tx_queue[0];
- bdp = txq->bd.base;
-
- do {
- pr_info("%3u %c%c 0x%04x 0x%08x %4u %p\n",
- index,
- bdp == txq->bd.cur ? 'S' : ' ',
- bdp == txq->dirty_tx ? 'H' : ' ',
- fec16_to_cpu(bdp->cbd_sc),
- fec32_to_cpu(bdp->cbd_bufaddr),
- fec16_to_cpu(bdp->cbd_datlen),
- txq->tx_skbuff[index]);
- bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
- index++;
- } while (bdp != txq->bd.base);
+ for (i = 0; i < fep->num_tx_queues; i++) {
+ struct fec_enet_priv_tx_q *txq = fep->tx_queue[i];
+ struct bufdesc *bdp = txq->bd.base;
+ int index = 0;
+
+ pr_info("tx queue %d\n", i);
+ do {
+ pr_info("%3u %c%c 0x%04x 0x%08x %4u %p\n",
+ index,
+ bdp == txq->bd.cur ? 'S' : ' ',
+ bdp == txq->dirty_tx ? 'H' : ' ',
+ fec16_to_cpu(bdp->cbd_sc),
+ fec32_to_cpu(bdp->cbd_bufaddr),
+ fec16_to_cpu(bdp->cbd_datlen),
+ txq->tx_skbuff[index]);
+ bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+ index++;
+ } while (bdp != txq->bd.base);
+ }
}
static inline bool is_ipv4_pkt(struct sk_buff *skb)
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 15/16] net: fec: call dma_unmap_single on mapped tx buffers at restart
From: Troy Kisky @ 2016-04-06 2:26 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
Make sure any pending tx buffers are unmapped when the
fec is restarted.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: no change
---
drivers/net/ethernet/freescale/fec_main.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index a38acf2..101d820 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -404,6 +404,7 @@ dma_mapping_error:
bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
dma_unmap_single(&fep->pdev->dev, fec32_to_cpu(bdp->cbd_bufaddr),
fec16_to_cpu(bdp->cbd_datlen), DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = cpu_to_fec32(0);
}
return ERR_PTR(-ENOMEM);
}
@@ -761,11 +762,18 @@ static void reset_tx_queue(struct fec_enet_private *fep,
txq->bd.cur = bdp;
for (i = 0; i < txq->bd.ring_size; i++) {
/* Initialize the BD for every fragment in the page. */
+ if (bdp->cbd_bufaddr) {
+ if (!IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr)))
+ dma_unmap_single(&fep->pdev->dev,
+ fec32_to_cpu(bdp->cbd_bufaddr),
+ fec16_to_cpu(bdp->cbd_datlen),
+ DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = cpu_to_fec32(0);
+ }
if (txq->tx_skbuff[i]) {
dev_kfree_skb_any(txq->tx_skbuff[i]);
txq->tx_skbuff[i] = NULL;
}
- bdp->cbd_bufaddr = cpu_to_fec32(0);
bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
BD_SC_WRAP : 0);
bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
@@ -2643,6 +2651,7 @@ static void fec_enet_free_buffers(struct net_device *ndev)
fec32_to_cpu(bdp->cbd_bufaddr),
FEC_ENET_RX_FRSIZE - fep->rx_align,
DMA_FROM_DEVICE);
+ bdp->cbd_bufaddr = cpu_to_fec32(0);
dev_kfree_skb(skb);
}
bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 13/16] net: fec: detect tx int lost
From: Troy Kisky @ 2016-04-06 2:25 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
If a tx int is lost, no need to reset
the fec. Just mark the event and call napi_schedule.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: no change
---
drivers/net/ethernet/freescale/fec_main.c | 38 ++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index be875fd..445443d 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1094,14 +1094,50 @@ fec_stop(struct net_device *ndev)
}
}
+static const uint txint_flags[] = {
+ FEC_ENET_TXF_0, FEC_ENET_TXF_1, FEC_ENET_TXF_2
+};
static void
fec_timeout(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
+ struct bufdesc *bdp;
+ unsigned short status;
+ int i;
+ uint events = 0;
- fec_dump(ndev);
+ for (i = 0; i < fep->num_tx_queues; i++) {
+ struct fec_enet_priv_tx_q *txq = fep->tx_queue[i];
+ int index;
+ struct sk_buff *skb = NULL;
+ bdp = txq->dirty_tx;
+ while (1) {
+ bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+ if (bdp == txq->bd.cur)
+ break;
+ index = fec_enet_get_bd_index(bdp, &txq->bd);
+ skb = txq->tx_skbuff[index];
+ if (skb) {
+ status = fec16_to_cpu(bdp->cbd_sc);
+ if ((status & BD_ENET_TX_READY) == 0)
+ events |= txint_flags[i];
+ break;
+ }
+ }
+ }
+ if (events) {
+ fep->events |= events;
+ /* Disable the RX/TX interrupt */
+ writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
+ napi_schedule(&fep->napi);
+ netif_wake_queue(fep->netdev);
+ pr_err("%s: tx int lost\n", __func__);
+ return;
+ }
+
+ fec_dump(ndev);
ndev->stats.tx_errors++;
schedule_work(&fep->tx_timeout_work);
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 09/16] net: fec: eliminate calls to fec_enet_get_prevdesc
From: Troy Kisky @ 2016-04-06 2:25 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
Eliminating calls to fec_enet_get_prevdesc shrinks
the code a little.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: Change commit message
s/unsigned status/unsigned int status/ as requested
---
drivers/net/ethernet/freescale/fec_main.c | 37 +++++++++----------------------
1 file changed, 11 insertions(+), 26 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 21d2cd0..349fda1 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -758,6 +758,7 @@ static void fec_enet_bd_init(struct net_device *dev)
struct bufdesc *bdp;
unsigned int i;
unsigned int q;
+ unsigned int status;
for (q = 0; q < fep->num_rx_queues; q++) {
/* Initialize the receive buffer descriptors. */
@@ -765,19 +766,13 @@ static void fec_enet_bd_init(struct net_device *dev)
bdp = rxq->bd.base;
for (i = 0; i < rxq->bd.ring_size; i++) {
-
/* Initialize the BD for every fragment in the page. */
- if (bdp->cbd_bufaddr)
- bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY);
- else
- bdp->cbd_sc = cpu_to_fec16(0);
+ status = bdp->cbd_bufaddr ? BD_ENET_RX_EMPTY : 0;
+ if (bdp == rxq->bd.last)
+ status |= BD_SC_WRAP;
+ bdp->cbd_sc = cpu_to_fec16(status);
bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
}
-
- /* Set the last buffer to wrap */
- bdp = fec_enet_get_prevdesc(bdp, &rxq->bd);
- bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
-
rxq->bd.cur = rxq->bd.base;
}
@@ -789,18 +784,16 @@ static void fec_enet_bd_init(struct net_device *dev)
for (i = 0; i < txq->bd.ring_size; i++) {
/* Initialize the BD for every fragment in the page. */
- bdp->cbd_sc = cpu_to_fec16(0);
if (txq->tx_skbuff[i]) {
dev_kfree_skb_any(txq->tx_skbuff[i]);
txq->tx_skbuff[i] = NULL;
}
bdp->cbd_bufaddr = cpu_to_fec32(0);
+ bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+ BD_SC_WRAP : 0);
bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
}
-
- /* Set the last buffer to wrap */
bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
- bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
txq->dirty_tx = bdp;
}
}
@@ -2717,19 +2710,16 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
}
rxq->rx_skbuff[i] = skb;
- bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY);
if (fep->bufdesc_ex) {
struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
ebdp->cbd_esc = cpu_to_fec32(BD_ENET_RX_INT);
}
+ bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY |
+ ((bdp == rxq->bd.last) ? BD_SC_WRAP : 0));
bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
}
-
- /* Set the last buffer to wrap. */
- bdp = fec_enet_get_prevdesc(bdp, &rxq->bd);
- bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
return 0;
err_alloc:
@@ -2752,21 +2742,16 @@ fec_enet_alloc_txq_buffers(struct net_device *ndev, unsigned int queue)
if (!txq->tx_bounce[i])
goto err_alloc;
- bdp->cbd_sc = cpu_to_fec16(0);
bdp->cbd_bufaddr = cpu_to_fec32(0);
if (fep->bufdesc_ex) {
struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
ebdp->cbd_esc = cpu_to_fec32(BD_ENET_TX_INT);
}
-
+ bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+ BD_SC_WRAP : 0);
bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
}
-
- /* Set the last buffer to wrap. */
- bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
- bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
-
return 0;
err_alloc:
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 11/16] net: fec: clear cbd_sc after transmission to help with debugging
From: Troy Kisky @ 2016-04-06 2:25 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
When the tx queue is dumped, it is easier to see that this
entry is idle if cbd_sc is cleared after transmission.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: change commit message
---
drivers/net/ethernet/freescale/fec_main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index a2a9dca..f96ea97 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1164,6 +1164,8 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
}
break;
}
+ bdp->cbd_sc = cpu_to_fec16((bdp == txq->bd.last) ?
+ BD_SC_WRAP : 0);
index = fec_enet_get_bd_index(bdp, &txq->bd);
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 10/16] net: fec: move restart test for efficiency
From: Troy Kisky @ 2016-04-06 2:25 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
Move restart test to earlier in fec_txq() which saves one comparison.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: change commit message
---
drivers/net/ethernet/freescale/fec_main.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 349fda1..a2a9dca 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1157,8 +1157,13 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
/* Order the load of bd.cur and cbd_sc */
rmb();
status = fec16_to_cpu(READ_ONCE(bdp->cbd_sc));
- if (status & BD_ENET_TX_READY)
+ if (status & BD_ENET_TX_READY) {
+ if (!readl(txq->bd.reg_desc_active)) {
+ /* ERR006358 has hit, restart tx */
+ writel(0, txq->bd.reg_desc_active);
+ }
break;
+ }
index = fec_enet_get_bd_index(bdp, &txq->bd);
@@ -1230,11 +1235,6 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
netif_tx_wake_queue(nq);
}
}
-
- /* ERR006538: Keep the transmitter going */
- if (bdp != txq->bd.cur &&
- readl(txq->bd.reg_desc_active) == 0)
- writel(0, txq->bd.reg_desc_active);
}
static int
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 08/16] net: fec: set cbd_sc without relying on previous value
From: Troy Kisky @ 2016-04-06 2:25 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
Relying on the wrap bit of cdb_sc to stay valid once
initialized when the controller also writes to this byte
seems undesirable since we can easily know what the value
should be.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: change commit message
---
drivers/net/ethernet/freescale/fec_main.c | 38 +++++++++----------------------
1 file changed, 11 insertions(+), 27 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 3cd0cdf..21d2cd0 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -340,9 +340,8 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
ebdp = (struct bufdesc_ex *)bdp;
- status = fec16_to_cpu(bdp->cbd_sc);
- status &= ~BD_ENET_TX_STATS;
- status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
+ status = BD_ENET_TX_TC | BD_ENET_TX_READY |
+ ((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
frag_len = skb_shinfo(skb)->frags[frag].size;
/* Handle the last BD specially */
@@ -436,8 +435,6 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
/* Fill in a Tx ring entry */
bdp = txq->bd.cur;
last_bdp = bdp;
- status = fec16_to_cpu(bdp->cbd_sc);
- status &= ~BD_ENET_TX_STATS;
/* Set buffer length and buffer pointer */
bufaddr = skb->data;
@@ -462,6 +459,8 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
return NETDEV_TX_OK;
}
+ status = BD_ENET_TX_TC | BD_ENET_TX_READY |
+ ((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
if (nr_frags) {
last_bdp = fec_enet_txq_submit_frag_skb(txq, skb, ndev);
if (IS_ERR(last_bdp)) {
@@ -512,7 +511,6 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
/* Send it on its way. Tell FEC it's ready, interrupt when done,
* it's the last BD of the frame, and to put the CRC on the end.
*/
- status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
bdp->cbd_sc = cpu_to_fec16(status);
/* If this was the last BD in the ring, start at the beginning again. */
@@ -544,11 +542,6 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
unsigned int estatus = 0;
dma_addr_t addr;
- status = fec16_to_cpu(bdp->cbd_sc);
- status &= ~BD_ENET_TX_STATS;
-
- status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
-
if (((unsigned long) data) & fep->tx_align ||
fep->quirks & FEC_QUIRK_SWAP_FRAME) {
memcpy(txq->tx_bounce[index], data, size);
@@ -578,15 +571,16 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
ebdp->cbd_esc = cpu_to_fec32(estatus);
}
+ status = BD_ENET_TX_TC | BD_ENET_TX_READY |
+ ((bdp == txq->bd.last) ? BD_SC_WRAP : 0);
/* Handle the last BD specially */
if (last_tcp)
- status |= (BD_ENET_TX_LAST | BD_ENET_TX_TC);
+ status |= BD_ENET_TX_LAST;
if (is_last) {
status |= BD_ENET_TX_INTR;
if (fep->bufdesc_ex)
ebdp->cbd_esc |= cpu_to_fec32(BD_ENET_TX_INT);
}
-
bdp->cbd_sc = cpu_to_fec16(status);
return 0;
@@ -602,13 +596,8 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
void *bufaddr;
unsigned long dmabuf;
- unsigned short status;
unsigned int estatus = 0;
- status = fec16_to_cpu(bdp->cbd_sc);
- status &= ~BD_ENET_TX_STATS;
- status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
-
bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
dmabuf = txq->tso_hdrs_dma + index * TSO_HEADER_SIZE;
if (((unsigned long)bufaddr) & fep->tx_align ||
@@ -641,8 +630,8 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
ebdp->cbd_esc = cpu_to_fec32(estatus);
}
- bdp->cbd_sc = cpu_to_fec16(status);
-
+ bdp->cbd_sc = cpu_to_fec16(BD_ENET_TX_TC | BD_ENET_TX_READY |
+ ((bdp == txq->bd.last) ? BD_SC_WRAP : 0));
return 0;
}
@@ -1454,12 +1443,6 @@ static int fec_rxq(struct net_device *ndev, struct fec_enet_priv_rx_q *rxq,
}
rx_processing_done:
- /* Clear the status flags for this buffer */
- status &= ~BD_ENET_RX_STATS;
-
- /* Mark the buffer empty */
- status |= BD_ENET_RX_EMPTY;
-
if (fep->bufdesc_ex) {
struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
@@ -1471,7 +1454,8 @@ rx_processing_done:
* performed before transferring ownership.
*/
wmb();
- bdp->cbd_sc = cpu_to_fec16(status);
+ bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY |
+ ((bdp == rxq->bd.last) ? BD_SC_WRAP : 0));
/* Update BD pointer to next entry */
bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 07/16] net: fec: don't clear all rx queue bits when just one is being checked
From: Troy Kisky @ 2016-04-06 2:25 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
FEC_ENET_RXF is 3 separate bits, we only check one queue
at a time. So, when the last queue is being checked, it is
bad to remove the interrupt on the 1st queue.
Also, since tx/rx interrupts are now cleared in the napi
routine and not the interrupt, it is not needed here any longer.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: change commit message
---
drivers/net/ethernet/freescale/fec_main.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 17140ea..3cd0cdf 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1339,8 +1339,6 @@ static int fec_rxq(struct net_device *ndev, struct fec_enet_priv_rx_q *rxq,
break;
pkt_received++;
- writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
-
/* Check for errors. */
status ^= BD_ENET_RX_LAST;
if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 06/16] net: fec: split off napi routine with 3 queues
From: Troy Kisky @ 2016-04-06 2:25 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
If we only have 1 tx/rx queue, we need not check
the other queues.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3: rebase changes only, fep is no longer passed as a parameter to
fec_rxq/fec_txq
---
drivers/net/ethernet/freescale/fec_main.c | 39 +++++++++++++++++++++++++++++--
1 file changed, 37 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 918ac82..17140ea 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1524,7 +1524,7 @@ fec_enet_interrupt(int irq, void *dev_id)
return ret;
}
-static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
+static int fec_enet_napi_q3(struct napi_struct *napi, int budget)
{
struct net_device *ndev = napi->dev;
struct fec_enet_private *fep = netdev_priv(ndev);
@@ -1564,6 +1564,39 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
return pkts;
}
+static int fec_enet_napi_q1(struct napi_struct *napi, int budget)
+{
+ struct net_device *ndev = napi->dev;
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ int pkts = 0;
+ uint events;
+
+ do {
+ events = readl(fep->hwp + FEC_IEVENT);
+ if (fep->events) {
+ events |= fep->events;
+ fep->events = 0;
+ }
+ events &= FEC_ENET_RXF_0 | FEC_ENET_TXF_0;
+ if (!events) {
+ if (budget) {
+ napi_complete(napi);
+ writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+ }
+ return pkts;
+ }
+
+ writel(events, fep->hwp + FEC_IEVENT);
+ if (events & FEC_ENET_RXF_0)
+ pkts += fec_rxq(ndev, fep->rx_queue[0],
+ budget - pkts);
+ if (events & FEC_ENET_TXF_0)
+ fec_txq(ndev, fep->tx_queue[0]);
+ } while (pkts < budget);
+ fep->events |= FEC_ENET_RXF_0; /* save for next callback */
+ return pkts;
+}
+
/* ------------------------------------------------------------------------- */
static void fec_get_mac(struct net_device *ndev)
{
@@ -3123,7 +3156,9 @@ static int fec_enet_init(struct net_device *ndev)
ndev->ethtool_ops = &fec_enet_ethtool_ops;
writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);
- netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, NAPI_POLL_WEIGHT);
+ netif_napi_add(ndev, &fep->napi, (fep->num_rx_queues |
+ fep->num_tx_queues) == 1 ? fec_enet_napi_q1 :
+ fec_enet_napi_q3, NAPI_POLL_WEIGHT);
if (fep->quirks & FEC_QUIRK_HAS_VLAN)
/* enable hw VLAN support */
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 05/16] net: fec: reduce interrupts
From: Troy Kisky @ 2016-04-06 2:25 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
By clearing the NAPI interrupts in the NAPI routine
and not in the interrupt handler, we can reduce the
number of interrupts. We also don't need any status
variables as the registers are still valid.
Also, notice that if budget pkts are received, the
next call to fec_enet_rx_napi will now continue to
receive the previously pending packets.
To test that this actually reduces interrupts, try
this command before/after patch
cat /proc/interrupts |grep ether; \
ping -s2800 192.168.0.201 -f -c1000 ; \
cat /proc/interrupts |grep ether
For me, before this patch is 2996 interrupts.
After patch is 2010 interrupts.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
v3:
Fix introduced bug of checking for FEC_ENET_TS_TIMER
before calling fec_ptp_check_pps_event
Changed commit message to show measured changes.
Used netdev_info instead of pr_info.
Fugang Duan suggested splitting TX and RX into two NAPI
contexts, but that should be a separate patch as it
is unrelated to what this patch does.
---
drivers/net/ethernet/freescale/fec.h | 6 +-
drivers/net/ethernet/freescale/fec_main.c | 118 +++++++++++-------------------
2 files changed, 45 insertions(+), 79 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 6dd0ba8..9d5bdc6 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -505,11 +505,7 @@ struct fec_enet_private {
unsigned int total_tx_ring_size;
unsigned int total_rx_ring_size;
-
- unsigned long work_tx;
- unsigned long work_rx;
- unsigned long work_ts;
- unsigned long work_mdio;
+ uint events;
struct platform_device *pdev;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index b4d46f8..918ac82 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -70,8 +70,6 @@ static void fec_enet_itr_coal_init(struct net_device *ndev);
#define DRIVER_NAME "fec"
-#define FEC_ENET_GET_QUQUE(_x) ((_x == 0) ? 1 : ((_x == 1) ? 2 : 0))
-
/* Pause frame feild and FIFO threshold */
#define FEC_ENET_FCE (1 << 5)
#define FEC_ENET_RSEM_V 0x84
@@ -1257,21 +1255,6 @@ static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
writel(0, txq->bd.reg_desc_active);
}
-static void
-fec_enet_tx(struct net_device *ndev)
-{
- struct fec_enet_private *fep = netdev_priv(ndev);
- struct fec_enet_priv_tx_q *txq;
- u16 queue_id;
- /* First process class A queue, then Class B and Best Effort queue */
- for_each_set_bit(queue_id, &fep->work_tx, FEC_ENET_MAX_TX_QS) {
- clear_bit(queue_id, &fep->work_tx);
- txq = fep->tx_queue[FEC_ENET_GET_QUQUE(queue_id)];
- fec_txq(ndev, txq);
- }
- return;
-}
-
static int
fec_enet_new_rxbdp(struct net_device *ndev, struct bufdesc *bdp, struct sk_buff *skb)
{
@@ -1505,70 +1488,34 @@ rx_processing_done:
return pkt_received;
}
-static int
-fec_enet_rx(struct net_device *ndev, int budget)
-{
- int pkt_received = 0;
- u16 queue_id;
- struct fec_enet_private *fep = netdev_priv(ndev);
- struct fec_enet_priv_rx_q *rxq;
-
- for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) {
- clear_bit(queue_id, &fep->work_rx);
- rxq = fep->rx_queue[FEC_ENET_GET_QUQUE(queue_id)];
- pkt_received += fec_rxq(ndev, rxq, budget - pkt_received);
- }
- return pkt_received;
-}
-
-static bool
-fec_enet_collect_events(struct fec_enet_private *fep, uint int_events)
-{
- if (int_events == 0)
- return false;
-
- if (int_events & FEC_ENET_RXF_0)
- fep->work_rx |= (1 << 2);
- if (int_events & FEC_ENET_RXF_1)
- fep->work_rx |= (1 << 0);
- if (int_events & FEC_ENET_RXF_2)
- fep->work_rx |= (1 << 1);
-
- if (int_events & FEC_ENET_TXF_0)
- fep->work_tx |= (1 << 2);
- if (int_events & FEC_ENET_TXF_1)
- fep->work_tx |= (1 << 0);
- if (int_events & FEC_ENET_TXF_2)
- fep->work_tx |= (1 << 1);
-
- return true;
-}
-
static irqreturn_t
fec_enet_interrupt(int irq, void *dev_id)
{
struct net_device *ndev = dev_id;
struct fec_enet_private *fep = netdev_priv(ndev);
- uint int_events;
irqreturn_t ret = IRQ_NONE;
+ uint eir = readl(fep->hwp + FEC_IEVENT);
+ uint int_events = eir & readl(fep->hwp + FEC_IMASK);
- int_events = readl(fep->hwp + FEC_IEVENT);
- writel(int_events, fep->hwp + FEC_IEVENT);
- fec_enet_collect_events(fep, int_events);
-
- if ((fep->work_tx || fep->work_rx) && fep->link) {
- ret = IRQ_HANDLED;
-
+ if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) {
if (napi_schedule_prep(&fep->napi)) {
/* Disable the NAPI interrupts */
writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
__napi_schedule(&fep->napi);
+ int_events &= ~(FEC_ENET_RXF | FEC_ENET_TXF);
+ ret = IRQ_HANDLED;
+ } else {
+ fep->events |= int_events;
+ netdev_info(ndev, "couldn't schedule NAPI\n");
}
}
- if (int_events & FEC_ENET_MII) {
+ if (int_events) {
ret = IRQ_HANDLED;
- complete(&fep->mdio_done);
+ writel(int_events, fep->hwp + FEC_IEVENT);
+ if (int_events & FEC_ENET_MII) {
+ complete(&fep->mdio_done);
+ }
}
if (fep->ptp_clock)
@@ -1581,16 +1528,39 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
{
struct net_device *ndev = napi->dev;
struct fec_enet_private *fep = netdev_priv(ndev);
- int pkts;
-
- pkts = fec_enet_rx(ndev, budget);
+ int pkts = 0;
+ uint events;
- fec_enet_tx(ndev);
+ do {
+ events = readl(fep->hwp + FEC_IEVENT);
+ if (fep->events) {
+ events |= fep->events;
+ fep->events = 0;
+ }
+ events &= FEC_ENET_RXF | FEC_ENET_TXF;
+ if (!events) {
+ if (budget) {
+ napi_complete(napi);
+ writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+ }
+ return pkts;
+ }
- if (pkts < budget) {
- napi_complete(napi);
- writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
- }
+ writel(events, fep->hwp + FEC_IEVENT);
+ if (events & FEC_ENET_RXF_1)
+ pkts += fec_rxq(ndev, fep->rx_queue[1], budget - pkts);
+ if (events & FEC_ENET_RXF_2)
+ pkts += fec_rxq(ndev, fep->rx_queue[2], budget - pkts);
+ if (events & FEC_ENET_RXF_0)
+ pkts += fec_rxq(ndev, fep->rx_queue[0], budget - pkts);
+ if (events & FEC_ENET_TXF_1)
+ fec_txq(ndev, fep->tx_queue[1]);
+ if (events & FEC_ENET_TXF_2)
+ fec_txq(ndev, fep->tx_queue[2]);
+ if (events & FEC_ENET_TXF_0)
+ fec_txq(ndev, fep->tx_queue[0]);
+ } while (pkts < budget);
+ fep->events |= events & FEC_ENET_RXF; /* save for next callback */
return pkts;
}
--
2.5.0
^ permalink raw reply related
* [PATCH net-next V3 04/16] net: fec: pass rxq/txq to fec_enet_rx/tx_queue instead of queue_id
From: Troy Kisky @ 2016-04-06 2:25 UTC (permalink / raw)
To: netdev, davem, fugang.duan, lznuaa
Cc: fabio.estevam, l.stach, andrew, tremyfr, gerg, linux-arm-kernel,
johannes, stillcompiling, sergei.shtylyov, arnd, Troy Kisky
In-Reply-To: <1459909562-22865-1-git-send-email-troy.kisky@boundarydevices.com>
The queue_id is the qid member of struct bufdesc_prop.
Passing rxq/txq will allow the macro FEC_ENET_GET_QUQUE to be removed
in the next patch.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Fugang Duan <fugang.duan@nxp.com>
---
v3:
add Acked-by
combine with "net: fec: pass txq to fec_enet_tx_queue instead of queue_id"
reverted change that passed fep as a parameter
---
drivers/net/ethernet/freescale/fec_main.c | 29 +++++++++++------------------
1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 7993040..b4d46f8 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1156,25 +1156,18 @@ fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
hwtstamps->hwtstamp = ns_to_ktime(ns);
}
-static void
-fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
+static void fec_txq(struct net_device *ndev, struct fec_enet_priv_tx_q *txq)
{
- struct fec_enet_private *fep;
+ struct fec_enet_private *fep = netdev_priv(ndev);
struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
- struct fec_enet_priv_tx_q *txq;
struct netdev_queue *nq;
int index = 0;
int entries_free;
- fep = netdev_priv(ndev);
-
- queue_id = FEC_ENET_GET_QUQUE(queue_id);
-
- txq = fep->tx_queue[queue_id];
/* get next bdp of dirty_tx */
- nq = netdev_get_tx_queue(ndev, queue_id);
+ nq = netdev_get_tx_queue(ndev, txq->bd.qid);
bdp = txq->dirty_tx;
/* get next bdp of dirty_tx */
@@ -1268,11 +1261,13 @@ static void
fec_enet_tx(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
+ struct fec_enet_priv_tx_q *txq;
u16 queue_id;
/* First process class A queue, then Class B and Best Effort queue */
for_each_set_bit(queue_id, &fep->work_tx, FEC_ENET_MAX_TX_QS) {
clear_bit(queue_id, &fep->work_tx);
- fec_enet_tx_queue(ndev, queue_id);
+ txq = fep->tx_queue[FEC_ENET_GET_QUQUE(queue_id)];
+ fec_txq(ndev, txq);
}
return;
}
@@ -1328,11 +1323,10 @@ static bool fec_enet_copybreak(struct net_device *ndev, struct sk_buff **skb,
* not been given to the system, we just set the empty indicator,
* effectively tossing the packet.
*/
-static int
-fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+static int fec_rxq(struct net_device *ndev, struct fec_enet_priv_rx_q *rxq,
+ int budget)
{
struct fec_enet_private *fep = netdev_priv(ndev);
- struct fec_enet_priv_rx_q *rxq;
struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb_new = NULL;
@@ -1350,8 +1344,6 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
#ifdef CONFIG_M532x
flush_cache_all();
#endif
- queue_id = FEC_ENET_GET_QUQUE(queue_id);
- rxq = fep->rx_queue[queue_id];
/* First, grab all of the stats for the incoming packet.
* These get messed up if we get called due to a busy condition.
@@ -1519,11 +1511,12 @@ fec_enet_rx(struct net_device *ndev, int budget)
int pkt_received = 0;
u16 queue_id;
struct fec_enet_private *fep = netdev_priv(ndev);
+ struct fec_enet_priv_rx_q *rxq;
for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) {
clear_bit(queue_id, &fep->work_rx);
- pkt_received += fec_enet_rx_queue(ndev,
- budget - pkt_received, queue_id);
+ rxq = fep->rx_queue[FEC_ENET_GET_QUQUE(queue_id)];
+ pkt_received += fec_rxq(ndev, rxq, budget - pkt_received);
}
return pkt_received;
}
--
2.5.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox