diff --git a/drivers/net/ethernet/yusur/yk3/yk3_cdev.c b/drivers/net/ethernet/yusur/yk3/yk3_cdev.c index 920ce9366452fd85051dbe43bee59b68c538d2c5..dc5f5d7afababc17b32b28731e14ac1530376a16 100644 --- a/drivers/net/ethernet/yusur/yk3/yk3_cdev.c +++ b/drivers/net/ethernet/yusur/yk3/yk3_cdev.c @@ -1271,7 +1271,7 @@ static long yk3_net_rss_reta(struct file *file, unsigned int cmd, unsigned long memcpy(indir_buf, rss_reta.indir, indir_size * sizeof(u32)); /* we need qcount as a parameter, cannot use ndo_ops set_rxfh */ - yk3_rss_indir_table_set(ndev, indir_buf, rss_reta.qcount); + ret = yk3_rss_indir_table_set(ndev, indir_buf, rss_reta.qcount); break; default: ret = -EINVAL; diff --git a/drivers/net/ethernet/yusur/yk3/yk3_ethtool.c b/drivers/net/ethernet/yusur/yk3/yk3_ethtool.c index f07bbd4c69344c3be204f1b768e33919dccd9e88..563e60563835e14aef0d80d2d37614668fa53bfd 100644 --- a/drivers/net/ethernet/yusur/yk3/yk3_ethtool.c +++ b/drivers/net/ethernet/yusur/yk3/yk3_ethtool.c @@ -428,40 +428,50 @@ static u32 yk3_get_rxfh_key_size(struct net_device *ndev) static int yk3_get_rxfh(struct net_device *ndev, struct ethtool_rxfh_param *param) { struct yk3_ndev_priv *ndev_priv = netdev_priv(ndev); + int ret = 0; mutex_lock(&ndev_priv->state_mlock); - if (param->indir) - yk3_rss_indir_table_get(ndev, param->indir); + if (param->indir) { + ret = yk3_rss_indir_table_get(ndev, param->indir); + if (ret) + goto out; + } if (param->hfunc) param->hfunc = ETH_RSS_HASH_TOP; if (param->key) - yk3_rss_key_get(ndev, param->key); + ret = yk3_rss_key_get(ndev, param->key); +out: mutex_unlock(&ndev_priv->state_mlock); - return 0; + return ret; } #else static int yk3_get_rxfh(struct net_device *ndev, u32 *indir, u8 *key, u8 *hfunc) { struct yk3_ndev_priv *ndev_priv = netdev_priv(ndev); + int ret = 0; mutex_lock(&ndev_priv->state_mlock); - if (indir) - yk3_rss_indir_table_get(ndev, indir); + if (indir) { + ret = yk3_rss_indir_table_get(ndev, indir); + if (ret) + goto out; + } if (hfunc) *hfunc = ETH_RSS_HASH_TOP; if (key) - yk3_rss_key_get(ndev, key); + ret = yk3_rss_key_get(ndev, key); +out: mutex_unlock(&ndev_priv->state_mlock); - return 0; + return ret; } #endif /* YK3_HAVE_ETHTOOL_GET_RXFH_PARAM */ @@ -471,39 +481,49 @@ static int yk3_set_rxfh(struct net_device *ndev, struct netlink_ext_ack *extack) { struct yk3_ndev_priv *ndev_priv = netdev_priv(ndev); + int ret = 0; if (param->hfunc != ETH_RSS_HASH_NO_CHANGE && param->hfunc != ETH_RSS_HASH_TOP) return -EOPNOTSUPP; mutex_lock(&ndev_priv->state_mlock); - if (param->key) - yk3_rss_key_set(ndev, param->key); + if (param->key) { + ret = yk3_rss_key_set(ndev, param->key); + if (ret) + goto out; + } if (param->indir) - yk3_rss_indir_table_set(ndev, param->indir, ndev->real_num_rx_queues); + ret = yk3_rss_indir_table_set(ndev, param->indir, ndev->real_num_rx_queues); +out: mutex_unlock(&ndev_priv->state_mlock); - return 0; + return ret; } #else static int yk3_set_rxfh(struct net_device *ndev, const u32 *indir, const u8 *key, const u8 hfunc) { struct yk3_ndev_priv *ndev_priv = netdev_priv(ndev); + int ret = 0; if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) return -EOPNOTSUPP; mutex_lock(&ndev_priv->state_mlock); - if (key) - yk3_rss_key_set(ndev, key); + if (key) { + ret = yk3_rss_key_set(ndev, key); + if (ret) + goto out; + } if (indir) - yk3_rss_indir_table_set(ndev, indir, ndev->real_num_rx_queues); + ret = yk3_rss_indir_table_set(ndev, indir, ndev->real_num_rx_queues); +out: mutex_unlock(&ndev_priv->state_mlock); - return 0; + return ret; } #endif /* YK3_HAVE_ETHTOOL_SET_RXFH_PARAM */ diff --git a/drivers/net/ethernet/yusur/yk3/yk3_rss.c b/drivers/net/ethernet/yusur/yk3/yk3_rss.c index 2eaeff805bdd174a8e4a8aa1101562b2b792c2bc..34d1644d9907208052fcb223674dd6afaacc58f5 100644 --- a/drivers/net/ethernet/yusur/yk3/yk3_rss.c +++ b/drivers/net/ethernet/yusur/yk3/yk3_rss.c @@ -74,7 +74,20 @@ static void yk3_pf_hash_key_get(void __iomem *hw_addr, u8 *out) } } -void yk3_rss_indir_table_set(struct net_device *ndev, const u32 *indir, u16 qcount) +static int yk3_rss_send_msg(struct yk3_pdev_priv *pdev_priv, + struct yk3_mbox_msg *msg, + struct yk3_mbox_option *opt, + struct yk3_mbox_msg *reply) +{ + int ret = yk3_mbox_send_msg(pdev_priv, msg, opt, reply); + + if (ret == YK3_MBOX_SEND_L3_NO_ACK) + return -ETIMEDOUT; + + return ret > 0 ? -EIO : ret; +} + +int yk3_rss_indir_table_set(struct net_device *ndev, const u32 *indir, u16 qcount) { struct yk3_ndev_priv *ndev_priv = netdev_priv(ndev); struct yk3_pdev_priv *pdev_priv = ndev_priv->pdev_priv; @@ -85,6 +98,7 @@ void yk3_rss_indir_table_set(struct net_device *ndev, const u32 *indir, u16 qcou u32 i = 0, val = 0; u16 qstart = ndev_priv->qbase[YK3_QUEUE_T_GLOBAL].start; u16 q_done = 0, q_left = 0; + int ret; if (yk3_ndev_is_vf(ndev_priv)) { mbox_msg.opcode = YK3_MBOX_OPCODE_RSS_INDIRECT; @@ -98,8 +112,9 @@ void yk3_rss_indir_table_set(struct net_device *ndev, const u32 *indir, u16 qcou cmd->qstart = qstart + q_done; for (i = 0; i < 4 * cmd->qnb; i++) cmd->cmd_data[i] = (u8)(indir[4 * q_done + i] & 0xff); - if (yk3_mbox_send_msg(pdev_priv, &mbox_msg, &mbox_opt, NULL)) - return; + ret = yk3_rss_send_msg(pdev_priv, &mbox_msg, &mbox_opt, NULL); + if (ret) + return ret; q_done += cmd->qnb; } } else { @@ -109,9 +124,11 @@ void yk3_rss_indir_table_set(struct net_device *ndev, const u32 *indir, u16 qcou yk3_wr32(hw_addr, YK3_RSS_INDIRECT_BASE + 4 * qstart + i, val); } } + + return 0; } -void yk3_rss_indir_table_get(struct net_device *ndev, u32 *indir) +int yk3_rss_indir_table_get(struct net_device *ndev, u32 *indir) { struct yk3_ndev_priv *ndev_priv = netdev_priv(ndev); struct yk3_pdev_priv *pdev_priv = ndev_priv->pdev_priv; @@ -123,6 +140,7 @@ void yk3_rss_indir_table_get(struct net_device *ndev, u32 *indir) u16 q_done = 0, q_left = 0; u16 qstart = ndev_priv->qbase[YK3_QUEUE_T_GLOBAL].start; u32 qcount = ndev->real_num_rx_queues; + int ret; if (yk3_ndev_is_vf(ndev_priv)) { mbox_msg.opcode = YK3_MBOX_OPCODE_RSS_INDIRECT; @@ -136,8 +154,9 @@ void yk3_rss_indir_table_get(struct net_device *ndev, u32 *indir) q_left = qcount - q_done; cmd->qnb = min_t(u16, q_left, YK3_RSS_INDIR_Q_CHUNK_SIZE); cmd->qstart = qstart + q_done; - if (yk3_mbox_send_msg(pdev_priv, &mbox_msg, &mbox_opt, &ack_msg)) - return; + ret = yk3_rss_send_msg(pdev_priv, &mbox_msg, &mbox_opt, &ack_msg); + if (ret) + return ret; ack_cmd = (struct yk3_mbox_rss_indir_cmd *)ack_msg.data; for (i = 0; i < 4 * cmd->qnb; i++) indir[4 * q_done + i] = ack_cmd->cmd_data[i]; @@ -153,9 +172,11 @@ void yk3_rss_indir_table_get(struct net_device *ndev, u32 *indir) indir[j++] = (val >> 24) & 0xff; } } + + return 0; } -void yk3_rss_key_set(struct net_device *ndev, const u8 *key) +int yk3_rss_key_set(struct net_device *ndev, const u8 *key) { struct yk3_ndev_priv *ndev_priv = netdev_priv(ndev); struct yk3_pdev_priv *pdev_priv = ndev_priv->pdev_priv; @@ -174,13 +195,15 @@ void yk3_rss_key_set(struct net_device *ndev, const u8 *key) cmd->qstart = qstart; cmd->qnb = (u16)(qcount); memcpy(cmd->cmd_data, key, YK3_RSS_HASH_KEY_SIZE); - yk3_mbox_send_msg(pdev_priv, &mbox_msg, &mbox_opt, NULL); + return yk3_rss_send_msg(pdev_priv, &mbox_msg, &mbox_opt, NULL); } else { yk3_pf_hash_key_set(hw_addr, key); } + + return 0; } -void yk3_rss_key_get(struct net_device *ndev, u8 *key) +int yk3_rss_key_get(struct net_device *ndev, u8 *key) { struct yk3_ndev_priv *ndev_priv = netdev_priv(ndev); struct yk3_pdev_priv *pdev_priv = ndev_priv->pdev_priv; @@ -190,6 +213,7 @@ void yk3_rss_key_get(struct net_device *ndev, u8 *key) void __iomem *hw_addr = pdev_priv->bar_addr[0] + YK3_RSS_BAR_BASE; u16 qstart = ndev_priv->qbase[YK3_QUEUE_T_GLOBAL].start; u32 qcount = ndev->real_num_rx_queues; + int ret; if (yk3_ndev_is_vf(ndev_priv)) { mbox_msg.opcode = YK3_MBOX_OPCODE_RSS_INDIRECT; @@ -200,13 +224,16 @@ void yk3_rss_key_get(struct net_device *ndev, u8 *key) cmd->qnb = (u16)(qcount); mbox_opt.wait_reply = MB_WAIT_REPLY; mbox_opt.timeout = 1000; - if (!yk3_mbox_send_msg(pdev_priv, &mbox_msg, &mbox_opt, &ack_msg)) { - ack_cmd = (struct yk3_mbox_rss_indir_cmd *)ack_msg.data; - memcpy(key, ack_cmd->cmd_data, YK3_RSS_HASH_KEY_SIZE); - } + ret = yk3_rss_send_msg(pdev_priv, &mbox_msg, &mbox_opt, &ack_msg); + if (ret) + return ret; + ack_cmd = (struct yk3_mbox_rss_indir_cmd *)ack_msg.data; + memcpy(key, ack_cmd->cmd_data, YK3_RSS_HASH_KEY_SIZE); } else { yk3_pf_hash_key_get(hw_addr, key); } + + return 0; } int yk3_rss_indir_table_init(struct yk3_ndev_priv *ndev_priv, u16 rxqnum) @@ -226,7 +253,7 @@ int yk3_rss_indir_table_init(struct yk3_ndev_priv *ndev_priv, u16 rxqnum) cmd->cmd_type = YK3_CMD_RSS_INDIRECT_TABLE_INIT; cmd->qstart = qstart; cmd->qnb = rxqnum; - return yk3_mbox_send_msg(pdev_priv, &mbox_msg, &mbox_opt, NULL); + return yk3_rss_send_msg(pdev_priv, &mbox_msg, &mbox_opt, NULL); } yk3_pf_rss_indir_table_default(hw_addr, qstart, rxqnum); diff --git a/drivers/net/ethernet/yusur/yk3/yk3_rss.h b/drivers/net/ethernet/yusur/yk3/yk3_rss.h index c5cde3b8cc8990984b25249aaed6aa77c7b02771..0cdf8e752f7571541bac4d4cca3c8e532017232d 100644 --- a/drivers/net/ethernet/yusur/yk3/yk3_rss.h +++ b/drivers/net/ethernet/yusur/yk3/yk3_rss.h @@ -3,10 +3,10 @@ #ifndef _YK3_RSS_H_ #define _YK3_RSS_H_ -void yk3_rss_indir_table_set(struct net_device *ndev, const u32 *indir, u16 qcount); -void yk3_rss_indir_table_get(struct net_device *ndev, u32 *indir); -void yk3_rss_key_set(struct net_device *ndev, const u8 *key); -void yk3_rss_key_get(struct net_device *ndev, u8 *key); +int yk3_rss_indir_table_set(struct net_device *ndev, const u32 *indir, u16 qcount); +int yk3_rss_indir_table_get(struct net_device *ndev, u32 *indir); +int yk3_rss_key_set(struct net_device *ndev, const u8 *key); +int yk3_rss_key_get(struct net_device *ndev, u8 *key); int yk3_rss_indir_table_init(struct yk3_ndev_priv *ndev_priv, u16 rxqnum); u32 yk3_rss_key_size(void); int yk3_rss_init(struct yk3_pdev_priv *pdev_priv);