* [PATCH net-next v3 0/4] net/mlx5e: Make little improvement for mlx5e
From: xiangxia.m.yue @ 2019-02-26 12:27 UTC (permalink / raw)
To: saeedm, gerlitz.or, roid; +Cc: netdev, Tonghao Zhang
From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
This serial patches are not bugfixes, and just little improvement for mlx5e.
v2->v3:
Patch 1 and 5 are merged to patch 4 now.
v1->v2
Patch 1: remove the duplicated error messages and stick to extack only
Patch 2: use the 'unknown' instead of empty string
Patch 5: is new patch
Tonghao Zhang (4):
net/mlx5e: Make the log friendly when decapsulation offload not
supported
net/mlx5e: Remove 'parse_attr' argument in parse_tc_fdb_actions()
net/mlx5e: Deletes unnecessary setting of esw_attr->parse_attr
net/mlx5e: Return -EOPNOTSUPP when attempting to offload an
unsupported action
.../net/ethernet/mellanox/mlx5/core/en/tc_tun.c | 8 +++++---
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 24 ++++++++++++++++------
2 files changed, 23 insertions(+), 9 deletions(-)
--
1.8.3.1
^ permalink raw reply
* Re: [PATCH net-next 2/8] devlink: add PF and VF port flavours
From: Jiri Pirko @ 2019-02-27 12:41 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: davem, oss-drivers, netdev
In-Reply-To: <20190227122327.GA10571@nanopsycho>
Wed, Feb 27, 2019 at 01:23:27PM CET, jiri@resnulli.us wrote:
>Tue, Feb 26, 2019 at 07:24:30PM CET, jakub.kicinski@netronome.com wrote:
>>Current port flavours cover simple switches and DSA. Add PF
>>and VF flavours to cover "switchdev" SR-IOV NICs.
>>
>>Example devlink user space output:
>>
>>$ devlink port
>>pci/0000:82:00.0/0: type eth netdev p4p1 flavour physical
>>pci/0000:82:00.0/10000: type eth netdev eth0 flavour pcie_pf pf 0
>>pci/0000:82:00.0/10001: type eth netdev eth1 flavour pcie_vf pf 0 vf 0
>>pci/0000:82:00.0/10002: type eth netdev eth2 flavour pcie_vf pf 0 vf 1
>
>Wait a second, howcome pf and vfs have the same PCI address?
Oh, I think you have these as eswitch port representors. Confusing...
^ permalink raw reply
* Re: [PATCH net-next 1/3] dt-bindings: net: dsa: document additional Microchip KSZ9477 family switches
From: Andrew Lunn @ 2019-02-27 12:41 UTC (permalink / raw)
To: Tristram.Ha; +Cc: Florian Fainelli, Pavel Machek, UNGLinuxDriver, netdev
In-Reply-To: <1551224265-9304-2-git-send-email-Tristram.Ha@microchip.com>
On Tue, Feb 26, 2019 at 03:37:43PM -0800, Tristram.Ha@microchip.com wrote:
> + port@3 {
> + reg = <3>;
> + label = "lan4";
> + };
> + port@4 {
> + reg = <6>;
Hi Tristram
The number after the @ must be the same as the register. So this needs
to be port@6.
Andrew
> + label = "cpu";
> + ethernet = <ð0>;
> + fixed-link {
> + speed = <1000>;
> + full-duplex;
> + };
> + };
> + };
> + };
> };
> --
> 1.9.1
>
^ permalink raw reply
* RE: [PATCH 4/8] qed: remove unnecessary memsets
From: Michal Kalderon @ 2019-02-27 12:39 UTC (permalink / raw)
To: Robert Eshleman
Cc: Tariq Toukan, David S. Miller, Ariel Elior, GR-everest-linux-l2,
netdev@vger.kernel.org, linux-rdma@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <c15478ba2ff607f901c78bd56162509f1f023d52.1551246708.git.bobbyeshleman@gmail.com>
> From: Robert Eshleman <bobbyeshleman@gmail.com>
> Sent: Wednesday, February 27, 2019 8:10 AM
>
> This patch replaces unnecessary memset(,0) calls with simply assigning
> structs to zero.
>
> Signed-off-by: Robert Eshleman <bobbyeshleman@gmail.com>
> ---
> drivers/net/ethernet/qlogic/qed/qed_cxt.c | 4 +-
> drivers/net/ethernet/qlogic/qed/qed_hw.c | 3 +-
> drivers/net/ethernet/qlogic/qed/qed_mcp.c | 70 ++++++++---------------
> 3 files changed, 25 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c
> b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
> index c2ad405b2f50..0452ef2fdf1d 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
> @@ -902,12 +902,10 @@ static int qed_cxt_src_t2_alloc(struct qed_hwfn
> *p_hwfn)
> struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
> u32 conn_num, total_size, ent_per_page, psz, i;
> struct qed_ilt_client_cfg *p_src;
> - struct qed_src_iids src_iids;
> + struct qed_src_iids src_iids = {0};
> struct qed_dma_mem *p_t2;
> int rc;
>
> - memset(&src_iids, 0, sizeof(src_iids));
> -
> /* if the SRC ILT client is inactive - there are no connection
> * requiring the searcer, leave.
> */
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_hw.c
> b/drivers/net/ethernet/qlogic/qed/qed_hw.c
> index 70504dcf4087..b8ca3a31409b 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_hw.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_hw.c
> @@ -831,7 +831,7 @@ int qed_dmae_sanity(struct qed_hwfn *p_hwfn,
> struct qed_ptt *p_ptt, const char *phase) {
> u32 size = PAGE_SIZE / 2, val;
> - struct qed_dmae_params params;
> + struct qed_dmae_params params = {0};
> int rc = 0;
> dma_addr_t p_phys;
> void *p_virt;
> @@ -864,7 +864,6 @@ int qed_dmae_sanity(struct qed_hwfn *p_hwfn,
> (u64)p_phys,
> p_virt, (u64)(p_phys + size), (u8 *)p_virt + size, size);
>
> - memset(¶ms, 0, sizeof(params));
> rc = qed_dmae_host2host(p_hwfn, p_ptt, p_phys, p_phys + size,
> size / 4 /* size_in_dwords */, ¶ms);
> if (rc) {
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
> b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
> index e7f18e34ff0d..e1b72fc819a9 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
> @@ -642,10 +642,9 @@ int qed_mcp_cmd(struct qed_hwfn *p_hwfn,
> u32 *o_mcp_resp,
> u32 *o_mcp_param)
> {
> - struct qed_mcp_mb_params mb_params;
> + struct qed_mcp_mb_params mb_params = {0};
> int rc;
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = cmd;
> mb_params.param = param;
>
> @@ -667,10 +666,9 @@ qed_mcp_nvm_wr_cmd(struct qed_hwfn *p_hwfn,
> u32 *o_mcp_resp,
> u32 *o_mcp_param, u32 i_txn_size, u32 *i_buf) {
> - struct qed_mcp_mb_params mb_params;
> + struct qed_mcp_mb_params mb_params = {0};
> int rc;
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = cmd;
> mb_params.param = param;
> mb_params.p_data_src = i_buf;
> @@ -695,11 +693,10 @@ int qed_mcp_nvm_rd_cmd(struct qed_hwfn
> *p_hwfn,
> u32 *o_mcp_resp,
> u32 *o_mcp_param, u32 *o_txn_size, u32 *o_buf) {
> - struct qed_mcp_mb_params mb_params;
> + struct qed_mcp_mb_params mb_params = {0};
> u8 raw_data[MCP_DRV_NVM_BUF_LEN];
> int rc;
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = cmd;
> mb_params.param = param;
> mb_params.p_data_dst = raw_data;
> @@ -821,13 +818,12 @@ __qed_mcp_load_req(struct qed_hwfn *p_hwfn,
> struct qed_load_req_in_params *p_in_params,
> struct qed_load_req_out_params *p_out_params) {
> - struct qed_mcp_mb_params mb_params;
> - struct load_req_stc load_req;
> + struct qed_mcp_mb_params mb_params = {0};
> + struct load_req_stc load_req = {0};
> struct load_rsp_stc load_rsp;
> u32 hsi_ver;
> int rc;
>
> - memset(&load_req, 0, sizeof(load_req));
> load_req.drv_ver_0 = p_in_params->drv_ver_0;
> load_req.drv_ver_1 = p_in_params->drv_ver_1;
> load_req.fw_ver = p_in_params->fw_ver; @@ -843,7 +839,6 @@
> __qed_mcp_load_req(struct qed_hwfn *p_hwfn,
> DRV_ID_MCP_HSI_VER_CURRENT :
> (p_in_params->hsi_ver << DRV_ID_MCP_HSI_VER_SHIFT);
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = DRV_MSG_CODE_LOAD_REQ;
> mb_params.param = PDA_COMP | hsi_ver | p_hwfn->cdev-
> >drv_type;
> mb_params.p_data_src = &load_req;
> @@ -959,12 +954,11 @@ int qed_mcp_load_req(struct qed_hwfn *p_hwfn,
> struct qed_ptt *p_ptt,
> struct qed_load_req_params *p_params) {
> - struct qed_load_req_out_params out_params;
> - struct qed_load_req_in_params in_params;
> + struct qed_load_req_out_params out_params = {0};
> + struct qed_load_req_in_params in_params = {0};
> u8 mfw_drv_role, mfw_force_cmd;
> int rc;
>
> - memset(&in_params, 0, sizeof(in_params));
> in_params.hsi_ver = QED_LOAD_REQ_HSI_VER_DEFAULT;
> in_params.drv_ver_0 = QED_VERSION;
> in_params.drv_ver_1 = qed_get_config_bitmap(); @@ -981,7 +975,6
> @@ int qed_mcp_load_req(struct qed_hwfn *p_hwfn,
> in_params.force_cmd = mfw_force_cmd;
> in_params.avoid_eng_reset = p_params->avoid_eng_reset;
>
> - memset(&out_params, 0, sizeof(out_params));
> rc = __qed_mcp_load_req(p_hwfn, p_ptt, &in_params,
> &out_params);
> if (rc)
> return rc;
> @@ -1072,7 +1065,7 @@ int qed_mcp_load_req(struct qed_hwfn *p_hwfn,
>
> int qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
> {
> - struct qed_mcp_mb_params mb_params;
> + struct qed_mcp_mb_params mb_params = {0};
> u32 wol_param;
>
> switch (p_hwfn->cdev->wol_config) {
> @@ -1091,7 +1084,6 @@ int qed_mcp_unload_req(struct qed_hwfn
> *p_hwfn, struct qed_ptt *p_ptt)
> wol_param = DRV_MB_PARAM_UNLOAD_WOL_MCP;
> }
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = DRV_MSG_CODE_UNLOAD_REQ;
> mb_params.param = wol_param;
> mb_params.flags = QED_MB_FLAG_CAN_SLEEP |
> QED_MB_FLAG_AVOID_BLOCK; @@ -1101,17 +1093,15 @@ int
> qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
>
> int qed_mcp_unload_done(struct qed_hwfn *p_hwfn, struct qed_ptt
> *p_ptt) {
> - struct qed_mcp_mb_params mb_params;
> - struct mcp_mac wol_mac;
> + struct qed_mcp_mb_params mb_params = {0};
> + struct mcp_mac wol_mac = {0};
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = DRV_MSG_CODE_UNLOAD_DONE;
>
> /* Set the primary MAC if WoL is enabled */
> if (p_hwfn->cdev->wol_config == QED_OV_WOL_ENABLED) {
> u8 *p_mac = p_hwfn->cdev->wol_mac;
>
> - memset(&wol_mac, 0, sizeof(wol_mac));
> wol_mac.mac_upper = p_mac[0] << 8 | p_mac[1];
> wol_mac.mac_lower = p_mac[2] << 24 | p_mac[3] << 16 |
> p_mac[4] << 8 | p_mac[5];
> @@ -1167,7 +1157,7 @@ int qed_mcp_ack_vf_flr(struct qed_hwfn
> *p_hwfn,
> u32 mfw_func_offsize = qed_rd(p_hwfn, p_ptt, addr);
> u32 func_addr = SECTION_ADDR(mfw_func_offsize,
> MCP_PF_ID(p_hwfn));
> - struct qed_mcp_mb_params mb_params;
> + struct qed_mcp_mb_params mb_params = {0};
> int rc;
> int i;
>
> @@ -1176,7 +1166,6 @@ int qed_mcp_ack_vf_flr(struct qed_hwfn
> *p_hwfn,
> "Acking VFs [%08x,...,%08x] - %08x\n",
> i * 32, (i + 1) * 32 - 1, vfs_to_ack[i]);
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = DRV_MSG_CODE_VF_DISABLED_DONE;
> mb_params.p_data_src = vfs_to_ack;
> mb_params.data_src_size = VF_MAX_STATIC / 8; @@ -1455,13
> +1444,12 @@ static void qed_mcp_handle_link_change(struct qed_hwfn
> *p_hwfn, int qed_mcp_set_link(struct qed_hwfn *p_hwfn, struct qed_ptt
> *p_ptt, bool b_up) {
> struct qed_mcp_link_params *params = &p_hwfn->mcp_info-
> >link_input;
> - struct qed_mcp_mb_params mb_params;
> - struct eth_phy_cfg phy_cfg;
> + struct qed_mcp_mb_params mb_params = {0};
> + struct eth_phy_cfg phy_cfg = {0};
> int rc = 0;
> u32 cmd;
>
> /* Set the shmem configuration according to params */
> - memset(&phy_cfg, 0, sizeof(phy_cfg));
> cmd = b_up ? DRV_MSG_CODE_INIT_PHY :
> DRV_MSG_CODE_LINK_RESET;
> if (!params->speed.autoneg)
> phy_cfg.speed = params->speed.forced_speed; @@ -1505,7
> +1493,6 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn, struct
> qed_ptt *p_ptt, bool b_up)
> "Resetting link\n");
> }
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = cmd;
> mb_params.p_data_src = &phy_cfg;
> mb_params.data_src_size = sizeof(phy_cfg); @@ -1534,7 +1521,7
> @@ static void qed_mcp_send_protocol_stats(struct qed_hwfn *p_hwfn, {
> enum qed_mcp_protocol_type stats_type;
> union qed_mcp_protocol_stats stats;
> - struct qed_mcp_mb_params mb_params;
> + struct qed_mcp_mb_params mb_params = {0};
> u32 hsi_param;
>
> switch (type) {
> @@ -1561,7 +1548,6 @@ static void qed_mcp_send_protocol_stats(struct
> qed_hwfn *p_hwfn,
>
> qed_get_protocol_stats(p_hwfn->cdev, stats_type, &stats);
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = DRV_MSG_CODE_GET_STATS;
> mb_params.param = hsi_param;
> mb_params.p_data_src = &stats;
> @@ -2370,20 +2356,18 @@ qed_mcp_send_drv_version(struct qed_hwfn
> *p_hwfn,
> struct qed_ptt *p_ptt,
> struct qed_mcp_drv_version *p_ver)
> {
> - struct qed_mcp_mb_params mb_params;
> - struct drv_version_stc drv_version;
> + struct qed_mcp_mb_params mb_params = {0};
> + struct drv_version_stc drv_version = {0};
> __be32 val;
> u32 i;
> int rc;
>
> - memset(&drv_version, 0, sizeof(drv_version));
> drv_version.version = p_ver->version;
> for (i = 0; i < (MCP_DRV_VER_STR_SIZE - 4) / sizeof(u32); i++) {
> val = cpu_to_be32(*((u32 *)&p_ver->name[i *
> sizeof(u32)]));
> *(__be32 *)&drv_version.name[i * sizeof(u32)] = val;
> }
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = DRV_MSG_CODE_SET_VERSION;
> mb_params.p_data_src = &drv_version;
> mb_params.data_src_size = sizeof(drv_version); @@ -2536,11
> +2520,10 @@ int qed_mcp_ov_update_mtu(struct qed_hwfn *p_hwfn, int
> qed_mcp_ov_update_mac(struct qed_hwfn *p_hwfn,
> struct qed_ptt *p_ptt, u8 *mac)
> {
> - struct qed_mcp_mb_params mb_params;
> + struct qed_mcp_mb_params mb_params = {0};
> u32 mfw_mac[2];
> int rc;
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = DRV_MSG_CODE_SET_VMAC;
> mb_params.param = DRV_MSG_CODE_VMAC_TYPE_MAC <<
> DRV_MSG_CODE_VMAC_TYPE_SHIFT;
> @@ -3197,12 +3180,10 @@ qed_mcp_resc_allocation_msg(struct qed_hwfn
> *p_hwfn,
> struct qed_resc_alloc_in_params *p_in_params,
> struct qed_resc_alloc_out_params
> *p_out_params) {
> - struct qed_mcp_mb_params mb_params;
> - struct resource_info mfw_resc_info;
> + struct qed_mcp_mb_params mb_params = {0};
> + struct resource_info mfw_resc_info = {0};
> int rc;
>
> - memset(&mfw_resc_info, 0, sizeof(mfw_resc_info));
> -
> mfw_resc_info.res_id = qed_mcp_get_mfw_res_id(p_in_params-
> >res_id);
> if (mfw_resc_info.res_id == RESOURCE_NUM_INVALID) {
> DP_ERR(p_hwfn,
> @@ -3224,7 +3205,6 @@ qed_mcp_resc_allocation_msg(struct qed_hwfn
> *p_hwfn,
> return -EINVAL;
> }
>
> - memset(&mb_params, 0, sizeof(mb_params));
> mb_params.cmd = p_in_params->cmd;
> mb_params.param = QED_RESC_ALLOC_VERSION;
> mb_params.p_data_src = &mfw_resc_info; @@ -3277,15 +3257,13
> @@ qed_mcp_set_resc_max_val(struct qed_hwfn *p_hwfn,
> enum qed_resources res_id,
> u32 resc_max_val, u32 *p_mcp_resp)
> {
> - struct qed_resc_alloc_out_params out_params;
> - struct qed_resc_alloc_in_params in_params;
> + struct qed_resc_alloc_out_params out_params = {0};
> + struct qed_resc_alloc_in_params in_params = {0};
> int rc;
>
> - memset(&in_params, 0, sizeof(in_params));
> in_params.cmd = DRV_MSG_SET_RESOURCE_VALUE_MSG;
> in_params.res_id = res_id;
> in_params.resc_max_val = resc_max_val;
> - memset(&out_params, 0, sizeof(out_params));
> rc = qed_mcp_resc_allocation_msg(p_hwfn, p_ptt, &in_params,
> &out_params);
> if (rc)
> @@ -3302,14 +3280,12 @@ qed_mcp_get_resc_info(struct qed_hwfn
> *p_hwfn,
> enum qed_resources res_id,
> u32 *p_mcp_resp, u32 *p_resc_num, u32 *p_resc_start)
> {
> - struct qed_resc_alloc_out_params out_params;
> - struct qed_resc_alloc_in_params in_params;
> + struct qed_resc_alloc_out_params out_params = {0};
> + struct qed_resc_alloc_in_params in_params = {0};
> int rc;
>
> - memset(&in_params, 0, sizeof(in_params));
> in_params.cmd = DRV_MSG_GET_RESOURCE_ALLOC_MSG;
> in_params.res_id = res_id;
> - memset(&out_params, 0, sizeof(out_params));
> rc = qed_mcp_resc_allocation_msg(p_hwfn, p_ptt, &in_params,
> &out_params);
> if (rc)
> --
> 2.20.1
Thanks,
Acked-by: Michal Kalderon <michal.kalderon@marvell.com>
^ permalink raw reply
* Re: [PATCH net-next 4/8] devlink: allow subports on devlink PCI ports
From: Jiri Pirko @ 2019-02-27 12:37 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: davem, oss-drivers, netdev, parav, jgg
In-Reply-To: <20190226182436.23811-5-jakub.kicinski@netronome.com>
Tue, Feb 26, 2019 at 07:24:32PM CET, jakub.kicinski@netronome.com wrote:
>PCI endpoint corresponds to a PCI device, but such device
>can have one more more logical device ports associated with it.
>We need a way to distinguish those. Add a PCI subport in the
>dumps and print the info in phys_port_name appropriately.
>
>This is not equivalent to port splitting, there is no split
>group. It's just a way of representing multiple netdevs on
>a single PCI function.
>
>Note that the quality of being multiport pertains only to
>the PCI function itself. A PF having multiple netdevs does
>not mean that its VFs will also have multiple, or that VFs
>are associated with any particular port of a multiport VF.
>
We've been discussing the problem of subport (we call it "subfunction"
or "SF") for some time internally. Turned out, this is probably harder
task to model. Please prove me wrong.
The nature of VF makes it a logically separate entity. It has a separate
PCI address, it should therefore have a separate devlink instance.
You can pass it through to VM, then the same devlink instance should be
created inside the VM and disappear from the host.
SF (or subport) feels similar to that. Basically it is exactly the same
thing as VF, only does reside under PF PCI function.
That is why I think, for sake of consistency, it should have a separate
devlink entity as well. The problem is correct sysfs modelling and
devlink handle derived from that. Parav is working on a simple soft
bus for this purpose called "subbus". There is a RFC floating around on
Mellanox internal mailing list, looks like it is time to send it
upstream.
Then each PF driver which have SFs would register subbus devices
according to SFs/subports and they would be properly handled by bus
probe, devlink and devlink port and netdev instances created.
Ccing Parav and Jason.
^ permalink raw reply
* Re: [PATCH net-next 7/8] net: switchdev: Replace port attr set SDO with a notification
From: Ido Schimmel @ 2019-02-27 12:32 UTC (permalink / raw)
To: Florian Fainelli
Cc: netdev@vger.kernel.org, David S. Miller, open list,
open list:STAGING SUBSYSTEM, moderated list:ETHERNET BRIDGE,
Jiri Pirko, andrew@lunn.ch, vivien.didelot@gmail.com
In-Reply-To: <2e91b708-a092-3839-4979-2712145a9951@gmail.com>
On Mon, Feb 25, 2019 at 11:47:12AM -0800, Florian Fainelli wrote:
> On 2/25/19 1:49 AM, Ido Schimmel wrote:
> > On Sun, Feb 24, 2019 at 08:47:27AM -0800, Florian Fainelli wrote:
> >> Le 2/23/19 à 2:32 AM, Ido Schimmel a écrit :
> >>> On Fri, Feb 22, 2019 at 03:59:25PM -0800, Florian Fainelli wrote:
> >>>> - if (attr->flags & SWITCHDEV_F_NO_RECURSE)
> >>>> + if (attr & SWITCHDEV_F_DEFER)
> >>>> + rc = call_switchdev_blocking_notifiers(nt, dev,
> >>>> + &attr_info.info, NULL);
> >>>> + else
> >>>> + rc = call_switchdev_notifiers(nt, dev, &attr_info.info, NULL);
> >>>
> >>> I don't believe this is needed. You're calling this function from
> >>> switchdev_port_attr_set_now() which is always called from process
> >>> context. switchdev_port_attr_set() takes care of that. Similar to
> >>> switchdev_port_obj_add().
> >>
> >> Except for net/bridge/br_switchdev.c when we check the bridge port's
> >> flags support with PRE_BRIDGE_FLAGS. In that case we are executing from
> >> the caller (atomic) context and we can't defer otherwise that trumps the
> >> whole idea of being able to do a quick check and return that to the
> >> caller that we cannot support specific flags. How would you recommend
> >> approaching that?
> >
> > In this case you can invoke call_switchdev_notifiers() directly from
> > br_switchdev_set_port_flag(). Eventually switchdev_port_attr_set() will
> > be gone and bridge code will invoke the notifiers directly.
>
> That can be done, but it still requires the target driver (mlxsw,
> ocelot, dsa, etc.) to support attribute notification from blocking and
> non-blocking context. Are you fine with that?
Yes. Sorry for the latency. I was away yesterday. Reviewed your v2 and
only found one problem. Will run some tests now.
Thanks!
^ permalink raw reply
* Re: [PATCH net-next v2 8/8] net: Remove switchdev_ops
From: Ido Schimmel @ 2019-02-27 12:30 UTC (permalink / raw)
To: Florian Fainelli
Cc: netdev@vger.kernel.org, David S. Miller, open list,
open list:STAGING SUBSYSTEM, moderated list:ETHERNET BRIDGE,
Jiri Pirko, andrew@lunn.ch, vivien.didelot@gmail.com
In-Reply-To: <20190227011427.16487-9-f.fainelli@gmail.com>
On Tue, Feb 26, 2019 at 05:14:27PM -0800, Florian Fainelli wrote:
> Now that we have converted all possible callers to using a switchdev
> notifier for attributes we do not have a need for implementing
> switchdev_ops anymore, and this can be removed from all drivers the
> net_device structure.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
^ permalink raw reply
* Re: [PATCH net-next v2 4/8] mlxsw: spectrum_switchdev: Handle SWITCHDEV_PORT_ATTR_SET
From: Ido Schimmel @ 2019-02-27 12:30 UTC (permalink / raw)
To: Florian Fainelli
Cc: netdev@vger.kernel.org, David S. Miller, open list,
open list:STAGING SUBSYSTEM, moderated list:ETHERNET BRIDGE,
Jiri Pirko, andrew@lunn.ch, vivien.didelot@gmail.com
In-Reply-To: <20190227011427.16487-5-f.fainelli@gmail.com>
On Tue, Feb 26, 2019 at 05:14:23PM -0800, Florian Fainelli wrote:
> Following patches will change the way we communicate setting a port's
> attribute and use a notifier to perform those tasks.
>
> Prepare mlxsw to support receiving notifier events targeting
> SWITCHDEV_PORT_ATTR_SET and utilize the switchdev_handle_port_attr_set()
> to handle stacking of devices.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
^ permalink raw reply
* Re: [PATCH net-next v2 1/8] switchdev: Add SWITCHDEV_PORT_ATTR_SET
From: Ido Schimmel @ 2019-02-27 12:30 UTC (permalink / raw)
To: Florian Fainelli
Cc: netdev@vger.kernel.org, David S. Miller, open list,
open list:STAGING SUBSYSTEM, moderated list:ETHERNET BRIDGE,
Jiri Pirko, andrew@lunn.ch, vivien.didelot@gmail.com
In-Reply-To: <20190227011427.16487-2-f.fainelli@gmail.com>
On Tue, Feb 26, 2019 at 05:14:20PM -0800, Florian Fainelli wrote:
> In preparation for allowing switchdev enabled drivers to veto specific
> attribute settings from within the context of the caller, introduce a
> new switchdev notifier type for port attributes.
>
> Suggested-by: Ido Schimmel <idosch@mellanox.com>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
^ permalink raw reply
* Re: [PATCH net-next v2 7/8] net: switchdev: Replace port attr set SDO with a notification
From: Ido Schimmel @ 2019-02-27 12:28 UTC (permalink / raw)
To: Florian Fainelli
Cc: netdev@vger.kernel.org, David S. Miller, open list,
open list:STAGING SUBSYSTEM, moderated list:ETHERNET BRIDGE,
Jiri Pirko, andrew@lunn.ch, vivien.didelot@gmail.com
In-Reply-To: <20190227011427.16487-8-f.fainelli@gmail.com>
On Tue, Feb 26, 2019 at 05:14:26PM -0800, Florian Fainelli wrote:
> diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
> index af57c4a2b78a..b7988d49d708 100644
> --- a/net/bridge/br_switchdev.c
> +++ b/net/bridge/br_switchdev.c
> @@ -67,12 +67,17 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
> .id = SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS,
> .u.brport_flags = mask,
> };
> + struct switchdev_notifier_port_attr_info info = {
> + .attr = &attr,
> + };
> int err;
>
> if (mask & ~BR_PORT_FLAGS_HW_OFFLOAD)
> return 0;
>
> - err = switchdev_port_attr_set(p->dev, &attr);
> + /* We run from atomic context here */
> + err = call_switchdev_notifiers(SWITCHDEV_PORT_ATTR_SET, p->dev,
> + &info.info, NULL);
> if (err == -EOPNOTSUPP)
Florian, this needs to use notifier_to_errno() and check for any error.
With the ops, `-EOPNOTSUPP` was returned for devices that did not
implement `switchdev_ops`. Now they will simply not listen / reply to
the notification.
> return 0;
^ permalink raw reply
* Re: [PATCH net-next 2/8] devlink: add PF and VF port flavours
From: Jiri Pirko @ 2019-02-27 12:23 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: davem, oss-drivers, netdev
In-Reply-To: <20190226182436.23811-3-jakub.kicinski@netronome.com>
Tue, Feb 26, 2019 at 07:24:30PM CET, jakub.kicinski@netronome.com wrote:
>Current port flavours cover simple switches and DSA. Add PF
>and VF flavours to cover "switchdev" SR-IOV NICs.
>
>Example devlink user space output:
>
>$ devlink port
>pci/0000:82:00.0/0: type eth netdev p4p1 flavour physical
>pci/0000:82:00.0/10000: type eth netdev eth0 flavour pcie_pf pf 0
>pci/0000:82:00.0/10001: type eth netdev eth1 flavour pcie_vf pf 0 vf 0
>pci/0000:82:00.0/10002: type eth netdev eth2 flavour pcie_vf pf 0 vf 1
Wait a second, howcome pf and vfs have the same PCI address?
^ permalink raw reply
* Re: [PATCH net] ipvs: get sctphdr by sctphoff in sctp_csum_check
From: Simon Horman @ 2019-02-27 12:21 UTC (permalink / raw)
To: Xin Long
Cc: network dev, netfilter-devel, Marcelo Ricardo Leitner,
Neil Horman, pablo
In-Reply-To: <cd1c829cfd9ee916e57c51f6879947f0f88c1eb1.1551094063.git.lucien.xin@gmail.com>
On Mon, Feb 25, 2019 at 07:27:43PM +0800, Xin Long wrote:
> sctp_csum_check() is called by sctp_s/dnat_handler() where it calls
> skb_make_writable() to ensure sctphdr to be linearized.
>
> So there's no need to get sctphdr by calling skb_header_pointer()
> in sctp_csum_check().
>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Simon Horman <horms@verge.net.au>
Pablo,
please consider applying this to nf-next.
> ---
> net/netfilter/ipvs/ip_vs_proto_sctp.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
> index b0cd7d0..0ecf241 100644
> --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
> +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
> @@ -183,7 +183,7 @@ static int
> sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
> {
> unsigned int sctphoff;
> - struct sctphdr *sh, _sctph;
> + struct sctphdr *sh;
> __le32 cmp, val;
>
> #ifdef CONFIG_IP_VS_IPV6
> @@ -193,10 +193,7 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
> #endif
> sctphoff = ip_hdrlen(skb);
>
> - sh = skb_header_pointer(skb, sctphoff, sizeof(_sctph), &_sctph);
> - if (sh == NULL)
> - return 0;
> -
> + sh = (struct sctphdr *)(skb->data + sctphoff);
> cmp = sh->checksum;
> val = sctp_compute_cksum(skb, sctphoff);
>
> --
> 2.1.0
>
^ permalink raw reply
* Re: [PATCH net-next 2/8] devlink: add PF and VF port flavours
From: Jiri Pirko @ 2019-02-27 12:16 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: davem, oss-drivers, netdev
In-Reply-To: <20190226182436.23811-3-jakub.kicinski@netronome.com>
Tue, Feb 26, 2019 at 07:24:30PM CET, jakub.kicinski@netronome.com wrote:
>Current port flavours cover simple switches and DSA. Add PF
>and VF flavours to cover "switchdev" SR-IOV NICs.
>
>Example devlink user space output:
>
>$ devlink port
>pci/0000:82:00.0/0: type eth netdev p4p1 flavour physical
>pci/0000:82:00.0/10000: type eth netdev eth0 flavour pcie_pf pf 0
>pci/0000:82:00.0/10001: type eth netdev eth1 flavour pcie_vf pf 0 vf 0
>pci/0000:82:00.0/10002: type eth netdev eth2 flavour pcie_vf pf 0 vf 1
I believe that that this output should be in sync with attr names. So
the names should be:
pci_vf
pci_pf
pf_number
vf_number
Like:
pci/0000:82:00.0/10002: type eth netdev eth2 flavour pci_vf pf_number 0 vf_number 1
But that is comment to the userspace part.
>
>$ devlink -jp port
>{
> "port": {
> "pci/0000:82:00.0/0": {
> "type": "eth",
> "netdev": "p4p1",
> "flavour": "physical"
> },
> "pci/0000:82:00.0/10000": {
> "type": "eth",
> "netdev": "eth0",
> "flavour": "pci_pf",
> "pf": 0,
> },
> "pci/0000:82:00.0/10001": {
> "type": "eth",
> "netdev": "eth1",
> "flavour": "pci_vf",
> "pf": 0,
> "vf": 0
> },
> "pci/0000:82:00.0/10002": {
> "type": "eth",
> "netdev": "eth2",
> "flavour": "pci_vf",
> "pf": 0,
> "vf": 1
> }
> }
>}
>
>Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
>---
> include/net/devlink.h | 25 ++++++++++--
> include/uapi/linux/devlink.h | 5 +++
> net/core/devlink.c | 73 +++++++++++++++++++++++++++++++-----
> 3 files changed, 91 insertions(+), 12 deletions(-)
>
>diff --git a/include/net/devlink.h b/include/net/devlink.h
>index 7f5a0bdca228..b5376ef492f1 100644
>--- a/include/net/devlink.h
>+++ b/include/net/devlink.h
>@@ -42,9 +42,19 @@ struct devlink {
> struct devlink_port_attrs {
> bool set;
> enum devlink_port_flavour flavour;
>- u32 port_number; /* same value as "split group" */
>- bool split;
>- u32 split_subport_number;
>+ union { /* port identifiers differ per-flavour */
>+ /* PHYSICAL, CPU, DSA */
>+ struct {
>+ bool split;
>+ u32 split_subport_number;
>+ u32 port_number; /* same value as "split group" */
>+ };
>+ /* PCI_PF, PCI_VF */
>+ struct {
>+ u32 pf_number;
>+ u32 vf_number;
>+ } pci;
>+ };
> };
>
> struct devlink_port {
>@@ -568,6 +578,9 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
> enum devlink_port_flavour flavour,
> u32 port_number, bool split,
> u32 split_subport_number);
>+void devlink_port_attrs_pci_set(struct devlink_port *devlink_port,
>+ enum devlink_port_flavour flavour,
>+ u32 pf_number, u32 vf_number);
> int devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
> char *name, size_t len);
> int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
>@@ -782,6 +795,12 @@ static inline void devlink_port_attrs_set(struct devlink_port *devlink_port,
> {
> }
>
>+static inline void devlink_port_attrs_pci_set(struct devlink_port *devlink_port,
>+ enum devlink_port_flavour flavour,
>+ u32 pf_number, u32 vf_number)
>+{
>+}
>+
> static inline int
> devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
> char *name, size_t len)
>diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
>index 5bb4ea67d84f..9ce76d4f640d 100644
>--- a/include/uapi/linux/devlink.h
>+++ b/include/uapi/linux/devlink.h
>@@ -167,6 +167,8 @@ enum devlink_port_flavour {
> DEVLINK_PORT_FLAVOUR_DSA, /* Distributed switch architecture
> * interconnect port.
> */
>+ DEVLINK_PORT_FLAVOUR_PCI_PF, /* PCI Physical function port */
>+ DEVLINK_PORT_FLAVOUR_PCI_VF, /* PCI Physical function port */
> };
>
> enum devlink_param_cmode {
>@@ -332,6 +334,9 @@ enum devlink_attr {
> DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME, /* string */
> DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, /* string */
>
>+ DEVLINK_ATTR_PORT_PCI_PF_NUMBER, /* u32 */
>+ DEVLINK_ATTR_PORT_PCI_VF_NUMBER, /* u32 */
>+
> /* add new attributes above here, update the policy in devlink.c */
>
> __DEVLINK_ATTR_MAX,
>diff --git a/net/core/devlink.c b/net/core/devlink.c
>index a49dee67e66f..af177284830b 100644
>--- a/net/core/devlink.c
>+++ b/net/core/devlink.c
>@@ -516,16 +516,35 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
> return 0;
> if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
> return -EMSGSIZE;
>- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, attrs->port_number))
>- return -EMSGSIZE;
>- if (!attrs->split)
>+
>+ switch (attrs->flavour) {
>+ case DEVLINK_PORT_FLAVOUR_PHYSICAL:
>+ case DEVLINK_PORT_FLAVOUR_CPU:
>+ case DEVLINK_PORT_FLAVOUR_DSA:
>+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
>+ attrs->port_number))
>+ return -EMSGSIZE;
>+
>+ if (attrs->split &&
>+ (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
>+ attrs->port_number) ||
>+ nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
>+ attrs->split_subport_number)))
>+ return -EMSGSIZE;
> return 0;
>- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, attrs->port_number))
>- return -EMSGSIZE;
>- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
>- attrs->split_subport_number))
>- return -EMSGSIZE;
>- return 0;
>+ case DEVLINK_PORT_FLAVOUR_PCI_VF:
>+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER,
>+ attrs->pci.vf_number))
>+ return -EMSGSIZE;
>+ /* fall through */
>+ case DEVLINK_PORT_FLAVOUR_PCI_PF:
>+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
>+ attrs->pci.pf_number))
>+ return -EMSGSIZE;
>+ return 0;
>+ default:
>+ return -EINVAL;
>+ }
> }
>
> static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
>@@ -5410,6 +5429,9 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
> {
> struct devlink_port_attrs *attrs = &devlink_port->attrs;
>
>+ WARN_ON(flavour == DEVLINK_PORT_FLAVOUR_PCI_PF ||
>+ flavour == DEVLINK_PORT_FLAVOUR_PCI_VF);
>+
> attrs->set = true;
> attrs->flavour = flavour;
> attrs->port_number = port_number;
>@@ -5419,6 +5441,32 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
> }
> EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
>
>+/**
>+ * devlink_port_attrs_pci_set - Set port attributes for a PCI port
>+ *
>+ * @devlink_port: devlink port
>+ * @flavour: flavour of the port (PF or VF only)
>+ * @pf_number: PCI PF number, in multi-host mapping to hosts depends
>+ * on the platform
>+ * @vf_number: PCI VF number within given PF (ignored for PF itself)
>+ */
>+void devlink_port_attrs_pci_set(struct devlink_port *devlink_port,
>+ enum devlink_port_flavour flavour,
>+ u32 pf_number, u32 vf_number)
Maybe nicer would be to have this static and have 2 helpers:
void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
u32 pf_number)
void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,
u32 pf_number, u32 vf_number)
Then you need no warnon. Also you won't have dead arg in driver api
case of pf
Other than this the patch looks good to me.
>+{
>+ struct devlink_port_attrs *attrs = &devlink_port->attrs;
>+
>+ WARN_ON(flavour != DEVLINK_PORT_FLAVOUR_PCI_PF &&
>+ flavour != DEVLINK_PORT_FLAVOUR_PCI_VF);
>+
>+ attrs->set = true;
>+ attrs->flavour = flavour;
>+ attrs->pci.pf_number = pf_number;
>+ attrs->pci.vf_number = vf_number;
>+ devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
>+}
>+EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_set);
>+
> int devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
> char *name, size_t len)
> {
>@@ -5443,6 +5491,13 @@ int devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
> */
> WARN_ON(1);
> return -EINVAL;
>+ case DEVLINK_PORT_FLAVOUR_PCI_PF:
>+ n = snprintf(name, len, "pf%u", attrs->pci.pf_number);
>+ break;
>+ case DEVLINK_PORT_FLAVOUR_PCI_VF:
>+ n = snprintf(name, len, "pf%uvf%u",
>+ attrs->pf_number, attrs->pci.vf_number);
>+ break;
> }
>
> if (n >= len)
>--
>2.19.2
>
^ permalink raw reply
* [PATCH v4] net: phy: Micrel KSZ8061: link failure after cable connect
From: Rajasingh Thavamani @ 2019-02-27 12:13 UTC (permalink / raw)
Cc: t.rajasingh, Rajasingh Thavamani, Alexander Onnasch, Andrew Lunn,
Florian Fainelli, Heiner Kallweit, David S. Miller, netdev,
linux-kernel
With Micrel KSZ8061 PHY, the link may occasionally not come up after
Ethernet cable connect. The vendor's (Microchip, former Micrel) errata
sheet 80000688A.pdf descripes the problem and possible workarounds in
detail, see below.
The batch implements workaround 1, which permanently fixes the issue.
DESCRIPTION
Link-up may not occur properly when the Ethernet cable is initially
connected. This issue occurs more commonly when the cable is connected
slowly, but it may occur any time a cable is connected. This issue occurs
in the auto-negotiation circuit, and will not occur if auto-negotiation
is disabled (which requires that the two link partners be set to the
same speed and duplex).
END USER IMPLICATIONS
When this issue occurs, link is not established. Subsequent cable
plug/unplaug cycle will not correct the issue.
WORk AROUND
There are four approaches to work around this issue:
1. This issue can be prevented by setting bit 15 in MMD device address 1,
register 2, prior to connecting the cable or prior to setting the
Restart Auto-negotiation bit in register 0h. The MMD registers are
accessed via the indirect access registers Dh and Eh, or via the Micrel
EthUtil utility as shown here:
. if using the EthUtil utility (usually with a Micrel KSZ8061
Evaluation Board), type the following commands:
> address 1
> mmd 1
> iw 2 b61a
. Alternatively, write the following registers to write to the
indirect MMD register:
Write register Dh, data 0001h
Write register Eh, data 0002h
Write register Dh, data 4001h
Write register Eh, data B61Ah
2. The issue can be avoided by disabling auto-negotiation in the KSZ8061,
either by the strapping option, or by clearing bit 12 in register 0h.
Care must be taken to ensure that the KSZ8061 and the link partner
will link with the same speed and duplex. Note that the KSZ8061
defaults to full-duplex when auto-negotiation is off, but other
devices may default to half-duplex in the event of failed
auto-negotiation.
3. The issue can be avoided by connecting the cable prior to powering-up
or resetting the KSZ8061, and leaving it plugged in thereafter.
4. If the above measures are not taken and the problem occurs, link can
be recovered by setting the Restart Auto-Negotiation bit in
register 0h, or by resetting or power cycling the device. Reset may
be either hardware reset or software reset (register 0h, bit 15).
PLAN
This errata will not be corrected in the future revision.
Fixes: 7ab59dc15e2f ("drivers/net/phy/micrel_phy: Add support for new PHYs")
Signed-off-by: Alexander Onnasch <alexander.onnasch@landisgyr.com>
Signed-off-by: Rajasingh Thavamani <T.Rajasingh@landisgyr.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/phy/micrel.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index b1f959935f50..b7df0295a3ca 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -344,6 +344,17 @@ static int ksz8041_config_aneg(struct phy_device *phydev)
return genphy_config_aneg(phydev);
}
+static int ksz8061_config_init(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A);
+ if (ret)
+ return ret;
+
+ return kszphy_config_init(phydev);
+}
+
static int ksz9021_load_values_from_of(struct phy_device *phydev,
const struct device_node *of_node,
u16 reg,
@@ -1040,7 +1051,7 @@ static struct phy_driver ksphy_driver[] = {
.name = "Micrel KSZ8061",
.phy_id_mask = MICREL_PHY_ID_MASK,
.features = PHY_BASIC_FEATURES,
- .config_init = kszphy_config_init,
+ .config_init = ksz8061_config_init,
.ack_interrupt = kszphy_ack_interrupt,
.config_intr = kszphy_config_intr,
.suspend = genphy_suspend,
--
2.17.1
^ permalink raw reply related
* [iproute2] tc/pedit: Fix wrong pedit ipv6 structure id
From: Dmytro Linkin @ 2019-02-27 12:10 UTC (permalink / raw)
To: netdev; +Cc: Dmytro Linkin
Tc pedit action with more than two ip6 munge in a row cause infinite
loop.
Example:
$ tc filter add dev eth0 protocol ipv6 parent ffff: \
flower ip_proto sctp \
action pedit ex \
munge ip6 hoplimit set 0x1 \
munge ip6 src set 2001:0db8:0:f101::1 \
munge that cause infinite loop
The example command never returns, instead of failing with parse error
as expected. Pedit ipv6 structure has wrong id, which leads to the
creation linked list with one node in tc/m_pedit.c:get_pedit_kind(),
referring to itself. This node is created if command have two ip6 munge
in a row, and any third ip6 munge will cause infinite loop.
Changing this id from "ipv6" to "ip6" solves the problem.
Fixes: f3e1b2448a95 ("pedit: Introduce ipv6 support")
Signed-off-by: Dmytro Linkin <dmitrolin@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
---
tc/p_ip6.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tc/p_ip6.c b/tc/p_ip6.c
index dbfdca42..7cc7997b 100644
--- a/tc/p_ip6.c
+++ b/tc/p_ip6.c
@@ -84,6 +84,6 @@ done:
}
struct m_pedit_util p_pedit_ip6 = {
- .id = "ipv6",
+ .id = "ip6",
.parse_peopt = parse_ip6,
};
--
2.13.6
^ permalink raw reply related
* [PATCH v2 net-next 6/6] net: aquantia: use better wrappers for state registers
From: Igor Russkikh @ 2019-02-27 12:10 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev@vger.kernel.org, Igor Russkikh, Nikita Danilov
In-Reply-To: <cover.1551269343.git.igor.russkikh@aquantia.com>
From: Nikita Danilov <nikita.danilov@aquantia.com>
Replace some direct registers reads with better
online functions.
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
.../net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | 6 +++---
.../ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index e5df40b00afd..eb4b99d56081 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -298,7 +298,7 @@ int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
bool is_locked;
hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
- is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
+ is_locked = hw_atl_sem_ram_get(self);
if (!is_locked) {
err = -ETIME;
goto err_exit;
@@ -337,7 +337,7 @@ static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
int err = 0;
bool is_locked;
- is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
+ is_locked = hw_atl_sem_ram_get(self);
if (!is_locked) {
err = -ETIME;
goto err_exit;
@@ -602,7 +602,7 @@ static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
{
- u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
+ u32 cp0x036C = hw_atl_utils_mpi_get_state(self);
u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
struct aq_hw_link_status_s *link_status = &self->aq_link_status;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index c628290d7546..fe6c5658e016 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -438,7 +438,7 @@ static int aq_fw2x_get_eee_rate(struct aq_hw_s *self, u32 *rate,
*supported_rates = fw2x_to_eee_mask(caps_hi);
- mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);
+ mpi_state = aq_fw2x_state2_get(self);
*rate = fw2x_to_eee_mask(mpi_state);
return err;
@@ -468,7 +468,7 @@ static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
static u32 aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fcmode)
{
- u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);
+ u32 mpi_state = aq_fw2x_state2_get(self);
if (mpi_state & HW_ATL_FW2X_CAP_PAUSE)
if (mpi_state & HW_ATL_FW2X_CAP_ASYM_PAUSE)
--
2.17.1
^ permalink raw reply related
* [PATCH v2 net-next 4/6] net: aquantia: fixed instack structure overflow
From: Igor Russkikh @ 2019-02-27 12:10 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev@vger.kernel.org, Igor Russkikh, Nikita Danilov
In-Reply-To: <cover.1551269343.git.igor.russkikh@aquantia.com>
This is a real stack undercorruption found by kasan build.
The issue did no harm normally because it only overflowed
2 bytes after `bitary` array which on most architectures
were mapped into `err` local.
Fixes: bab6de8fd180 ("net: ethernet: aquantia: Atlantic A0 and B0 specific functions.")
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 4 ++--
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index 2469ed4d86b9..30fdcb9b11fd 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -207,8 +207,8 @@ static int hw_atl_a0_hw_rss_set(struct aq_hw_s *self,
u32 i = 0U;
u32 num_rss_queues = max(1U, self->aq_nic_cfg->num_rss_queues);
int err = 0;
- u16 bitary[(HW_ATL_A0_RSS_REDIRECTION_MAX *
- HW_ATL_A0_RSS_REDIRECTION_BITS / 16U)];
+ u16 bitary[1 + (HW_ATL_A0_RSS_REDIRECTION_MAX *
+ HW_ATL_A0_RSS_REDIRECTION_BITS / 16U)];
memset(bitary, 0, sizeof(bitary));
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index b58ca7cb8e9d..c4cdc51350b2 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -199,8 +199,8 @@ static int hw_atl_b0_hw_rss_set(struct aq_hw_s *self,
u32 i = 0U;
u32 num_rss_queues = max(1U, self->aq_nic_cfg->num_rss_queues);
int err = 0;
- u16 bitary[(HW_ATL_B0_RSS_REDIRECTION_MAX *
- HW_ATL_B0_RSS_REDIRECTION_BITS / 16U)];
+ u16 bitary[1 + (HW_ATL_B0_RSS_REDIRECTION_MAX *
+ HW_ATL_B0_RSS_REDIRECTION_BITS / 16U)];
memset(bitary, 0, sizeof(bitary));
--
2.17.1
^ permalink raw reply related
* [PATCH v2 net-next 2/6] net: aquantia: added newline at end of file
From: Igor Russkikh @ 2019-02-27 12:10 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev@vger.kernel.org, Igor Russkikh, Nikita Danilov
In-Reply-To: <cover.1551269343.git.igor.russkikh@aquantia.com>
From: Nikita Danilov <nikita.danilov@aquantia.com>
drivers/net/ethernet/aquantia/atlantic/aq_nic.c: 991:1:
warning: no newline at end of file
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 0147c037ca96..ff83667410bd 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -986,4 +986,4 @@ void aq_nic_shutdown(struct aq_nic_s *self)
err_exit:
rtnl_unlock();
-}
\ No newline at end of file
+}
--
2.17.1
^ permalink raw reply related
* [PATCH v2 net-next 5/6] net: aquantia: replace AQ_HW_WAIT_FOR with readx_poll_timeout_atomic
From: Igor Russkikh @ 2019-02-27 12:10 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev@vger.kernel.org, Igor Russkikh, Nikita Danilov
In-Reply-To: <cover.1551269343.git.igor.russkikh@aquantia.com>
From: Nikita Danilov <nikita.danilov@aquantia.com>
David noticed the original define was hiding 'err' variable
reference. Thats confusing and counterintuitive.
Andrew noted the whole macro could be replaced with standard readx_poll
kernel macro. This makes code more readable.
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
.../ethernet/aquantia/atlantic/aq_hw_utils.h | 14 +--
.../aquantia/atlantic/hw_atl/hw_atl_a0.c | 21 +++-
.../aquantia/atlantic/hw_atl/hw_atl_b0.c | 12 +-
.../aquantia/atlantic/hw_atl/hw_atl_llh.c | 21 ++++
.../aquantia/atlantic/hw_atl/hw_atl_llh.h | 12 ++
.../atlantic/hw_atl/hw_atl_llh_internal.h | 2 +
.../aquantia/atlantic/hw_atl/hw_atl_utils.c | 110 +++++++++++++-----
.../atlantic/hw_atl/hw_atl_utils_fw2x.c | 64 +++++++---
8 files changed, 184 insertions(+), 72 deletions(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
index dc88a1221f1d..bc711238ca0c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h
@@ -14,6 +14,8 @@
#ifndef AQ_HW_UTILS_H
#define AQ_HW_UTILS_H
+#include <linux/iopoll.h>
+
#include "aq_common.h"
#ifndef HIDWORD
@@ -23,18 +25,6 @@
#define AQ_HW_SLEEP(_US_) mdelay(_US_)
-#define AQ_HW_WAIT_FOR(_B_, _US_, _N_) \
-do { \
- unsigned int AQ_HW_WAIT_FOR_i; \
- for (AQ_HW_WAIT_FOR_i = _N_; (!(_B_)) && (AQ_HW_WAIT_FOR_i);\
- --AQ_HW_WAIT_FOR_i) {\
- udelay(_US_); \
- } \
- if (!AQ_HW_WAIT_FOR_i) {\
- err = -ETIME; \
- } \
-} while (0)
-
#define aq_pr_err(...) pr_err(AQ_CFG_DRV_NAME ": " __VA_ARGS__)
#define aq_pr_trace(...) pr_info(AQ_CFG_DRV_NAME ": " __VA_ARGS__)
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index 30fdcb9b11fd..f6f8338153a2 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -85,6 +85,7 @@ const struct aq_hw_caps_s hw_atl_a0_caps_aqc109 = {
static int hw_atl_a0_hw_reset(struct aq_hw_s *self)
{
int err = 0;
+ u32 val;
hw_atl_glb_glb_reg_res_dis_set(self, 1U);
hw_atl_pci_pci_reg_res_dis_set(self, 0U);
@@ -95,7 +96,9 @@ static int hw_atl_a0_hw_reset(struct aq_hw_s *self)
hw_atl_glb_soft_res_set(self, 1);
/* check 10 times by 1ms */
- AQ_HW_WAIT_FOR(hw_atl_glb_soft_res_get(self) == 0, 1000U, 10U);
+ err = readx_poll_timeout_atomic(hw_atl_glb_soft_res_get,
+ self, val, val == 0,
+ 1000U, 10000U);
if (err < 0)
goto err_exit;
@@ -103,7 +106,9 @@ static int hw_atl_a0_hw_reset(struct aq_hw_s *self)
hw_atl_itr_res_irq_set(self, 1U);
/* check 10 times by 1ms */
- AQ_HW_WAIT_FOR(hw_atl_itr_res_irq_get(self) == 0, 1000U, 10U);
+ err = readx_poll_timeout_atomic(hw_atl_itr_res_irq_get,
+ self, val, val == 0,
+ 1000U, 10000U);
if (err < 0)
goto err_exit;
@@ -181,6 +186,7 @@ static int hw_atl_a0_hw_rss_hash_set(struct aq_hw_s *self,
int err = 0;
unsigned int i = 0U;
unsigned int addr = 0U;
+ u32 val;
for (i = 10, addr = 0U; i--; ++addr) {
u32 key_data = cfg->is_rss ?
@@ -188,8 +194,9 @@ static int hw_atl_a0_hw_rss_hash_set(struct aq_hw_s *self,
hw_atl_rpf_rss_key_wr_data_set(self, key_data);
hw_atl_rpf_rss_key_addr_set(self, addr);
hw_atl_rpf_rss_key_wr_en_set(self, 1U);
- AQ_HW_WAIT_FOR(hw_atl_rpf_rss_key_wr_en_get(self) == 0,
- 1000U, 10U);
+ err = readx_poll_timeout_atomic(hw_atl_rpf_rss_key_wr_en_get,
+ self, val, val == 0,
+ 1000U, 10000U);
if (err < 0)
goto err_exit;
}
@@ -209,6 +216,7 @@ static int hw_atl_a0_hw_rss_set(struct aq_hw_s *self,
int err = 0;
u16 bitary[1 + (HW_ATL_A0_RSS_REDIRECTION_MAX *
HW_ATL_A0_RSS_REDIRECTION_BITS / 16U)];
+ u32 val;
memset(bitary, 0, sizeof(bitary));
@@ -222,8 +230,9 @@ static int hw_atl_a0_hw_rss_set(struct aq_hw_s *self,
hw_atl_rpf_rss_redir_tbl_wr_data_set(self, bitary[i]);
hw_atl_rpf_rss_redir_tbl_addr_set(self, i);
hw_atl_rpf_rss_redir_wr_en_set(self, 1U);
- AQ_HW_WAIT_FOR(hw_atl_rpf_rss_redir_wr_en_get(self) == 0,
- 1000U, 10U);
+ err = readx_poll_timeout_atomic(hw_atl_rpf_rss_redir_wr_en_get,
+ self, val, val == 0,
+ 1000U, 10000U);
if (err < 0)
goto err_exit;
}
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index c4cdc51350b2..7eb5ea948d61 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -173,6 +173,7 @@ static int hw_atl_b0_hw_rss_hash_set(struct aq_hw_s *self,
int err = 0;
unsigned int i = 0U;
unsigned int addr = 0U;
+ u32 val;
for (i = 10, addr = 0U; i--; ++addr) {
u32 key_data = cfg->is_rss ?
@@ -180,8 +181,9 @@ static int hw_atl_b0_hw_rss_hash_set(struct aq_hw_s *self,
hw_atl_rpf_rss_key_wr_data_set(self, key_data);
hw_atl_rpf_rss_key_addr_set(self, addr);
hw_atl_rpf_rss_key_wr_en_set(self, 1U);
- AQ_HW_WAIT_FOR(hw_atl_rpf_rss_key_wr_en_get(self) == 0,
- 1000U, 10U);
+ err = readx_poll_timeout_atomic(hw_atl_rpf_rss_key_wr_en_get,
+ self, val, val == 0,
+ 1000U, 10000U);
if (err < 0)
goto err_exit;
}
@@ -201,6 +203,7 @@ static int hw_atl_b0_hw_rss_set(struct aq_hw_s *self,
int err = 0;
u16 bitary[1 + (HW_ATL_B0_RSS_REDIRECTION_MAX *
HW_ATL_B0_RSS_REDIRECTION_BITS / 16U)];
+ u32 val;
memset(bitary, 0, sizeof(bitary));
@@ -214,8 +217,9 @@ static int hw_atl_b0_hw_rss_set(struct aq_hw_s *self,
hw_atl_rpf_rss_redir_tbl_wr_data_set(self, bitary[i]);
hw_atl_rpf_rss_redir_tbl_addr_set(self, i);
hw_atl_rpf_rss_redir_wr_en_set(self, 1U);
- AQ_HW_WAIT_FOR(hw_atl_rpf_rss_redir_wr_en_get(self) == 0,
- 1000U, 10U);
+ err = readx_poll_timeout_atomic(hw_atl_rpf_rss_redir_wr_en_get,
+ self, val, val == 0,
+ 1000U, 10000U);
if (err < 0)
goto err_exit;
}
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
index 939f77e2e117..f72194c77f5f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
@@ -1585,3 +1585,24 @@ void hw_atl_rpfl3l4_ipv6_dest_addr_set(struct aq_hw_s *aq_hw, u8 location,
HW_ATL_RPF_L3_DSTA_ADR(location + i),
ipv6_dest[i]);
}
+
+u32 hw_atl_sem_ram_get(struct aq_hw_s *self)
+{
+ return hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
+}
+
+u32 hw_atl_scrpad_get(struct aq_hw_s *aq_hw, u32 scratch_scp)
+{
+ return aq_hw_read_reg(aq_hw,
+ HW_ATL_GLB_CPU_SCRATCH_SCP_ADR(scratch_scp));
+}
+
+u32 hw_atl_scrpad12_get(struct aq_hw_s *self)
+{
+ return hw_atl_scrpad_get(self, 0xB);
+}
+
+u32 hw_atl_scrpad25_get(struct aq_hw_s *self)
+{
+ return hw_atl_scrpad_get(self, 0x18);
+}
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
index 03c570d115fe..40e6c1e44b5b 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
@@ -752,4 +752,16 @@ void hw_atl_rpfl3l4_ipv6_src_addr_set(struct aq_hw_s *aq_hw, u8 location,
void hw_atl_rpfl3l4_ipv6_dest_addr_set(struct aq_hw_s *aq_hw, u8 location,
u32 *ipv6_dest);
+/* get global microprocessor ram semaphore */
+u32 hw_atl_sem_ram_get(struct aq_hw_s *self);
+
+/* get global microprocessor scratch pad register */
+u32 hw_atl_scrpad_get(struct aq_hw_s *aq_hw, u32 scratch_scp);
+
+/* get global microprocessor scratch pad 12 register */
+u32 hw_atl_scrpad12_get(struct aq_hw_s *self);
+
+/* get global microprocessor scratch pad 25 register */
+u32 hw_atl_scrpad25_get(struct aq_hw_s *self);
+
#endif /* HW_ATL_LLH_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
index 8470d92db812..50b4dee5562d 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
@@ -2519,4 +2519,6 @@
/* Default value of bitfield l3_da0[1F:0] */
#define HW_ATL_RPF_L3_DSTA_DEFAULT 0x0
+#define HW_ATL_FW_SM_RAM 0x2U
+
#endif /* HW_ATL_LLH_INTERNAL_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index 9b74a3197d7f..e5df40b00afd 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -25,7 +25,9 @@
#define HW_ATL_MIF_ADDR 0x0208U
#define HW_ATL_MIF_VAL 0x020CU
-#define HW_ATL_FW_SM_RAM 0x2U
+#define HW_ATL_RPC_CONTROL_ADR 0x0338U
+#define HW_ATL_RPC_STATE_ADR 0x033CU
+
#define HW_ATL_MPI_FW_VERSION 0x18
#define HW_ATL_MPI_CONTROL_ADR 0x0368U
#define HW_ATL_MPI_STATE_ADR 0x036CU
@@ -53,6 +55,12 @@ static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
enum hal_atl_utils_fw_state_e state);
+static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self);
+static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self);
+static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self);
+static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self);
+static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self);
+
int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
{
int err = 0;
@@ -234,6 +242,7 @@ int hw_atl_utils_soft_reset(struct aq_hw_s *self)
{
int k;
u32 boot_exit_code = 0;
+ u32 val;
for (k = 0; k < 1000; ++k) {
u32 flb_status = aq_hw_read_reg(self,
@@ -260,9 +269,11 @@ int hw_atl_utils_soft_reset(struct aq_hw_s *self)
int err = 0;
hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
- AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) &
- HW_ATL_MPI_STATE_MSK) == MPI_DEINIT,
- 10, 1000U);
+ err = readx_poll_timeout_atomic(hw_atl_utils_mpi_get_state,
+ self, val,
+ (val & HW_ATL_MPI_STATE_MSK) ==
+ MPI_DEINIT,
+ 10, 10000U);
if (err)
return err;
}
@@ -277,10 +288,11 @@ int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
u32 *p, u32 cnt)
{
int err = 0;
+ u32 val;
- AQ_HW_WAIT_FOR(hw_atl_reg_glb_cpu_sem_get(self,
- HW_ATL_FW_SM_RAM) == 1U,
- 1U, 10000U);
+ err = readx_poll_timeout_atomic(hw_atl_sem_ram_get,
+ self, val, val == 1U,
+ 1U, 10000U);
if (err < 0) {
bool is_locked;
@@ -299,13 +311,14 @@ int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U);
if (IS_CHIP_FEATURE(REVISION_B1))
- AQ_HW_WAIT_FOR(a != aq_hw_read_reg(self,
- HW_ATL_MIF_ADDR),
- 1, 1000U);
+ err = readx_poll_timeout_atomic(hw_atl_utils_mif_addr_get,
+ self, val, val != a,
+ 1U, 1000U);
else
- AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self,
- HW_ATL_MIF_CMD)),
- 1, 1000U);
+ err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get,
+ self, val,
+ !(val & 0x100),
+ 1U, 1000U);
*(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);
a += 4;
@@ -320,6 +333,7 @@ int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
u32 cnt)
{
+ u32 val;
int err = 0;
bool is_locked;
@@ -337,10 +351,11 @@ static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
(0x80000000 | (0xFFFF & (offset * 4))));
hw_atl_mcp_up_force_intr_set(self, 1);
/* 1000 times by 10us = 10ms */
- AQ_HW_WAIT_FOR((aq_hw_read_reg(self,
- 0x32C) & 0xF0000000) !=
- 0x80000000,
- 10, 1000);
+ err = readx_poll_timeout_atomic(hw_atl_scrpad12_get,
+ self, val,
+ (val & 0xF0000000) ==
+ 0x80000000,
+ 10U, 10000U);
}
} else {
u32 offset = 0;
@@ -351,8 +366,10 @@ static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
aq_hw_write_reg(self, 0x20C, p[offset]);
aq_hw_write_reg(self, 0x200, 0xC000);
- AQ_HW_WAIT_FOR((aq_hw_read_reg(self, 0x200U) &
- 0x100) == 0, 10, 1000);
+ err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get,
+ self, val,
+ (val & 0x100) == 0,
+ 1000U, 10000U);
}
}
@@ -395,15 +412,14 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
hw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);
/* check 10 times by 1ms */
- AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
- aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
+ err = readx_poll_timeout_atomic(hw_atl_scrpad25_get,
+ self, self->mbox_addr,
+ self->mbox_addr != 0U,
+ 1000U, 10000U);
return err;
}
-#define HW_ATL_RPC_CONTROL_ADR 0x0338U
-#define HW_ATL_RPC_STATE_ADR 0x033CU
-
struct aq_hw_atl_utils_fw_rpc_tid_s {
union {
u32 val;
@@ -452,10 +468,10 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
self->rpc_tid = sw.tid;
- AQ_HW_WAIT_FOR(sw.tid ==
- (fw.val =
- aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),
- fw.tid), 1000U, 100U);
+ err = readx_poll_timeout_atomic(hw_atl_utils_rpc_state_get,
+ self, fw.val,
+ sw.tid == fw.tid,
+ 1000U, 100000U);
if (fw.len == 0xFFFFU) {
err = hw_atl_utils_fw_rpc_call(self, sw.len);
@@ -559,10 +575,11 @@ static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
transaction_id = mbox.transaction_id;
- AQ_HW_WAIT_FOR(transaction_id !=
- (hw_atl_utils_mpi_read_mbox(self, &mbox),
- mbox.transaction_id),
- 1000U, 100U);
+ err = readx_poll_timeout_atomic(hw_atl_utils_get_mpi_mbox_tid,
+ self, mbox.transaction_id,
+ transaction_id !=
+ mbox.transaction_id,
+ 1000U, 100000U);
if (err < 0)
goto err_exit;
}
@@ -905,6 +922,35 @@ static int aq_fw1x_set_power(struct aq_hw_s *self, unsigned int power_state,
return err;
}
+static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self)
+{
+ struct hw_atl_utils_mbox_header mbox;
+
+ hw_atl_utils_mpi_read_mbox(self, &mbox);
+
+ return mbox.transaction_id;
+}
+
+static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self)
+{
+ return aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
+}
+
+static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self)
+{
+ return aq_hw_read_reg(self, HW_ATL_MIF_CMD);
+}
+
+static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self)
+{
+ return aq_hw_read_reg(self, HW_ATL_MIF_ADDR);
+}
+
+static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self)
+{
+ return aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR);
+}
+
const struct aq_fw_ops aq_fw_1x_ops = {
.init = hw_atl_utils_mpi_create,
.deinit = hw_atl_fw1x_deinit,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index 7de3220d9cab..c628290d7546 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -20,15 +20,14 @@
#include "hw_atl_utils.h"
#include "hw_atl_llh.h"
-#define HW_ATL_FW2X_MPI_EFUSE_ADDR 0x364
-#define HW_ATL_FW2X_MPI_MBOX_ADDR 0x360
#define HW_ATL_FW2X_MPI_RPC_ADDR 0x334
+#define HW_ATL_FW2X_MPI_MBOX_ADDR 0x360
+#define HW_ATL_FW2X_MPI_EFUSE_ADDR 0x364
#define HW_ATL_FW2X_MPI_CONTROL_ADDR 0x368
#define HW_ATL_FW2X_MPI_CONTROL2_ADDR 0x36C
-
#define HW_ATL_FW2X_MPI_STATE_ADDR 0x370
-#define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374
+#define HW_ATL_FW2X_MPI_STATE2_ADDR 0x374
#define HW_ATL_FW2X_CAP_PAUSE BIT(CAPS_HI_PAUSE)
#define HW_ATL_FW2X_CAP_ASYM_PAUSE BIT(CAPS_HI_ASYMMETRIC_PAUSE)
@@ -72,17 +71,24 @@ static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed);
static int aq_fw2x_set_state(struct aq_hw_s *self,
enum hal_atl_utils_fw_state_e state);
+static u32 aq_fw2x_mbox_get(struct aq_hw_s *self);
+static u32 aq_fw2x_rpc_get(struct aq_hw_s *self);
+static u32 aq_fw2x_state2_get(struct aq_hw_s *self);
+
static int aq_fw2x_init(struct aq_hw_s *self)
{
int err = 0;
/* check 10 times by 1ms */
- AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
- aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR)),
- 1000U, 10U);
- AQ_HW_WAIT_FOR(0U != (self->rpc_addr =
- aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR)),
- 1000U, 100U);
+ err = readx_poll_timeout_atomic(aq_fw2x_mbox_get,
+ self, self->mbox_addr,
+ self->mbox_addr != 0U,
+ 1000U, 10000U);
+
+ err = readx_poll_timeout_atomic(aq_fw2x_rpc_get,
+ self, self->rpc_addr,
+ self->rpc_addr != 0U,
+ 1000U, 100000U);
return err;
}
@@ -286,16 +292,18 @@ static int aq_fw2x_update_stats(struct aq_hw_s *self)
int err = 0;
u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
u32 orig_stats_val = mpi_opts & BIT(CAPS_HI_STATISTICS);
+ u32 stats_val;
/* Toggle statistics bit for FW to update */
mpi_opts = mpi_opts ^ BIT(CAPS_HI_STATISTICS);
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
/* Wait FW to report back */
- AQ_HW_WAIT_FOR(orig_stats_val !=
- (aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &
- BIT(CAPS_HI_STATISTICS)),
- 1U, 10000U);
+ err = readx_poll_timeout_atomic(aq_fw2x_state2_get,
+ self, stats_val,
+ orig_stats_val != (stats_val &
+ BIT(CAPS_HI_STATISTICS)),
+ 1U, 10000U);
if (err)
return err;
@@ -309,6 +317,7 @@ static int aq_fw2x_set_sleep_proxy(struct aq_hw_s *self, u8 *mac)
unsigned int rpc_size = 0U;
u32 mpi_opts;
int err = 0;
+ u32 val;
rpc_size = sizeof(rpc->msg_id) + sizeof(*cfg);
@@ -337,8 +346,10 @@ static int aq_fw2x_set_sleep_proxy(struct aq_hw_s *self, u8 *mac)
mpi_opts |= HW_ATL_FW2X_CTRL_SLEEP_PROXY;
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
- AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &
- HW_ATL_FW2X_CTRL_SLEEP_PROXY), 1U, 10000U);
+ err = readx_poll_timeout_atomic(aq_fw2x_state2_get,
+ self, val,
+ val & HW_ATL_FW2X_CTRL_SLEEP_PROXY,
+ 1U, 10000U);
err_exit:
return err;
@@ -350,6 +361,7 @@ static int aq_fw2x_set_wol_params(struct aq_hw_s *self, u8 *mac)
struct fw2x_msg_wol *msg = NULL;
u32 mpi_opts;
int err = 0;
+ u32 val;
err = hw_atl_utils_fw_rpc_wait(self, &rpc);
if (err < 0)
@@ -374,8 +386,9 @@ static int aq_fw2x_set_wol_params(struct aq_hw_s *self, u8 *mac)
mpi_opts |= HW_ATL_FW2X_CTRL_WOL;
aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
- AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &
- HW_ATL_FW2X_CTRL_WOL), 1U, 10000U);
+ err = readx_poll_timeout_atomic(aq_fw2x_state2_get,
+ self, val, val & HW_ATL_FW2X_CTRL_WOL,
+ 1U, 10000U);
err_exit:
return err;
@@ -471,6 +484,21 @@ static u32 aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fcmode)
return 0;
}
+static u32 aq_fw2x_mbox_get(struct aq_hw_s *self)
+{
+ return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR);
+}
+
+static u32 aq_fw2x_rpc_get(struct aq_hw_s *self)
+{
+ return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR);
+}
+
+static u32 aq_fw2x_state2_get(struct aq_hw_s *self)
+{
+ return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);
+}
+
const struct aq_fw_ops aq_fw_2x_ops = {
.init = aq_fw2x_init,
.deinit = aq_fw2x_deinit,
--
2.17.1
^ permalink raw reply related
* [PATCH v2 net-next 3/6] net: aquantia: fixed buffer overflow
From: Igor Russkikh @ 2019-02-27 12:10 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev@vger.kernel.org, Igor Russkikh, Nikita Danilov
In-Reply-To: <cover.1551269343.git.igor.russkikh@aquantia.com>
From: Nikita Danilov <nikita.danilov@aquantia.com>
The overflow is detected by smatch:
drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c: 175
aq_pci_func_free_irqs() error: buffer overflow 'self->aq_vec' 8 <= 31
In reality msix_entry_mask always restricts number of iterations.
Adding extra condition to make logic clear and smatch happy.
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
index c8b44cdb91c1..0217ff4669a4 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
@@ -170,6 +170,8 @@ void aq_pci_func_free_irqs(struct aq_nic_s *self)
for (i = 32U; i--;) {
if (!((1U << i) & self->msix_entry_mask))
continue;
+ if (i >= AQ_CFG_VECS_MAX)
+ continue;
if (pdev->msix_enabled)
irq_set_affinity_hint(pci_irq_vector(pdev, i), NULL);
--
2.17.1
^ permalink raw reply related
* [PATCH v2 net-next 1/6] net: aquantia: fixed memcpy size
From: Igor Russkikh @ 2019-02-27 12:10 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev@vger.kernel.org, Igor Russkikh, Nikita Danilov
In-Reply-To: <cover.1551269343.git.igor.russkikh@aquantia.com>
From: Nikita Danilov <nikita.danilov@aquantia.com>
Not careful array dereference caused analysis tools
to think there could be memory overflow.
There was actually no corruption because the array is
two dimensional.
drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c: 140
aq_ethtool_get_strings() error:
memcpy() '*aq_ethtool_stat_names' too small (32 vs 704)
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index 38e87eed76b9..a718d7a1f76c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -138,7 +138,7 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
u8 *p = data;
if (stringset == ETH_SS_STATS) {
- memcpy(p, *aq_ethtool_stat_names,
+ memcpy(p, aq_ethtool_stat_names,
sizeof(aq_ethtool_stat_names));
p = p + sizeof(aq_ethtool_stat_names);
for (i = 0; i < cfg->vecs; i++) {
--
2.17.1
^ permalink raw reply related
* [PATCH v2 net-next 0/6] net: aquantia: minor bug fixes after static analysis
From: Igor Russkikh @ 2019-02-27 12:10 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev@vger.kernel.org, Igor Russkikh
This patchset fixes minor errors and warnings found by smatch and kasan.
Extra patch is to replace AQ_HW_WAIT_FOR with readx_poll_timeout
to improve readability.
V2:
use readx_poll
resubmitted to net-next since the changeset became quite big.
Igor Russkikh (1):
net: aquantia: fixed instack structure overflow
Nikita Danilov (5):
net: aquantia: fixed memcpy size
net: aquantia: added newline at end of file
net: aquantia: fixed buffer overflow
net: aquantia: replace AQ_HW_WAIT_FOR with readx_poll_timeout_atomic
net: aquantia: use better wrappers for state registers
.../ethernet/aquantia/atlantic/aq_ethtool.c | 2 +-
.../ethernet/aquantia/atlantic/aq_hw_utils.h | 14 +--
.../net/ethernet/aquantia/atlantic/aq_nic.c | 2 +-
.../ethernet/aquantia/atlantic/aq_pci_func.c | 2 +
.../aquantia/atlantic/hw_atl/hw_atl_a0.c | 25 ++--
.../aquantia/atlantic/hw_atl/hw_atl_b0.c | 16 ++-
.../aquantia/atlantic/hw_atl/hw_atl_llh.c | 21 ++++
.../aquantia/atlantic/hw_atl/hw_atl_llh.h | 12 ++
.../atlantic/hw_atl/hw_atl_llh_internal.h | 2 +
.../aquantia/atlantic/hw_atl/hw_atl_utils.c | 116 ++++++++++++------
.../atlantic/hw_atl/hw_atl_utils_fw2x.c | 68 +++++++---
11 files changed, 197 insertions(+), 83 deletions(-)
--
2.17.1
^ permalink raw reply
* Request for suggestion on net device re-naming/re-ordering based on DT alias
From: Harini Katakam @ 2019-02-27 11:54 UTC (permalink / raw)
To: netdev, linux-kernel, Nicolas Ferre, David Miller
Cc: Michal Simek, Harini Katakam, Harini Katakam
Hi,
We've had some users requesting control over net device name order
when multiple ethernet devices are present on a system. I've tried a
few solutions to this and looked it up on forums. But I apologize if
I have missed something.
I know that the current system allocates eth<n> as per probe order
but that is obviously not stably controlled by user (tried DT
re-ordering and defer probe). One solution is to use DT alias names
to write to (net_device)->name as follows:
Devicetree:
aliases {
ethernet0 = &mac1;
ethernet1 = &mac0;
};
Driver probe:
+ /* Read ethernet DT alias id and assign to right device name*/
+ id = of_alias_get_id(np, "ethernet");
+ if (id < 0) {
+ dev_warn(&pdev->dev, "failed to get alias id (%u)\n", id);
+ return id;
+ }
+ snprintf(dev->name, sizeof(dev->name), "eth%d", id);
+
These three drivers seem to have something similar for mdio/phy bus IDs:
drivers/net/ethernet/broadcom/genet/bcmmii.c:409: id =
of_alias_get_id(dn, "eth");
drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c:43: plat->bus_id =
of_alias_get_id(np, "ethernet");
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c:404:
plat->bus_id = of_alias_get_id(np, "ethernet");
Drawback: This approach will break if alias is not provided for one
of the interfaces on board. Not to mention, there could be systems
with multiple ethernet makes (for ex. Cadence macb and Xilinx axienet)
If one of the drivers does not have an alias read mechanism, it is
possible to have clashing ID assignments. Is there any way this
solution can be changed to be stable/acceptable?
One other alternative I've tried is netdev kernel bootargs but this
device name was not being picked by the kernel:
https://www.kernel.org/doc/html/v4.19/admin-guide/kernel-parameters.html
netdev= <mac1’s interrupt id>, <mac1’s base address>, eth0
netdev=<mac0’s interrupt id>, <mac0’s base address>, eth1
Could you please suggest any alternatives?
Thanks!
Regards,
Harini
^ permalink raw reply
* Re: [PATCH net-next v2 1/5] net/mlx5e: Return -EOPNOTSUPP when modify header action zero
From: Tonghao Zhang @ 2019-02-27 11:47 UTC (permalink / raw)
To: Or Gerlitz; +Cc: Saeed Mahameed, Linux Netdev List
In-Reply-To: <CAJ3xEMh7GU8W=kfnM3eU4-0CxGyqB_1TvMWcr8WB3AK=xRM6gA@mail.gmail.com>
On Wed, Feb 27, 2019 at 6:37 AM Or Gerlitz <gerlitz.or@gmail.com> wrote:
>
> On Mon, Feb 25, 2019 at 1:06 PM <xiangxia.m.yue@gmail.com> wrote:
>>
>> From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
>>
>> When max modify header action is zero, we return -EOPNOTSUPP
>> directly. In this way, we can ignore wrong message info (e.g.
>> "mlx5: parsed 0 pedit actions, can't do more").
>>
>> This happens when offloading pedit actions on mlx VFs.
>>
>> For example:
>> $ tc filter add dev mlx5_vf parent ffff: protocol ip prio 1 \
>> flower skip_sw dst_mac 00:10:56:fb:64:e8 \
>> dst_ip 1.1.1.100 src_ip 1.1.1.200 \
>> action pedit ex munge eth src set 00:10:56:b4:5d:20
>
>
>
> this command should work, we support header re-write (pedit offload) for tc NIC rules
>
> Is this CX5 VF? if yes, something broke
No, this is cx4
>
^ permalink raw reply
* Re: [PATCH net-next v2 1/5] net/mlx5e: Return -EOPNOTSUPP when modify header action zero
From: Tonghao Zhang @ 2019-02-27 11:46 UTC (permalink / raw)
To: Roi Dayan; +Cc: Saeed Mahameed, gerlitz.or@gmail.com, netdev@vger.kernel.org
In-Reply-To: <bbaaf93a-b9a3-289a-afc3-fcaa5068f322@mellanox.com>
On Tue, Feb 26, 2019 at 9:54 PM Roi Dayan <roid@mellanox.com> wrote:
>
>
>
> On 25/02/2019 12:40, xiangxia.m.yue@gmail.com wrote:
> > From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> >
> > When max modify header action is zero, we return -EOPNOTSUPP
> > directly. In this way, we can ignore wrong message info (e.g.
> > "mlx5: parsed 0 pedit actions, can't do more").
> >
> > This happens when offloading pedit actions on mlx VFs.
> >
> > For example:
> > $ tc filter add dev mlx5_vf parent ffff: protocol ip prio 1 \
> > flower skip_sw dst_mac 00:10:56:fb:64:e8 \
> > dst_ip 1.1.1.100 src_ip 1.1.1.200 \
> > action pedit ex munge eth src set 00:10:56:b4:5d:20
> >
> > Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> > ---
> > drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 12 ++++++++++--
> > 1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
> > index b38986e..708f819 100644
> > --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
> > +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
> > @@ -2002,7 +2002,8 @@ static int offload_pedit_fields(struct pedit_headers_action *hdrs,
> > static int alloc_mod_hdr_actions(struct mlx5e_priv *priv,
> > struct pedit_headers_action *hdrs,
> > int namespace,
> > - struct mlx5e_tc_flow_parse_attr *parse_attr)
> > + struct mlx5e_tc_flow_parse_attr *parse_attr,
> > + struct netlink_ext_ack *extack)
> > {
> > int nkeys, action_size, max_actions;
> >
> > @@ -2015,6 +2016,12 @@ static int alloc_mod_hdr_actions(struct mlx5e_priv *priv,
> > else /* namespace is MLX5_FLOW_NAMESPACE_KERNEL - NIC offloading */
> > max_actions = MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, max_modify_header_actions);
> >
> > + if (!max_actions) {
> > + NL_SET_ERR_MSG_MOD(extack,
> > + "don't support pedit actions, can't offload");
>
> can we rephrase that to match the msg style you did in patch 5 ?
Yes, good idea
> i.e. The pedit offload action is not supported
>
>
> > + return -EOPNOTSUPP;
> > + }
> > +
> > /* can get up to crazingly 16 HW actions in 32 bits pedit SW key */
> > max_actions = min(max_actions, nkeys * 16);
> >
> > @@ -2072,7 +2079,8 @@ static int alloc_tc_pedit_action(struct mlx5e_priv *priv, int namespace,
> > u8 cmd;
> >
> > if (!parse_attr->mod_hdr_actions) {
> > - err = alloc_mod_hdr_actions(priv, hdrs, namespace, parse_attr);
> > + err = alloc_mod_hdr_actions(priv, hdrs,
> > + namespace, parse_attr, extack);
> > if (err)
> > goto out_err;
> > }
> >
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox