Merge branch 'hns3-fixes'
Guangbin Huang says: ==================== net: hns3: add some fixes for -net This series adds some fixes for the HNS3 ethernet driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
424a4f52c5
@ -568,6 +568,7 @@ struct hnae3_ae_ops {
|
||||
u32 *auto_neg, u32 *rx_en, u32 *tx_en);
|
||||
int (*set_pauseparam)(struct hnae3_handle *handle,
|
||||
u32 auto_neg, u32 rx_en, u32 tx_en);
|
||||
int (*restore_pauseparam)(struct hnae3_handle *handle);
|
||||
|
||||
int (*set_autoneg)(struct hnae3_handle *handle, bool enable);
|
||||
int (*get_autoneg)(struct hnae3_handle *handle);
|
||||
|
@ -137,7 +137,7 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
|
||||
.name = "uc",
|
||||
.cmd = HNAE3_DBG_CMD_MAC_UC,
|
||||
.dentry = HNS3_DBG_DENTRY_MAC,
|
||||
.buf_len = HNS3_DBG_READ_LEN,
|
||||
.buf_len = HNS3_DBG_READ_LEN_128KB,
|
||||
.init = hns3_dbg_common_file_init,
|
||||
},
|
||||
{
|
||||
@ -256,7 +256,7 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
|
||||
.name = "tqp",
|
||||
.cmd = HNAE3_DBG_CMD_REG_TQP,
|
||||
.dentry = HNS3_DBG_DENTRY_REG,
|
||||
.buf_len = HNS3_DBG_READ_LEN,
|
||||
.buf_len = HNS3_DBG_READ_LEN_128KB,
|
||||
.init = hns3_dbg_common_file_init,
|
||||
},
|
||||
{
|
||||
@ -298,7 +298,7 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
|
||||
.name = "fd_tcam",
|
||||
.cmd = HNAE3_DBG_CMD_FD_TCAM,
|
||||
.dentry = HNS3_DBG_DENTRY_FD,
|
||||
.buf_len = HNS3_DBG_READ_LEN,
|
||||
.buf_len = HNS3_DBG_READ_LEN_1MB,
|
||||
.init = hns3_dbg_common_file_init,
|
||||
},
|
||||
{
|
||||
@ -462,7 +462,7 @@ static const struct hns3_dbg_item rx_queue_info_items[] = {
|
||||
{ "TAIL", 2 },
|
||||
{ "HEAD", 2 },
|
||||
{ "FBDNUM", 2 },
|
||||
{ "PKTNUM", 2 },
|
||||
{ "PKTNUM", 5 },
|
||||
{ "COPYBREAK", 2 },
|
||||
{ "RING_EN", 2 },
|
||||
{ "RX_RING_EN", 2 },
|
||||
@ -565,7 +565,7 @@ static const struct hns3_dbg_item tx_queue_info_items[] = {
|
||||
{ "HEAD", 2 },
|
||||
{ "FBDNUM", 2 },
|
||||
{ "OFFSET", 2 },
|
||||
{ "PKTNUM", 2 },
|
||||
{ "PKTNUM", 5 },
|
||||
{ "RING_EN", 2 },
|
||||
{ "TX_RING_EN", 2 },
|
||||
{ "BASE_ADDR", 10 },
|
||||
@ -790,13 +790,13 @@ static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
|
||||
}
|
||||
|
||||
static const struct hns3_dbg_item tx_bd_info_items[] = {
|
||||
{ "BD_IDX", 5 },
|
||||
{ "ADDRESS", 2 },
|
||||
{ "BD_IDX", 2 },
|
||||
{ "ADDRESS", 13 },
|
||||
{ "VLAN_TAG", 2 },
|
||||
{ "SIZE", 2 },
|
||||
{ "T_CS_VLAN_TSO", 2 },
|
||||
{ "OT_VLAN_TAG", 3 },
|
||||
{ "TV", 2 },
|
||||
{ "TV", 5 },
|
||||
{ "OLT_VLAN_LEN", 2 },
|
||||
{ "PAYLEN_OL4CS", 2 },
|
||||
{ "BD_FE_SC_VLD", 2 },
|
||||
|
@ -824,6 +824,26 @@ static int hns3_check_ksettings_param(const struct net_device *netdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns3_set_phy_link_ksettings(struct net_device *netdev,
|
||||
const struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
struct hnae3_handle *handle = hns3_get_handle(netdev);
|
||||
const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
|
||||
int ret;
|
||||
|
||||
if (cmd->base.speed == SPEED_1000 &&
|
||||
cmd->base.autoneg == AUTONEG_DISABLE)
|
||||
return -EINVAL;
|
||||
|
||||
if (cmd->base.autoneg == AUTONEG_DISABLE && ops->restore_pauseparam) {
|
||||
ret = ops->restore_pauseparam(handle);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return phy_ethtool_ksettings_set(netdev->phydev, cmd);
|
||||
}
|
||||
|
||||
static int hns3_set_link_ksettings(struct net_device *netdev,
|
||||
const struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
@ -842,16 +862,11 @@ static int hns3_set_link_ksettings(struct net_device *netdev,
|
||||
cmd->base.autoneg, cmd->base.speed, cmd->base.duplex);
|
||||
|
||||
/* Only support ksettings_set for netdev with phy attached for now */
|
||||
if (netdev->phydev) {
|
||||
if (cmd->base.speed == SPEED_1000 &&
|
||||
cmd->base.autoneg == AUTONEG_DISABLE)
|
||||
return -EINVAL;
|
||||
|
||||
return phy_ethtool_ksettings_set(netdev->phydev, cmd);
|
||||
} else if (test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps) &&
|
||||
ops->set_phy_link_ksettings) {
|
||||
if (netdev->phydev)
|
||||
return hns3_set_phy_link_ksettings(netdev, cmd);
|
||||
else if (test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps) &&
|
||||
ops->set_phy_link_ksettings)
|
||||
return ops->set_phy_link_ksettings(handle, cmd);
|
||||
}
|
||||
|
||||
if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -391,7 +391,7 @@ static int hclge_dbg_dump_mac(struct hclge_dev *hdev, char *buf, int len)
|
||||
static int hclge_dbg_dump_dcb_qset(struct hclge_dev *hdev, char *buf, int len,
|
||||
int *pos)
|
||||
{
|
||||
struct hclge_dbg_bitmap_cmd *bitmap;
|
||||
struct hclge_dbg_bitmap_cmd req;
|
||||
struct hclge_desc desc;
|
||||
u16 qset_id, qset_num;
|
||||
int ret;
|
||||
@ -408,12 +408,12 @@ static int hclge_dbg_dump_dcb_qset(struct hclge_dev *hdev, char *buf, int len,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bitmap = (struct hclge_dbg_bitmap_cmd *)&desc.data[1];
|
||||
req.bitmap = (u8)le32_to_cpu(desc.data[1]);
|
||||
|
||||
*pos += scnprintf(buf + *pos, len - *pos,
|
||||
"%04u %#x %#x %#x %#x\n",
|
||||
qset_id, bitmap->bit0, bitmap->bit1,
|
||||
bitmap->bit2, bitmap->bit3);
|
||||
qset_id, req.bit0, req.bit1, req.bit2,
|
||||
req.bit3);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -422,7 +422,7 @@ static int hclge_dbg_dump_dcb_qset(struct hclge_dev *hdev, char *buf, int len,
|
||||
static int hclge_dbg_dump_dcb_pri(struct hclge_dev *hdev, char *buf, int len,
|
||||
int *pos)
|
||||
{
|
||||
struct hclge_dbg_bitmap_cmd *bitmap;
|
||||
struct hclge_dbg_bitmap_cmd req;
|
||||
struct hclge_desc desc;
|
||||
u8 pri_id, pri_num;
|
||||
int ret;
|
||||
@ -439,12 +439,11 @@ static int hclge_dbg_dump_dcb_pri(struct hclge_dev *hdev, char *buf, int len,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bitmap = (struct hclge_dbg_bitmap_cmd *)&desc.data[1];
|
||||
req.bitmap = (u8)le32_to_cpu(desc.data[1]);
|
||||
|
||||
*pos += scnprintf(buf + *pos, len - *pos,
|
||||
"%03u %#x %#x %#x\n",
|
||||
pri_id, bitmap->bit0, bitmap->bit1,
|
||||
bitmap->bit2);
|
||||
pri_id, req.bit0, req.bit1, req.bit2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -453,7 +452,7 @@ static int hclge_dbg_dump_dcb_pri(struct hclge_dev *hdev, char *buf, int len,
|
||||
static int hclge_dbg_dump_dcb_pg(struct hclge_dev *hdev, char *buf, int len,
|
||||
int *pos)
|
||||
{
|
||||
struct hclge_dbg_bitmap_cmd *bitmap;
|
||||
struct hclge_dbg_bitmap_cmd req;
|
||||
struct hclge_desc desc;
|
||||
u8 pg_id;
|
||||
int ret;
|
||||
@ -466,12 +465,11 @@ static int hclge_dbg_dump_dcb_pg(struct hclge_dev *hdev, char *buf, int len,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bitmap = (struct hclge_dbg_bitmap_cmd *)&desc.data[1];
|
||||
req.bitmap = (u8)le32_to_cpu(desc.data[1]);
|
||||
|
||||
*pos += scnprintf(buf + *pos, len - *pos,
|
||||
"%03u %#x %#x %#x\n",
|
||||
pg_id, bitmap->bit0, bitmap->bit1,
|
||||
bitmap->bit2);
|
||||
pg_id, req.bit0, req.bit1, req.bit2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -511,7 +509,7 @@ static int hclge_dbg_dump_dcb_queue(struct hclge_dev *hdev, char *buf, int len,
|
||||
static int hclge_dbg_dump_dcb_port(struct hclge_dev *hdev, char *buf, int len,
|
||||
int *pos)
|
||||
{
|
||||
struct hclge_dbg_bitmap_cmd *bitmap;
|
||||
struct hclge_dbg_bitmap_cmd req;
|
||||
struct hclge_desc desc;
|
||||
u8 port_id = 0;
|
||||
int ret;
|
||||
@ -521,12 +519,12 @@ static int hclge_dbg_dump_dcb_port(struct hclge_dev *hdev, char *buf, int len,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bitmap = (struct hclge_dbg_bitmap_cmd *)&desc.data[1];
|
||||
req.bitmap = (u8)le32_to_cpu(desc.data[1]);
|
||||
|
||||
*pos += scnprintf(buf + *pos, len - *pos, "port_mask: %#x\n",
|
||||
bitmap->bit0);
|
||||
req.bit0);
|
||||
*pos += scnprintf(buf + *pos, len - *pos, "port_shaping_pass: %#x\n",
|
||||
bitmap->bit1);
|
||||
req.bit1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2847,33 +2847,29 @@ static void hclge_mbx_task_schedule(struct hclge_dev *hdev)
|
||||
{
|
||||
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
|
||||
!test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state))
|
||||
mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
|
||||
hclge_wq, &hdev->service_task, 0);
|
||||
mod_delayed_work(hclge_wq, &hdev->service_task, 0);
|
||||
}
|
||||
|
||||
static void hclge_reset_task_schedule(struct hclge_dev *hdev)
|
||||
{
|
||||
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
|
||||
test_bit(HCLGE_STATE_SERVICE_INITED, &hdev->state) &&
|
||||
!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
|
||||
mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
|
||||
hclge_wq, &hdev->service_task, 0);
|
||||
mod_delayed_work(hclge_wq, &hdev->service_task, 0);
|
||||
}
|
||||
|
||||
static void hclge_errhand_task_schedule(struct hclge_dev *hdev)
|
||||
{
|
||||
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
|
||||
!test_and_set_bit(HCLGE_STATE_ERR_SERVICE_SCHED, &hdev->state))
|
||||
mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
|
||||
hclge_wq, &hdev->service_task, 0);
|
||||
mod_delayed_work(hclge_wq, &hdev->service_task, 0);
|
||||
}
|
||||
|
||||
void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time)
|
||||
{
|
||||
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
|
||||
!test_bit(HCLGE_STATE_RST_FAIL, &hdev->state))
|
||||
mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
|
||||
hclge_wq, &hdev->service_task,
|
||||
delay_time);
|
||||
mod_delayed_work(hclge_wq, &hdev->service_task, delay_time);
|
||||
}
|
||||
|
||||
static int hclge_get_mac_link_status(struct hclge_dev *hdev, int *link_status)
|
||||
@ -3491,33 +3487,14 @@ static void hclge_get_misc_vector(struct hclge_dev *hdev)
|
||||
hdev->num_msi_used += 1;
|
||||
}
|
||||
|
||||
static void hclge_irq_affinity_notify(struct irq_affinity_notify *notify,
|
||||
const cpumask_t *mask)
|
||||
{
|
||||
struct hclge_dev *hdev = container_of(notify, struct hclge_dev,
|
||||
affinity_notify);
|
||||
|
||||
cpumask_copy(&hdev->affinity_mask, mask);
|
||||
}
|
||||
|
||||
static void hclge_irq_affinity_release(struct kref *ref)
|
||||
{
|
||||
}
|
||||
|
||||
static void hclge_misc_affinity_setup(struct hclge_dev *hdev)
|
||||
{
|
||||
irq_set_affinity_hint(hdev->misc_vector.vector_irq,
|
||||
&hdev->affinity_mask);
|
||||
|
||||
hdev->affinity_notify.notify = hclge_irq_affinity_notify;
|
||||
hdev->affinity_notify.release = hclge_irq_affinity_release;
|
||||
irq_set_affinity_notifier(hdev->misc_vector.vector_irq,
|
||||
&hdev->affinity_notify);
|
||||
}
|
||||
|
||||
static void hclge_misc_affinity_teardown(struct hclge_dev *hdev)
|
||||
{
|
||||
irq_set_affinity_notifier(hdev->misc_vector.vector_irq, NULL);
|
||||
irq_set_affinity_hint(hdev->misc_vector.vector_irq, NULL);
|
||||
}
|
||||
|
||||
@ -11021,6 +10998,35 @@ static int hclge_set_pauseparam(struct hnae3_handle *handle, u32 auto_neg,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int hclge_restore_pauseparam(struct hnae3_handle *handle)
|
||||
{
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
u32 auto_neg, rx_pause, tx_pause;
|
||||
int ret;
|
||||
|
||||
hclge_get_pauseparam(handle, &auto_neg, &rx_pause, &tx_pause);
|
||||
/* when autoneg is disabled, the pause setting of phy has no effect
|
||||
* unless the link goes down.
|
||||
*/
|
||||
ret = phy_suspend(hdev->hw.mac.phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
phy_set_asym_pause(hdev->hw.mac.phydev, rx_pause, tx_pause);
|
||||
|
||||
ret = phy_resume(hdev->hw.mac.phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = hclge_mac_pause_setup_hw(hdev);
|
||||
if (ret)
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"restore pauseparam error, ret = %d.\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hclge_get_ksettings_an_result(struct hnae3_handle *handle,
|
||||
u8 *auto_neg, u32 *speed, u8 *duplex)
|
||||
{
|
||||
@ -12984,6 +12990,7 @@ static const struct hnae3_ae_ops hclge_ops = {
|
||||
.halt_autoneg = hclge_halt_autoneg,
|
||||
.get_pauseparam = hclge_get_pauseparam,
|
||||
.set_pauseparam = hclge_set_pauseparam,
|
||||
.restore_pauseparam = hclge_restore_pauseparam,
|
||||
.set_mtu = hclge_set_mtu,
|
||||
.reset_queue = hclge_reset_tqp,
|
||||
.get_stats = hclge_get_stats,
|
||||
@ -13052,7 +13059,7 @@ static int hclge_init(void)
|
||||
{
|
||||
pr_info("%s is initializing\n", HCLGE_NAME);
|
||||
|
||||
hclge_wq = alloc_workqueue("%s", 0, 0, HCLGE_NAME);
|
||||
hclge_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, HCLGE_NAME);
|
||||
if (!hclge_wq) {
|
||||
pr_err("%s: failed to create workqueue\n", HCLGE_NAME);
|
||||
return -ENOMEM;
|
||||
|
@ -944,7 +944,6 @@ struct hclge_dev {
|
||||
|
||||
/* affinity mask and notify for misc interrupt */
|
||||
cpumask_t affinity_mask;
|
||||
struct irq_affinity_notify affinity_notify;
|
||||
struct hclge_ptp *ptp;
|
||||
struct devlink *devlink;
|
||||
};
|
||||
|
@ -1435,7 +1435,7 @@ static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev)
|
||||
int hclge_mac_pause_setup_hw(struct hclge_dev *hdev)
|
||||
{
|
||||
bool tx_en, rx_en;
|
||||
|
||||
|
@ -244,6 +244,7 @@ int hclge_tm_get_pri_weight(struct hclge_dev *hdev, u8 pri_id, u8 *weight);
|
||||
int hclge_tm_get_pri_shaper(struct hclge_dev *hdev, u8 pri_id,
|
||||
enum hclge_opcode_type cmd,
|
||||
struct hclge_tm_shaper_para *para);
|
||||
int hclge_mac_pause_setup_hw(struct hclge_dev *hdev);
|
||||
int hclge_tm_get_q_to_qs_map(struct hclge_dev *hdev, u16 q_id, u16 *qset_id);
|
||||
int hclge_tm_get_q_to_tc(struct hclge_dev *hdev, u16 q_id, u8 *tc_id);
|
||||
int hclge_tm_get_pg_to_pri_map(struct hclge_dev *hdev, u8 pg_id,
|
||||
|
@ -2232,6 +2232,7 @@ static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev)
|
||||
void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev)
|
||||
{
|
||||
if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) &&
|
||||
test_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state) &&
|
||||
!test_and_set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED,
|
||||
&hdev->state))
|
||||
mod_delayed_work(hclgevf_wq, &hdev->service_task, 0);
|
||||
@ -3449,6 +3450,8 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
|
||||
|
||||
hclgevf_init_rxd_adv_layout(hdev);
|
||||
|
||||
set_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state);
|
||||
|
||||
hdev->last_reset_time = jiffies;
|
||||
dev_info(&hdev->pdev->dev, "finished initializing %s driver\n",
|
||||
HCLGEVF_DRIVER_NAME);
|
||||
@ -3899,7 +3902,7 @@ static int hclgevf_init(void)
|
||||
{
|
||||
pr_info("%s is initializing\n", HCLGEVF_NAME);
|
||||
|
||||
hclgevf_wq = alloc_workqueue("%s", 0, 0, HCLGEVF_NAME);
|
||||
hclgevf_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, HCLGEVF_NAME);
|
||||
if (!hclgevf_wq) {
|
||||
pr_err("%s: failed to create workqueue\n", HCLGEVF_NAME);
|
||||
return -ENOMEM;
|
||||
|
@ -146,6 +146,7 @@ enum hclgevf_states {
|
||||
HCLGEVF_STATE_REMOVING,
|
||||
HCLGEVF_STATE_NIC_REGISTERED,
|
||||
HCLGEVF_STATE_ROCE_REGISTERED,
|
||||
HCLGEVF_STATE_SERVICE_INITED,
|
||||
/* task states */
|
||||
HCLGEVF_STATE_RST_SERVICE_SCHED,
|
||||
HCLGEVF_STATE_RST_HANDLING,
|
||||
|
Loading…
x
Reference in New Issue
Block a user