Commit 4ee5489e authored by David S. Miller's avatar David S. Miller

Merge branch 'hns3-fixes'

Salil Mehta says:

====================
Misc. bug fixes & small enhancements for HNS3 Driver

This patch-set presents some fixes and minor enhancements to HNS3 Driver
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 05a6843c 12f46bc1
...@@ -1662,11 +1662,24 @@ static int hns3_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) ...@@ -1662,11 +1662,24 @@ static int hns3_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
return 0; return 0;
} }
static void hns3_shutdown(struct pci_dev *pdev)
{
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
hnae3_unregister_ae_dev(ae_dev);
devm_kfree(&pdev->dev, ae_dev);
pci_set_drvdata(pdev, NULL);
if (system_state == SYSTEM_POWER_OFF)
pci_set_power_state(pdev, PCI_D3hot);
}
static struct pci_driver hns3_driver = { static struct pci_driver hns3_driver = {
.name = hns3_driver_name, .name = hns3_driver_name,
.id_table = hns3_pci_tbl, .id_table = hns3_pci_tbl,
.probe = hns3_probe, .probe = hns3_probe,
.remove = hns3_remove, .remove = hns3_remove,
.shutdown = hns3_shutdown,
.sriov_configure = hns3_pci_sriov_configure, .sriov_configure = hns3_pci_sriov_configure,
}; };
......
...@@ -100,41 +100,26 @@ static int hns3_lp_up(struct net_device *ndev, enum hnae3_loop loop_mode) ...@@ -100,41 +100,26 @@ static int hns3_lp_up(struct net_device *ndev, enum hnae3_loop loop_mode)
struct hnae3_handle *h = hns3_get_handle(ndev); struct hnae3_handle *h = hns3_get_handle(ndev);
int ret; int ret;
if (!h->ae_algo->ops->start)
return -EOPNOTSUPP;
ret = hns3_nic_reset_all_ring(h); ret = hns3_nic_reset_all_ring(h);
if (ret) if (ret)
return ret; return ret;
ret = h->ae_algo->ops->start(h);
if (ret) {
netdev_err(ndev,
"hns3_lb_up ae start return error: %d\n", ret);
return ret;
}
ret = hns3_lp_setup(ndev, loop_mode, true); ret = hns3_lp_setup(ndev, loop_mode, true);
usleep_range(10000, 20000); usleep_range(10000, 20000);
return ret; return 0;
} }
static int hns3_lp_down(struct net_device *ndev, enum hnae3_loop loop_mode) static int hns3_lp_down(struct net_device *ndev, enum hnae3_loop loop_mode)
{ {
struct hnae3_handle *h = hns3_get_handle(ndev);
int ret; int ret;
if (!h->ae_algo->ops->stop)
return -EOPNOTSUPP;
ret = hns3_lp_setup(ndev, loop_mode, false); ret = hns3_lp_setup(ndev, loop_mode, false);
if (ret) { if (ret) {
netdev_err(ndev, "lb_setup return error: %d\n", ret); netdev_err(ndev, "lb_setup return error: %d\n", ret);
return ret; return ret;
} }
h->ae_algo->ops->stop(h);
usleep_range(10000, 20000); usleep_range(10000, 20000);
return 0; return 0;
...@@ -152,6 +137,7 @@ static void hns3_lp_setup_skb(struct sk_buff *skb) ...@@ -152,6 +137,7 @@ static void hns3_lp_setup_skb(struct sk_buff *skb)
packet = skb_put(skb, HNS3_NIC_LB_TEST_PACKET_SIZE); packet = skb_put(skb, HNS3_NIC_LB_TEST_PACKET_SIZE);
memcpy(ethh->h_dest, ndev->dev_addr, ETH_ALEN); memcpy(ethh->h_dest, ndev->dev_addr, ETH_ALEN);
ethh->h_dest[5] += 0x1f;
eth_zero_addr(ethh->h_source); eth_zero_addr(ethh->h_source);
ethh->h_proto = htons(ETH_P_ARP); ethh->h_proto = htons(ETH_P_ARP);
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
...@@ -309,7 +295,7 @@ static void hns3_self_test(struct net_device *ndev, ...@@ -309,7 +295,7 @@ static void hns3_self_test(struct net_device *ndev,
h->flags & HNAE3_SUPPORT_SERDES_LOOPBACK; h->flags & HNAE3_SUPPORT_SERDES_LOOPBACK;
if (if_running) if (if_running)
dev_close(ndev); ndev->netdev_ops->ndo_stop(ndev);
#if IS_ENABLED(CONFIG_VLAN_8021Q) #if IS_ENABLED(CONFIG_VLAN_8021Q)
/* Disable the vlan filter for selftest does not support it */ /* Disable the vlan filter for selftest does not support it */
...@@ -347,7 +333,7 @@ static void hns3_self_test(struct net_device *ndev, ...@@ -347,7 +333,7 @@ static void hns3_self_test(struct net_device *ndev,
#endif #endif
if (if_running) if (if_running)
dev_open(ndev); ndev->netdev_ops->ndo_open(ndev);
} }
static int hns3_get_sset_count(struct net_device *netdev, int stringset) static int hns3_get_sset_count(struct net_device *netdev, int stringset)
...@@ -560,62 +546,62 @@ static int hns3_get_link_ksettings(struct net_device *netdev, ...@@ -560,62 +546,62 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *cmd) struct ethtool_link_ksettings *cmd)
{ {
struct hnae3_handle *h = hns3_get_handle(netdev); struct hnae3_handle *h = hns3_get_handle(netdev);
u32 flowctrl_adv = 0; const struct hnae3_ae_ops *ops;
u8 link_stat; u8 link_stat;
if (!h->ae_algo || !h->ae_algo->ops) if (!h->ae_algo || !h->ae_algo->ops)
return -EOPNOTSUPP; return -EOPNOTSUPP;
/* 1.auto_neg & speed & duplex from cmd */ ops = h->ae_algo->ops;
if (netdev->phydev) { if (ops->get_port_type)
phy_ethtool_ksettings_get(netdev->phydev, cmd); ops->get_port_type(h, &cmd->base.port);
else
return 0; return -EOPNOTSUPP;
}
if (h->ae_algo->ops->get_ksettings_an_result) switch (cmd->base.port) {
h->ae_algo->ops->get_ksettings_an_result(h, case PORT_FIBRE:
/* 1.auto_neg & speed & duplex from cmd */
if (ops->get_ksettings_an_result)
ops->get_ksettings_an_result(h,
&cmd->base.autoneg, &cmd->base.autoneg,
&cmd->base.speed, &cmd->base.speed,
&cmd->base.duplex); &cmd->base.duplex);
else else
return -EOPNOTSUPP; return -EOPNOTSUPP;
link_stat = hns3_get_link(netdev); /* 2.get link mode*/
if (!link_stat) { if (ops->get_link_mode)
cmd->base.speed = SPEED_UNKNOWN; ops->get_link_mode(h,
cmd->base.duplex = DUPLEX_UNKNOWN;
}
/* 2.get link mode and port type*/
if (h->ae_algo->ops->get_link_mode)
h->ae_algo->ops->get_link_mode(h,
cmd->link_modes.supported, cmd->link_modes.supported,
cmd->link_modes.advertising); cmd->link_modes.advertising);
cmd->base.port = PORT_NONE;
if (h->ae_algo->ops->get_port_type)
h->ae_algo->ops->get_port_type(h,
&cmd->base.port);
/* 3.mdix_ctrl&mdix get from phy reg */ /* 3.mdix_ctrl&mdix get from phy reg */
if (h->ae_algo->ops->get_mdix_mode) if (ops->get_mdix_mode)
h->ae_algo->ops->get_mdix_mode(h, &cmd->base.eth_tp_mdix_ctrl, ops->get_mdix_mode(h, &cmd->base.eth_tp_mdix_ctrl,
&cmd->base.eth_tp_mdix); &cmd->base.eth_tp_mdix);
/* 4.mdio_support */
cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C22;
/* 5.get flow control setttings */ break;
if (h->ae_algo->ops->get_flowctrl_adv) case PORT_TP:
h->ae_algo->ops->get_flowctrl_adv(h, &flowctrl_adv); if (!netdev->phydev)
return -EOPNOTSUPP;
phy_ethtool_ksettings_get(netdev->phydev, cmd);
break;
default:
netdev_warn(netdev,
"Unknown port type, neither Fibre/Copper detected");
return 0;
}
if (flowctrl_adv & ADVERTISED_Pause) /* mdio_support */
ethtool_link_ksettings_add_link_mode(cmd, advertising, cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C22;
Pause);
if (flowctrl_adv & ADVERTISED_Asym_Pause) link_stat = hns3_get_link(netdev);
ethtool_link_ksettings_add_link_mode(cmd, advertising, if (!link_stat) {
Asym_Pause); cmd->base.speed = SPEED_UNKNOWN;
cmd->base.duplex = DUPLEX_UNKNOWN;
}
return 0; return 0;
} }
......
...@@ -2066,19 +2066,17 @@ static int hclge_init_msi(struct hclge_dev *hdev) ...@@ -2066,19 +2066,17 @@ static int hclge_init_msi(struct hclge_dev *hdev)
return 0; return 0;
} }
static void hclge_check_speed_dup(struct hclge_dev *hdev, int duplex, int speed) static u8 hclge_check_speed_dup(u8 duplex, int speed)
{ {
struct hclge_mac *mac = &hdev->hw.mac;
if ((speed == HCLGE_MAC_SPEED_10M) || (speed == HCLGE_MAC_SPEED_100M)) if (!(speed == HCLGE_MAC_SPEED_10M || speed == HCLGE_MAC_SPEED_100M))
mac->duplex = (u8)duplex; duplex = HCLGE_MAC_FULL;
else
mac->duplex = HCLGE_MAC_FULL;
mac->speed = speed; return duplex;
} }
int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex) static int hclge_cfg_mac_speed_dup_hw(struct hclge_dev *hdev, int speed,
u8 duplex)
{ {
struct hclge_config_mac_speed_dup_cmd *req; struct hclge_config_mac_speed_dup_cmd *req;
struct hclge_desc desc; struct hclge_desc desc;
...@@ -2138,7 +2136,23 @@ int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex) ...@@ -2138,7 +2136,23 @@ int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex)
return ret; return ret;
} }
hclge_check_speed_dup(hdev, duplex, speed); return 0;
}
int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex)
{
int ret;
duplex = hclge_check_speed_dup(duplex, speed);
if (hdev->hw.mac.speed == speed && hdev->hw.mac.duplex == duplex)
return 0;
ret = hclge_cfg_mac_speed_dup_hw(hdev, speed, duplex);
if (ret)
return ret;
hdev->hw.mac.speed = speed;
hdev->hw.mac.duplex = duplex;
return 0; return 0;
} }
...@@ -2259,7 +2273,9 @@ static int hclge_mac_init(struct hclge_dev *hdev) ...@@ -2259,7 +2273,9 @@ static int hclge_mac_init(struct hclge_dev *hdev)
int ret; int ret;
int i; int i;
ret = hclge_cfg_mac_speed_dup(hdev, hdev->hw.mac.speed, HCLGE_MAC_FULL); hdev->hw.mac.duplex = HCLGE_MAC_FULL;
ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed,
hdev->hw.mac.duplex);
if (ret) { if (ret) {
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"Config mac speed dup fail ret=%d\n", ret); "Config mac speed dup fail ret=%d\n", ret);
...@@ -2415,14 +2431,12 @@ static int hclge_update_speed_duplex(struct hclge_dev *hdev) ...@@ -2415,14 +2431,12 @@ static int hclge_update_speed_duplex(struct hclge_dev *hdev)
return ret; return ret;
} }
if ((mac.speed != speed) || (mac.duplex != duplex)) {
ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex); ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex);
if (ret) { if (ret) {
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"mac speed/duplex config failed %d\n", ret); "mac speed/duplex config failed %d\n", ret);
return ret; return ret;
} }
}
return 0; return 0;
} }
...@@ -3659,6 +3673,8 @@ static int hclge_set_mac_loopback(struct hclge_dev *hdev, bool en) ...@@ -3659,6 +3673,8 @@ static int hclge_set_mac_loopback(struct hclge_dev *hdev, bool en)
/* 2 Then setup the loopback flag */ /* 2 Then setup the loopback flag */
loop_en = le32_to_cpu(req->txrx_pad_fcs_loop_en); loop_en = le32_to_cpu(req->txrx_pad_fcs_loop_en);
hnae3_set_bit(loop_en, HCLGE_MAC_APP_LP_B, en ? 1 : 0); hnae3_set_bit(loop_en, HCLGE_MAC_APP_LP_B, en ? 1 : 0);
hnae3_set_bit(loop_en, HCLGE_MAC_TX_EN_B, en ? 1 : 0);
hnae3_set_bit(loop_en, HCLGE_MAC_RX_EN_B, en ? 1 : 0);
req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en); req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en);
...@@ -3719,15 +3735,36 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en) ...@@ -3719,15 +3735,36 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en)
return -EIO; return -EIO;
} }
hclge_cfg_mac_mode(hdev, en);
return 0; return 0;
} }
static int hclge_tqp_enable(struct hclge_dev *hdev, int tqp_id,
int stream_id, bool enable)
{
struct hclge_desc desc;
struct hclge_cfg_com_tqp_queue_cmd *req =
(struct hclge_cfg_com_tqp_queue_cmd *)desc.data;
int ret;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_COM_TQP_QUEUE, false);
req->tqp_id = cpu_to_le16(tqp_id & HCLGE_RING_ID_MASK);
req->stream_id = cpu_to_le16(stream_id);
req->enable |= enable << HCLGE_TQP_ENABLE_B;
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret)
dev_err(&hdev->pdev->dev,
"Tqp enable fail, status =%d.\n", ret);
return ret;
}
static int hclge_set_loopback(struct hnae3_handle *handle, static int hclge_set_loopback(struct hnae3_handle *handle,
enum hnae3_loop loop_mode, bool en) enum hnae3_loop loop_mode, bool en)
{ {
struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
int ret; int i, ret;
switch (loop_mode) { switch (loop_mode) {
case HNAE3_MAC_INTER_LOOP_MAC: case HNAE3_MAC_INTER_LOOP_MAC:
...@@ -3743,27 +3780,13 @@ static int hclge_set_loopback(struct hnae3_handle *handle, ...@@ -3743,27 +3780,13 @@ static int hclge_set_loopback(struct hnae3_handle *handle,
break; break;
} }
return ret; for (i = 0; i < vport->alloc_tqps; i++) {
} ret = hclge_tqp_enable(hdev, i, 0, en);
static int hclge_tqp_enable(struct hclge_dev *hdev, int tqp_id,
int stream_id, bool enable)
{
struct hclge_desc desc;
struct hclge_cfg_com_tqp_queue_cmd *req =
(struct hclge_cfg_com_tqp_queue_cmd *)desc.data;
int ret;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_COM_TQP_QUEUE, false);
req->tqp_id = cpu_to_le16(tqp_id & HCLGE_RING_ID_MASK);
req->stream_id = cpu_to_le16(stream_id);
req->enable |= enable << HCLGE_TQP_ENABLE_B;
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) if (ret)
dev_err(&hdev->pdev->dev,
"Tqp enable fail, status =%d.\n", ret);
return ret; return ret;
}
return 0;
} }
static void hclge_reset_tqp_stats(struct hnae3_handle *handle) static void hclge_reset_tqp_stats(struct hnae3_handle *handle)
...@@ -4362,7 +4385,7 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport, ...@@ -4362,7 +4385,7 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport,
hnae3_set_bit(req.flags, HCLGE_MAC_VLAN_BIT0_EN_B, 1); hnae3_set_bit(req.flags, HCLGE_MAC_VLAN_BIT0_EN_B, 1);
hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0); hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0);
hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT1_EN_B, 1); hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT1_EN_B, 1);
hnae3_set_bit(req.mc_mac_en, HCLGE_MAC_VLAN_BIT0_EN_B, 0); hnae3_set_bit(req.mc_mac_en, HCLGE_MAC_VLAN_BIT0_EN_B, 1);
hclge_prepare_mac_addr(&req, addr); hclge_prepare_mac_addr(&req, addr);
status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true); status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true);
if (!status) { if (!status) {
...@@ -4429,7 +4452,7 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport, ...@@ -4429,7 +4452,7 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport,
hnae3_set_bit(req.flags, HCLGE_MAC_VLAN_BIT0_EN_B, 1); hnae3_set_bit(req.flags, HCLGE_MAC_VLAN_BIT0_EN_B, 1);
hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0); hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0);
hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT1_EN_B, 1); hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT1_EN_B, 1);
hnae3_set_bit(req.mc_mac_en, HCLGE_MAC_VLAN_BIT0_EN_B, 0); hnae3_set_bit(req.mc_mac_en, HCLGE_MAC_VLAN_BIT0_EN_B, 1);
hclge_prepare_mac_addr(&req, addr); hclge_prepare_mac_addr(&req, addr);
status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true); status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true);
if (!status) { if (!status) {
...@@ -4686,9 +4709,17 @@ static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid, ...@@ -4686,9 +4709,17 @@ static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
"Add vf vlan filter fail, ret =%d.\n", "Add vf vlan filter fail, ret =%d.\n",
req0->resp_code); req0->resp_code);
} else { } else {
#define HCLGE_VF_VLAN_DEL_NO_FOUND 1
if (!req0->resp_code) if (!req0->resp_code)
return 0; return 0;
if (req0->resp_code == HCLGE_VF_VLAN_DEL_NO_FOUND) {
dev_warn(&hdev->pdev->dev,
"vlan %d filter is not in vf vlan table\n",
vlan);
return 0;
}
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"Kill vf vlan filter fail, ret =%d.\n", "Kill vf vlan filter fail, ret =%d.\n",
req0->resp_code); req0->resp_code);
...@@ -4732,6 +4763,9 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto, ...@@ -4732,6 +4763,9 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
u16 vport_idx, vport_num = 0; u16 vport_idx, vport_num = 0;
int ret; int ret;
if (is_kill && !vlan_id)
return 0;
ret = hclge_set_vf_vlan_common(hdev, vport_id, is_kill, vlan_id, ret = hclge_set_vf_vlan_common(hdev, vport_id, is_kill, vlan_id,
0, proto); 0, proto);
if (ret) { if (ret) {
...@@ -4761,7 +4795,7 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto, ...@@ -4761,7 +4795,7 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
return -EINVAL; return -EINVAL;
} }
for_each_set_bit(vport_idx, hdev->vlan_table[vlan_id], VLAN_N_VID) for_each_set_bit(vport_idx, hdev->vlan_table[vlan_id], HCLGE_VPORT_NUM)
vport_num++; vport_num++;
if ((is_kill && vport_num == 0) || (!is_kill && vport_num == 1)) if ((is_kill && vport_num == 0) || (!is_kill && vport_num == 1))
...@@ -5187,20 +5221,6 @@ static u32 hclge_get_fw_version(struct hnae3_handle *handle) ...@@ -5187,20 +5221,6 @@ static u32 hclge_get_fw_version(struct hnae3_handle *handle)
return hdev->fw_version; return hdev->fw_version;
} }
static void hclge_get_flowctrl_adv(struct hnae3_handle *handle,
u32 *flowctrl_adv)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
struct phy_device *phydev = hdev->hw.mac.phydev;
if (!phydev)
return;
*flowctrl_adv |= (phydev->advertising & ADVERTISED_Pause) |
(phydev->advertising & ADVERTISED_Asym_Pause);
}
static void hclge_set_flowctrl_adv(struct hclge_dev *hdev, u32 rx_en, u32 tx_en) static void hclge_set_flowctrl_adv(struct hclge_dev *hdev, u32 rx_en, u32 tx_en)
{ {
struct phy_device *phydev = hdev->hw.mac.phydev; struct phy_device *phydev = hdev->hw.mac.phydev;
...@@ -6301,7 +6321,6 @@ static const struct hnae3_ae_ops hclge_ops = { ...@@ -6301,7 +6321,6 @@ static const struct hnae3_ae_ops hclge_ops = {
.get_tqps_and_rss_info = hclge_get_tqps_and_rss_info, .get_tqps_and_rss_info = hclge_get_tqps_and_rss_info,
.set_channels = hclge_set_channels, .set_channels = hclge_set_channels,
.get_channels = hclge_get_channels, .get_channels = hclge_get_channels,
.get_flowctrl_adv = hclge_get_flowctrl_adv,
.get_regs_len = hclge_get_regs_len, .get_regs_len = hclge_get_regs_len,
.get_regs = hclge_get_regs, .get_regs = hclge_get_regs,
.set_led_id = hclge_set_led_id, .set_led_id = hclge_set_led_id,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment