aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/Kconfig1
-rw-r--r--drivers/net/ethernet/Makefile1
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-main.c10
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_filters.c5
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_main.c4
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_nic.c2
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_vec.c3
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c7
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c17
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c36
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c9
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c12
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c8
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h6
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c1
-rw-r--r--drivers/net/ethernet/cadence/macb_main.c2
-rw-r--r--drivers/net/ethernet/cavium/common/cavium_ptp.c2
-rw-r--r--drivers/net/ethernet/cavium/liquidio/request_manager.c4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c4
-rw-r--r--drivers/net/ethernet/ezchip/nps_enet.h4
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_ptp.c5
-rw-r--r--drivers/net/ethernet/google/gve/gve_main.c2
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c2
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.c9
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c18
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c12
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c29
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c3
-rw-r--r--drivers/net/ethernet/marvell/sky2.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c19
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c48
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c97
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c46
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c33
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.h4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c12
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/health.c22
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c138
-rw-r--r--drivers/net/ethernet/micrel/Kconfig11
-rw-r--r--drivers/net/ethernet/micrel/Makefile1
-rw-r--r--drivers/net/ethernet/micrel/ks8695net.c1632
-rw-r--r--drivers/net/ethernet/micrel/ks8695net.h108
-rw-r--r--drivers/net/ethernet/mscc/ocelot_ace.c2
-rw-r--r--drivers/net/ethernet/mscc/ocelot_flower.c12
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge.c2
-rw-r--r--drivers/net/ethernet/natsemi/sonic.c6
-rw-r--r--drivers/net/ethernet/netronome/nfp/bpf/jit.c17
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/cmsg.c10
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/offload.c14
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/qos_conf.c2
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c8
-rw-r--r--drivers/net/ethernet/nuvoton/Kconfig29
-rw-r--r--drivers/net/ethernet/nuvoton/Makefile6
-rw-r--r--drivers/net/ethernet/nuvoton/w90p910_ether.c1082
-rw-r--r--drivers/net/ethernet/nvidia/forcedeth.c143
-rw-r--r--drivers/net/ethernet/nxp/Kconfig2
-rw-r--r--drivers/net/ethernet/nxp/lpc_eth.c45
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_main.c4
-rw-r--r--drivers/net/ethernet/realtek/r8169_main.c1
-rw-r--r--drivers/net/ethernet/renesas/ravb_main.c8
-rw-r--r--drivers/net/ethernet/seeq/sgiseeq.c7
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c7
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c2
-rw-r--r--drivers/net/ethernet/ti/cpsw.c2
-rw-r--r--drivers/net/ethernet/toshiba/tc35815.c2
-rw-r--r--drivers/net/ethernet/tundra/tsi108_eth.c5
77 files changed, 559 insertions, 3301 deletions
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index 93a2d4deb27c..dc9dee55976b 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -151,7 +151,6 @@ config NET_NETX
To compile this driver as a module, choose M here. The module
will be called netx-eth.
-source "drivers/net/ethernet/nuvoton/Kconfig"
source "drivers/net/ethernet/nvidia/Kconfig"
source "drivers/net/ethernet/nxp/Kconfig"
source "drivers/net/ethernet/oki-semi/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index fb9155cffcff..4bc3c95562bf 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -65,7 +65,6 @@ obj-$(CONFIG_NET_VENDOR_NETERION) += neterion/
obj-$(CONFIG_NET_VENDOR_NETRONOME) += netronome/
obj-$(CONFIG_NET_VENDOR_NI) += ni/
obj-$(CONFIG_NET_NETX) += netx-eth.o
-obj-$(CONFIG_NET_VENDOR_NUVOTON) += nuvoton/
obj-$(CONFIG_NET_VENDOR_NVIDIA) += nvidia/
obj-$(CONFIG_LPC_ENET) += nxp/
obj-$(CONFIG_NET_VENDOR_OKI) += oki-semi/
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index b41f23679a08..7ce9c69e9c44 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -469,13 +469,19 @@ static int __init xgbe_mod_init(void)
ret = xgbe_platform_init();
if (ret)
- return ret;
+ goto err_platform_init;
ret = xgbe_pci_init();
if (ret)
- return ret;
+ goto err_pci_init;
return 0;
+
+err_pci_init:
+ xgbe_platform_exit();
+err_platform_init:
+ unregister_netdevice_notifier(&xgbe_netdev_notifier);
+ return ret;
}
static void __exit xgbe_mod_exit(void)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c
index 440690b18734..aee827f07c16 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c
@@ -431,7 +431,8 @@ int aq_del_fvlan_by_vlan(struct aq_nic_s *aq_nic, u16 vlan_id)
if (be16_to_cpu(rule->aq_fsp.h_ext.vlan_tci) == vlan_id)
break;
}
- if (rule && be16_to_cpu(rule->aq_fsp.h_ext.vlan_tci) == vlan_id) {
+ if (rule && rule->type == aq_rx_filter_vlan &&
+ be16_to_cpu(rule->aq_fsp.h_ext.vlan_tci) == vlan_id) {
struct ethtool_rxnfc cmd;
cmd.fs.location = rule->aq_fsp.location;
@@ -843,7 +844,7 @@ int aq_filters_vlans_update(struct aq_nic_s *aq_nic)
return err;
if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) {
- if (hweight < AQ_VLAN_MAX_FILTERS && hweight > 0) {
+ if (hweight <= AQ_VLAN_MAX_FILTERS && hweight > 0) {
err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw,
!(aq_nic->packet_filter & IFF_PROMISC));
aq_nic->aq_nic_cfg.is_vlan_force_promisc = false;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index 100722ad5c2d..b4a0fb281e69 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -61,6 +61,10 @@ static int aq_ndev_open(struct net_device *ndev)
if (err < 0)
goto err_exit;
+ err = aq_filters_vlans_update(aq_nic);
+ if (err < 0)
+ goto err_exit;
+
err = aq_nic_start(aq_nic);
if (err < 0)
goto err_exit;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index e1392766e21e..8f66e7817811 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -393,7 +393,7 @@ int aq_nic_start(struct aq_nic_s *self)
self->aq_nic_cfg.link_irq_vec);
err = request_threaded_irq(irqvec, NULL,
aq_linkstate_threaded_isr,
- IRQF_SHARED,
+ IRQF_SHARED | IRQF_ONESHOT,
self->ndev->name, self);
if (err < 0)
goto err_exit;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
index 715685aa48c3..28892b8acd0e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
@@ -86,6 +86,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
}
}
+err_exit:
if (!was_tx_cleaned)
work_done = budget;
@@ -95,7 +96,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
1U << self->aq_ring_param.vec_idx);
}
}
-err_exit:
+
return work_done;
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index e47ea92e2ae3..d10b421ed1f1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3057,12 +3057,13 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
/* if VF indicate to PF this function is going down (PF will delete sp
* elements and clear initializations
*/
- if (IS_VF(bp))
+ if (IS_VF(bp)) {
+ bnx2x_clear_vlan_info(bp);
bnx2x_vfpf_close_vf(bp);
- else if (unload_mode != UNLOAD_RECOVERY)
+ } else if (unload_mode != UNLOAD_RECOVERY) {
/* if this is a normal/close unload need to clean up chip*/
bnx2x_chip_cleanup(bp, unload_mode, keep_link);
- else {
+ } else {
/* Send the UNLOAD_REQUEST to the MCP */
bnx2x_send_unload_req(bp, unload_mode);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index c2f6e44e9a3f..8b08cb18e363 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -425,6 +425,8 @@ void bnx2x_set_reset_global(struct bnx2x *bp);
void bnx2x_disable_close_the_gate(struct bnx2x *bp);
int bnx2x_init_hw_func_cnic(struct bnx2x *bp);
+void bnx2x_clear_vlan_info(struct bnx2x *bp);
+
/**
* bnx2x_sp_event - handle ramrods completion.
*
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 2cc14db8f0ec..192ff8d5da32 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -8482,11 +8482,21 @@ int bnx2x_set_vlan_one(struct bnx2x *bp, u16 vlan,
return rc;
}
+void bnx2x_clear_vlan_info(struct bnx2x *bp)
+{
+ struct bnx2x_vlan_entry *vlan;
+
+ /* Mark that hw forgot all entries */
+ list_for_each_entry(vlan, &bp->vlan_reg, link)
+ vlan->hw = false;
+
+ bp->vlan_cnt = 0;
+}
+
static int bnx2x_del_all_vlans(struct bnx2x *bp)
{
struct bnx2x_vlan_mac_obj *vlan_obj = &bp->sp_objs[0].vlan_obj;
unsigned long ramrod_flags = 0, vlan_flags = 0;
- struct bnx2x_vlan_entry *vlan;
int rc;
__set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
@@ -8495,10 +8505,7 @@ static int bnx2x_del_all_vlans(struct bnx2x *bp)
if (rc)
return rc;
- /* Mark that hw forgot all entries */
- list_for_each_entry(vlan, &bp->vlan_reg, link)
- vlan->hw = false;
- bp->vlan_cnt = 0;
+ bnx2x_clear_vlan_info(bp);
return 0;
}
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 7070349915bc..8dce4069472b 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -2021,9 +2021,9 @@ static void __bnxt_poll_work_done(struct bnxt *bp, struct bnxt_napi *bnapi)
if (bnapi->events & BNXT_RX_EVENT) {
struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
- bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod);
if (bnapi->events & BNXT_AGG_EVENT)
bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod);
+ bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod);
}
bnapi->events = 0;
}
@@ -5064,6 +5064,7 @@ static void bnxt_set_db(struct bnxt *bp, struct bnxt_db_info *db, u32 ring_type,
static int bnxt_hwrm_ring_alloc(struct bnxt *bp)
{
+ bool agg_rings = !!(bp->flags & BNXT_FLAG_AGG_RINGS);
int i, rc = 0;
u32 type;
@@ -5139,7 +5140,9 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp)
if (rc)
goto err_out;
bnxt_set_db(bp, &rxr->rx_db, type, map_idx, ring->fw_ring_id);
- bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod);
+ /* If we have agg rings, post agg buffers first. */
+ if (!agg_rings)
+ bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod);
bp->grp_info[map_idx].rx_fw_ring_id = ring->fw_ring_id;
if (bp->flags & BNXT_FLAG_CHIP_P5) {
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
@@ -5158,7 +5161,7 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp)
}
}
- if (bp->flags & BNXT_FLAG_AGG_RINGS) {
+ if (agg_rings) {
type = HWRM_RING_ALLOC_AGG;
for (i = 0; i < bp->rx_nr_rings; i++) {
struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
@@ -5174,6 +5177,7 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp)
bnxt_set_db(bp, &rxr->rx_agg_db, type, map_idx,
ring->fw_ring_id);
bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod);
+ bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod);
bp->grp_info[grp_idx].agg_fw_ring_id = ring->fw_ring_id;
}
}
@@ -7016,19 +7020,29 @@ static void bnxt_hwrm_clear_vnic_rss(struct bnxt *bp)
bnxt_hwrm_vnic_set_rss(bp, i, false);
}
-static void bnxt_hwrm_resource_free(struct bnxt *bp, bool close_path,
- bool irq_re_init)
+static void bnxt_clear_vnic(struct bnxt *bp)
{
- if (bp->vnic_info) {
- bnxt_hwrm_clear_vnic_filter(bp);
+ if (!bp->vnic_info)
+ return;
+
+ bnxt_hwrm_clear_vnic_filter(bp);
+ if (!(bp->flags & BNXT_FLAG_CHIP_P5)) {
/* clear all RSS setting before free vnic ctx */
bnxt_hwrm_clear_vnic_rss(bp);
bnxt_hwrm_vnic_ctx_free(bp);
- /* before free the vnic, undo the vnic tpa settings */
- if (bp->flags & BNXT_FLAG_TPA)
- bnxt_set_tpa(bp, false);
- bnxt_hwrm_vnic_free(bp);
}
+ /* before free the vnic, undo the vnic tpa settings */
+ if (bp->flags & BNXT_FLAG_TPA)
+ bnxt_set_tpa(bp, false);
+ bnxt_hwrm_vnic_free(bp);
+ if (bp->flags & BNXT_FLAG_CHIP_P5)
+ bnxt_hwrm_vnic_ctx_free(bp);
+}
+
+static void bnxt_hwrm_resource_free(struct bnxt *bp, bool close_path,
+ bool irq_re_init)
+{
+ bnxt_clear_vnic(bp);
bnxt_hwrm_ring_free(bp, close_path);
bnxt_hwrm_ring_grp_free(bp);
if (irq_re_init) {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
index 549c90d3e465..c05d663212b2 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
@@ -98,10 +98,13 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
if (idx)
req->dimensions = cpu_to_le16(1);
- if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE))
+ if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) {
memcpy(data_addr, buf, bytesize);
-
- rc = hwrm_send_message(bp, msg, msg_len, HWRM_CMD_TIMEOUT);
+ rc = hwrm_send_message(bp, msg, msg_len, HWRM_CMD_TIMEOUT);
+ } else {
+ rc = hwrm_send_message_silent(bp, msg, msg_len,
+ HWRM_CMD_TIMEOUT);
+ }
if (!rc && req->req_type == cpu_to_le16(HWRM_NVM_GET_VARIABLE))
memcpy(buf, data_addr, bytesize);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index c7ee63d69679..8445a0cce849 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -2016,21 +2016,19 @@ static int bnxt_flash_package_from_file(struct net_device *dev,
mutex_lock(&bp->hwrm_cmd_lock);
hwrm_err = _hwrm_send_message(bp, &install, sizeof(install),
INSTALL_PACKAGE_TIMEOUT);
- if (hwrm_err)
- goto flash_pkg_exit;
-
- if (resp->error_code) {
+ if (hwrm_err) {
u8 error_code = ((struct hwrm_err_output *)resp)->cmd_err;
- if (error_code == NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) {
+ if (resp->error_code && error_code ==
+ NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) {
install.flags |= cpu_to_le16(
NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG);
hwrm_err = _hwrm_send_message(bp, &install,
sizeof(install),
INSTALL_PACKAGE_TIMEOUT);
- if (hwrm_err)
- goto flash_pkg_exit;
}
+ if (hwrm_err)
+ goto flash_pkg_exit;
}
if (resp->result) {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
index 6fe4a7174271..dd621f6bd127 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
@@ -1236,7 +1236,7 @@ static int __bnxt_tc_del_flow(struct bnxt *bp,
static void bnxt_tc_set_flow_dir(struct bnxt *bp, struct bnxt_tc_flow *flow,
u16 src_fid)
{
- flow->dir = (bp->pf.fw_fid == src_fid) ? BNXT_DIR_RX : BNXT_DIR_TX;
+ flow->l2_key.dir = (bp->pf.fw_fid == src_fid) ? BNXT_DIR_RX : BNXT_DIR_TX;
}
static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow,
@@ -1285,9 +1285,7 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid,
goto free_node;
bnxt_tc_set_src_fid(bp, flow, src_fid);
-
- if (bp->fw_cap & BNXT_FW_CAP_OVS_64BIT_HANDLE)
- bnxt_tc_set_flow_dir(bp, flow, src_fid);
+ bnxt_tc_set_flow_dir(bp, flow, flow->src_fid);
if (!bnxt_tc_can_offload(bp, flow)) {
rc = -EOPNOTSUPP;
@@ -1407,7 +1405,7 @@ static void bnxt_fill_cfa_stats_req(struct bnxt *bp,
* 2. 15th bit of flow_handle must specify the flow
* direction (TX/RX).
*/
- if (flow_node->flow.dir == BNXT_DIR_RX)
+ if (flow_node->flow.l2_key.dir == BNXT_DIR_RX)
handle = CFA_FLOW_INFO_REQ_FLOW_HANDLE_DIR_RX |
CFA_FLOW_INFO_REQ_FLOW_HANDLE_MAX_MASK;
else
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h
index ffec57d1a5ec..4f05305052f2 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h
@@ -23,6 +23,9 @@ struct bnxt_tc_l2_key {
__be16 inner_vlan_tci;
__be16 ether_type;
u8 num_vlans;
+ u8 dir;
+#define BNXT_DIR_RX 1
+#define BNXT_DIR_TX 0
};
struct bnxt_tc_l3_key {
@@ -98,9 +101,6 @@ struct bnxt_tc_flow {
/* flow applicable to pkts ingressing on this fid */
u16 src_fid;
- u8 dir;
-#define BNXT_DIR_RX 1
-#define BNXT_DIR_TX 0
struct bnxt_tc_l2_key l2_key;
struct bnxt_tc_l2_key l2_mask;
struct bnxt_tc_l3_key l3_key;
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index d3a0b614dbfa..b22196880d6d 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1124,6 +1124,7 @@ static const struct ethtool_ops bcmgenet_ethtool_ops = {
.set_coalesce = bcmgenet_set_coalesce,
.get_link_ksettings = bcmgenet_get_link_ksettings,
.set_link_ksettings = bcmgenet_set_link_ksettings,
+ .get_ts_info = ethtool_op_get_ts_info,
};
/* Power down the unimac, based on mode. */
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 5ca17e62dc3e..35b59b5edf0f 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4154,7 +4154,7 @@ static const struct of_device_id macb_dt_ids[] = {
{ .compatible = "cdns,emac", .data = &emac_config },
{ .compatible = "cdns,zynqmp-gem", .data = &zynqmp_config},
{ .compatible = "cdns,zynq-gem", .data = &zynq_config },
- { .compatible = "sifive,fu540-macb", .data = &fu540_c000_config },
+ { .compatible = "sifive,fu540-c000-gem", .data = &fu540_c000_config },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, macb_dt_ids);
diff --git a/drivers/net/ethernet/cavium/common/cavium_ptp.c b/drivers/net/ethernet/cavium/common/cavium_ptp.c
index 73632b843749..b821c9e1604c 100644
--- a/drivers/net/ethernet/cavium/common/cavium_ptp.c
+++ b/drivers/net/ethernet/cavium/common/cavium_ptp.c
@@ -10,7 +10,7 @@
#include "cavium_ptp.h"
-#define DRV_NAME "Cavium PTP Driver"
+#define DRV_NAME "cavium_ptp"
#define PCI_DEVICE_ID_CAVIUM_PTP 0xA00C
#define PCI_DEVICE_ID_CAVIUM_RST 0xA00E
diff --git a/drivers/net/ethernet/cavium/liquidio/request_manager.c b/drivers/net/ethernet/cavium/liquidio/request_manager.c
index 032224178b64..6dd65f9b347c 100644
--- a/drivers/net/ethernet/cavium/liquidio/request_manager.c
+++ b/drivers/net/ethernet/cavium/liquidio/request_manager.c
@@ -237,8 +237,10 @@ int octeon_setup_iq(struct octeon_device *oct,
}
oct->num_iqs++;
- if (oct->fn_list.enable_io_queues(oct))
+ if (oct->fn_list.enable_io_queues(oct)) {
+ octeon_delete_instr_queue(oct, iq_no);
return 1;
+ }
return 0;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 02959035ed3f..d692251ee252 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -3236,8 +3236,10 @@ static ssize_t blocked_fl_write(struct file *filp, const char __user *ubuf,
return -ENOMEM;
err = bitmap_parse_user(ubuf, count, t, adap->sge.egr_sz);
- if (err)
+ if (err) {
+ kvfree(t);
return err;
+ }
bitmap_copy(adap->sge.blocked_fl, t, adap->sge.egr_sz);
kvfree(t);
diff --git a/drivers/net/ethernet/ezchip/nps_enet.h b/drivers/net/ethernet/ezchip/nps_enet.h
index 133acca0bf31..092da2d90026 100644
--- a/drivers/net/ethernet/ezchip/nps_enet.h
+++ b/drivers/net/ethernet/ezchip/nps_enet.h
@@ -167,7 +167,7 @@ struct nps_enet_priv {
};
/**
- * nps_reg_set - Sets ENET register with provided value.
+ * nps_enet_reg_set - Sets ENET register with provided value.
* @priv: Pointer to EZchip ENET private data structure.
* @reg: Register offset from base address.
* @value: Value to set in register.
@@ -179,7 +179,7 @@ static inline void nps_enet_reg_set(struct nps_enet_priv *priv,
}
/**
- * nps_reg_get - Gets value of specified ENET register.
+ * nps_enet_reg_get - Gets value of specified ENET register.
* @priv: Pointer to EZchip ENET private data structure.
* @reg: Register offset from base address.
*
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
index 2fd2586e42bf..bc594892507a 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
@@ -82,7 +82,7 @@ static int enetc_ptp_probe(struct pci_dev *pdev,
n = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
if (n != 1) {
err = -EPERM;
- goto err_irq;
+ goto err_irq_vectors;
}
ptp_qoriq->irq = pci_irq_vector(pdev, 0);
@@ -107,6 +107,8 @@ static int enetc_ptp_probe(struct pci_dev *pdev,
err_no_clock:
free_irq(ptp_qoriq->irq, ptp_qoriq);
err_irq:
+ pci_free_irq_vectors(pdev);
+err_irq_vectors:
iounmap(base);
err_ioremap:
kfree(ptp_qoriq);
@@ -125,6 +127,7 @@ static void enetc_ptp_remove(struct pci_dev *pdev)
enetc_phc_index = -1;
ptp_qoriq_free(ptp_qoriq);
+ pci_free_irq_vectors(pdev);
kfree(ptp_qoriq);
pci_release_mem_regions(pdev);
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index 497298752381..aca95f64bde8 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -50,7 +50,7 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
u64_stats_fetch_begin(&priv->tx[ring].statss);
s->tx_packets += priv->tx[ring].pkt_done;
s->tx_bytes += priv->tx[ring].bytes_done;
- } while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+ } while (u64_stats_fetch_retry(&priv->tx[ring].statss,
start));
}
}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c
index 0a7243825e7b..85a3b062371d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c
@@ -98,7 +98,7 @@ static const struct hclge_hw_error hclge_igu_egu_tnl_int[] = {
.reset_level = HNAE3_GLOBAL_RESET },
{ .int_msk = BIT(1), .msg = "rx_stp_fifo_overflow",
.reset_level = HNAE3_GLOBAL_RESET },
- { .int_msk = BIT(2), .msg = "rx_stp_fifo_undeflow",
+ { .int_msk = BIT(2), .msg = "rx_stp_fifo_underflow",
.reset_level = HNAE3_GLOBAL_RESET },
{ .int_msk = BIT(3), .msg = "tx_buf_overflow",
.reset_level = HNAE3_GLOBAL_RESET },
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index d654c234aaf7..c5be4ebd8437 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -1605,7 +1605,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
struct net_device *netdev;
struct ibmveth_adapter *adapter;
unsigned char *mac_addr_p;
- unsigned int *mcastFilterSize_p;
+ __be32 *mcastFilterSize_p;
long ret;
unsigned long ret_attr;
@@ -1627,8 +1627,9 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
return -EINVAL;
}
- mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev,
- VETH_MCAST_FILTER_SIZE, NULL);
+ mcastFilterSize_p = (__be32 *)vio_get_attribute(dev,
+ VETH_MCAST_FILTER_SIZE,
+ NULL);
if (!mcastFilterSize_p) {
dev_err(&dev->dev, "Can't find VETH_MCAST_FILTER_SIZE "
"attribute\n");
@@ -1645,7 +1646,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
adapter->vdev = dev;
adapter->netdev = netdev;
- adapter->mcastFilterSize = *mcastFilterSize_p;
+ adapter->mcastFilterSize = be32_to_cpu(*mcastFilterSize_p);
adapter->pool_config = 0;
netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16);
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 3da680073265..5cb55ea671e3 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1568,6 +1568,8 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
lpar_rc = send_subcrq_indirect(adapter, handle_array[queue_num],
(u64)tx_buff->indir_dma,
(u64)num_entries);
+ dma_unmap_single(dev, tx_buff->indir_dma,
+ sizeof(tx_buff->indir_arr), DMA_TO_DEVICE);
} else {
tx_buff->num_entries = num_entries;
lpar_rc = send_subcrq(adapter, handle_array[queue_num],
@@ -1981,6 +1983,13 @@ static void __ibmvnic_reset(struct work_struct *work)
rwi = get_next_rwi(adapter);
while (rwi) {
+ if (adapter->state == VNIC_REMOVING ||
+ adapter->state == VNIC_REMOVED) {
+ kfree(rwi);
+ rc = EBUSY;
+ break;
+ }
+
if (adapter->force_reset_recovery) {
adapter->force_reset_recovery = false;
rc = do_hard_reset(adapter, rwi, reset_state);
@@ -2788,7 +2797,6 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
union sub_crq *next;
int index;
int i, j;
- u8 *first;
restart_loop:
while (pending_scrq(adapter, scrq)) {
@@ -2818,14 +2826,6 @@ restart_loop:
txbuff->data_dma[j] = 0;
}
- /* if sub_crq was sent indirectly */
- first = &txbuff->indir_arr[0].generic.first;
- if (*first == IBMVNIC_CRQ_CMD) {
- dma_unmap_single(dev, txbuff->indir_dma,
- sizeof(txbuff->indir_arr),
- DMA_TO_DEVICE);
- *first = 0;
- }
if (txbuff->last_frag) {
dev_kfree_skb_any(txbuff->skb);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index cbaf712d6529..51c696b6bf64 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -36,6 +36,7 @@
#include <net/vxlan.h>
#include <net/mpls.h>
#include <net/xdp_sock.h>
+#include <net/xfrm.h>
#include "ixgbe.h"
#include "ixgbe_common.h"
@@ -2621,7 +2622,7 @@ adjust_by_size:
/* 16K ints/sec to 9.2K ints/sec */
avg_wire_size *= 15;
avg_wire_size += 11452;
- } else if (avg_wire_size <= 1980) {
+ } else if (avg_wire_size < 1968) {
/* 9.2K ints/sec to 8K ints/sec */
avg_wire_size *= 5;
avg_wire_size += 22420;
@@ -2654,6 +2655,8 @@ adjust_by_size:
case IXGBE_LINK_SPEED_2_5GB_FULL:
case IXGBE_LINK_SPEED_1GB_FULL:
case IXGBE_LINK_SPEED_10_FULL:
+ if (avg_wire_size > 8064)
+ avg_wire_size = 8064;
itr += DIV_ROUND_UP(avg_wire_size,
IXGBE_ITR_ADAPTIVE_MIN_INC * 64) *
IXGBE_ITR_ADAPTIVE_MIN_INC;
@@ -7897,11 +7900,8 @@ static void ixgbe_service_task(struct work_struct *work)
return;
}
if (ixgbe_check_fw_error(adapter)) {
- if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
- rtnl_lock();
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
unregister_netdev(adapter->netdev);
- rtnl_unlock();
- }
ixgbe_service_event_complete(adapter);
return;
}
@@ -8698,7 +8698,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
#endif /* IXGBE_FCOE */
#ifdef CONFIG_IXGBE_IPSEC
- if (secpath_exists(skb) &&
+ if (xfrm_offload(skb) &&
!ixgbe_ipsec_tx(tx_ring, first, &ipsec_tx))
goto out_drop;
#endif
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
index 6b609553329f..a3b6d8c89127 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
@@ -633,19 +633,17 @@ static void ixgbe_clean_xdp_tx_buffer(struct ixgbe_ring *tx_ring,
bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *tx_ring, int napi_budget)
{
+ u16 ntc = tx_ring->next_to_clean, ntu = tx_ring->next_to_use;
unsigned int total_packets = 0, total_bytes = 0;
- u32 i = tx_ring->next_to_clean, xsk_frames = 0;
- unsigned int budget = q_vector->tx.work_limit;
struct xdp_umem *umem = tx_ring->xsk_umem;
union ixgbe_adv_tx_desc *tx_desc;
struct ixgbe_tx_buffer *tx_bi;
- bool xmit_done;
+ u32 xsk_frames = 0;
- tx_bi = &tx_ring->tx_buffer_info[i];
- tx_desc = IXGBE_TX_DESC(tx_ring, i);
- i -= tx_ring->count;
+ tx_bi = &tx_ring->tx_buffer_info[ntc];
+ tx_desc = IXGBE_TX_DESC(tx_ring, ntc);
- do {
+ while (ntc != ntu) {
if (!(tx_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)))
break;
@@ -661,22 +659,18 @@ bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
tx_bi++;
tx_desc++;
- i++;
- if (unlikely(!i)) {
- i -= tx_ring->count;
+ ntc++;
+ if (unlikely(ntc == tx_ring->count)) {
+ ntc = 0;
tx_bi = tx_ring->tx_buffer_info;
tx_desc = IXGBE_TX_DESC(tx_ring, 0);
}
/* issue prefetch for next Tx descriptor */
prefetch(tx_desc);
+ }
- /* update budget accounting */
- budget--;
- } while (likely(budget));
-
- i += tx_ring->count;
- tx_ring->next_to_clean = i;
+ tx_ring->next_to_clean = ntc;
u64_stats_update_begin(&tx_ring->syncp);
tx_ring->stats.bytes += total_bytes;
@@ -688,8 +682,7 @@ bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
if (xsk_frames)
xsk_umem_complete_tx(umem, xsk_frames);
- xmit_done = ixgbe_xmit_zc(tx_ring, q_vector->tx.work_limit);
- return budget > 0 && xmit_done;
+ return ixgbe_xmit_zc(tx_ring, q_vector->tx.work_limit);
}
int ixgbe_xsk_async_xmit(struct net_device *dev, u32 qid)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index d2b41f9f87f8..72872d6ca80c 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -30,6 +30,7 @@
#include <linux/bpf.h>
#include <linux/bpf_trace.h>
#include <linux/atomic.h>
+#include <net/xfrm.h>
#include "ixgbevf.h"
@@ -4161,7 +4162,7 @@ static int ixgbevf_xmit_frame_ring(struct sk_buff *skb,
first->protocol = vlan_get_protocol(skb);
#ifdef CONFIG_IXGBEVF_IPSEC
- if (secpath_exists(skb) && !ixgbevf_ipsec_tx(tx_ring, first, &ipsec_tx))
+ if (xfrm_offload(skb) && !ixgbevf_ipsec_tx(tx_ring, first, &ipsec_tx))
goto out_drop;
#endif
tso = ixgbevf_tso(tx_ring, first, &hdr_len, &ipsec_tx);
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index a01c75ede871..e0363870f3a5 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4931,6 +4931,13 @@ static const struct dmi_system_id msi_blacklist[] = {
DMI_MATCH(DMI_BOARD_NAME, "P6T"),
},
},
+ {
+ .ident = "ASUS P6X",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "P6X"),
+ },
+ },
{}
};
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index 6c01314e87b0..db3552f2d087 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -1187,7 +1187,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, rss_map->indir_qp);
if (err) {
en_err(priv, "Failed to allocate RSS indirection QP\n");
- goto rss_err;
+ goto qp_alloc_err;
}
rss_map->indir_qp->event = mlx4_en_sqp_event;
@@ -1241,6 +1241,7 @@ indir_err:
MLX4_QP_STATE_RST, NULL, 0, 0, rss_map->indir_qp);
mlx4_qp_remove(mdev->dev, rss_map->indir_qp);
mlx4_qp_free(mdev->dev, rss_map->indir_qp);
+qp_alloc_err:
kfree(rss_map->indir_qp);
rss_map->indir_qp = NULL;
rss_err:
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 1f6e16d5ea6b..309470ec0219 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2240,7 +2240,7 @@ static int mlx4_validate_optimized_steering(struct mlx4_dev *dev)
for (i = 1; i <= dev->caps.num_ports; i++) {
if (mlx4_dev_port(dev, i, &port_cap)) {
mlx4_err(dev,
- "QUERY_DEV_CAP command failed, can't veify DMFS high rate steering.\n");
+ "QUERY_DEV_CAP command failed, can't verify DMFS high rate steering.\n");
} else if ((dev->caps.dmfs_high_steer_mode !=
MLX4_STEERING_DMFS_A0_DEFAULT) &&
(port_cap.dmfs_optimized_state ==
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index ce1be2a84231..65bec19a438f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -184,8 +184,13 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
struct mlx5e_tx_wqe {
struct mlx5_wqe_ctrl_seg ctrl;
- struct mlx5_wqe_eth_seg eth;
- struct mlx5_wqe_data_seg data[0];
+ union {
+ struct {
+ struct mlx5_wqe_eth_seg eth;
+ struct mlx5_wqe_data_seg data[0];
+ };
+ u8 tls_progress_params_ctx[0];
+ };
};
struct mlx5e_rx_wqe_ll {
@@ -1100,6 +1105,8 @@ u32 mlx5e_ethtool_get_rxfh_key_size(struct mlx5e_priv *priv);
u32 mlx5e_ethtool_get_rxfh_indir_size(struct mlx5e_priv *priv);
int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv,
struct ethtool_ts_info *info);
+int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
+ struct ethtool_flash *flash);
void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv,
struct ethtool_pauseparam *pauseparam);
int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
index f3d98748b211..c7f86453c638 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
@@ -76,26 +76,21 @@ static int mlx5e_tx_reporter_err_cqe_recover(struct mlx5e_txqsq *sq)
u8 state;
int err;
- if (!test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state))
- return 0;
-
err = mlx5_core_query_sq_state(mdev, sq->sqn, &state);
if (err) {
netdev_err(dev, "Failed to query SQ 0x%x state. err = %d\n",
sq->sqn, err);
- return err;
+ goto out;
}
- if (state != MLX5_SQC_STATE_ERR) {
- netdev_err(dev, "SQ 0x%x not in ERROR state\n", sq->sqn);
- return -EINVAL;
- }
+ if (state != MLX5_SQC_STATE_ERR)
+ goto out;
mlx5e_tx_disable_queue(sq->txq);
err = mlx5e_wait_for_sq_flush(sq);
if (err)
- return err;
+ goto out;
/* At this point, no new packets will arrive from the stack as TXQ is
* marked with QUEUE_STATE_DRV_XOFF. In addition, NAPI cleared all
@@ -104,13 +99,17 @@ static int mlx5e_tx_reporter_err_cqe_recover(struct mlx5e_txqsq *sq)
err = mlx5e_sq_to_ready(sq, state);
if (err)
- return err;
+ goto out;
mlx5e_reset_txqsq_cc_pc(sq);
sq->stats->recover++;
+ clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state);
mlx5e_activate_txqsq(sq);
return 0;
+out:
+ clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state);
+ return err;
}
static int mlx5_tx_health_report(struct devlink_health_reporter *tx_reporter,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
index aaffa6f68dc0..7f78c004d12f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
@@ -143,7 +143,10 @@ void mlx5e_activate_xsk(struct mlx5e_channel *c)
{
set_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
/* TX queue is created active. */
+
+ spin_lock(&c->xskicosq_lock);
mlx5e_trigger_irq(&c->xskicosq);
+ spin_unlock(&c->xskicosq_lock);
}
void mlx5e_deactivate_xsk(struct mlx5e_channel *c)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h
index 407da83474ef..b7298f9ee3d3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h
@@ -11,12 +11,14 @@
#include "accel/tls.h"
#define MLX5E_KTLS_STATIC_UMR_WQE_SZ \
- (sizeof(struct mlx5e_umr_wqe) + MLX5_ST_SZ_BYTES(tls_static_params))
+ (offsetof(struct mlx5e_umr_wqe, tls_static_params_ctx) + \
+ MLX5_ST_SZ_BYTES(tls_static_params))
#define MLX5E_KTLS_STATIC_WQEBBS \
(DIV_ROUND_UP(MLX5E_KTLS_STATIC_UMR_WQE_SZ, MLX5_SEND_WQE_BB))
#define MLX5E_KTLS_PROGRESS_WQE_SZ \
- (sizeof(struct mlx5e_tx_wqe) + MLX5_ST_SZ_BYTES(tls_progress_params))
+ (offsetof(struct mlx5e_tx_wqe, tls_progress_params_ctx) + \
+ MLX5_ST_SZ_BYTES(tls_progress_params))
#define MLX5E_KTLS_PROGRESS_WQEBBS \
(DIV_ROUND_UP(MLX5E_KTLS_PROGRESS_WQE_SZ, MLX5_SEND_WQE_BB))
#define MLX5E_KTLS_MAX_DUMP_WQEBBS 2
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
index 3766545ce259..7833ddef0427 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
@@ -69,7 +69,7 @@ build_static_params(struct mlx5e_umr_wqe *wqe, u16 pc, u32 sqn,
cseg->qpn_ds = cpu_to_be32((sqn << MLX5_WQE_CTRL_QPN_SHIFT) |
STATIC_PARAMS_DS_CNT);
cseg->fm_ce_se = fence ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
- cseg->imm = cpu_to_be32(priv_tx->tisn);
+ cseg->tisn = cpu_to_be32(priv_tx->tisn << 8);
ucseg->flags = MLX5_UMR_INLINE;
ucseg->bsf_octowords = cpu_to_be16(MLX5_ST_SZ_BYTES(tls_static_params) / 16);
@@ -80,7 +80,7 @@ build_static_params(struct mlx5e_umr_wqe *wqe, u16 pc, u32 sqn,
static void
fill_progress_params_ctx(void *ctx, struct mlx5e_ktls_offload_context_tx *priv_tx)
{
- MLX5_SET(tls_progress_params, ctx, pd, priv_tx->tisn);
+ MLX5_SET(tls_progress_params, ctx, tisn, priv_tx->tisn);
MLX5_SET(tls_progress_params, ctx, record_tracker_state,
MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START);
MLX5_SET(tls_progress_params, ctx, auth_state,
@@ -104,18 +104,20 @@ build_progress_params(struct mlx5e_tx_wqe *wqe, u16 pc, u32 sqn,
PROGRESS_PARAMS_DS_CNT);
cseg->fm_ce_se = fence ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
- fill_progress_params_ctx(wqe->data, priv_tx);
+ fill_progress_params_ctx(wqe->tls_progress_params_ctx, priv_tx);
}
static void tx_fill_wi(struct mlx5e_txqsq *sq,
u16 pi, u8 num_wqebbs,
- skb_frag_t *resync_dump_frag)
+ skb_frag_t *resync_dump_frag,
+ u32 num_bytes)
{
struct mlx5e_tx_wqe_info *wi = &sq->db.wqe_info[pi];
wi->skb = NULL;
wi->num_wqebbs = num_wqebbs;
wi->resync_dump_frag = resync_dump_frag;
+ wi->num_bytes = num_bytes;
}
void mlx5e_ktls_tx_offload_set_pending(struct mlx5e_ktls_offload_context_tx *priv_tx)
@@ -143,7 +145,7 @@ post_static_params(struct mlx5e_txqsq *sq,
umr_wqe = mlx5e_sq_fetch_wqe(sq, MLX5E_KTLS_STATIC_UMR_WQE_SZ, &pi);
build_static_params(umr_wqe, sq->pc, sq->sqn, priv_tx, fence);
- tx_fill_wi(sq, pi, MLX5E_KTLS_STATIC_WQEBBS, NULL);
+ tx_fill_wi(sq, pi, MLX5E_KTLS_STATIC_WQEBBS, NULL, 0);
sq->pc += MLX5E_KTLS_STATIC_WQEBBS;
}
@@ -157,7 +159,7 @@ post_progress_params(struct mlx5e_txqsq *sq,
wqe = mlx5e_sq_fetch_wqe(sq, MLX5E_KTLS_PROGRESS_WQE_SZ, &pi);
build_progress_params(wqe, sq->pc, sq->sqn, priv_tx, fence);
- tx_fill_wi(sq, pi, MLX5E_KTLS_PROGRESS_WQEBBS, NULL);
+ tx_fill_wi(sq, pi, MLX5E_KTLS_PROGRESS_WQEBBS, NULL, 0);
sq->pc += MLX5E_KTLS_PROGRESS_WQEBBS;
}
@@ -248,43 +250,37 @@ tx_post_resync_params(struct mlx5e_txqsq *sq,
mlx5e_ktls_tx_post_param_wqes(sq, priv_tx, skip_static_post, true);
}
+struct mlx5e_dump_wqe {
+ struct mlx5_wqe_ctrl_seg ctrl;
+ struct mlx5_wqe_data_seg data;
+};
+
static int
tx_post_resync_dump(struct mlx5e_txqsq *sq, struct sk_buff *skb,
skb_frag_t *frag, u32 tisn, bool first)
{
struct mlx5_wqe_ctrl_seg *cseg;
- struct mlx5_wqe_eth_seg *eseg;
struct mlx5_wqe_data_seg *dseg;
- struct mlx5e_tx_wqe *wqe;
+ struct mlx5e_dump_wqe *wqe;
dma_addr_t dma_addr = 0;
- u16 ds_cnt, ds_cnt_inl;
u8 num_wqebbs;
- u16 pi, ihs;
+ u16 ds_cnt;
int fsz;
-
- ds_cnt = sizeof(*wqe) / MLX5_SEND_WQE_DS;
- ihs = eth_get_headlen(skb->dev, skb->data, skb_headlen(skb));
- ds_cnt_inl = DIV_ROUND_UP(ihs - INL_HDR_START_SZ, MLX5_SEND_WQE_DS);
- ds_cnt += ds_cnt_inl;
- ds_cnt += 1; /* one frag */
+ u16 pi;
wqe = mlx5e_sq_fetch_wqe(sq, sizeof(*wqe), &pi);
+ ds_cnt = sizeof(*wqe) / MLX5_SEND_WQE_DS;
num_wqebbs = DIV_ROUND_UP(ds_cnt, MLX5_SEND_WQEBB_NUM_DS);
cseg = &wqe->ctrl;
- eseg = &wqe->eth;
- dseg = wqe->data;
+ dseg = &wqe->data;
cseg->opmod_idx_opcode = cpu_to_be32((sq->pc << 8) | MLX5_OPCODE_DUMP);
cseg->qpn_ds = cpu_to_be32((sq->sqn << 8) | ds_cnt);
- cseg->imm = cpu_to_be32(tisn);
+ cseg->tisn = cpu_to_be32(tisn << 8);
cseg->fm_ce_se = first ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
- eseg->inline_hdr.sz = cpu_to_be16(ihs);
- memcpy(eseg->inline_hdr.start, skb->data, ihs);
- dseg += ds_cnt_inl;
-
fsz = skb_frag_size(frag);
dma_addr = skb_frag_dma_map(sq->pdev, frag, 0, fsz,
DMA_TO_DEVICE);
@@ -296,7 +292,7 @@ tx_post_resync_dump(struct mlx5e_txqsq *sq, struct sk_buff *skb,
dseg->byte_count = cpu_to_be32(fsz);
mlx5e_dma_push(sq, dma_addr, fsz, MLX5E_DMA_MAP_PAGE);
- tx_fill_wi(sq, pi, num_wqebbs, frag);
+ tx_fill_wi(sq, pi, num_wqebbs, frag, fsz);
sq->pc += num_wqebbs;
WARN(num_wqebbs > MLX5E_KTLS_MAX_DUMP_WQEBBS,
@@ -323,7 +319,7 @@ static void tx_post_fence_nop(struct mlx5e_txqsq *sq)
struct mlx5_wq_cyc *wq = &sq->wq;
u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
- tx_fill_wi(sq, pi, 1, NULL);
+ tx_fill_wi(sq, pi, 1, NULL, 0);
mlx5e_post_nop_fence(wq, sq->sqn, &sq->pc);
}
@@ -434,7 +430,7 @@ struct sk_buff *mlx5e_ktls_handle_tx_skb(struct net_device *netdev,
priv_tx->expected_seq = seq + datalen;
cseg = &(*wqe)->ctrl;
- cseg->imm = cpu_to_be32(priv_tx->tisn);
+ cseg->tisn = cpu_to_be32(priv_tx->tisn << 8);
stats->tls_encrypted_packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1;
stats->tls_encrypted_bytes += datalen;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
index 8657e0f26995..2c75b2752f58 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
@@ -437,12 +437,6 @@ arfs_hash_bucket(struct arfs_table *arfs_t, __be16 src_port,
return &arfs_t->rules_hash[bucket_idx];
}
-static u8 arfs_get_ip_proto(const struct sk_buff *skb)
-{
- return (skb->protocol == htons(ETH_P_IP)) ?
- ip_hdr(skb)->protocol : ipv6_hdr(skb)->nexthdr;
-}
-
static struct arfs_table *arfs_get_table(struct mlx5e_arfs_tables *arfs,
u8 ip_proto, __be16 etype)
{
@@ -602,31 +596,9 @@ out:
arfs_may_expire_flow(priv);
}
-/* return L4 destination port from ip4/6 packets */
-static __be16 arfs_get_dst_port(const struct sk_buff *skb)
-{
- char *transport_header;
-
- transport_header = skb_transport_header(skb);
- if (arfs_get_ip_proto(skb) == IPPROTO_TCP)
- return ((struct tcphdr *)transport_header)->dest;
- return ((struct udphdr *)transport_header)->dest;
-}
-
-/* return L4 source port from ip4/6 packets */
-static __be16 arfs_get_src_port(const struct sk_buff *skb)
-{
- char *transport_header;
-
- transport_header = skb_transport_header(skb);
- if (arfs_get_ip_proto(skb) == IPPROTO_TCP)
- return ((struct tcphdr *)transport_header)->source;
- return ((struct udphdr *)transport_header)->source;
-}
-
static struct arfs_rule *arfs_alloc_rule(struct mlx5e_priv *priv,
struct arfs_table *arfs_t,
- const struct sk_buff *skb,
+ const struct flow_keys *fk,
u16 rxq, u32 flow_id)
{
struct arfs_rule *rule;
@@ -641,19 +613,19 @@ static struct arfs_rule *arfs_alloc_rule(struct mlx5e_priv *priv,
INIT_WORK(&rule->arfs_work, arfs_handle_work);
tuple = &rule->tuple;
- tuple->etype = skb->protocol;
+ tuple->etype = fk->basic.n_proto;
+ tuple->ip_proto = fk->basic.ip_proto;
if (tuple->etype == htons(ETH_P_IP)) {
- tuple->src_ipv4 = ip_hdr(skb)->saddr;
- tuple->dst_ipv4 = ip_hdr(skb)->daddr;
+ tuple->src_ipv4 = fk->addrs.v4addrs.src;
+ tuple->dst_ipv4 = fk->addrs.v4addrs.dst;
} else {
- memcpy(&tuple->src_ipv6, &ipv6_hdr(skb)->saddr,
+ memcpy(&tuple->src_ipv6, &fk->addrs.v6addrs.src,
sizeof(struct in6_addr));
- memcpy(&tuple->dst_ipv6, &ipv6_hdr(skb)->daddr,
+ memcpy(&tuple->dst_ipv6, &fk->addrs.v6addrs.dst,
sizeof(struct in6_addr));
}
- tuple->ip_proto = arfs_get_ip_proto(skb);
- tuple->src_port = arfs_get_src_port(skb);
- tuple->dst_port = arfs_get_dst_port(skb);
+ tuple->src_port = fk->ports.src;
+ tuple->dst_port = fk->ports.dst;
rule->flow_id = flow_id;
rule->filter_id = priv->fs.arfs.last_filter_id++ % RPS_NO_FILTER;
@@ -664,37 +636,33 @@ static struct arfs_rule *arfs_alloc_rule(struct mlx5e_priv *priv,
return rule;
}
-static bool arfs_cmp_ips(struct arfs_tuple *tuple,
- const struct sk_buff *skb)
+static bool arfs_cmp(const struct arfs_tuple *tuple, const struct flow_keys *fk)
{
- if (tuple->etype == htons(ETH_P_IP) &&
- tuple->src_ipv4 == ip_hdr(skb)->saddr &&
- tuple->dst_ipv4 == ip_hdr(skb)->daddr)
- return true;
- if (tuple->etype == htons(ETH_P_IPV6) &&
- (!memcmp(&tuple->src_ipv6, &ipv6_hdr(skb)->saddr,
- sizeof(struct in6_addr))) &&
- (!memcmp(&tuple->dst_ipv6, &ipv6_hdr(skb)->daddr,
- sizeof(struct in6_addr))))
- return true;
+ if (tuple->src_port != fk->ports.src || tuple->dst_port != fk->ports.dst)
+ return false;
+ if (tuple->etype != fk->basic.n_proto)
+ return false;
+ if (tuple->etype == htons(ETH_P_IP))
+ return tuple->src_ipv4 == fk->addrs.v4addrs.src &&
+ tuple->dst_ipv4 == fk->addrs.v4addrs.dst;
+ if (tuple->etype == htons(ETH_P_IPV6))
+ return !memcmp(&tuple->src_ipv6, &fk->addrs.v6addrs.src,
+ sizeof(struct in6_addr)) &&
+ !memcmp(&tuple->dst_ipv6, &fk->addrs.v6addrs.dst,
+ sizeof(struct in6_addr));
return false;
}
static struct arfs_rule *arfs_find_rule(struct arfs_table *arfs_t,
- const struct sk_buff *skb)
+ const struct flow_keys *fk)
{
struct arfs_rule *arfs_rule;
struct hlist_head *head;
- __be16 src_port = arfs_get_src_port(skb);
- __be16 dst_port = arfs_get_dst_port(skb);
- head = arfs_hash_bucket(arfs_t, src_port, dst_port);
+ head = arfs_hash_bucket(arfs_t, fk->ports.src, fk->ports.dst);
hlist_for_each_entry(arfs_rule, head, hlist) {
- if (arfs_rule->tuple.src_port == src_port &&
- arfs_rule->tuple.dst_port == dst_port &&
- arfs_cmp_ips(&arfs_rule->tuple, skb)) {
+ if (arfs_cmp(&arfs_rule->tuple, fk))
return arfs_rule;
- }
}
return NULL;
@@ -707,20 +675,24 @@ int mlx5e_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
struct mlx5e_arfs_tables *arfs = &priv->fs.arfs;
struct arfs_table *arfs_t;
struct arfs_rule *arfs_rule;
+ struct flow_keys fk;
+
+ if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
+ return -EPROTONOSUPPORT;
- if (skb->protocol != htons(ETH_P_IP) &&
- skb->protocol != htons(ETH_P_IPV6))
+ if (fk.basic.n_proto != htons(ETH_P_IP) &&
+ fk.basic.n_proto != htons(ETH_P_IPV6))
return -EPROTONOSUPPORT;
if (skb->encapsulation)
return -EPROTONOSUPPORT;
- arfs_t = arfs_get_table(arfs, arfs_get_ip_proto(skb), skb->protocol);
+ arfs_t = arfs_get_table(arfs, fk.basic.ip_proto, fk.basic.n_proto);
if (!arfs_t)
return -EPROTONOSUPPORT;
spin_lock_bh(&arfs->arfs_lock);
- arfs_rule = arfs_find_rule(arfs_t, skb);
+ arfs_rule = arfs_find_rule(arfs_t, &fk);
if (arfs_rule) {
if (arfs_rule->rxq == rxq_index) {
spin_unlock_bh(&arfs->arfs_lock);
@@ -728,8 +700,7 @@ int mlx5e_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
}
arfs_rule->rxq = rxq_index;
} else {
- arfs_rule = arfs_alloc_rule(priv, arfs_t, skb,
- rxq_index, flow_id);
+ arfs_rule = arfs_alloc_rule(priv, arfs_t, &fk, rxq_index, flow_id);
if (!arfs_rule) {
spin_unlock_bh(&arfs->arfs_lock);
return -ENOMEM;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 03bed714bac3..20e628c907e5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -1081,6 +1081,14 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) :
mlx5e_port_speed2linkmodes(mdev, speed, !ext);
+ if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) &&
+ autoneg != AUTONEG_ENABLE) {
+ netdev_err(priv->netdev, "%s: 56G link speed requires autoneg enabled\n",
+ __func__);
+ err = -EINVAL;
+ goto out;
+ }
+
link_modes = link_modes & eproto.cap;
if (!link_modes) {
netdev_err(priv->netdev, "%s: Not supported link mode(s) requested",
@@ -1338,6 +1346,9 @@ int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
struct mlx5_core_dev *mdev = priv->mdev;
int err;
+ if (!MLX5_CAP_GEN(mdev, vport_group_manager))
+ return -EOPNOTSUPP;
+
if (pauseparam->autoneg)
return -EINVAL;
@@ -1679,6 +1690,40 @@ static int mlx5e_get_module_eeprom(struct net_device *netdev,
return 0;
}
+int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
+ struct ethtool_flash *flash)
+{
+ struct mlx5_core_dev *mdev = priv->mdev;
+ struct net_device *dev = priv->netdev;
+ const struct firmware *fw;
+ int err;
+
+ if (flash->region != ETHTOOL_FLASH_ALL_REGIONS)
+ return -EOPNOTSUPP;
+
+ err = request_firmware_direct(&fw, flash->data, &dev->dev);
+ if (err)
+ return err;
+
+ dev_hold(dev);
+ rtnl_unlock();
+
+ err = mlx5_firmware_flash(mdev, fw, NULL);
+ release_firmware(fw);
+
+ rtnl_lock();
+ dev_put(dev);
+ return err;
+}
+
+static int mlx5e_flash_device(struct net_device *dev,
+ struct ethtool_flash *flash)
+{
+ struct mlx5e_priv *priv = netdev_priv(dev);
+
+ return mlx5e_ethtool_flash_device(priv, flash);
+}
+
static int set_pflag_cqe_based_moder(struct net_device *netdev, bool enable,
bool is_rx_cq)
{
@@ -1961,6 +2006,7 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
.set_wol = mlx5e_set_wol,
.get_module_info = mlx5e_get_module_info,
.get_module_eeprom = mlx5e_get_module_eeprom,
+ .flash_device = mlx5e_flash_device,
.get_priv_flags = mlx5e_get_priv_flags,
.set_priv_flags = mlx5e_set_priv_flags,
.self_test = mlx5e_self_test,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 6c712c5be4d8..9d5f6e56188f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1321,7 +1321,6 @@ err_free_txqsq:
void mlx5e_activate_txqsq(struct mlx5e_txqsq *sq)
{
sq->txq = netdev_get_tx_queue(sq->channel->netdev, sq->txq_ix);
- clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state);
set_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
netdev_tx_reset_queue(sq->txq);
netif_tx_start_queue(sq->txq);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 7ecfc53cf5f6..00b2d4a86159 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1480,7 +1480,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
struct mlx5_flow_spec *spec,
struct flow_cls_offload *f,
struct net_device *filter_dev,
- u8 *match_level, u8 *tunnel_match_level)
+ u8 *inner_match_level, u8 *outer_match_level)
{
struct netlink_ext_ack *extack = f->common.extack;
void *headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
@@ -1495,8 +1495,9 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
struct flow_dissector *dissector = rule->match.dissector;
u16 addr_type = 0;
u8 ip_proto = 0;
+ u8 *match_level;
- *match_level = MLX5_MATCH_NONE;
+ match_level = outer_match_level;
if (dissector->used_keys &
~(BIT(FLOW_DISSECTOR_KEY_META) |
@@ -1524,12 +1525,14 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
}
if (mlx5e_get_tc_tun(filter_dev)) {
- if (parse_tunnel_attr(priv, spec, f, filter_dev, tunnel_match_level))
+ if (parse_tunnel_attr(priv, spec, f, filter_dev,
+ outer_match_level))
return -EOPNOTSUPP;
- /* In decap flow, header pointers should point to the inner
+ /* At this point, header pointers should point to the inner
* headers, outer header were already set by parse_tunnel_attr
*/
+ match_level = inner_match_level;
headers_c = get_match_headers_criteria(MLX5_FLOW_CONTEXT_ACTION_DECAP,
spec);
headers_v = get_match_headers_value(MLX5_FLOW_CONTEXT_ACTION_DECAP,
@@ -1831,35 +1834,41 @@ static int parse_cls_flower(struct mlx5e_priv *priv,
struct flow_cls_offload *f,
struct net_device *filter_dev)
{
+ u8 inner_match_level, outer_match_level, non_tunnel_match_level;
struct netlink_ext_ack *extack = f->common.extack;
struct mlx5_core_dev *dev = priv->mdev;
struct mlx5_eswitch *esw = dev->priv.eswitch;
struct mlx5e_rep_priv *rpriv = priv->ppriv;
- u8 match_level, tunnel_match_level = MLX5_MATCH_NONE;
struct mlx5_eswitch_rep *rep;
int err;
- err = __parse_cls_flower(priv, spec, f, filter_dev, &match_level, &tunnel_match_level);
+ inner_match_level = MLX5_MATCH_NONE;
+ outer_match_level = MLX5_MATCH_NONE;
+
+ err = __parse_cls_flower(priv, spec, f, filter_dev, &inner_match_level,
+ &outer_match_level);
+ non_tunnel_match_level = (inner_match_level == MLX5_MATCH_NONE) ?
+ outer_match_level : inner_match_level;
if (!err && (flow->flags & MLX5E_TC_FLOW_ESWITCH)) {
rep = rpriv->rep;
if (rep->vport != MLX5_VPORT_UPLINK &&
(esw->offloads.inline_mode != MLX5_INLINE_MODE_NONE &&
- esw->offloads.inline_mode < match_level)) {
+ esw->offloads.inline_mode < non_tunnel_match_level)) {
NL_SET_ERR_MSG_MOD(extack,
"Flow is not offloaded due to min inline setting");
netdev_warn(priv->netdev,
"Flow is not offloaded due to min inline setting, required %d actual %d\n",
- match_level, esw->offloads.inline_mode);
+ non_tunnel_match_level, esw->offloads.inline_mode);
return -EOPNOTSUPP;
}
}
if (flow->flags & MLX5E_TC_FLOW_ESWITCH) {
- flow->esw_attr->match_level = match_level;
- flow->esw_attr->tunnel_match_level = tunnel_match_level;
+ flow->esw_attr->inner_match_level = inner_match_level;
+ flow->esw_attr->outer_match_level = outer_match_level;
} else {
- flow->nic_attr->match_level = match_level;
+ flow->nic_attr->match_level = non_tunnel_match_level;
}
return err;
@@ -3158,7 +3167,7 @@ mlx5e_flow_esw_attr_init(struct mlx5_esw_flow_attr *esw_attr,
esw_attr->parse_attr = parse_attr;
esw_attr->chain = f->common.chain_index;
- esw_attr->prio = TC_H_MAJ(f->common.prio) >> 16;
+ esw_attr->prio = f->common.prio;
esw_attr->in_rep = in_rep;
esw_attr->in_mdev = in_mdev;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index a38e8a3c7c9a..04685dbb280c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -377,8 +377,8 @@ struct mlx5_esw_flow_attr {
struct mlx5_termtbl_handle *termtbl;
} dests[MLX5_MAX_FLOW_FWD_VPORTS];
u32 mod_hdr_id;
- u8 match_level;
- u8 tunnel_match_level;
+ u8 inner_match_level;
+ u8 outer_match_level;
struct mlx5_fc *counter;
u32 chain;
u16 prio;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 089ae4d48a82..0323fd078271 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -207,14 +207,10 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
mlx5_eswitch_set_rule_source_port(esw, spec, attr);
- if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DECAP) {
- if (attr->tunnel_match_level != MLX5_MATCH_NONE)
- spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS;
- if (attr->match_level != MLX5_MATCH_NONE)
- spec->match_criteria_enable |= MLX5_MATCH_INNER_HEADERS;
- } else if (attr->match_level != MLX5_MATCH_NONE) {
+ if (attr->outer_match_level != MLX5_MATCH_NONE)
spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS;
- }
+ if (attr->inner_match_level != MLX5_MATCH_NONE)
+ spec->match_criteria_enable |= MLX5_MATCH_INNER_HEADERS;
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)
flow_act.modify_id = attr->mod_hdr_id;
@@ -290,7 +286,7 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw,
mlx5_eswitch_set_rule_source_port(esw, spec, attr);
spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS;
- if (attr->match_level != MLX5_MATCH_NONE)
+ if (attr->outer_match_level != MLX5_MATCH_NONE)
spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS;
rule = mlx5_add_flow_rules(fast_fdb, spec, &flow_act, dest, i);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
index 9314777d99e3..d685122d9ff7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -590,7 +590,8 @@ mlx5_fw_fatal_reporter_dump(struct devlink_health_reporter *reporter,
data_size = crdump_size - offset;
else
data_size = MLX5_CR_DUMP_CHUNK_SIZE;
- err = devlink_fmsg_binary_put(fmsg, cr_data, data_size);
+ err = devlink_fmsg_binary_put(fmsg, (char *)cr_data + offset,
+ data_size);
if (err)
goto free_data;
}
@@ -700,6 +701,16 @@ static void poll_health(struct timer_list *t)
if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
goto out;
+ fatal_error = check_fatal_sensors(dev);
+
+ if (fatal_error && !health->fatal_error) {
+ mlx5_core_err(dev, "Fatal error %u detected\n", fatal_error);
+ dev->priv.health.fatal_error = fatal_error;
+ print_health_info(dev);
+ mlx5_trigger_health_work(dev);
+ goto out;
+ }
+
count = ioread32be(health->health_counter);
if (count == health->prev)
++health->miss_counter;
@@ -718,15 +729,6 @@ static void poll_health(struct timer_list *t)
if (health->synd && health->synd != prev_synd)
queue_work(health->wq, &health->report_work);
- fatal_error = check_fatal_sensors(dev);
-
- if (fatal_error && !health->fatal_error) {
- mlx5_core_err(dev, "Fatal error %u detected\n", fatal_error);
- dev->priv.health.fatal_error = fatal_error;
- print_health_info(dev);
- mlx5_trigger_health_work(dev);
- }
-
out:
mod_timer(&health->timer, get_next_poll_jiffies());
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
index ebd81f6b556e..90cb50fe17fd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
@@ -122,6 +122,14 @@ static int mlx5i_get_ts_info(struct net_device *netdev,
return mlx5e_ethtool_get_ts_info(priv, info);
}
+static int mlx5i_flash_device(struct net_device *netdev,
+ struct ethtool_flash *flash)
+{
+ struct mlx5e_priv *priv = mlx5i_epriv(netdev);
+
+ return mlx5e_ethtool_flash_device(priv, flash);
+}
+
enum mlx5_ptys_width {
MLX5_PTYS_WIDTH_1X = 1 << 0,
MLX5_PTYS_WIDTH_2X = 1 << 1,
@@ -233,6 +241,7 @@ const struct ethtool_ops mlx5i_ethtool_ops = {
.get_ethtool_stats = mlx5i_get_ethtool_stats,
.get_ringparam = mlx5i_get_ringparam,
.set_ringparam = mlx5i_set_ringparam,
+ .flash_device = mlx5i_flash_device,
.get_channels = mlx5i_get_channels,
.set_channels = mlx5i_set_channels,
.get_coalesce = mlx5i_get_coalesce,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c
index ea9ee88491e5..ea1d4d26ece0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c
@@ -27,6 +27,7 @@ int mlx5_create_encryption_key(struct mlx5_core_dev *mdev,
case 128:
general_obj_key_size =
MLX5_GENERAL_OBJECT_TYPE_ENCRYPTION_KEY_KEY_SIZE_128;
+ key_p += sz_bytes;
break;
case 256:
general_obj_key_size =
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
index e8ac90564dbe..84a87d059333 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
@@ -471,7 +471,7 @@ int mlxsw_sp_acl_rulei_commit(struct mlxsw_sp_acl_rule_info *rulei)
void mlxsw_sp_acl_rulei_priority(struct mlxsw_sp_acl_rule_info *rulei,
unsigned int priority)
{
- rulei->priority = priority >> 16;
+ rulei->priority = priority;
}
void mlxsw_sp_acl_rulei_keymask_u32(struct mlxsw_sp_acl_rule_info *rulei,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
index 63b07edd9d81..38bb1cfe4e8c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
@@ -29,7 +29,7 @@
struct mlxsw_sp_ptp_state {
struct mlxsw_sp *mlxsw_sp;
- struct rhashtable unmatched_ht;
+ struct rhltable unmatched_ht;
spinlock_t unmatched_lock; /* protects the HT */
struct delayed_work ht_gc_dw;
u32 gc_cycle;
@@ -45,7 +45,7 @@ struct mlxsw_sp1_ptp_key {
struct mlxsw_sp1_ptp_unmatched {
struct mlxsw_sp1_ptp_key key;
- struct rhash_head ht_node;
+ struct rhlist_head ht_node;
struct rcu_head rcu;
struct sk_buff *skb;
u64 timestamp;
@@ -359,7 +359,7 @@ static int mlxsw_sp_ptp_parse(struct sk_buff *skb,
/* Returns NULL on successful insertion, a pointer on conflict, or an ERR_PTR on
* error.
*/
-static struct mlxsw_sp1_ptp_unmatched *
+static int
mlxsw_sp1_ptp_unmatched_save(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp1_ptp_key key,
struct sk_buff *skb,
@@ -368,41 +368,51 @@ mlxsw_sp1_ptp_unmatched_save(struct mlxsw_sp *mlxsw_sp,
int cycles = MLXSW_SP1_PTP_HT_GC_TIMEOUT / MLXSW_SP1_PTP_HT_GC_INTERVAL;
struct mlxsw_sp_ptp_state *ptp_state = mlxsw_sp->ptp_state;
struct mlxsw_sp1_ptp_unmatched *unmatched;
- struct mlxsw_sp1_ptp_unmatched *conflict;
+ int err;
unmatched = kzalloc(sizeof(*unmatched), GFP_ATOMIC);
if (!unmatched)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
unmatched->key = key;
unmatched->skb = skb;
unmatched->timestamp = timestamp;
unmatched->gc_cycle = mlxsw_sp->ptp_state->gc_cycle + cycles;
- conflict = rhashtable_lookup_get_insert_fast(&ptp_state->unmatched_ht,
- &unmatched->ht_node,
- mlxsw_sp1_ptp_unmatched_ht_params);
- if (conflict)
+ err = rhltable_insert(&ptp_state->unmatched_ht, &unmatched->ht_node,
+ mlxsw_sp1_ptp_unmatched_ht_params);
+ if (err)
kfree(unmatched);
- return conflict;
+ return err;
}
static struct mlxsw_sp1_ptp_unmatched *
mlxsw_sp1_ptp_unmatched_lookup(struct mlxsw_sp *mlxsw_sp,
- struct mlxsw_sp1_ptp_key key)
+ struct mlxsw_sp1_ptp_key key, int *p_length)
{
- return rhashtable_lookup(&mlxsw_sp->ptp_state->unmatched_ht, &key,
- mlxsw_sp1_ptp_unmatched_ht_params);
+ struct mlxsw_sp1_ptp_unmatched *unmatched, *last = NULL;
+ struct rhlist_head *tmp, *list;
+ int length = 0;
+
+ list = rhltable_lookup(&mlxsw_sp->ptp_state->unmatched_ht, &key,
+ mlxsw_sp1_ptp_unmatched_ht_params);
+ rhl_for_each_entry_rcu(unmatched, tmp, list, ht_node) {
+ last = unmatched;
+ length++;
+ }
+
+ *p_length = length;
+ return last;
}
static int
mlxsw_sp1_ptp_unmatched_remove(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp1_ptp_unmatched *unmatched)
{
- return rhashtable_remove_fast(&mlxsw_sp->ptp_state->unmatched_ht,
- &unmatched->ht_node,
- mlxsw_sp1_ptp_unmatched_ht_params);
+ return rhltable_remove(&mlxsw_sp->ptp_state->unmatched_ht,
+ &unmatched->ht_node,
+ mlxsw_sp1_ptp_unmatched_ht_params);
}
/* This function is called in the following scenarios:
@@ -489,75 +499,38 @@ static void mlxsw_sp1_ptp_got_piece(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp1_ptp_key key,
struct sk_buff *skb, u64 timestamp)
{
- struct mlxsw_sp1_ptp_unmatched *unmatched, *conflict;
+ struct mlxsw_sp1_ptp_unmatched *unmatched;
+ int length;
int err;
rcu_read_lock();
- unmatched = mlxsw_sp1_ptp_unmatched_lookup(mlxsw_sp, key);
-
spin_lock(&mlxsw_sp->ptp_state->unmatched_lock);
- if (unmatched) {
- /* There was an unmatched entry when we looked, but it may have
- * been removed before we took the lock.
- */
- err = mlxsw_sp1_ptp_unmatched_remove(mlxsw_sp, unmatched);
- if (err)
- unmatched = NULL;
- }
-
- if (!unmatched) {
- /* We have no unmatched entry, but one may have been added after
- * we looked, but before we took the lock.
- */
- unmatched = mlxsw_sp1_ptp_unmatched_save(mlxsw_sp, key,
- skb, timestamp);
- if (IS_ERR(unmatched)) {
- if (skb)
- mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb,
- key.local_port,
- key.ingress, NULL);
- unmatched = NULL;
- } else if (unmatched) {
- /* Save just told us, under lock, that the entry is
- * there, so this has to work.
- */
- err = mlxsw_sp1_ptp_unmatched_remove(mlxsw_sp,
- unmatched);
- WARN_ON_ONCE(err);
- }
- }
-
- /* If unmatched is non-NULL here, it comes either from the lookup, or
- * from the save attempt above. In either case the entry was removed
- * from the hash table. If unmatched is NULL, a new unmatched entry was
- * added to the hash table, and there was no conflict.
- */
-
+ unmatched = mlxsw_sp1_ptp_unmatched_lookup(mlxsw_sp, key, &length);
if (skb && unmatched && unmatched->timestamp) {
unmatched->skb = skb;
} else if (timestamp && unmatched && unmatched->skb) {
unmatched->timestamp = timestamp;
- } else if (unmatched) {
- /* unmatched holds an older entry of the same type: either an
- * skb if we are handling skb, or a timestamp if we are handling
- * timestamp. We can't match that up, so save what we have.
+ } else {
+ /* Either there is no entry to match, or one that is there is
+ * incompatible.
*/
- conflict = mlxsw_sp1_ptp_unmatched_save(mlxsw_sp, key,
- skb, timestamp);
- if (IS_ERR(conflict)) {
- if (skb)
- mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb,
- key.local_port,
- key.ingress, NULL);
- } else {
- /* Above, we removed an object with this key from the
- * hash table, under lock, so conflict can not be a
- * valid pointer.
- */
- WARN_ON_ONCE(conflict);
- }
+ if (length < 100)
+ err = mlxsw_sp1_ptp_unmatched_save(mlxsw_sp, key,
+ skb, timestamp);
+ else
+ err = -E2BIG;
+ if (err && skb)
+ mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb,
+ key.local_port,
+ key.ingress, NULL);
+ unmatched = NULL;
+ }
+
+ if (unmatched) {
+ err = mlxsw_sp1_ptp_unmatched_remove(mlxsw_sp, unmatched);
+ WARN_ON_ONCE(err);
}
spin_unlock(&mlxsw_sp->ptp_state->unmatched_lock);
@@ -669,9 +642,8 @@ mlxsw_sp1_ptp_ht_gc_collect(struct mlxsw_sp_ptp_state *ptp_state,
local_bh_disable();
spin_lock(&ptp_state->unmatched_lock);
- err = rhashtable_remove_fast(&ptp_state->unmatched_ht,
- &unmatched->ht_node,
- mlxsw_sp1_ptp_unmatched_ht_params);
+ err = rhltable_remove(&ptp_state->unmatched_ht, &unmatched->ht_node,
+ mlxsw_sp1_ptp_unmatched_ht_params);
spin_unlock(&ptp_state->unmatched_lock);
if (err)
@@ -702,7 +674,7 @@ static void mlxsw_sp1_ptp_ht_gc(struct work_struct *work)
ptp_state = container_of(dwork, struct mlxsw_sp_ptp_state, ht_gc_dw);
gc_cycle = ptp_state->gc_cycle++;
- rhashtable_walk_enter(&ptp_state->unmatched_ht, &iter);
+ rhltable_walk_enter(&ptp_state->unmatched_ht, &iter);
rhashtable_walk_start(&iter);
while ((obj = rhashtable_walk_next(&iter))) {
if (IS_ERR(obj))
@@ -855,8 +827,8 @@ struct mlxsw_sp_ptp_state *mlxsw_sp1_ptp_init(struct mlxsw_sp *mlxsw_sp)
spin_lock_init(&ptp_state->unmatched_lock);
- err = rhashtable_init(&ptp_state->unmatched_ht,
- &mlxsw_sp1_ptp_unmatched_ht_params);
+ err = rhltable_init(&ptp_state->unmatched_ht,
+ &mlxsw_sp1_ptp_unmatched_ht_params);
if (err)
goto err_hashtable_init;
@@ -891,7 +863,7 @@ err_fifo_clr:
err_mtptpt1_set:
mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP0, 0);
err_mtptpt_set:
- rhashtable_destroy(&ptp_state->unmatched_ht);
+ rhltable_destroy(&ptp_state->unmatched_ht);
err_hashtable_init:
kfree(ptp_state);
return ERR_PTR(err);
@@ -906,8 +878,8 @@ void mlxsw_sp1_ptp_fini(struct mlxsw_sp_ptp_state *ptp_state)
mlxsw_sp1_ptp_set_fifo_clr_on_trap(mlxsw_sp, false);
mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP1, 0);
mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP0, 0);
- rhashtable_free_and_destroy(&ptp_state->unmatched_ht,
- &mlxsw_sp1_ptp_unmatched_free_fn, NULL);
+ rhltable_free_and_destroy(&ptp_state->unmatched_ht,
+ &mlxsw_sp1_ptp_unmatched_free_fn, NULL);
kfree(ptp_state);
}
diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig
index 90a8c6bead56..b9c4d48e28e4 100644
--- a/drivers/net/ethernet/micrel/Kconfig
+++ b/drivers/net/ethernet/micrel/Kconfig
@@ -6,8 +6,7 @@
config NET_VENDOR_MICREL
bool "Micrel devices"
default y
- depends on (HAS_IOMEM && DMA_ENGINE) || SPI || PCI || HAS_IOMEM || \
- (ARM && ARCH_KS8695)
+ depends on (HAS_IOMEM && DMA_ENGINE) || SPI || PCI || HAS_IOMEM
---help---
If you have a network (Ethernet) card belonging to this class, say Y.
@@ -18,14 +17,6 @@ config NET_VENDOR_MICREL
if NET_VENDOR_MICREL
-config ARM_KS8695_ETHER
- tristate "KS8695 Ethernet support"
- depends on ARM && ARCH_KS8695
- select MII
- ---help---
- If you wish to compile a kernel for the KS8695 and want to
- use the internal ethernet then you should answer Y to this.
-
config KS8842
tristate "Micrel KSZ8841/42 with generic bus interface"
depends on HAS_IOMEM && DMA_ENGINE
diff --git a/drivers/net/ethernet/micrel/Makefile b/drivers/net/ethernet/micrel/Makefile
index 848fc1c5a5dc..6d8ac5527aef 100644
--- a/drivers/net/ethernet/micrel/Makefile
+++ b/drivers/net/ethernet/micrel/Makefile
@@ -3,7 +3,6 @@
# Makefile for the Micrel network device drivers.
#
-obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o
obj-$(CONFIG_KS8842) += ks8842.o
obj-$(CONFIG_KS8851) += ks8851.o
obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c
deleted file mode 100644
index 1390ef5323a2..000000000000
--- a/drivers/net/ethernet/micrel/ks8695net.c
+++ /dev/null
@@ -1,1632 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Micrel KS8695 (Centaur) Ethernet.
- *
- * Copyright 2008 Simtec Electronics
- * Daniel Silverstone <dsilvers@simtec.co.uk>
- * Vincent Sanders <vince@simtec.co.uk>
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/interrupt.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <asm/irq.h>
-
-#include <mach/regs-switch.h>
-#include <mach/regs-misc.h>
-#include <asm/mach/irq.h>
-#include <mach/regs-irq.h>
-
-#include "ks8695net.h"
-
-#define MODULENAME "ks8695_ether"
-#define MODULEVERSION "1.02"
-
-/*
- * Transmit and device reset timeout, default 5 seconds.
- */
-static int watchdog = 5000;
-
-/* Hardware structures */
-
-/**
- * struct rx_ring_desc - Receive descriptor ring element
- * @status: The status of the descriptor element (E.g. who owns it)
- * @length: The number of bytes in the block pointed to by data_ptr
- * @data_ptr: The physical address of the data block to receive into
- * @next_desc: The physical address of the next descriptor element.
- */
-struct rx_ring_desc {
- __le32 status;
- __le32 length;
- __le32 data_ptr;
- __le32 next_desc;
-};
-
-/**
- * struct tx_ring_desc - Transmit descriptor ring element
- * @owner: Who owns the descriptor
- * @status: The number of bytes in the block pointed to by data_ptr
- * @data_ptr: The physical address of the data block to receive into
- * @next_desc: The physical address of the next descriptor element.
- */
-struct tx_ring_desc {
- __le32 owner;
- __le32 status;
- __le32 data_ptr;
- __le32 next_desc;
-};
-
-/**
- * struct ks8695_skbuff - sk_buff wrapper for rx/tx rings.
- * @skb: The buffer in the ring
- * @dma_ptr: The mapped DMA pointer of the buffer
- * @length: The number of bytes mapped to dma_ptr
- */
-struct ks8695_skbuff {
- struct sk_buff *skb;
- dma_addr_t dma_ptr;
- u32 length;
-};
-
-/* Private device structure */
-
-#define MAX_TX_DESC 8
-#define MAX_TX_DESC_MASK 0x7
-#define MAX_RX_DESC 16
-#define MAX_RX_DESC_MASK 0xf
-
-/*napi_weight have better more than rx DMA buffers*/
-#define NAPI_WEIGHT 64
-
-#define MAX_RXBUF_SIZE 0x700
-
-#define TX_RING_DMA_SIZE (sizeof(struct tx_ring_desc) * MAX_TX_DESC)
-#define RX_RING_DMA_SIZE (sizeof(struct rx_ring_desc) * MAX_RX_DESC)
-#define RING_DMA_SIZE (TX_RING_DMA_SIZE + RX_RING_DMA_SIZE)
-
-/**
- * enum ks8695_dtype - Device type
- * @KS8695_DTYPE_WAN: This device is a WAN interface
- * @KS8695_DTYPE_LAN: This device is a LAN interface
- * @KS8695_DTYPE_HPNA: This device is an HPNA interface
- */
-enum ks8695_dtype {
- KS8695_DTYPE_WAN,
- KS8695_DTYPE_LAN,
- KS8695_DTYPE_HPNA,
-};
-
-/**
- * struct ks8695_priv - Private data for the KS8695 Ethernet
- * @in_suspend: Flag to indicate if we're suspending/resuming
- * @ndev: The net_device for this interface
- * @dev: The platform device object for this interface
- * @dtype: The type of this device
- * @io_regs: The ioremapped registers for this interface
- * @napi : Add support NAPI for Rx
- * @rx_irq_name: The textual name of the RX IRQ from the platform data
- * @tx_irq_name: The textual name of the TX IRQ from the platform data
- * @link_irq_name: The textual name of the link IRQ from the
- * platform data if available
- * @rx_irq: The IRQ number for the RX IRQ
- * @tx_irq: The IRQ number for the TX IRQ
- * @link_irq: The IRQ number for the link IRQ if available
- * @regs_req: The resource request for the registers region
- * @phyiface_req: The resource request for the phy/switch region
- * if available
- * @phyiface_regs: The ioremapped registers for the phy/switch if available
- * @ring_base: The base pointer of the dma coherent memory for the rings
- * @ring_base_dma: The DMA mapped equivalent of ring_base
- * @tx_ring: The pointer in ring_base of the TX ring
- * @tx_ring_used: The number of slots in the TX ring which are occupied
- * @tx_ring_next_slot: The next slot to fill in the TX ring
- * @tx_ring_dma: The DMA mapped equivalent of tx_ring
- * @tx_buffers: The sk_buff mappings for the TX ring
- * @txq_lock: A lock to protect the tx_buffers tx_ring_used etc variables
- * @rx_ring: The pointer in ring_base of the RX ring
- * @rx_ring_dma: The DMA mapped equivalent of rx_ring
- * @rx_buffers: The sk_buff mappings for the RX ring
- * @next_rx_desc_read: The next RX descriptor to read from on IRQ
- * @rx_lock: A lock to protect Rx irq function
- * @msg_enable: The flags for which messages to emit
- */
-struct ks8695_priv {
- int in_suspend;
- struct net_device *ndev;
- struct device *dev;
- enum ks8695_dtype dtype;
- void __iomem *io_regs;
-
- struct napi_struct napi;
-
- const char *rx_irq_name, *tx_irq_name, *link_irq_name;
- int rx_irq, tx_irq, link_irq;
-
- struct resource *regs_req, *phyiface_req;
- void __iomem *phyiface_regs;
-
- void *ring_base;
- dma_addr_t ring_base_dma;
-
- struct tx_ring_desc *tx_ring;
- int tx_ring_used;
- int tx_ring_next_slot;
- dma_addr_t tx_ring_dma;
- struct ks8695_skbuff tx_buffers[MAX_TX_DESC];
- spinlock_t txq_lock;
-
- struct rx_ring_desc *rx_ring;
- dma_addr_t rx_ring_dma;
- struct ks8695_skbuff rx_buffers[MAX_RX_DESC];
- int next_rx_desc_read;
- spinlock_t rx_lock;
-
- int msg_enable;
-};
-
-/* Register access */
-
-/**
- * ks8695_readreg - Read from a KS8695 ethernet register
- * @ksp: The device to read from
- * @reg: The register to read
- */
-static inline u32
-ks8695_readreg(struct ks8695_priv *ksp, int reg)
-{
- return readl(ksp->io_regs + reg);
-}
-
-/**
- * ks8695_writereg - Write to a KS8695 ethernet register
- * @ksp: The device to write to
- * @reg: The register to write
- * @value: The value to write to the register
- */
-static inline void
-ks8695_writereg(struct ks8695_priv *ksp, int reg, u32 value)
-{
- writel(value, ksp->io_regs + reg);
-}
-
-/* Utility functions */
-
-/**
- * ks8695_port_type - Retrieve port-type as user-friendly string
- * @ksp: The device to return the type for
- *
- * Returns a string indicating which of the WAN, LAN or HPNA
- * ports this device is likely to represent.
- */
-static const char *
-ks8695_port_type(struct ks8695_priv *ksp)
-{
- switch (ksp->dtype) {
- case KS8695_DTYPE_LAN:
- return "LAN";
- case KS8695_DTYPE_WAN:
- return "WAN";
- case KS8695_DTYPE_HPNA:
- return "HPNA";
- }
-
- return "UNKNOWN";
-}
-
-/**
- * ks8695_update_mac - Update the MAC registers in the device
- * @ksp: The device to update
- *
- * Updates the MAC registers in the KS8695 device from the address in the
- * net_device structure associated with this interface.
- */
-static void
-ks8695_update_mac(struct ks8695_priv *ksp)
-{
- /* Update the HW with the MAC from the net_device */
- struct net_device *ndev = ksp->ndev;
- u32 machigh, maclow;
-
- maclow = ((ndev->dev_addr[2] << 24) | (ndev->dev_addr[3] << 16) |
- (ndev->dev_addr[4] << 8) | (ndev->dev_addr[5] << 0));
- machigh = ((ndev->dev_addr[0] << 8) | (ndev->dev_addr[1] << 0));
-
- ks8695_writereg(ksp, KS8695_MAL, maclow);
- ks8695_writereg(ksp, KS8695_MAH, machigh);
-
-}
-
-/**
- * ks8695_refill_rxbuffers - Re-fill the RX buffer ring
- * @ksp: The device to refill
- *
- * Iterates the RX ring of the device looking for empty slots.
- * For each empty slot, we allocate and map a new SKB and give it
- * to the hardware.
- * This can be called from interrupt context safely.
- */
-static void
-ks8695_refill_rxbuffers(struct ks8695_priv *ksp)
-{
- /* Run around the RX ring, filling in any missing sk_buff's */
- int buff_n;
-
- for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
- if (!ksp->rx_buffers[buff_n].skb) {
- struct sk_buff *skb =
- netdev_alloc_skb(ksp->ndev, MAX_RXBUF_SIZE);
- dma_addr_t mapping;
-
- ksp->rx_buffers[buff_n].skb = skb;
- if (skb == NULL) {
- /* Failed to allocate one, perhaps
- * we'll try again later.
- */
- break;
- }
-
- mapping = dma_map_single(ksp->dev, skb->data,
- MAX_RXBUF_SIZE,
- DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(ksp->dev, mapping))) {
- /* Failed to DMA map this SKB, try later */
- dev_kfree_skb_irq(skb);
- ksp->rx_buffers[buff_n].skb = NULL;
- break;
- }
- ksp->rx_buffers[buff_n].dma_ptr = mapping;
- ksp->rx_buffers[buff_n].length = MAX_RXBUF_SIZE;
-
- /* Record this into the DMA ring */
- ksp->rx_ring[buff_n].data_ptr = cpu_to_le32(mapping);
- ksp->rx_ring[buff_n].length =
- cpu_to_le32(MAX_RXBUF_SIZE);
-
- wmb();
-
- /* And give ownership over to the hardware */
- ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
- }
- }
-}
-
-/* Maximum number of multicast addresses which the KS8695 HW supports */
-#define KS8695_NR_ADDRESSES 16
-
-/**
- * ks8695_init_partial_multicast - Init the mcast addr registers
- * @ksp: The device to initialise
- * @addr: The multicast address list to use
- * @nr_addr: The number of addresses in the list
- *
- * This routine is a helper for ks8695_set_multicast - it writes
- * the additional-address registers in the KS8695 ethernet device
- * and cleans up any others left behind.
- */
-static void
-ks8695_init_partial_multicast(struct ks8695_priv *ksp,
- struct net_device *ndev)
-{
- u32 low, high;
- int i;
- struct netdev_hw_addr *ha;
-
- i = 0;
- netdev_for_each_mc_addr(ha, ndev) {
- /* Ran out of space in chip? */
- BUG_ON(i == KS8695_NR_ADDRESSES);
-
- low = (ha->addr[2] << 24) | (ha->addr[3] << 16) |
- (ha->addr[4] << 8) | (ha->addr[5]);
- high = (ha->addr[0] << 8) | (ha->addr[1]);
-
- ks8695_writereg(ksp, KS8695_AAL_(i), low);
- ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high);
- i++;
- }
-
- /* Clear the remaining Additional Station Addresses */
- for (; i < KS8695_NR_ADDRESSES; i++) {
- ks8695_writereg(ksp, KS8695_AAL_(i), 0);
- ks8695_writereg(ksp, KS8695_AAH_(i), 0);
- }
-}
-
-/* Interrupt handling */
-
-/**
- * ks8695_tx_irq - Transmit IRQ handler
- * @irq: The IRQ which went off (ignored)
- * @dev_id: The net_device for the interrupt
- *
- * Process the TX ring, clearing out any transmitted slots.
- * Allows the net_device to pass us new packets once slots are
- * freed.
- */
-static irqreturn_t
-ks8695_tx_irq(int irq, void *dev_id)
-{
- struct net_device *ndev = (struct net_device *)dev_id;
- struct ks8695_priv *ksp = netdev_priv(ndev);
- int buff_n;
-
- for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
- if (ksp->tx_buffers[buff_n].skb &&
- !(ksp->tx_ring[buff_n].owner & cpu_to_le32(TDES_OWN))) {
- rmb();
- /* An SKB which is not owned by HW is present */
- /* Update the stats for the net_device */
- ndev->stats.tx_packets++;
- ndev->stats.tx_bytes += ksp->tx_buffers[buff_n].length;
-
- /* Free the packet from the ring */
- ksp->tx_ring[buff_n].data_ptr = 0;
-
- /* Free the sk_buff */
- dma_unmap_single(ksp->dev,
- ksp->tx_buffers[buff_n].dma_ptr,
- ksp->tx_buffers[buff_n].length,
- DMA_TO_DEVICE);
- dev_consume_skb_irq(ksp->tx_buffers[buff_n].skb);
- ksp->tx_buffers[buff_n].skb = NULL;
- ksp->tx_ring_used--;
- }
- }
-
- netif_wake_queue(ndev);
-
- return IRQ_HANDLED;
-}
-
-/**
- * ks8695_get_rx_enable_bit - Get rx interrupt enable/status bit
- * @ksp: Private data for the KS8695 Ethernet
- *
- * For KS8695 document:
- * Interrupt Enable Register (offset 0xE204)
- * Bit29 : WAN MAC Receive Interrupt Enable
- * Bit16 : LAN MAC Receive Interrupt Enable
- * Interrupt Status Register (Offset 0xF208)
- * Bit29: WAN MAC Receive Status
- * Bit16: LAN MAC Receive Status
- * So, this Rx interrupt enable/status bit number is equal
- * as Rx IRQ number.
- */
-static inline u32 ks8695_get_rx_enable_bit(struct ks8695_priv *ksp)
-{
- return ksp->rx_irq;
-}
-
-/**
- * ks8695_rx_irq - Receive IRQ handler
- * @irq: The IRQ which went off (ignored)
- * @dev_id: The net_device for the interrupt
- *
- * Inform NAPI that packet reception needs to be scheduled
- */
-
-static irqreturn_t
-ks8695_rx_irq(int irq, void *dev_id)
-{
- struct net_device *ndev = (struct net_device *)dev_id;
- struct ks8695_priv *ksp = netdev_priv(ndev);
-
- spin_lock(&ksp->rx_lock);
-
- if (napi_schedule_prep(&ksp->napi)) {
- unsigned long status = readl(KS8695_IRQ_VA + KS8695_INTEN);
- unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp);
- /*disable rx interrupt*/
- status &= ~mask_bit;
- writel(status , KS8695_IRQ_VA + KS8695_INTEN);
- __napi_schedule(&ksp->napi);
- }
-
- spin_unlock(&ksp->rx_lock);
- return IRQ_HANDLED;
-}
-
-/**
- * ks8695_rx - Receive packets called by NAPI poll method
- * @ksp: Private data for the KS8695 Ethernet
- * @budget: Number of packets allowed to process
- */
-static int ks8695_rx(struct ks8695_priv *ksp, int budget)
-{
- struct net_device *ndev = ksp->ndev;
- struct sk_buff *skb;
- int buff_n;
- u32 flags;
- int pktlen;
- int received = 0;
-
- buff_n = ksp->next_rx_desc_read;
- while (received < budget
- && ksp->rx_buffers[buff_n].skb
- && (!(ksp->rx_ring[buff_n].status &
- cpu_to_le32(RDES_OWN)))) {
- rmb();
- flags = le32_to_cpu(ksp->rx_ring[buff_n].status);
-
- /* Found an SKB which we own, this means we
- * received a packet
- */
- if ((flags & (RDES_FS | RDES_LS)) !=
- (RDES_FS | RDES_LS)) {
- /* This packet is not the first and
- * the last segment. Therefore it is
- * a "spanning" packet and we can't
- * handle it
- */
- goto rx_failure;
- }
-
- if (flags & (RDES_ES | RDES_RE)) {
- /* It's an error packet */
- ndev->stats.rx_errors++;
- if (flags & RDES_TL)
- ndev->stats.rx_length_errors++;
- if (flags & RDES_RF)
- ndev->stats.rx_length_errors++;
- if (flags & RDES_CE)
- ndev->stats.rx_crc_errors++;
- if (flags & RDES_RE)
- ndev->stats.rx_missed_errors++;
-
- goto rx_failure;
- }
-
- pktlen = flags & RDES_FLEN;
- pktlen -= 4; /* Drop the CRC */
-
- /* Retrieve the sk_buff */
- skb = ksp->rx_buffers[buff_n].skb;
-
- /* Clear it from the ring */
- ksp->rx_buffers[buff_n].skb = NULL;
- ksp->rx_ring[buff_n].data_ptr = 0;
-
- /* Unmap the SKB */
- dma_unmap_single(ksp->dev,
- ksp->rx_buffers[buff_n].dma_ptr,
- ksp->rx_buffers[buff_n].length,
- DMA_FROM_DEVICE);
-
- /* Relinquish the SKB to the network layer */
- skb_put(skb, pktlen);
- skb->protocol = eth_type_trans(skb, ndev);
- napi_gro_receive(&ksp->napi, skb);
-
- /* Record stats */
- ndev->stats.rx_packets++;
- ndev->stats.rx_bytes += pktlen;
- goto rx_finished;
-
-rx_failure:
- /* This ring entry is an error, but we can
- * re-use the skb
- */
- /* Give the ring entry back to the hardware */
- ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
-rx_finished:
- received++;
- buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
- }
-
- /* And note which RX descriptor we last did */
- ksp->next_rx_desc_read = buff_n;
-
- /* And refill the buffers */
- ks8695_refill_rxbuffers(ksp);
-
- /* Kick the RX DMA engine, in case it became suspended */
- ks8695_writereg(ksp, KS8695_DRSC, 0);
-
- return received;
-}
-
-
-/**
- * ks8695_poll - Receive packet by NAPI poll method
- * @ksp: Private data for the KS8695 Ethernet
- * @budget: The remaining number packets for network subsystem
- *
- * Invoked by the network core when it requests for new
- * packets from the driver
- */
-static int ks8695_poll(struct napi_struct *napi, int budget)
-{
- struct ks8695_priv *ksp = container_of(napi, struct ks8695_priv, napi);
- unsigned long isr = readl(KS8695_IRQ_VA + KS8695_INTEN);
- unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp);
- int work_done;
-
- work_done = ks8695_rx(ksp, budget);
-
- if (work_done < budget && napi_complete_done(napi, work_done)) {
- unsigned long flags;
-
- spin_lock_irqsave(&ksp->rx_lock, flags);
- /* enable rx interrupt */
- writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
- spin_unlock_irqrestore(&ksp->rx_lock, flags);
- }
- return work_done;
-}
-
-/**
- * ks8695_link_irq - Link change IRQ handler
- * @irq: The IRQ which went off (ignored)
- * @dev_id: The net_device for the interrupt
- *
- * The WAN interface can generate an IRQ when the link changes,
- * report this to the net layer and the user.
- */
-static irqreturn_t
-ks8695_link_irq(int irq, void *dev_id)
-{
- struct net_device *ndev = (struct net_device *)dev_id;
- struct ks8695_priv *ksp = netdev_priv(ndev);
- u32 ctrl;
-
- ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
- if (ctrl & WMC_WLS) {
- netif_carrier_on(ndev);
- if (netif_msg_link(ksp))
- dev_info(ksp->dev,
- "%s: Link is now up (10%sMbps/%s-duplex)\n",
- ndev->name,
- (ctrl & WMC_WSS) ? "0" : "",
- (ctrl & WMC_WDS) ? "Full" : "Half");
- } else {
- netif_carrier_off(ndev);
- if (netif_msg_link(ksp))
- dev_info(ksp->dev, "%s: Link is now down.\n",
- ndev->name);
- }
-
- return IRQ_HANDLED;
-}
-
-
-/* KS8695 Device functions */
-
-/**
- * ks8695_reset - Reset a KS8695 ethernet interface
- * @ksp: The interface to reset
- *
- * Perform an engine reset of the interface and re-program it
- * with sensible defaults.
- */
-static void
-ks8695_reset(struct ks8695_priv *ksp)
-{
- int reset_timeout = watchdog;
- /* Issue the reset via the TX DMA control register */
- ks8695_writereg(ksp, KS8695_DTXC, DTXC_TRST);
- while (reset_timeout--) {
- if (!(ks8695_readreg(ksp, KS8695_DTXC) & DTXC_TRST))
- break;
- msleep(1);
- }
-
- if (reset_timeout < 0) {
- dev_crit(ksp->dev,
- "Timeout waiting for DMA engines to reset\n");
- /* And blithely carry on */
- }
-
- /* Definitely wait long enough before attempting to program
- * the engines
- */
- msleep(10);
-
- /* RX: unicast and broadcast */
- ks8695_writereg(ksp, KS8695_DRXC, DRXC_RU | DRXC_RB);
- /* TX: pad and add CRC */
- ks8695_writereg(ksp, KS8695_DTXC, DTXC_TEP | DTXC_TAC);
-}
-
-/**
- * ks8695_shutdown - Shut down a KS8695 ethernet interface
- * @ksp: The interface to shut down
- *
- * This disables packet RX/TX, cleans up IRQs, drains the rings,
- * and basically places the interface into a clean shutdown
- * state.
- */
-static void
-ks8695_shutdown(struct ks8695_priv *ksp)
-{
- u32 ctrl;
- int buff_n;
-
- /* Disable packet transmission */
- ctrl = ks8695_readreg(ksp, KS8695_DTXC);
- ks8695_writereg(ksp, KS8695_DTXC, ctrl & ~DTXC_TE);
-
- /* Disable packet reception */
- ctrl = ks8695_readreg(ksp, KS8695_DRXC);
- ks8695_writereg(ksp, KS8695_DRXC, ctrl & ~DRXC_RE);
-
- /* Release the IRQs */
- free_irq(ksp->rx_irq, ksp->ndev);
- free_irq(ksp->tx_irq, ksp->ndev);
- if (ksp->link_irq != -1)
- free_irq(ksp->link_irq, ksp->ndev);
-
- /* Throw away any pending TX packets */
- for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
- if (ksp->tx_buffers[buff_n].skb) {
- /* Remove this SKB from the TX ring */
- ksp->tx_ring[buff_n].owner = 0;
- ksp->tx_ring[buff_n].status = 0;
- ksp->tx_ring[buff_n].data_ptr = 0;
-
- /* Unmap and bin this SKB */
- dma_unmap_single(ksp->dev,
- ksp->tx_buffers[buff_n].dma_ptr,
- ksp->tx_buffers[buff_n].length,
- DMA_TO_DEVICE);
- dev_kfree_skb_irq(ksp->tx_buffers[buff_n].skb);
- ksp->tx_buffers[buff_n].skb = NULL;
- }
- }
-
- /* Purge the RX buffers */
- for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
- if (ksp->rx_buffers[buff_n].skb) {
- /* Remove the SKB from the RX ring */
- ksp->rx_ring[buff_n].status = 0;
- ksp->rx_ring[buff_n].data_ptr = 0;
-
- /* Unmap and bin the SKB */
- dma_unmap_single(ksp->dev,
- ksp->rx_buffers[buff_n].dma_ptr,
- ksp->rx_buffers[buff_n].length,
- DMA_FROM_DEVICE);
- dev_kfree_skb_irq(ksp->rx_buffers[buff_n].skb);
- ksp->rx_buffers[buff_n].skb = NULL;
- }
- }
-}
-
-
-/**
- * ks8695_setup_irq - IRQ setup helper function
- * @irq: The IRQ number to claim
- * @irq_name: The name to give the IRQ claimant
- * @handler: The function to call to handle the IRQ
- * @ndev: The net_device to pass in as the dev_id argument to the handler
- *
- * Return 0 on success.
- */
-static int
-ks8695_setup_irq(int irq, const char *irq_name,
- irq_handler_t handler, struct net_device *ndev)
-{
- int ret;
-
- ret = request_irq(irq, handler, IRQF_SHARED, irq_name, ndev);
-
- if (ret) {
- dev_err(&ndev->dev, "failure to request IRQ %d\n", irq);
- return ret;
- }
-
- return 0;
-}
-
-/**
- * ks8695_init_net - Initialise a KS8695 ethernet interface
- * @ksp: The interface to initialise
- *
- * This routine fills the RX ring, initialises the DMA engines,
- * allocates the IRQs and then starts the packet TX and RX
- * engines.
- */
-static int
-ks8695_init_net(struct ks8695_priv *ksp)
-{
- int ret;
- u32 ctrl;
-
- ks8695_refill_rxbuffers(ksp);
-
- /* Initialise the DMA engines */
- ks8695_writereg(ksp, KS8695_RDLB, (u32) ksp->rx_ring_dma);
- ks8695_writereg(ksp, KS8695_TDLB, (u32) ksp->tx_ring_dma);
-
- /* Request the IRQs */
- ret = ks8695_setup_irq(ksp->rx_irq, ksp->rx_irq_name,
- ks8695_rx_irq, ksp->ndev);
- if (ret)
- return ret;
- ret = ks8695_setup_irq(ksp->tx_irq, ksp->tx_irq_name,
- ks8695_tx_irq, ksp->ndev);
- if (ret)
- return ret;
- if (ksp->link_irq != -1) {
- ret = ks8695_setup_irq(ksp->link_irq, ksp->link_irq_name,
- ks8695_link_irq, ksp->ndev);
- if (ret)
- return ret;
- }
-
- /* Set up the ring indices */
- ksp->next_rx_desc_read = 0;
- ksp->tx_ring_next_slot = 0;
- ksp->tx_ring_used = 0;
-
- /* Bring up transmission */
- ctrl = ks8695_readreg(ksp, KS8695_DTXC);
- /* Enable packet transmission */
- ks8695_writereg(ksp, KS8695_DTXC, ctrl | DTXC_TE);
-
- /* Bring up the reception */
- ctrl = ks8695_readreg(ksp, KS8695_DRXC);
- /* Enable packet reception */
- ks8695_writereg(ksp, KS8695_DRXC, ctrl | DRXC_RE);
- /* And start the DMA engine */
- ks8695_writereg(ksp, KS8695_DRSC, 0);
-
- /* All done */
- return 0;
-}
-
-/**
- * ks8695_release_device - HW resource release for KS8695 e-net
- * @ksp: The device to be freed
- *
- * This unallocates io memory regions, dma-coherent regions etc
- * which were allocated in ks8695_probe.
- */
-static void
-ks8695_release_device(struct ks8695_priv *ksp)
-{
- /* Unmap the registers */
- iounmap(ksp->io_regs);
- if (ksp->phyiface_regs)
- iounmap(ksp->phyiface_regs);
-
- /* And release the request */
- release_resource(ksp->regs_req);
- kfree(ksp->regs_req);
- if (ksp->phyiface_req) {
- release_resource(ksp->phyiface_req);
- kfree(ksp->phyiface_req);
- }
-
- /* Free the ring buffers */
- dma_free_coherent(ksp->dev, RING_DMA_SIZE,
- ksp->ring_base, ksp->ring_base_dma);
-}
-
-/* Ethtool support */
-
-/**
- * ks8695_get_msglevel - Get the messages enabled for emission
- * @ndev: The network device to read from
- */
-static u32
-ks8695_get_msglevel(struct net_device *ndev)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
-
- return ksp->msg_enable;
-}
-
-/**
- * ks8695_set_msglevel - Set the messages enabled for emission
- * @ndev: The network device to configure
- * @value: The messages to set for emission
- */
-static void
-ks8695_set_msglevel(struct net_device *ndev, u32 value)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
-
- ksp->msg_enable = value;
-}
-
-/**
- * ks8695_wan_get_link_ksettings - Get device-specific settings.
- * @ndev: The network device to read settings from
- * @cmd: The ethtool structure to read into
- */
-static int
-ks8695_wan_get_link_ksettings(struct net_device *ndev,
- struct ethtool_link_ksettings *cmd)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
- u32 ctrl;
- u32 supported, advertising;
-
- /* All ports on the KS8695 support these... */
- supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
- SUPPORTED_TP | SUPPORTED_MII);
-
- advertising = ADVERTISED_TP | ADVERTISED_MII;
- cmd->base.port = PORT_MII;
- supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause);
- cmd->base.phy_address = 0;
-
- ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
- if ((ctrl & WMC_WAND) == 0) {
- /* auto-negotiation is enabled */
- advertising |= ADVERTISED_Autoneg;
- if (ctrl & WMC_WANA100F)
- advertising |= ADVERTISED_100baseT_Full;
- if (ctrl & WMC_WANA100H)
- advertising |= ADVERTISED_100baseT_Half;
- if (ctrl & WMC_WANA10F)
- advertising |= ADVERTISED_10baseT_Full;
- if (ctrl & WMC_WANA10H)
- advertising |= ADVERTISED_10baseT_Half;
- if (ctrl & WMC_WANAP)
- advertising |= ADVERTISED_Pause;
- cmd->base.autoneg = AUTONEG_ENABLE;
-
- cmd->base.speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
- cmd->base.duplex = (ctrl & WMC_WDS) ?
- DUPLEX_FULL : DUPLEX_HALF;
- } else {
- /* auto-negotiation is disabled */
- cmd->base.autoneg = AUTONEG_DISABLE;
-
- cmd->base.speed = (ctrl & WMC_WANF100) ?
- SPEED_100 : SPEED_10;
- cmd->base.duplex = (ctrl & WMC_WANFF) ?
- DUPLEX_FULL : DUPLEX_HALF;
- }
-
- ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
- supported);
- ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
- advertising);
-
- return 0;
-}
-
-/**
- * ks8695_wan_set_link_ksettings - Set device-specific settings.
- * @ndev: The network device to configure
- * @cmd: The settings to configure
- */
-static int
-ks8695_wan_set_link_ksettings(struct net_device *ndev,
- const struct ethtool_link_ksettings *cmd)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
- u32 ctrl;
- u32 advertising;
-
- ethtool_convert_link_mode_to_legacy_u32(&advertising,
- cmd->link_modes.advertising);
-
- if ((cmd->base.speed != SPEED_10) && (cmd->base.speed != SPEED_100))
- return -EINVAL;
- if ((cmd->base.duplex != DUPLEX_HALF) &&
- (cmd->base.duplex != DUPLEX_FULL))
- return -EINVAL;
- if (cmd->base.port != PORT_MII)
- return -EINVAL;
- if ((cmd->base.autoneg != AUTONEG_DISABLE) &&
- (cmd->base.autoneg != AUTONEG_ENABLE))
- return -EINVAL;
-
- if (cmd->base.autoneg == AUTONEG_ENABLE) {
- if ((advertising & (ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full)) == 0)
- return -EINVAL;
-
- ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
- ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
- WMC_WANA10F | WMC_WANA10H);
- if (advertising & ADVERTISED_100baseT_Full)
- ctrl |= WMC_WANA100F;
- if (advertising & ADVERTISED_100baseT_Half)
- ctrl |= WMC_WANA100H;
- if (advertising & ADVERTISED_10baseT_Full)
- ctrl |= WMC_WANA10F;
- if (advertising & ADVERTISED_10baseT_Half)
- ctrl |= WMC_WANA10H;
-
- /* force a re-negotiation */
- ctrl |= WMC_WANR;
- writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
- } else {
- ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
- /* disable auto-negotiation */
- ctrl |= WMC_WAND;
- ctrl &= ~(WMC_WANF100 | WMC_WANFF);
-
- if (cmd->base.speed == SPEED_100)
- ctrl |= WMC_WANF100;
- if (cmd->base.duplex == DUPLEX_FULL)
- ctrl |= WMC_WANFF;
-
- writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
- }
-
- return 0;
-}
-
-/**
- * ks8695_wan_nwayreset - Restart the autonegotiation on the port.
- * @ndev: The network device to restart autoneotiation on
- */
-static int
-ks8695_wan_nwayreset(struct net_device *ndev)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
- u32 ctrl;
-
- ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
- if ((ctrl & WMC_WAND) == 0)
- writel(ctrl | WMC_WANR,
- ksp->phyiface_regs + KS8695_WMC);
- else
- /* auto-negotiation not enabled */
- return -EINVAL;
-
- return 0;
-}
-
-/**
- * ks8695_wan_get_pause - Retrieve network pause/flow-control advertising
- * @ndev: The device to retrieve settings from
- * @param: The structure to fill out with the information
- */
-static void
-ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
- u32 ctrl;
-
- ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
- /* advertise Pause */
- param->autoneg = (ctrl & WMC_WANAP);
-
- /* current Rx Flow-control */
- ctrl = ks8695_readreg(ksp, KS8695_DRXC);
- param->rx_pause = (ctrl & DRXC_RFCE);
-
- /* current Tx Flow-control */
- ctrl = ks8695_readreg(ksp, KS8695_DTXC);
- param->tx_pause = (ctrl & DTXC_TFCE);
-}
-
-/**
- * ks8695_get_drvinfo - Retrieve driver information
- * @ndev: The network device to retrieve info about
- * @info: The info structure to fill out.
- */
-static void
-ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, MODULENAME, sizeof(info->driver));
- strlcpy(info->version, MODULEVERSION, sizeof(info->version));
- strlcpy(info->bus_info, dev_name(ndev->dev.parent),
- sizeof(info->bus_info));
-}
-
-static const struct ethtool_ops ks8695_ethtool_ops = {
- .get_msglevel = ks8695_get_msglevel,
- .set_msglevel = ks8695_set_msglevel,
- .get_drvinfo = ks8695_get_drvinfo,
-};
-
-static const struct ethtool_ops ks8695_wan_ethtool_ops = {
- .get_msglevel = ks8695_get_msglevel,
- .set_msglevel = ks8695_set_msglevel,
- .nway_reset = ks8695_wan_nwayreset,
- .get_link = ethtool_op_get_link,
- .get_pauseparam = ks8695_wan_get_pause,
- .get_drvinfo = ks8695_get_drvinfo,
- .get_link_ksettings = ks8695_wan_get_link_ksettings,
- .set_link_ksettings = ks8695_wan_set_link_ksettings,
-};
-
-/* Network device interface functions */
-
-/**
- * ks8695_set_mac - Update MAC in net dev and HW
- * @ndev: The network device to update
- * @addr: The new MAC address to set
- */
-static int
-ks8695_set_mac(struct net_device *ndev, void *addr)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
- struct sockaddr *address = addr;
-
- if (!is_valid_ether_addr(address->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(ndev->dev_addr, address->sa_data, ndev->addr_len);
-
- ks8695_update_mac(ksp);
-
- dev_dbg(ksp->dev, "%s: Updated MAC address to %pM\n",
- ndev->name, ndev->dev_addr);
-
- return 0;
-}
-
-/**
- * ks8695_set_multicast - Set up the multicast behaviour of the interface
- * @ndev: The net_device to configure
- *
- * This routine, called by the net layer, configures promiscuity
- * and multicast reception behaviour for the interface.
- */
-static void
-ks8695_set_multicast(struct net_device *ndev)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
- u32 ctrl;
-
- ctrl = ks8695_readreg(ksp, KS8695_DRXC);
-
- if (ndev->flags & IFF_PROMISC) {
- /* enable promiscuous mode */
- ctrl |= DRXC_RA;
- } else if (ndev->flags & ~IFF_PROMISC) {
- /* disable promiscuous mode */
- ctrl &= ~DRXC_RA;
- }
-
- if (ndev->flags & IFF_ALLMULTI) {
- /* enable all multicast mode */
- ctrl |= DRXC_RM;
- } else if (netdev_mc_count(ndev) > KS8695_NR_ADDRESSES) {
- /* more specific multicast addresses than can be
- * handled in hardware
- */
- ctrl |= DRXC_RM;
- } else {
- /* enable specific multicasts */
- ctrl &= ~DRXC_RM;
- ks8695_init_partial_multicast(ksp, ndev);
- }
-
- ks8695_writereg(ksp, KS8695_DRXC, ctrl);
-}
-
-/**
- * ks8695_timeout - Handle a network tx/rx timeout.
- * @ndev: The net_device which timed out.
- *
- * A network transaction timed out, reset the device.
- */
-static void
-ks8695_timeout(struct net_device *ndev)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
-
- netif_stop_queue(ndev);
- ks8695_shutdown(ksp);
-
- ks8695_reset(ksp);
-
- ks8695_update_mac(ksp);
-
- /* We ignore the return from this since it managed to init
- * before it probably will be okay to init again.
- */
- ks8695_init_net(ksp);
-
- /* Reconfigure promiscuity etc */
- ks8695_set_multicast(ndev);
-
- /* And start the TX queue once more */
- netif_start_queue(ndev);
-}
-
-/**
- * ks8695_start_xmit - Start a packet transmission
- * @skb: The packet to transmit
- * @ndev: The network device to send the packet on
- *
- * This routine, called by the net layer, takes ownership of the
- * sk_buff and adds it to the TX ring. It then kicks the TX DMA
- * engine to ensure transmission begins.
- */
-static netdev_tx_t
-ks8695_start_xmit(struct sk_buff *skb, struct net_device *ndev)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
- int buff_n;
- dma_addr_t dmap;
-
- spin_lock_irq(&ksp->txq_lock);
-
- if (ksp->tx_ring_used == MAX_TX_DESC) {
- /* Somehow we got entered when we have no room */
- spin_unlock_irq(&ksp->txq_lock);
- return NETDEV_TX_BUSY;
- }
-
- buff_n = ksp->tx_ring_next_slot;
-
- BUG_ON(ksp->tx_buffers[buff_n].skb);
-
- dmap = dma_map_single(ksp->dev, skb->data, skb->len, DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(ksp->dev, dmap))) {
- /* Failed to DMA map this SKB, give it back for now */
- spin_unlock_irq(&ksp->txq_lock);
- dev_dbg(ksp->dev, "%s: Could not map DMA memory for "\
- "transmission, trying later\n", ndev->name);
- return NETDEV_TX_BUSY;
- }
-
- ksp->tx_buffers[buff_n].dma_ptr = dmap;
- /* Mapped okay, store the buffer pointer and length for later */
- ksp->tx_buffers[buff_n].skb = skb;
- ksp->tx_buffers[buff_n].length = skb->len;
-
- /* Fill out the TX descriptor */
- ksp->tx_ring[buff_n].data_ptr =
- cpu_to_le32(ksp->tx_buffers[buff_n].dma_ptr);
- ksp->tx_ring[buff_n].status =
- cpu_to_le32(TDES_IC | TDES_FS | TDES_LS |
- (skb->len & TDES_TBS));
-
- wmb();
-
- /* Hand it over to the hardware */
- ksp->tx_ring[buff_n].owner = cpu_to_le32(TDES_OWN);
-
- if (++ksp->tx_ring_used == MAX_TX_DESC)
- netif_stop_queue(ndev);
-
- /* Kick the TX DMA in case it decided to go IDLE */
- ks8695_writereg(ksp, KS8695_DTSC, 0);
-
- /* And update the next ring slot */
- ksp->tx_ring_next_slot = (buff_n + 1) & MAX_TX_DESC_MASK;
-
- spin_unlock_irq(&ksp->txq_lock);
- return NETDEV_TX_OK;
-}
-
-/**
- * ks8695_stop - Stop (shutdown) a KS8695 ethernet interface
- * @ndev: The net_device to stop
- *
- * This disables the TX queue and cleans up a KS8695 ethernet
- * device.
- */
-static int
-ks8695_stop(struct net_device *ndev)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
-
- netif_stop_queue(ndev);
- napi_disable(&ksp->napi);
-
- ks8695_shutdown(ksp);
-
- return 0;
-}
-
-/**
- * ks8695_open - Open (bring up) a KS8695 ethernet interface
- * @ndev: The net_device to open
- *
- * This resets, configures the MAC, initialises the RX ring and
- * DMA engines and starts the TX queue for a KS8695 ethernet
- * device.
- */
-static int
-ks8695_open(struct net_device *ndev)
-{
- struct ks8695_priv *ksp = netdev_priv(ndev);
- int ret;
-
- ks8695_reset(ksp);
-
- ks8695_update_mac(ksp);
-
- ret = ks8695_init_net(ksp);
- if (ret) {
- ks8695_shutdown(ksp);
- return ret;
- }
-
- napi_enable(&ksp->napi);
- netif_start_queue(ndev);
-
- return 0;
-}
-
-/* Platform device driver */
-
-/**
- * ks8695_init_switch - Init LAN switch to known good defaults.
- * @ksp: The device to initialise
- *
- * This initialises the LAN switch in the KS8695 to a known-good
- * set of defaults.
- */
-static void
-ks8695_init_switch(struct ks8695_priv *ksp)
-{
- u32 ctrl;
-
- /* Default value for SEC0 according to datasheet */
- ctrl = 0x40819e00;
-
- /* LED0 = Speed LED1 = Link/Activity */
- ctrl &= ~(SEC0_LLED1S | SEC0_LLED0S);
- ctrl |= (LLED0S_LINK | LLED1S_LINK_ACTIVITY);
-
- /* Enable Switch */
- ctrl |= SEC0_ENABLE;
-
- writel(ctrl, ksp->phyiface_regs + KS8695_SEC0);
-
- /* Defaults for SEC1 */
- writel(0x9400100, ksp->phyiface_regs + KS8695_SEC1);
-}
-
-/**
- * ks8695_init_wan_phy - Initialise the WAN PHY to sensible defaults
- * @ksp: The device to initialise
- *
- * This initialises a KS8695's WAN phy to sensible values for
- * autonegotiation etc.
- */
-static void
-ks8695_init_wan_phy(struct ks8695_priv *ksp)
-{
- u32 ctrl;
-
- /* Support auto-negotiation */
- ctrl = (WMC_WANAP | WMC_WANA100F | WMC_WANA100H |
- WMC_WANA10F | WMC_WANA10H);
-
- /* LED0 = Activity , LED1 = Link */
- ctrl |= (WLED0S_ACTIVITY | WLED1S_LINK);
-
- /* Restart Auto-negotiation */
- ctrl |= WMC_WANR;
-
- writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
-
- writel(0, ksp->phyiface_regs + KS8695_WPPM);
- writel(0, ksp->phyiface_regs + KS8695_PPS);
-}
-
-static const struct net_device_ops ks8695_netdev_ops = {
- .ndo_open = ks8695_open,
- .ndo_stop = ks8695_stop,
- .ndo_start_xmit = ks8695_start_xmit,
- .ndo_tx_timeout = ks8695_timeout,
- .ndo_set_mac_address = ks8695_set_mac,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_rx_mode = ks8695_set_multicast,
-};
-
-/**
- * ks8695_probe - Probe and initialise a KS8695 ethernet interface
- * @pdev: The platform device to probe
- *
- * Initialise a KS8695 ethernet device from platform data.
- *
- * This driver requires at least one IORESOURCE_MEM for the
- * registers and two IORESOURCE_IRQ for the RX and TX IRQs
- * respectively. It can optionally take an additional
- * IORESOURCE_MEM for the switch or phy in the case of the lan or
- * wan ports, and an IORESOURCE_IRQ for the link IRQ for the wan
- * port.
- */
-static int
-ks8695_probe(struct platform_device *pdev)
-{
- struct ks8695_priv *ksp;
- struct net_device *ndev;
- struct resource *regs_res, *phyiface_res;
- struct resource *rxirq_res, *txirq_res, *linkirq_res;
- int ret = 0;
- int buff_n;
- bool inv_mac_addr = false;
- u32 machigh, maclow;
-
- /* Initialise a net_device */
- ndev = alloc_etherdev(sizeof(struct ks8695_priv));
- if (!ndev)
- return -ENOMEM;
-
- SET_NETDEV_DEV(ndev, &pdev->dev);
-
- dev_dbg(&pdev->dev, "ks8695_probe() called\n");
-
- /* Configure our private structure a little */
- ksp = netdev_priv(ndev);
-
- ksp->dev = &pdev->dev;
- ksp->ndev = ndev;
- ksp->msg_enable = NETIF_MSG_LINK;
-
- /* Retrieve resources */
- regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- phyiface_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-
- rxirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- txirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
- linkirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
-
- if (!(regs_res && rxirq_res && txirq_res)) {
- dev_err(ksp->dev, "insufficient resources\n");
- ret = -ENOENT;
- goto failure;
- }
-
- ksp->regs_req = request_mem_region(regs_res->start,
- resource_size(regs_res),
- pdev->name);
-
- if (!ksp->regs_req) {
- dev_err(ksp->dev, "cannot claim register space\n");
- ret = -EIO;
- goto failure;
- }
-
- ksp->io_regs = ioremap(regs_res->start, resource_size(regs_res));
-
- if (!ksp->io_regs) {
- dev_err(ksp->dev, "failed to ioremap registers\n");
- ret = -EINVAL;
- goto failure;
- }
-
- if (phyiface_res) {
- ksp->phyiface_req =
- request_mem_region(phyiface_res->start,
- resource_size(phyiface_res),
- phyiface_res->name);
-
- if (!ksp->phyiface_req) {
- dev_err(ksp->dev,
- "cannot claim switch register space\n");
- ret = -EIO;
- goto failure;
- }
-
- ksp->phyiface_regs = ioremap(phyiface_res->start,
- resource_size(phyiface_res));
-
- if (!ksp->phyiface_regs) {
- dev_err(ksp->dev,
- "failed to ioremap switch registers\n");
- ret = -EINVAL;
- goto failure;
- }
- }
-
- ksp->rx_irq = rxirq_res->start;
- ksp->rx_irq_name = rxirq_res->name ? rxirq_res->name : "Ethernet RX";
- ksp->tx_irq = txirq_res->start;
- ksp->tx_irq_name = txirq_res->name ? txirq_res->name : "Ethernet TX";
- ksp->link_irq = (linkirq_res ? linkirq_res->start : -1);
- ksp->link_irq_name = (linkirq_res && linkirq_res->name) ?
- linkirq_res->name : "Ethernet Link";
-
- /* driver system setup */
- ndev->netdev_ops = &ks8695_netdev_ops;
- ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
-
- netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT);
-
- /* Retrieve the default MAC addr from the chip. */
- /* The bootloader should have left it in there for us. */
-
- machigh = ks8695_readreg(ksp, KS8695_MAH);
- maclow = ks8695_readreg(ksp, KS8695_MAL);
-
- ndev->dev_addr[0] = (machigh >> 8) & 0xFF;
- ndev->dev_addr[1] = machigh & 0xFF;
- ndev->dev_addr[2] = (maclow >> 24) & 0xFF;
- ndev->dev_addr[3] = (maclow >> 16) & 0xFF;
- ndev->dev_addr[4] = (maclow >> 8) & 0xFF;
- ndev->dev_addr[5] = maclow & 0xFF;
-
- if (!is_valid_ether_addr(ndev->dev_addr))
- inv_mac_addr = true;
-
- /* In order to be efficient memory-wise, we allocate both
- * rings in one go.
- */
- ksp->ring_base = dma_alloc_coherent(&pdev->dev, RING_DMA_SIZE,
- &ksp->ring_base_dma, GFP_KERNEL);
- if (!ksp->ring_base) {
- ret = -ENOMEM;
- goto failure;
- }
-
- /* Specify the TX DMA ring buffer */
- ksp->tx_ring = ksp->ring_base;
- ksp->tx_ring_dma = ksp->ring_base_dma;
-
- /* And initialise the queue's lock */
- spin_lock_init(&ksp->txq_lock);
- spin_lock_init(&ksp->rx_lock);
-
- /* Specify the RX DMA ring buffer */
- ksp->rx_ring = ksp->ring_base + TX_RING_DMA_SIZE;
- ksp->rx_ring_dma = ksp->ring_base_dma + TX_RING_DMA_SIZE;
-
- /* Zero the descriptor rings */
- memset(ksp->tx_ring, 0, TX_RING_DMA_SIZE);
- memset(ksp->rx_ring, 0, RX_RING_DMA_SIZE);
-
- /* Build the rings */
- for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
- ksp->tx_ring[buff_n].next_desc =
- cpu_to_le32(ksp->tx_ring_dma +
- (sizeof(struct tx_ring_desc) *
- ((buff_n + 1) & MAX_TX_DESC_MASK)));
- }
-
- for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
- ksp->rx_ring[buff_n].next_desc =
- cpu_to_le32(ksp->rx_ring_dma +
- (sizeof(struct rx_ring_desc) *
- ((buff_n + 1) & MAX_RX_DESC_MASK)));
- }
-
- /* Initialise the port (physically) */
- if (ksp->phyiface_regs && ksp->link_irq == -1) {
- ks8695_init_switch(ksp);
- ksp->dtype = KS8695_DTYPE_LAN;
- ndev->ethtool_ops = &ks8695_ethtool_ops;
- } else if (ksp->phyiface_regs && ksp->link_irq != -1) {
- ks8695_init_wan_phy(ksp);
- ksp->dtype = KS8695_DTYPE_WAN;
- ndev->ethtool_ops = &ks8695_wan_ethtool_ops;
- } else {
- /* No initialisation since HPNA does not have a PHY */
- ksp->dtype = KS8695_DTYPE_HPNA;
- ndev->ethtool_ops = &ks8695_ethtool_ops;
- }
-
- /* And bring up the net_device with the net core */
- platform_set_drvdata(pdev, ndev);
- ret = register_netdev(ndev);
-
- if (ret == 0) {
- if (inv_mac_addr)
- dev_warn(ksp->dev, "%s: Invalid ethernet MAC address. Please set using ip\n",
- ndev->name);
- dev_info(ksp->dev, "ks8695 ethernet (%s) MAC: %pM\n",
- ks8695_port_type(ksp), ndev->dev_addr);
- } else {
- /* Report the failure to register the net_device */
- dev_err(ksp->dev, "ks8695net: failed to register netdev.\n");
- goto failure;
- }
-
- /* All is well */
- return 0;
-
- /* Error exit path */
-failure:
- ks8695_release_device(ksp);
- free_netdev(ndev);
-
- return ret;
-}
-
-/**
- * ks8695_drv_suspend - Suspend a KS8695 ethernet platform device.
- * @pdev: The device to suspend
- * @state: The suspend state
- *
- * This routine detaches and shuts down a KS8695 ethernet device.
- */
-static int
-ks8695_drv_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct net_device *ndev = platform_get_drvdata(pdev);
- struct ks8695_priv *ksp = netdev_priv(ndev);
-
- ksp->in_suspend = 1;
-
- if (netif_running(ndev)) {
- netif_device_detach(ndev);
- ks8695_shutdown(ksp);
- }
-
- return 0;
-}
-
-/**
- * ks8695_drv_resume - Resume a KS8695 ethernet platform device.
- * @pdev: The device to resume
- *
- * This routine re-initialises and re-attaches a KS8695 ethernet
- * device.
- */
-static int
-ks8695_drv_resume(struct platform_device *pdev)
-{
- struct net_device *ndev = platform_get_drvdata(pdev);
- struct ks8695_priv *ksp = netdev_priv(ndev);
-
- if (netif_running(ndev)) {
- ks8695_reset(ksp);
- ks8695_init_net(ksp);
- ks8695_set_multicast(ndev);
- netif_device_attach(ndev);
- }
-
- ksp->in_suspend = 0;
-
- return 0;
-}
-
-/**
- * ks8695_drv_remove - Remove a KS8695 net device on driver unload.
- * @pdev: The platform device to remove
- *
- * This unregisters and releases a KS8695 ethernet device.
- */
-static int
-ks8695_drv_remove(struct platform_device *pdev)
-{
- struct net_device *ndev = platform_get_drvdata(pdev);
- struct ks8695_priv *ksp = netdev_priv(ndev);
-
- netif_napi_del(&ksp->napi);
-
- unregister_netdev(ndev);
- ks8695_release_device(ksp);
- free_netdev(ndev);
-
- dev_dbg(&pdev->dev, "released and freed device\n");
- return 0;
-}
-
-static struct platform_driver ks8695_driver = {
- .driver = {
- .name = MODULENAME,
- },
- .probe = ks8695_probe,
- .remove = ks8695_drv_remove,
- .suspend = ks8695_drv_suspend,
- .resume = ks8695_drv_resume,
-};
-
-module_platform_driver(ks8695_driver);
-
-MODULE_AUTHOR("Simtec Electronics");
-MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" MODULENAME);
-
-module_param(watchdog, int, 0400);
-MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
diff --git a/drivers/net/ethernet/micrel/ks8695net.h b/drivers/net/ethernet/micrel/ks8695net.h
deleted file mode 100644
index b18fad4ad5fd..000000000000
--- a/drivers/net/ethernet/micrel/ks8695net.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Micrel KS8695 (Centaur) Ethernet.
- *
- * Copyright 2008 Simtec Electronics
- * Daniel Silverstone <dsilvers@simtec.co.uk>
- * Vincent Sanders <vince@simtec.co.uk>
- */
-
-#ifndef KS8695NET_H
-#define KS8695NET_H
-
-/* Receive descriptor flags */
-#define RDES_OWN (1 << 31) /* Ownership */
-#define RDES_FS (1 << 30) /* First Descriptor */
-#define RDES_LS (1 << 29) /* Last Descriptor */
-#define RDES_IPE (1 << 28) /* IP Checksum error */
-#define RDES_TCPE (1 << 27) /* TCP Checksum error */
-#define RDES_UDPE (1 << 26) /* UDP Checksum error */
-#define RDES_ES (1 << 25) /* Error summary */
-#define RDES_MF (1 << 24) /* Multicast Frame */
-#define RDES_RE (1 << 19) /* MII Error reported */
-#define RDES_TL (1 << 18) /* Frame too Long */
-#define RDES_RF (1 << 17) /* Runt Frame */
-#define RDES_CE (1 << 16) /* CRC error */
-#define RDES_FT (1 << 15) /* Frame Type */
-#define RDES_FLEN (0x7ff) /* Frame Length */
-
-#define RDES_RER (1 << 25) /* Receive End of Ring */
-#define RDES_RBS (0x7ff) /* Receive Buffer Size */
-
-/* Transmit descriptor flags */
-
-#define TDES_OWN (1 << 31) /* Ownership */
-
-#define TDES_IC (1 << 31) /* Interrupt on Completion */
-#define TDES_FS (1 << 30) /* First Segment */
-#define TDES_LS (1 << 29) /* Last Segment */
-#define TDES_IPCKG (1 << 28) /* IP Checksum generate */
-#define TDES_TCPCKG (1 << 27) /* TCP Checksum generate */
-#define TDES_UDPCKG (1 << 26) /* UDP Checksum generate */
-#define TDES_TER (1 << 25) /* Transmit End of Ring */
-#define TDES_TBS (0x7ff) /* Transmit Buffer Size */
-
-/*
- * Network controller register offsets
- */
-#define KS8695_DTXC (0x00) /* DMA Transmit Control */
-#define KS8695_DRXC (0x04) /* DMA Receive Control */
-#define KS8695_DTSC (0x08) /* DMA Transmit Start Command */
-#define KS8695_DRSC (0x0c) /* DMA Receive Start Command */
-#define KS8695_TDLB (0x10) /* Transmit Descriptor List
- * Base Address
- */
-#define KS8695_RDLB (0x14) /* Receive Descriptor List
- * Base Address
- */
-#define KS8695_MAL (0x18) /* MAC Station Address Low */
-#define KS8695_MAH (0x1c) /* MAC Station Address High */
-#define KS8695_AAL_(n) (0x80 + ((n)*8)) /* MAC Additional
- * Station Address
- * (0..15) Low
- */
-#define KS8695_AAH_(n) (0x84 + ((n)*8)) /* MAC Additional
- * Station Address
- * (0..15) High
- */
-
-
-/* DMA Transmit Control Register */
-#define DTXC_TRST (1 << 31) /* Soft Reset */
-#define DTXC_TBS (0x3f << 24) /* Transmit Burst Size */
-#define DTXC_TUCG (1 << 18) /* Transmit UDP
- * Checksum Generate
- */
-#define DTXC_TTCG (1 << 17) /* Transmit TCP
- * Checksum Generate
- */
-#define DTXC_TICG (1 << 16) /* Transmit IP
- * Checksum Generate
- */
-#define DTXC_TFCE (1 << 9) /* Transmit Flow
- * Control Enable
- */
-#define DTXC_TLB (1 << 8) /* Loopback mode */
-#define DTXC_TEP (1 << 2) /* Transmit Enable Padding */
-#define DTXC_TAC (1 << 1) /* Transmit Add CRC */
-#define DTXC_TE (1 << 0) /* TX Enable */
-
-/* DMA Receive Control Register */
-#define DRXC_RBS (0x3f << 24) /* Receive Burst Size */
-#define DRXC_RUCC (1 << 18) /* Receive UDP Checksum check */
-#define DRXC_RTCG (1 << 17) /* Receive TCP Checksum check */
-#define DRXC_RICG (1 << 16) /* Receive IP Checksum check */
-#define DRXC_RFCE (1 << 9) /* Receive Flow Control
- * Enable
- */
-#define DRXC_RB (1 << 6) /* Receive Broadcast */
-#define DRXC_RM (1 << 5) /* Receive Multicast */
-#define DRXC_RU (1 << 4) /* Receive Unicast */
-#define DRXC_RERR (1 << 3) /* Receive Error Frame */
-#define DRXC_RA (1 << 2) /* Receive All */
-#define DRXC_RE (1 << 0) /* RX Enable */
-
-/* Additional Station Address High */
-#define AAH_E (1 << 31) /* Address Enabled */
-
-#endif /* KS8695NET_H */
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
index 39aca1ab4687..86fc6e6b46dd 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -317,7 +317,7 @@ static void is2_action_set(struct vcap_data *data,
break;
case OCELOT_ACL_ACTION_TRAP:
VCAP_ACT_SET(PORT_MASK, 0x0);
- VCAP_ACT_SET(MASK_MODE, 0x0);
+ VCAP_ACT_SET(MASK_MODE, 0x1);
VCAP_ACT_SET(POLICE_ENA, 0x0);
VCAP_ACT_SET(POLICE_IDX, 0x0);
VCAP_ACT_SET(CPU_QU_NUM, 0x0);
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
index 59487d446a09..b894bc0c9c16 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -13,12 +13,6 @@ struct ocelot_port_block {
struct ocelot_port *port;
};
-static u16 get_prio(u32 prio)
-{
- /* prio starts from 0x1000 while the ids starts from 0 */
- return prio >> 16;
-}
-
static int ocelot_flower_parse_action(struct flow_cls_offload *f,
struct ocelot_ace_rule *rule)
{
@@ -168,7 +162,7 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
}
finished_key_parsing:
- ocelot_rule->prio = get_prio(f->common.prio);
+ ocelot_rule->prio = f->common.prio;
ocelot_rule->id = f->cookie;
return ocelot_flower_parse_action(f, ocelot_rule);
}
@@ -218,7 +212,7 @@ static int ocelot_flower_destroy(struct flow_cls_offload *f,
struct ocelot_ace_rule rule;
int ret;
- rule.prio = get_prio(f->common.prio);
+ rule.prio = f->common.prio;
rule.port = port_block->port;
rule.id = f->cookie;
@@ -236,7 +230,7 @@ static int ocelot_flower_stats_update(struct flow_cls_offload *f,
struct ocelot_ace_rule rule;
int ret;
- rule.prio = get_prio(f->common.prio);
+ rule.prio = f->common.prio;
rule.port = port_block->port;
rule.id = f->cookie;
ret = ocelot_ace_rule_stats_update(&rule);
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index d8b7fba96d58..337b0cbfd153 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -3919,7 +3919,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* setup (if available). */
status = myri10ge_request_irq(mgp);
if (status != 0)
- goto abort_with_firmware;
+ goto abort_with_slices;
myri10ge_free_irq(mgp);
/* Save configuration space to be restored if the
diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c
index d0a01e8f000a..b339125b2f09 100644
--- a/drivers/net/ethernet/natsemi/sonic.c
+++ b/drivers/net/ethernet/natsemi/sonic.c
@@ -232,9 +232,9 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
laddr = dma_map_single(lp->device, skb->data, length, DMA_TO_DEVICE);
if (!laddr) {
- printk(KERN_ERR "%s: failed to map tx DMA buffer.\n", dev->name);
- dev_kfree_skb(skb);
- return NETDEV_TX_BUSY;
+ pr_err_ratelimited("%s: failed to map tx DMA buffer.\n", dev->name);
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
}
sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0); /* clear status */
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
index 4054b70d7719..5afcb3c4c2ef 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
@@ -1163,7 +1163,7 @@ mem_op_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
bool clr_gpr, lmem_step step)
{
s32 off = nfp_prog->stack_frame_depth + meta->insn.off + ptr_off;
- bool first = true, last;
+ bool first = true, narrow_ld, last;
bool needs_inc = false;
swreg stack_off_reg;
u8 prev_gpr = 255;
@@ -1209,13 +1209,22 @@ mem_op_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
needs_inc = true;
}
+
+ narrow_ld = clr_gpr && size < 8;
+
if (lm3) {
+ unsigned int nop_cnt;
+
emit_csr_wr(nfp_prog, imm_b(nfp_prog), NFP_CSR_ACT_LM_ADDR3);
- /* For size < 4 one slot will be filled by zeroing of upper. */
- wrp_nops(nfp_prog, clr_gpr && size < 8 ? 2 : 3);
+ /* For size < 4 one slot will be filled by zeroing of upper,
+ * but be careful, that zeroing could be eliminated by zext
+ * optimization.
+ */
+ nop_cnt = narrow_ld && meta->flags & FLAG_INSN_DO_ZEXT ? 2 : 3;
+ wrp_nops(nfp_prog, nop_cnt);
}
- if (clr_gpr && size < 8)
+ if (narrow_ld)
wrp_zext(nfp_prog, meta, gpr);
while (size) {
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
index d5bbe3d6048b..05981b54eaab 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
@@ -260,9 +260,6 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
type = cmsg_hdr->type;
switch (type) {
- case NFP_FLOWER_CMSG_TYPE_PORT_REIFY:
- nfp_flower_cmsg_portreify_rx(app, skb);
- break;
case NFP_FLOWER_CMSG_TYPE_PORT_MOD:
nfp_flower_cmsg_portmod_rx(app, skb);
break;
@@ -328,8 +325,7 @@ nfp_flower_queue_ctl_msg(struct nfp_app *app, struct sk_buff *skb, int type)
struct nfp_flower_priv *priv = app->priv;
struct sk_buff_head *skb_head;
- if (type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY ||
- type == NFP_FLOWER_CMSG_TYPE_PORT_MOD)
+ if (type == NFP_FLOWER_CMSG_TYPE_PORT_MOD)
skb_head = &priv->cmsg_skbs_high;
else
skb_head = &priv->cmsg_skbs_low;
@@ -368,6 +364,10 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
} else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH) {
/* Acks from the NFP that the route is added - ignore. */
dev_consume_skb_any(skb);
+ } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY) {
+ /* Handle REIFY acks outside wq to prevent RTNL conflict. */
+ nfp_flower_cmsg_portreify_rx(app, skb);
+ dev_consume_skb_any(skb);
} else {
nfp_flower_queue_ctl_msg(app, skb, cmsg_hdr->type);
}
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index e209f150c5f2..457bdc60f3ee 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -1409,13 +1409,21 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
struct nfp_flower_priv *priv = app->priv;
struct flow_block_cb *block_cb;
- if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS &&
- !(f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS &&
- nfp_flower_internal_port_can_offload(app, netdev)))
+ if ((f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS &&
+ !nfp_flower_internal_port_can_offload(app, netdev)) ||
+ (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS &&
+ nfp_flower_internal_port_can_offload(app, netdev)))
return -EOPNOTSUPP;
switch (f->command) {
case FLOW_BLOCK_BIND:
+ cb_priv = nfp_flower_indr_block_cb_priv_lookup(app, netdev);
+ if (cb_priv &&
+ flow_block_cb_is_busy(nfp_flower_setup_indr_block_cb,
+ cb_priv,
+ &nfp_block_cb_list))
+ return -EBUSY;
+
cb_priv = kmalloc(sizeof(*cb_priv), GFP_KERNEL);
if (!cb_priv)
return -ENOMEM;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c
index 86e968cd5ffd..124a43dc136a 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c
@@ -93,7 +93,7 @@ nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev,
return -EOPNOTSUPP;
}
- if (flow->common.prio != (1 << 16)) {
+ if (flow->common.prio != 1) {
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: qos rate limit offload requires highest priority");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
index a7a80f4b722a..f0ee982eb1b5 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
@@ -328,13 +328,13 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
flow.daddr = *(__be32 *)n->primary_key;
- /* Only concerned with route changes for representors. */
- if (!nfp_netdev_is_nfp_repr(n->dev))
- return NOTIFY_DONE;
-
app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb);
app = app_priv->app;
+ if (!nfp_netdev_is_nfp_repr(n->dev) &&
+ !nfp_flower_internal_port_can_offload(app, n->dev))
+ return NOTIFY_DONE;
+
/* Only concerned with changes to routes already added to NFP. */
if (!nfp_tun_has_route(app, flow.daddr))
return NOTIFY_DONE;
diff --git a/drivers/net/ethernet/nuvoton/Kconfig b/drivers/net/ethernet/nuvoton/Kconfig
deleted file mode 100644
index 325e26c549f8..000000000000
--- a/drivers/net/ethernet/nuvoton/Kconfig
+++ /dev/null
@@ -1,29 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Nuvoton network device configuration
-#
-
-config NET_VENDOR_NUVOTON
- bool "Nuvoton devices"
- default y
- depends on ARM && ARCH_W90X900
- ---help---
- If you have a network (Ethernet) card belonging to this class, say Y.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about Nuvoton cards. If you say Y, you will be asked
- for your specific card in the following questions.
-
-if NET_VENDOR_NUVOTON
-
-config W90P910_ETH
- tristate "Nuvoton w90p910 Ethernet support"
- depends on ARM && ARCH_W90X900
- select PHYLIB
- select MII
- ---help---
- Say Y here if you want to use built-in Ethernet ports
- on w90p910 processor.
-
-endif # NET_VENDOR_NUVOTON
diff --git a/drivers/net/ethernet/nuvoton/Makefile b/drivers/net/ethernet/nuvoton/Makefile
deleted file mode 100644
index 66f6e728d54b..000000000000
--- a/drivers/net/ethernet/nuvoton/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the Nuvoton network device drivers.
-#
-
-obj-$(CONFIG_W90P910_ETH) += w90p910_ether.o
diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c
deleted file mode 100644
index 3d73970b3a2e..000000000000
--- a/drivers/net/ethernet/nuvoton/w90p910_ether.c
+++ /dev/null
@@ -1,1082 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2008-2009 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/mii.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ethtool.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/gfp.h>
-
-#define DRV_MODULE_NAME "w90p910-emc"
-#define DRV_MODULE_VERSION "0.1"
-
-/* Ethernet MAC Registers */
-#define REG_CAMCMR 0x00
-#define REG_CAMEN 0x04
-#define REG_CAMM_BASE 0x08
-#define REG_CAML_BASE 0x0c
-#define REG_TXDLSA 0x88
-#define REG_RXDLSA 0x8C
-#define REG_MCMDR 0x90
-#define REG_MIID 0x94
-#define REG_MIIDA 0x98
-#define REG_FFTCR 0x9C
-#define REG_TSDR 0xa0
-#define REG_RSDR 0xa4
-#define REG_DMARFC 0xa8
-#define REG_MIEN 0xac
-#define REG_MISTA 0xb0
-#define REG_CTXDSA 0xcc
-#define REG_CTXBSA 0xd0
-#define REG_CRXDSA 0xd4
-#define REG_CRXBSA 0xd8
-
-/* mac controller bit */
-#define MCMDR_RXON 0x01
-#define MCMDR_ACP (0x01 << 3)
-#define MCMDR_SPCRC (0x01 << 5)
-#define MCMDR_TXON (0x01 << 8)
-#define MCMDR_FDUP (0x01 << 18)
-#define MCMDR_ENMDC (0x01 << 19)
-#define MCMDR_OPMOD (0x01 << 20)
-#define SWR (0x01 << 24)
-
-/* cam command regiser */
-#define CAMCMR_AUP 0x01
-#define CAMCMR_AMP (0x01 << 1)
-#define CAMCMR_ABP (0x01 << 2)
-#define CAMCMR_CCAM (0x01 << 3)
-#define CAMCMR_ECMP (0x01 << 4)
-#define CAM0EN 0x01
-
-/* mac mii controller bit */
-#define MDCCR (0x0a << 20)
-#define PHYAD (0x01 << 8)
-#define PHYWR (0x01 << 16)
-#define PHYBUSY (0x01 << 17)
-#define PHYPRESP (0x01 << 18)
-#define CAM_ENTRY_SIZE 0x08
-
-/* rx and tx status */
-#define TXDS_TXCP (0x01 << 19)
-#define RXDS_CRCE (0x01 << 17)
-#define RXDS_PTLE (0x01 << 19)
-#define RXDS_RXGD (0x01 << 20)
-#define RXDS_ALIE (0x01 << 21)
-#define RXDS_RP (0x01 << 22)
-
-/* mac interrupt status*/
-#define MISTA_EXDEF (0x01 << 19)
-#define MISTA_TXBERR (0x01 << 24)
-#define MISTA_TDU (0x01 << 23)
-#define MISTA_RDU (0x01 << 10)
-#define MISTA_RXBERR (0x01 << 11)
-
-#define ENSTART 0x01
-#define ENRXINTR 0x01
-#define ENRXGD (0x01 << 4)
-#define ENRXBERR (0x01 << 11)
-#define ENTXINTR (0x01 << 16)
-#define ENTXCP (0x01 << 18)
-#define ENTXABT (0x01 << 21)
-#define ENTXBERR (0x01 << 24)
-#define ENMDC (0x01 << 19)
-#define PHYBUSY (0x01 << 17)
-#define MDCCR_VAL 0xa00000
-
-/* rx and tx owner bit */
-#define RX_OWEN_DMA (0x01 << 31)
-#define RX_OWEN_CPU (~(0x03 << 30))
-#define TX_OWEN_DMA (0x01 << 31)
-#define TX_OWEN_CPU (~(0x01 << 31))
-
-/* tx frame desc controller bit */
-#define MACTXINTEN 0x04
-#define CRCMODE 0x02
-#define PADDINGMODE 0x01
-
-/* fftcr controller bit */
-#define TXTHD (0x03 << 8)
-#define BLENGTH (0x01 << 20)
-
-/* global setting for driver */
-#define RX_DESC_SIZE 50
-#define TX_DESC_SIZE 10
-#define MAX_RBUFF_SZ 0x600
-#define MAX_TBUFF_SZ 0x600
-#define TX_TIMEOUT (HZ/2)
-#define DELAY 1000
-#define CAM0 0x0
-
-static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg);
-
-struct w90p910_rxbd {
- unsigned int sl;
- unsigned int buffer;
- unsigned int reserved;
- unsigned int next;
-};
-
-struct w90p910_txbd {
- unsigned int mode;
- unsigned int buffer;
- unsigned int sl;
- unsigned int next;
-};
-
-struct recv_pdesc {
- struct w90p910_rxbd desclist[RX_DESC_SIZE];
- char recv_buf[RX_DESC_SIZE][MAX_RBUFF_SZ];
-};
-
-struct tran_pdesc {
- struct w90p910_txbd desclist[TX_DESC_SIZE];
- char tran_buf[TX_DESC_SIZE][MAX_TBUFF_SZ];
-};
-
-struct w90p910_ether {
- struct recv_pdesc *rdesc;
- struct tran_pdesc *tdesc;
- dma_addr_t rdesc_phys;
- dma_addr_t tdesc_phys;
- struct platform_device *pdev;
- struct resource *res;
- struct sk_buff *skb;
- struct clk *clk;
- struct clk *rmiiclk;
- struct mii_if_info mii;
- struct timer_list check_timer;
- void __iomem *reg;
- int rxirq;
- int txirq;
- unsigned int cur_tx;
- unsigned int cur_rx;
- unsigned int finish_tx;
- unsigned int rx_packets;
- unsigned int rx_bytes;
- unsigned int start_tx_ptr;
- unsigned int start_rx_ptr;
- unsigned int linkflag;
-};
-
-static void update_linkspeed_register(struct net_device *dev,
- unsigned int speed, unsigned int duplex)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- unsigned int val;
-
- val = __raw_readl(ether->reg + REG_MCMDR);
-
- if (speed == SPEED_100) {
- /* 100 full/half duplex */
- if (duplex == DUPLEX_FULL) {
- val |= (MCMDR_OPMOD | MCMDR_FDUP);
- } else {
- val |= MCMDR_OPMOD;
- val &= ~MCMDR_FDUP;
- }
- } else {
- /* 10 full/half duplex */
- if (duplex == DUPLEX_FULL) {
- val |= MCMDR_FDUP;
- val &= ~MCMDR_OPMOD;
- } else {
- val &= ~(MCMDR_FDUP | MCMDR_OPMOD);
- }
- }
-
- __raw_writel(val, ether->reg + REG_MCMDR);
-}
-
-static void update_linkspeed(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- struct platform_device *pdev;
- unsigned int bmsr, bmcr, lpa, speed, duplex;
-
- pdev = ether->pdev;
-
- if (!mii_link_ok(&ether->mii)) {
- ether->linkflag = 0x0;
- netif_carrier_off(dev);
- dev_warn(&pdev->dev, "%s: Link down.\n", dev->name);
- return;
- }
-
- if (ether->linkflag == 1)
- return;
-
- bmsr = w90p910_mdio_read(dev, ether->mii.phy_id, MII_BMSR);
- bmcr = w90p910_mdio_read(dev, ether->mii.phy_id, MII_BMCR);
-
- if (bmcr & BMCR_ANENABLE) {
- if (!(bmsr & BMSR_ANEGCOMPLETE))
- return;
-
- lpa = w90p910_mdio_read(dev, ether->mii.phy_id, MII_LPA);
-
- if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF))
- speed = SPEED_100;
- else
- speed = SPEED_10;
-
- if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL))
- duplex = DUPLEX_FULL;
- else
- duplex = DUPLEX_HALF;
-
- } else {
- speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
- duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
- }
-
- update_linkspeed_register(dev, speed, duplex);
-
- dev_info(&pdev->dev, "%s: Link now %i-%s\n", dev->name, speed,
- (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
- ether->linkflag = 0x01;
-
- netif_carrier_on(dev);
-}
-
-static void w90p910_check_link(struct timer_list *t)
-{
- struct w90p910_ether *ether = from_timer(ether, t, check_timer);
- struct net_device *dev = ether->mii.dev;
-
- update_linkspeed(dev);
- mod_timer(&ether->check_timer, jiffies + msecs_to_jiffies(1000));
-}
-
-static void w90p910_write_cam(struct net_device *dev,
- unsigned int x, unsigned char *pval)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- unsigned int msw, lsw;
-
- msw = (pval[0] << 24) | (pval[1] << 16) | (pval[2] << 8) | pval[3];
-
- lsw = (pval[4] << 24) | (pval[5] << 16);
-
- __raw_writel(lsw, ether->reg + REG_CAML_BASE + x * CAM_ENTRY_SIZE);
- __raw_writel(msw, ether->reg + REG_CAMM_BASE + x * CAM_ENTRY_SIZE);
-}
-
-static int w90p910_init_desc(struct net_device *dev)
-{
- struct w90p910_ether *ether;
- struct w90p910_txbd *tdesc;
- struct w90p910_rxbd *rdesc;
- struct platform_device *pdev;
- unsigned int i;
-
- ether = netdev_priv(dev);
- pdev = ether->pdev;
-
- ether->tdesc = dma_alloc_coherent(&pdev->dev, sizeof(struct tran_pdesc),
- &ether->tdesc_phys, GFP_KERNEL);
- if (!ether->tdesc)
- return -ENOMEM;
-
- ether->rdesc = dma_alloc_coherent(&pdev->dev, sizeof(struct recv_pdesc),
- &ether->rdesc_phys, GFP_KERNEL);
- if (!ether->rdesc) {
- dma_free_coherent(&pdev->dev, sizeof(struct tran_pdesc),
- ether->tdesc, ether->tdesc_phys);
- return -ENOMEM;
- }
-
- for (i = 0; i < TX_DESC_SIZE; i++) {
- unsigned int offset;
-
- tdesc = &(ether->tdesc->desclist[i]);
-
- if (i == TX_DESC_SIZE - 1)
- offset = offsetof(struct tran_pdesc, desclist[0]);
- else
- offset = offsetof(struct tran_pdesc, desclist[i + 1]);
-
- tdesc->next = ether->tdesc_phys + offset;
- tdesc->buffer = ether->tdesc_phys +
- offsetof(struct tran_pdesc, tran_buf[i]);
- tdesc->sl = 0;
- tdesc->mode = 0;
- }
-
- ether->start_tx_ptr = ether->tdesc_phys;
-
- for (i = 0; i < RX_DESC_SIZE; i++) {
- unsigned int offset;
-
- rdesc = &(ether->rdesc->desclist[i]);
-
- if (i == RX_DESC_SIZE - 1)
- offset = offsetof(struct recv_pdesc, desclist[0]);
- else
- offset = offsetof(struct recv_pdesc, desclist[i + 1]);
-
- rdesc->next = ether->rdesc_phys + offset;
- rdesc->sl = RX_OWEN_DMA;
- rdesc->buffer = ether->rdesc_phys +
- offsetof(struct recv_pdesc, recv_buf[i]);
- }
-
- ether->start_rx_ptr = ether->rdesc_phys;
-
- return 0;
-}
-
-static void w90p910_set_fifo_threshold(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- unsigned int val;
-
- val = TXTHD | BLENGTH;
- __raw_writel(val, ether->reg + REG_FFTCR);
-}
-
-static void w90p910_return_default_idle(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- unsigned int val;
-
- val = __raw_readl(ether->reg + REG_MCMDR);
- val |= SWR;
- __raw_writel(val, ether->reg + REG_MCMDR);
-}
-
-static void w90p910_trigger_rx(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
-
- __raw_writel(ENSTART, ether->reg + REG_RSDR);
-}
-
-static void w90p910_trigger_tx(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
-
- __raw_writel(ENSTART, ether->reg + REG_TSDR);
-}
-
-static void w90p910_enable_mac_interrupt(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- unsigned int val;
-
- val = ENTXINTR | ENRXINTR | ENRXGD | ENTXCP;
- val |= ENTXBERR | ENRXBERR | ENTXABT;
-
- __raw_writel(val, ether->reg + REG_MIEN);
-}
-
-static void w90p910_get_and_clear_int(struct net_device *dev,
- unsigned int *val)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
-
- *val = __raw_readl(ether->reg + REG_MISTA);
- __raw_writel(*val, ether->reg + REG_MISTA);
-}
-
-static void w90p910_set_global_maccmd(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- unsigned int val;
-
- val = __raw_readl(ether->reg + REG_MCMDR);
- val |= MCMDR_SPCRC | MCMDR_ENMDC | MCMDR_ACP | ENMDC;
- __raw_writel(val, ether->reg + REG_MCMDR);
-}
-
-static void w90p910_enable_cam(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- unsigned int val;
-
- w90p910_write_cam(dev, CAM0, dev->dev_addr);
-
- val = __raw_readl(ether->reg + REG_CAMEN);
- val |= CAM0EN;
- __raw_writel(val, ether->reg + REG_CAMEN);
-}
-
-static void w90p910_enable_cam_command(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- unsigned int val;
-
- val = CAMCMR_ECMP | CAMCMR_ABP | CAMCMR_AMP;
- __raw_writel(val, ether->reg + REG_CAMCMR);
-}
-
-static void w90p910_enable_tx(struct net_device *dev, unsigned int enable)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- unsigned int val;
-
- val = __raw_readl(ether->reg + REG_MCMDR);
-
- if (enable)
- val |= MCMDR_TXON;
- else
- val &= ~MCMDR_TXON;
-
- __raw_writel(val, ether->reg + REG_MCMDR);
-}
-
-static void w90p910_enable_rx(struct net_device *dev, unsigned int enable)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- unsigned int val;
-
- val = __raw_readl(ether->reg + REG_MCMDR);
-
- if (enable)
- val |= MCMDR_RXON;
- else
- val &= ~MCMDR_RXON;
-
- __raw_writel(val, ether->reg + REG_MCMDR);
-}
-
-static void w90p910_set_curdest(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
-
- __raw_writel(ether->start_rx_ptr, ether->reg + REG_RXDLSA);
- __raw_writel(ether->start_tx_ptr, ether->reg + REG_TXDLSA);
-}
-
-static void w90p910_reset_mac(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
-
- w90p910_enable_tx(dev, 0);
- w90p910_enable_rx(dev, 0);
- w90p910_set_fifo_threshold(dev);
- w90p910_return_default_idle(dev);
-
- if (!netif_queue_stopped(dev))
- netif_stop_queue(dev);
-
- w90p910_init_desc(dev);
-
- netif_trans_update(dev); /* prevent tx timeout */
- ether->cur_tx = 0x0;
- ether->finish_tx = 0x0;
- ether->cur_rx = 0x0;
-
- w90p910_set_curdest(dev);
- w90p910_enable_cam(dev);
- w90p910_enable_cam_command(dev);
- w90p910_enable_mac_interrupt(dev);
- w90p910_enable_tx(dev, 1);
- w90p910_enable_rx(dev, 1);
- w90p910_trigger_tx(dev);
- w90p910_trigger_rx(dev);
-
- netif_trans_update(dev); /* prevent tx timeout */
-
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
-}
-
-static void w90p910_mdio_write(struct net_device *dev,
- int phy_id, int reg, int data)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- struct platform_device *pdev;
- unsigned int val, i;
-
- pdev = ether->pdev;
-
- __raw_writel(data, ether->reg + REG_MIID);
-
- val = (phy_id << 0x08) | reg;
- val |= PHYBUSY | PHYWR | MDCCR_VAL;
- __raw_writel(val, ether->reg + REG_MIIDA);
-
- for (i = 0; i < DELAY; i++) {
- if ((__raw_readl(ether->reg + REG_MIIDA) & PHYBUSY) == 0)
- break;
- }
-
- if (i == DELAY)
- dev_warn(&pdev->dev, "mdio write timed out\n");
-}
-
-static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- struct platform_device *pdev;
- unsigned int val, i, data;
-
- pdev = ether->pdev;
-
- val = (phy_id << 0x08) | reg;
- val |= PHYBUSY | MDCCR_VAL;
- __raw_writel(val, ether->reg + REG_MIIDA);
-
- for (i = 0; i < DELAY; i++) {
- if ((__raw_readl(ether->reg + REG_MIIDA) & PHYBUSY) == 0)
- break;
- }
-
- if (i == DELAY) {
- dev_warn(&pdev->dev, "mdio read timed out\n");
- data = 0xffff;
- } else {
- data = __raw_readl(ether->reg + REG_MIID);
- }
-
- return data;
-}
-
-static int w90p910_set_mac_address(struct net_device *dev, void *addr)
-{
- struct sockaddr *address = addr;
-
- if (!is_valid_ether_addr(address->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
- w90p910_write_cam(dev, CAM0, dev->dev_addr);
-
- return 0;
-}
-
-static int w90p910_ether_close(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- struct platform_device *pdev;
-
- pdev = ether->pdev;
-
- dma_free_coherent(&pdev->dev, sizeof(struct recv_pdesc),
- ether->rdesc, ether->rdesc_phys);
- dma_free_coherent(&pdev->dev, sizeof(struct tran_pdesc),
- ether->tdesc, ether->tdesc_phys);
-
- netif_stop_queue(dev);
-
- del_timer_sync(&ether->check_timer);
- clk_disable(ether->rmiiclk);
- clk_disable(ether->clk);
-
- free_irq(ether->txirq, dev);
- free_irq(ether->rxirq, dev);
-
- return 0;
-}
-
-static int w90p910_send_frame(struct net_device *dev,
- unsigned char *data, int length)
-{
- struct w90p910_ether *ether;
- struct w90p910_txbd *txbd;
- struct platform_device *pdev;
- unsigned char *buffer;
-
- ether = netdev_priv(dev);
- pdev = ether->pdev;
-
- txbd = &ether->tdesc->desclist[ether->cur_tx];
- buffer = ether->tdesc->tran_buf[ether->cur_tx];
-
- if (length > 1514) {
- dev_err(&pdev->dev, "send data %d bytes, check it\n", length);
- length = 1514;
- }
-
- txbd->sl = length & 0xFFFF;
-
- memcpy(buffer, data, length);
-
- txbd->mode = TX_OWEN_DMA | PADDINGMODE | CRCMODE | MACTXINTEN;
-
- w90p910_enable_tx(dev, 1);
-
- w90p910_trigger_tx(dev);
-
- if (++ether->cur_tx >= TX_DESC_SIZE)
- ether->cur_tx = 0;
-
- txbd = &ether->tdesc->desclist[ether->cur_tx];
-
- if (txbd->mode & TX_OWEN_DMA)
- netif_stop_queue(dev);
-
- return 0;
-}
-
-static int w90p910_ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
-
- if (!(w90p910_send_frame(dev, skb->data, skb->len))) {
- ether->skb = skb;
- dev_consume_skb_irq(skb);
- return 0;
- }
- return -EAGAIN;
-}
-
-static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)
-{
- struct w90p910_ether *ether;
- struct w90p910_txbd *txbd;
- struct platform_device *pdev;
- struct net_device *dev;
- unsigned int cur_entry, entry, status;
-
- dev = dev_id;
- ether = netdev_priv(dev);
- pdev = ether->pdev;
-
- w90p910_get_and_clear_int(dev, &status);
-
- cur_entry = __raw_readl(ether->reg + REG_CTXDSA);
-
- entry = ether->tdesc_phys +
- offsetof(struct tran_pdesc, desclist[ether->finish_tx]);
-
- while (entry != cur_entry) {
- txbd = &ether->tdesc->desclist[ether->finish_tx];
-
- if (++ether->finish_tx >= TX_DESC_SIZE)
- ether->finish_tx = 0;
-
- if (txbd->sl & TXDS_TXCP) {
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += txbd->sl & 0xFFFF;
- } else {
- dev->stats.tx_errors++;
- }
-
- txbd->sl = 0x0;
- txbd->mode = 0x0;
-
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
-
- entry = ether->tdesc_phys +
- offsetof(struct tran_pdesc, desclist[ether->finish_tx]);
- }
-
- if (status & MISTA_EXDEF) {
- dev_err(&pdev->dev, "emc defer exceed interrupt\n");
- } else if (status & MISTA_TXBERR) {
- dev_err(&pdev->dev, "emc bus error interrupt\n");
- w90p910_reset_mac(dev);
- } else if (status & MISTA_TDU) {
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
- }
-
- return IRQ_HANDLED;
-}
-
-static void netdev_rx(struct net_device *dev)
-{
- struct w90p910_ether *ether;
- struct w90p910_rxbd *rxbd;
- struct platform_device *pdev;
- struct sk_buff *skb;
- unsigned char *data;
- unsigned int length, status, val, entry;
-
- ether = netdev_priv(dev);
- pdev = ether->pdev;
-
- rxbd = &ether->rdesc->desclist[ether->cur_rx];
-
- do {
- val = __raw_readl(ether->reg + REG_CRXDSA);
-
- entry = ether->rdesc_phys +
- offsetof(struct recv_pdesc, desclist[ether->cur_rx]);
-
- if (val == entry)
- break;
-
- status = rxbd->sl;
- length = status & 0xFFFF;
-
- if (status & RXDS_RXGD) {
- data = ether->rdesc->recv_buf[ether->cur_rx];
- skb = netdev_alloc_skb(dev, length + 2);
- if (!skb) {
- dev->stats.rx_dropped++;
- return;
- }
-
- skb_reserve(skb, 2);
- skb_put(skb, length);
- skb_copy_to_linear_data(skb, data, length);
- skb->protocol = eth_type_trans(skb, dev);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += length;
- netif_rx(skb);
- } else {
- dev->stats.rx_errors++;
-
- if (status & RXDS_RP) {
- dev_err(&pdev->dev, "rx runt err\n");
- dev->stats.rx_length_errors++;
- } else if (status & RXDS_CRCE) {
- dev_err(&pdev->dev, "rx crc err\n");
- dev->stats.rx_crc_errors++;
- } else if (status & RXDS_ALIE) {
- dev_err(&pdev->dev, "rx alignment err\n");
- dev->stats.rx_frame_errors++;
- } else if (status & RXDS_PTLE) {
- dev_err(&pdev->dev, "rx longer err\n");
- dev->stats.rx_over_errors++;
- }
- }
-
- rxbd->sl = RX_OWEN_DMA;
- rxbd->reserved = 0x0;
-
- if (++ether->cur_rx >= RX_DESC_SIZE)
- ether->cur_rx = 0;
-
- rxbd = &ether->rdesc->desclist[ether->cur_rx];
-
- } while (1);
-}
-
-static irqreturn_t w90p910_rx_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev;
- struct w90p910_ether *ether;
- struct platform_device *pdev;
- unsigned int status;
-
- dev = dev_id;
- ether = netdev_priv(dev);
- pdev = ether->pdev;
-
- w90p910_get_and_clear_int(dev, &status);
-
- if (status & MISTA_RDU) {
- netdev_rx(dev);
- w90p910_trigger_rx(dev);
-
- return IRQ_HANDLED;
- } else if (status & MISTA_RXBERR) {
- dev_err(&pdev->dev, "emc rx bus error\n");
- w90p910_reset_mac(dev);
- }
-
- netdev_rx(dev);
- return IRQ_HANDLED;
-}
-
-static int w90p910_ether_open(struct net_device *dev)
-{
- struct w90p910_ether *ether;
- struct platform_device *pdev;
-
- ether = netdev_priv(dev);
- pdev = ether->pdev;
-
- w90p910_reset_mac(dev);
- w90p910_set_fifo_threshold(dev);
- w90p910_set_curdest(dev);
- w90p910_enable_cam(dev);
- w90p910_enable_cam_command(dev);
- w90p910_enable_mac_interrupt(dev);
- w90p910_set_global_maccmd(dev);
- w90p910_enable_rx(dev, 1);
-
- clk_enable(ether->rmiiclk);
- clk_enable(ether->clk);
-
- ether->rx_packets = 0x0;
- ether->rx_bytes = 0x0;
-
- if (request_irq(ether->txirq, w90p910_tx_interrupt,
- 0x0, pdev->name, dev)) {
- dev_err(&pdev->dev, "register irq tx failed\n");
- return -EAGAIN;
- }
-
- if (request_irq(ether->rxirq, w90p910_rx_interrupt,
- 0x0, pdev->name, dev)) {
- dev_err(&pdev->dev, "register irq rx failed\n");
- free_irq(ether->txirq, dev);
- return -EAGAIN;
- }
-
- mod_timer(&ether->check_timer, jiffies + msecs_to_jiffies(1000));
- netif_start_queue(dev);
- w90p910_trigger_rx(dev);
-
- dev_info(&pdev->dev, "%s is OPENED\n", dev->name);
-
- return 0;
-}
-
-static void w90p910_ether_set_multicast_list(struct net_device *dev)
-{
- struct w90p910_ether *ether;
- unsigned int rx_mode;
-
- ether = netdev_priv(dev);
-
- if (dev->flags & IFF_PROMISC)
- rx_mode = CAMCMR_AUP | CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP;
- else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev))
- rx_mode = CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP;
- else
- rx_mode = CAMCMR_ECMP | CAMCMR_ABP;
- __raw_writel(rx_mode, ether->reg + REG_CAMCMR);
-}
-
-static int w90p910_ether_ioctl(struct net_device *dev,
- struct ifreq *ifr, int cmd)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- struct mii_ioctl_data *data = if_mii(ifr);
-
- return generic_mii_ioctl(&ether->mii, data, cmd, NULL);
-}
-
-static void w90p910_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
-}
-
-static int w90p910_get_link_ksettings(struct net_device *dev,
- struct ethtool_link_ksettings *cmd)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
-
- mii_ethtool_get_link_ksettings(&ether->mii, cmd);
-
- return 0;
-}
-
-static int w90p910_set_link_ksettings(struct net_device *dev,
- const struct ethtool_link_ksettings *cmd)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- return mii_ethtool_set_link_ksettings(&ether->mii, cmd);
-}
-
-static int w90p910_nway_reset(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- return mii_nway_restart(&ether->mii);
-}
-
-static u32 w90p910_get_link(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- return mii_link_ok(&ether->mii);
-}
-
-static const struct ethtool_ops w90p910_ether_ethtool_ops = {
- .get_drvinfo = w90p910_get_drvinfo,
- .nway_reset = w90p910_nway_reset,
- .get_link = w90p910_get_link,
- .get_link_ksettings = w90p910_get_link_ksettings,
- .set_link_ksettings = w90p910_set_link_ksettings,
-};
-
-static const struct net_device_ops w90p910_ether_netdev_ops = {
- .ndo_open = w90p910_ether_open,
- .ndo_stop = w90p910_ether_close,
- .ndo_start_xmit = w90p910_ether_start_xmit,
- .ndo_set_rx_mode = w90p910_ether_set_multicast_list,
- .ndo_set_mac_address = w90p910_set_mac_address,
- .ndo_do_ioctl = w90p910_ether_ioctl,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static void get_mac_address(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
- struct platform_device *pdev;
- char addr[ETH_ALEN];
-
- pdev = ether->pdev;
-
- addr[0] = 0x00;
- addr[1] = 0x02;
- addr[2] = 0xac;
- addr[3] = 0x55;
- addr[4] = 0x88;
- addr[5] = 0xa8;
-
- if (is_valid_ether_addr(addr))
- memcpy(dev->dev_addr, &addr, ETH_ALEN);
- else
- dev_err(&pdev->dev, "invalid mac address\n");
-}
-
-static int w90p910_ether_setup(struct net_device *dev)
-{
- struct w90p910_ether *ether = netdev_priv(dev);
-
- dev->netdev_ops = &w90p910_ether_netdev_ops;
- dev->ethtool_ops = &w90p910_ether_ethtool_ops;
-
- dev->tx_queue_len = 16;
- dev->dma = 0x0;
- dev->watchdog_timeo = TX_TIMEOUT;
-
- get_mac_address(dev);
-
- ether->cur_tx = 0x0;
- ether->cur_rx = 0x0;
- ether->finish_tx = 0x0;
- ether->linkflag = 0x0;
- ether->mii.phy_id = 0x01;
- ether->mii.phy_id_mask = 0x1f;
- ether->mii.reg_num_mask = 0x1f;
- ether->mii.dev = dev;
- ether->mii.mdio_read = w90p910_mdio_read;
- ether->mii.mdio_write = w90p910_mdio_write;
-
- timer_setup(&ether->check_timer, w90p910_check_link, 0);
-
- return 0;
-}
-
-static int w90p910_ether_probe(struct platform_device *pdev)
-{
- struct w90p910_ether *ether;
- struct net_device *dev;
- int error;
-
- dev = alloc_etherdev(sizeof(struct w90p910_ether));
- if (!dev)
- return -ENOMEM;
-
- ether = netdev_priv(dev);
-
- ether->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (ether->res == NULL) {
- dev_err(&pdev->dev, "failed to get I/O memory\n");
- error = -ENXIO;
- goto failed_free;
- }
-
- if (!request_mem_region(ether->res->start,
- resource_size(ether->res), pdev->name)) {
- dev_err(&pdev->dev, "failed to request I/O memory\n");
- error = -EBUSY;
- goto failed_free;
- }
-
- ether->reg = ioremap(ether->res->start, resource_size(ether->res));
- if (ether->reg == NULL) {
- dev_err(&pdev->dev, "failed to remap I/O memory\n");
- error = -ENXIO;
- goto failed_free_mem;
- }
-
- ether->txirq = platform_get_irq(pdev, 0);
- if (ether->txirq < 0) {
- dev_err(&pdev->dev, "failed to get ether tx irq\n");
- error = -ENXIO;
- goto failed_free_io;
- }
-
- ether->rxirq = platform_get_irq(pdev, 1);
- if (ether->rxirq < 0) {
- dev_err(&pdev->dev, "failed to get ether rx irq\n");
- error = -ENXIO;
- goto failed_free_io;
- }
-
- platform_set_drvdata(pdev, dev);
-
- ether->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(ether->clk)) {
- dev_err(&pdev->dev, "failed to get ether clock\n");
- error = PTR_ERR(ether->clk);
- goto failed_free_io;
- }
-
- ether->rmiiclk = clk_get(&pdev->dev, "RMII");
- if (IS_ERR(ether->rmiiclk)) {
- dev_err(&pdev->dev, "failed to get ether clock\n");
- error = PTR_ERR(ether->rmiiclk);
- goto failed_put_clk;
- }
-
- ether->pdev = pdev;
-
- w90p910_ether_setup(dev);
-
- error = register_netdev(dev);
- if (error != 0) {
- dev_err(&pdev->dev, "Register EMC w90p910 FAILED\n");
- error = -ENODEV;
- goto failed_put_rmiiclk;
- }
-
- return 0;
-failed_put_rmiiclk:
- clk_put(ether->rmiiclk);
-failed_put_clk:
- clk_put(ether->clk);
-failed_free_io:
- iounmap(ether->reg);
-failed_free_mem:
- release_mem_region(ether->res->start, resource_size(ether->res));
-failed_free:
- free_netdev(dev);
- return error;
-}
-
-static int w90p910_ether_remove(struct platform_device *pdev)
-{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct w90p910_ether *ether = netdev_priv(dev);
-
- unregister_netdev(dev);
-
- clk_put(ether->rmiiclk);
- clk_put(ether->clk);
-
- iounmap(ether->reg);
- release_mem_region(ether->res->start, resource_size(ether->res));
-
- del_timer_sync(&ether->check_timer);
-
- free_netdev(dev);
- return 0;
-}
-
-static struct platform_driver w90p910_ether_driver = {
- .probe = w90p910_ether_probe,
- .remove = w90p910_ether_remove,
- .driver = {
- .name = "nuc900-emc",
- },
-};
-
-module_platform_driver(w90p910_ether_driver);
-
-MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
-MODULE_DESCRIPTION("w90p910 MAC driver!");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:nuc900-emc");
-
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index b327b29f5d57..a6b4bfae4684 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -713,6 +713,21 @@ struct nv_skb_map {
struct nv_skb_map *next_tx_ctx;
};
+struct nv_txrx_stats {
+ u64 stat_rx_packets;
+ u64 stat_rx_bytes; /* not always available in HW */
+ u64 stat_rx_missed_errors;
+ u64 stat_rx_dropped;
+ u64 stat_tx_packets; /* not always available in HW */
+ u64 stat_tx_bytes;
+ u64 stat_tx_dropped;
+};
+
+#define nv_txrx_stats_inc(member) \
+ __this_cpu_inc(np->txrx_stats->member)
+#define nv_txrx_stats_add(member, count) \
+ __this_cpu_add(np->txrx_stats->member, (count))
+
/*
* SMP locking:
* All hardware access under netdev_priv(dev)->lock, except the performance
@@ -797,10 +812,7 @@ struct fe_priv {
/* RX software stats */
struct u64_stats_sync swstats_rx_syncp;
- u64 stat_rx_packets;
- u64 stat_rx_bytes; /* not always available in HW */
- u64 stat_rx_missed_errors;
- u64 stat_rx_dropped;
+ struct nv_txrx_stats __percpu *txrx_stats;
/* media detection workaround.
* Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
@@ -826,9 +838,6 @@ struct fe_priv {
/* TX software stats */
struct u64_stats_sync swstats_tx_syncp;
- u64 stat_tx_packets; /* not always available in HW */
- u64 stat_tx_bytes;
- u64 stat_tx_dropped;
/* msi/msi-x fields */
u32 msi_flags;
@@ -1721,6 +1730,39 @@ static void nv_update_stats(struct net_device *dev)
}
}
+static void nv_get_stats(int cpu, struct fe_priv *np,
+ struct rtnl_link_stats64 *storage)
+{
+ struct nv_txrx_stats *src = per_cpu_ptr(np->txrx_stats, cpu);
+ unsigned int syncp_start;
+ u64 rx_packets, rx_bytes, rx_dropped, rx_missed_errors;
+ u64 tx_packets, tx_bytes, tx_dropped;
+
+ do {
+ syncp_start = u64_stats_fetch_begin_irq(&np->swstats_rx_syncp);
+ rx_packets = src->stat_rx_packets;
+ rx_bytes = src->stat_rx_bytes;
+ rx_dropped = src->stat_rx_dropped;
+ rx_missed_errors = src->stat_rx_missed_errors;
+ } while (u64_stats_fetch_retry_irq(&np->swstats_rx_syncp, syncp_start));
+
+ storage->rx_packets += rx_packets;
+ storage->rx_bytes += rx_bytes;
+ storage->rx_dropped += rx_dropped;
+ storage->rx_missed_errors += rx_missed_errors;
+
+ do {
+ syncp_start = u64_stats_fetch_begin_irq(&np->swstats_tx_syncp);
+ tx_packets = src->stat_tx_packets;
+ tx_bytes = src->stat_tx_bytes;
+ tx_dropped = src->stat_tx_dropped;
+ } while (u64_stats_fetch_retry_irq(&np->swstats_tx_syncp, syncp_start));
+
+ storage->tx_packets += tx_packets;
+ storage->tx_bytes += tx_bytes;
+ storage->tx_dropped += tx_dropped;
+}
+
/*
* nv_get_stats64: dev->ndo_get_stats64 function
* Get latest stats value from the nic.
@@ -1733,7 +1775,7 @@ nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage)
__releases(&netdev_priv(dev)->hwstats_lock)
{
struct fe_priv *np = netdev_priv(dev);
- unsigned int syncp_start;
+ int cpu;
/*
* Note: because HW stats are not always available and for
@@ -1746,20 +1788,8 @@ nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage)
*/
/* software stats */
- do {
- syncp_start = u64_stats_fetch_begin_irq(&np->swstats_rx_syncp);
- storage->rx_packets = np->stat_rx_packets;
- storage->rx_bytes = np->stat_rx_bytes;
- storage->rx_dropped = np->stat_rx_dropped;
- storage->rx_missed_errors = np->stat_rx_missed_errors;
- } while (u64_stats_fetch_retry_irq(&np->swstats_rx_syncp, syncp_start));
-
- do {
- syncp_start = u64_stats_fetch_begin_irq(&np->swstats_tx_syncp);
- storage->tx_packets = np->stat_tx_packets;
- storage->tx_bytes = np->stat_tx_bytes;
- storage->tx_dropped = np->stat_tx_dropped;
- } while (u64_stats_fetch_retry_irq(&np->swstats_tx_syncp, syncp_start));
+ for_each_online_cpu(cpu)
+ nv_get_stats(cpu, np, storage);
/* If the nic supports hw counters then retrieve latest values */
if (np->driver_data & DEV_HAS_STATISTICS_V123) {
@@ -1827,7 +1857,7 @@ static int nv_alloc_rx(struct net_device *dev)
} else {
packet_dropped:
u64_stats_update_begin(&np->swstats_rx_syncp);
- np->stat_rx_dropped++;
+ nv_txrx_stats_inc(stat_rx_dropped);
u64_stats_update_end(&np->swstats_rx_syncp);
return 1;
}
@@ -1869,7 +1899,7 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
} else {
packet_dropped:
u64_stats_update_begin(&np->swstats_rx_syncp);
- np->stat_rx_dropped++;
+ nv_txrx_stats_inc(stat_rx_dropped);
u64_stats_update_end(&np->swstats_rx_syncp);
return 1;
}
@@ -2013,7 +2043,7 @@ static void nv_drain_tx(struct net_device *dev)
}
if (nv_release_txskb(np, &np->tx_skb[i])) {
u64_stats_update_begin(&np->swstats_tx_syncp);
- np->stat_tx_dropped++;
+ nv_txrx_stats_inc(stat_tx_dropped);
u64_stats_update_end(&np->swstats_tx_syncp);
}
np->tx_skb[i].dma = 0;
@@ -2227,7 +2257,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* on DMA mapping error - drop the packet */
dev_kfree_skb_any(skb);
u64_stats_update_begin(&np->swstats_tx_syncp);
- np->stat_tx_dropped++;
+ nv_txrx_stats_inc(stat_tx_dropped);
u64_stats_update_end(&np->swstats_tx_syncp);
return NETDEV_TX_OK;
}
@@ -2273,7 +2303,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev_kfree_skb_any(skb);
np->put_tx_ctx = start_tx_ctx;
u64_stats_update_begin(&np->swstats_tx_syncp);
- np->stat_tx_dropped++;
+ nv_txrx_stats_inc(stat_tx_dropped);
u64_stats_update_end(&np->swstats_tx_syncp);
return NETDEV_TX_OK;
}
@@ -2384,7 +2414,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
/* on DMA mapping error - drop the packet */
dev_kfree_skb_any(skb);
u64_stats_update_begin(&np->swstats_tx_syncp);
- np->stat_tx_dropped++;
+ nv_txrx_stats_inc(stat_tx_dropped);
u64_stats_update_end(&np->swstats_tx_syncp);
return NETDEV_TX_OK;
}
@@ -2431,7 +2461,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
dev_kfree_skb_any(skb);
np->put_tx_ctx = start_tx_ctx;
u64_stats_update_begin(&np->swstats_tx_syncp);
- np->stat_tx_dropped++;
+ nv_txrx_stats_inc(stat_tx_dropped);
u64_stats_update_end(&np->swstats_tx_syncp);
return NETDEV_TX_OK;
}
@@ -2560,9 +2590,12 @@ static int nv_tx_done(struct net_device *dev, int limit)
&& !(flags & NV_TX_RETRYCOUNT_MASK))
nv_legacybackoff_reseed(dev);
} else {
+ unsigned int len;
+
u64_stats_update_begin(&np->swstats_tx_syncp);
- np->stat_tx_packets++;
- np->stat_tx_bytes += np->get_tx_ctx->skb->len;
+ nv_txrx_stats_inc(stat_tx_packets);
+ len = np->get_tx_ctx->skb->len;
+ nv_txrx_stats_add(stat_tx_bytes, len);
u64_stats_update_end(&np->swstats_tx_syncp);
}
bytes_compl += np->get_tx_ctx->skb->len;
@@ -2577,9 +2610,12 @@ static int nv_tx_done(struct net_device *dev, int limit)
&& !(flags & NV_TX2_RETRYCOUNT_MASK))
nv_legacybackoff_reseed(dev);
} else {
+ unsigned int len;
+
u64_stats_update_begin(&np->swstats_tx_syncp);
- np->stat_tx_packets++;
- np->stat_tx_bytes += np->get_tx_ctx->skb->len;
+ nv_txrx_stats_inc(stat_tx_packets);
+ len = np->get_tx_ctx->skb->len;
+ nv_txrx_stats_add(stat_tx_bytes, len);
u64_stats_update_end(&np->swstats_tx_syncp);
}
bytes_compl += np->get_tx_ctx->skb->len;
@@ -2627,9 +2663,12 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
nv_legacybackoff_reseed(dev);
}
} else {
+ unsigned int len;
+
u64_stats_update_begin(&np->swstats_tx_syncp);
- np->stat_tx_packets++;
- np->stat_tx_bytes += np->get_tx_ctx->skb->len;
+ nv_txrx_stats_inc(stat_tx_packets);
+ len = np->get_tx_ctx->skb->len;
+ nv_txrx_stats_add(stat_tx_bytes, len);
u64_stats_update_end(&np->swstats_tx_syncp);
}
@@ -2806,6 +2845,15 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen)
}
}
+static void rx_missing_handler(u32 flags, struct fe_priv *np)
+{
+ if (flags & NV_RX_MISSEDFRAME) {
+ u64_stats_update_begin(&np->swstats_rx_syncp);
+ nv_txrx_stats_inc(stat_rx_missed_errors);
+ u64_stats_update_end(&np->swstats_rx_syncp);
+ }
+}
+
static int nv_rx_process(struct net_device *dev, int limit)
{
struct fe_priv *np = netdev_priv(dev);
@@ -2848,11 +2896,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
}
/* the rest are hard errors */
else {
- if (flags & NV_RX_MISSEDFRAME) {
- u64_stats_update_begin(&np->swstats_rx_syncp);
- np->stat_rx_missed_errors++;
- u64_stats_update_end(&np->swstats_rx_syncp);
- }
+ rx_missing_handler(flags, np);
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -2896,8 +2940,8 @@ static int nv_rx_process(struct net_device *dev, int limit)
skb->protocol = eth_type_trans(skb, dev);
napi_gro_receive(&np->napi, skb);
u64_stats_update_begin(&np->swstats_rx_syncp);
- np->stat_rx_packets++;
- np->stat_rx_bytes += len;
+ nv_txrx_stats_inc(stat_rx_packets);
+ nv_txrx_stats_add(stat_rx_bytes, len);
u64_stats_update_end(&np->swstats_rx_syncp);
next_pkt:
if (unlikely(np->get_rx.orig++ == np->last_rx.orig))
@@ -2982,8 +3026,8 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
}
napi_gro_receive(&np->napi, skb);
u64_stats_update_begin(&np->swstats_rx_syncp);
- np->stat_rx_packets++;
- np->stat_rx_bytes += len;
+ nv_txrx_stats_inc(stat_rx_packets);
+ nv_txrx_stats_add(stat_rx_bytes, len);
u64_stats_update_end(&np->swstats_rx_syncp);
} else {
dev_kfree_skb(skb);
@@ -5651,6 +5695,12 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
SET_NETDEV_DEV(dev, &pci_dev->dev);
u64_stats_init(&np->swstats_rx_syncp);
u64_stats_init(&np->swstats_tx_syncp);
+ np->txrx_stats = alloc_percpu(struct nv_txrx_stats);
+ if (!np->txrx_stats) {
+ pr_err("np->txrx_stats, alloc memory error.\n");
+ err = -ENOMEM;
+ goto out_alloc_percpu;
+ }
timer_setup(&np->oom_kick, nv_do_rx_refill, 0);
timer_setup(&np->nic_poll, nv_do_nic_poll, 0);
@@ -6060,6 +6110,8 @@ out_relreg:
out_disable:
pci_disable_device(pci_dev);
out_free:
+ free_percpu(np->txrx_stats);
+out_alloc_percpu:
free_netdev(dev);
out:
return err;
@@ -6105,6 +6157,9 @@ static void nv_restore_mac_addr(struct pci_dev *pci_dev)
static void nv_remove(struct pci_dev *pci_dev)
{
struct net_device *dev = pci_get_drvdata(pci_dev);
+ struct fe_priv *np = netdev_priv(dev);
+
+ free_percpu(np->txrx_stats);
unregister_netdev(dev);
diff --git a/drivers/net/ethernet/nxp/Kconfig b/drivers/net/ethernet/nxp/Kconfig
index 261f107e2be0..418afb84c84b 100644
--- a/drivers/net/ethernet/nxp/Kconfig
+++ b/drivers/net/ethernet/nxp/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config LPC_ENET
tristate "NXP ethernet MAC on LPC devices"
- depends on ARCH_LPC32XX
+ depends on ARCH_LPC32XX || COMPILE_TEST
select PHYLIB
help
Say Y or M here if you want to use the NXP ethernet MAC included on
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
index f7e11f1b0426..141571e2ec11 100644
--- a/drivers/net/ethernet/nxp/lpc_eth.c
+++ b/drivers/net/ethernet/nxp/lpc_eth.c
@@ -14,14 +14,12 @@
#include <linux/crc32.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
-
-#include <mach/board.h>
-#include <mach/hardware.h>
-#include <mach/platform.h>
+#include <linux/soc/nxp/lpc32xx-misc.h>
#define MODNAME "lpc-eth"
#define DRV_VERSION "1.00"
@@ -1237,16 +1235,9 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
dma_addr_t dma_handle;
struct resource *res;
int irq, ret;
- u32 tmp;
/* Setup network interface for RMII or MII mode */
- tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
- tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
- if (lpc_phy_interface_mode(dev) == PHY_INTERFACE_MODE_MII)
- tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS;
- else
- tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
- __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
+ lpc32xx_set_phy_interface_mode(lpc_phy_interface_mode(dev));
/* Get platform resources */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1311,19 +1302,18 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
/* Get size of DMA buffers/descriptors region */
pldat->dma_buff_size = (ENET_TX_DESC + ENET_RX_DESC) * (ENET_MAXF_SIZE +
sizeof(struct txrx_desc_t) + sizeof(struct rx_status_t));
- pldat->dma_buff_base_v = 0;
if (use_iram_for_net(dev)) {
- dma_handle = LPC32XX_IRAM_BASE;
- if (pldat->dma_buff_size <= lpc32xx_return_iram_size())
- pldat->dma_buff_base_v =
- io_p2v(LPC32XX_IRAM_BASE);
- else
+ if (pldat->dma_buff_size >
+ lpc32xx_return_iram(&pldat->dma_buff_base_v, &dma_handle)) {
+ pldat->dma_buff_base_v = NULL;
+ pldat->dma_buff_size = 0;
netdev_err(ndev,
"IRAM not big enough for net buffers, using SDRAM instead.\n");
+ }
}
- if (pldat->dma_buff_base_v == 0) {
+ if (pldat->dma_buff_base_v == NULL) {
ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret)
goto err_out_free_irq;
@@ -1344,13 +1334,14 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
pldat->dma_buff_base_p = dma_handle;
netdev_dbg(ndev, "IO address space :%pR\n", res);
- netdev_dbg(ndev, "IO address size :%d\n", resource_size(res));
+ netdev_dbg(ndev, "IO address size :%zd\n",
+ (size_t)resource_size(res));
netdev_dbg(ndev, "IO address (mapped) :0x%p\n",
pldat->net_base);
netdev_dbg(ndev, "IRQ number :%d\n", ndev->irq);
- netdev_dbg(ndev, "DMA buffer size :%d\n", pldat->dma_buff_size);
- netdev_dbg(ndev, "DMA buffer P address :0x%08x\n",
- pldat->dma_buff_base_p);
+ netdev_dbg(ndev, "DMA buffer size :%zd\n", pldat->dma_buff_size);
+ netdev_dbg(ndev, "DMA buffer P address :%pad\n",
+ &pldat->dma_buff_base_p);
netdev_dbg(ndev, "DMA buffer V address :0x%p\n",
pldat->dma_buff_base_v);
@@ -1397,8 +1388,8 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
if (ret)
goto err_out_unregister_netdev;
- netdev_info(ndev, "LPC mac at 0x%08x irq %d\n",
- res->start, ndev->irq);
+ netdev_info(ndev, "LPC mac at 0x%08lx irq %d\n",
+ (unsigned long)res->start, ndev->irq);
device_init_wakeup(dev, 1);
device_set_wakeup_enable(dev, 0);
@@ -1409,7 +1400,7 @@ err_out_unregister_netdev:
unregister_netdev(ndev);
err_out_dma_unmap:
if (!use_iram_for_net(dev) ||
- pldat->dma_buff_size > lpc32xx_return_iram_size())
+ pldat->dma_buff_size > lpc32xx_return_iram(NULL, NULL))
dma_free_coherent(dev, pldat->dma_buff_size,
pldat->dma_buff_base_v,
pldat->dma_buff_base_p);
@@ -1436,7 +1427,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
unregister_netdev(ndev);
if (!use_iram_for_net(&pldat->pdev->dev) ||
- pldat->dma_buff_size > lpc32xx_return_iram_size())
+ pldat->dma_buff_size > lpc32xx_return_iram(NULL, NULL))
dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size,
pldat->dma_buff_base_v,
pldat->dma_buff_base_p);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 829dd60ab937..1efff7f68ef6 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -1325,7 +1325,7 @@ static int qed_slowpath_start(struct qed_dev *cdev,
&drv_version);
if (rc) {
DP_NOTICE(cdev, "Failed sending drv version command\n");
- return rc;
+ goto err4;
}
}
@@ -1333,6 +1333,8 @@ static int qed_slowpath_start(struct qed_dev *cdev,
return 0;
+err4:
+ qed_ll2_dealloc_if(cdev);
err3:
qed_hw_stop(cdev);
err2:
diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
index e1dd6ea60d67..bae0074ab9aa 100644
--- a/drivers/net/ethernet/realtek/r8169_main.c
+++ b/drivers/net/ethernet/realtek/r8169_main.c
@@ -5921,6 +5921,7 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data,
skb = napi_alloc_skb(&tp->napi, pkt_size);
if (skb)
skb_copy_to_linear_data(skb, data, pkt_size);
+ dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
return skb;
}
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index ef8f08931fe8..6cacd5e893ac 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/* Renesas Ethernet AVB device driver
*
- * Copyright (C) 2014-2015 Renesas Electronics Corporation
+ * Copyright (C) 2014-2019 Renesas Electronics Corporation
* Copyright (C) 2015 Renesas Solutions Corp.
* Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
*
@@ -513,7 +513,10 @@ static void ravb_get_tx_tstamp(struct net_device *ndev)
kfree(ts_skb);
if (tag == tfa_tag) {
skb_tstamp_tx(skb, &shhwtstamps);
+ dev_consume_skb_any(skb);
break;
+ } else {
+ dev_kfree_skb_any(skb);
}
}
ravb_modify(ndev, TCCR, TCCR_TFR, TCCR_TFR);
@@ -1564,7 +1567,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
goto unmap;
}
- ts_skb->skb = skb;
+ ts_skb->skb = skb_get(skb);
ts_skb->tag = priv->ts_skb_tag++;
priv->ts_skb_tag &= 0x3ff;
list_add_tail(&ts_skb->list, &priv->ts_skb_list);
@@ -1693,6 +1696,7 @@ static int ravb_close(struct net_device *ndev)
/* Clear the timestamp list */
list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) {
list_del(&ts_skb->list);
+ kfree_skb(ts_skb->skb);
kfree(ts_skb);
}
diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c
index 7a5e6c5abb57..276c7cae7cee 100644
--- a/drivers/net/ethernet/seeq/sgiseeq.c
+++ b/drivers/net/ethernet/seeq/sgiseeq.c
@@ -794,15 +794,16 @@ static int sgiseeq_probe(struct platform_device *pdev)
printk(KERN_ERR "Sgiseeq: Cannot register net device, "
"aborting.\n");
err = -ENODEV;
- goto err_out_free_page;
+ goto err_out_free_attrs;
}
printk(KERN_INFO "%s: %s %pM\n", dev->name, sgiseeqstr, dev->dev_addr);
return 0;
-err_out_free_page:
- free_page((unsigned long) sp->srings);
+err_out_free_attrs:
+ dma_free_attrs(&pdev->dev, sizeof(*sp->srings), sp->srings,
+ sp->srings_dma, DMA_ATTR_NON_CONSISTENT);
err_out_free_dev:
free_netdev(dev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 4644b2aeeba1..e2e469c37a4d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1194,10 +1194,8 @@ static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
int ret;
struct device *dev = &bsp_priv->pdev->dev;
- if (!ldo) {
- dev_err(dev, "no regulator found\n");
- return -1;
- }
+ if (!ldo)
+ return 0;
if (enable) {
ret = regulator_enable(ldo);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 4083019c547a..f97a4096f8fc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -873,7 +873,12 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
int ret;
u32 reg, val;
- regmap_field_read(gmac->regmap_field, &val);
+ ret = regmap_field_read(gmac->regmap_field, &val);
+ if (ret) {
+ dev_err(priv->device, "Fail to read from regmap field.\n");
+ return ret;
+ }
+
reg = gmac->variant->default_syscon_value;
if (reg != val)
dev_warn(priv->device,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
index 37c0bc699cd9..6c305b6ecad0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -94,7 +94,7 @@ static int tc_fill_entry(struct stmmac_priv *priv,
struct stmmac_tc_entry *entry, *frag = NULL;
struct tc_u32_sel *sel = cls->knode.sel;
u32 off, data, mask, real_off, rem;
- u32 prio = cls->common.prio;
+ u32 prio = cls->common.prio << 16;
int ret;
/* Only 1 match per entry */
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 32a89744972d..a46b8b2e44e1 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -2775,6 +2775,7 @@ static int cpsw_probe(struct platform_device *pdev)
if (!cpsw)
return -ENOMEM;
+ platform_set_drvdata(pdev, cpsw);
cpsw->dev = dev;
mode = devm_gpiod_get_array_optional(dev, "mode", GPIOD_OUT_LOW);
@@ -2879,7 +2880,6 @@ static int cpsw_probe(struct platform_device *pdev)
goto clean_cpts;
}
- platform_set_drvdata(pdev, cpsw);
priv = netdev_priv(ndev);
priv->cpsw = cpsw;
priv->ndev = ndev;
diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c
index 8479a440527b..12466a72cefc 100644
--- a/drivers/net/ethernet/toshiba/tc35815.c
+++ b/drivers/net/ethernet/toshiba/tc35815.c
@@ -1504,7 +1504,7 @@ tc35815_rx(struct net_device *dev, int limit)
pci_unmap_single(lp->pci_dev,
lp->rx_skbs[cur_bd].skb_dma,
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- if (!HAVE_DMA_RXALIGN(lp) && NET_IP_ALIGN)
+ if (!HAVE_DMA_RXALIGN(lp) && NET_IP_ALIGN != 0)
memmove(skb->data, skb->data - NET_IP_ALIGN,
pkt_len);
data = skb_put(skb, pkt_len);
diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c
index 78a7de3fb622..c62f474b6d08 100644
--- a/drivers/net/ethernet/tundra/tsi108_eth.c
+++ b/drivers/net/ethernet/tundra/tsi108_eth.c
@@ -371,9 +371,10 @@ tsi108_stat_carry_one(int carry, int carry_bit, int carry_shift,
static void tsi108_stat_carry(struct net_device *dev)
{
struct tsi108_prv_data *data = netdev_priv(dev);
+ unsigned long flags;
u32 carry1, carry2;
- spin_lock_irq(&data->misclock);
+ spin_lock_irqsave(&data->misclock, flags);
carry1 = TSI_READ(TSI108_STAT_CARRY1);
carry2 = TSI_READ(TSI108_STAT_CARRY2);
@@ -441,7 +442,7 @@ static void tsi108_stat_carry(struct net_device *dev)
TSI108_STAT_TXPAUSEDROP_CARRY,
&data->tx_pause_drop);
- spin_unlock_irq(&data->misclock);
+ spin_unlock_irqrestore(&data->misclock, flags);
}
/* Read a stat counter atomically with respect to carries.