mirror of https://gitee.com/openkylin/linux.git
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
4ee5489e54
|
@ -1662,11 +1662,24 @@ static int hns3_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
|
|||
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 = {
|
||||
.name = hns3_driver_name,
|
||||
.id_table = hns3_pci_tbl,
|
||||
.probe = hns3_probe,
|
||||
.remove = hns3_remove,
|
||||
.shutdown = hns3_shutdown,
|
||||
.sriov_configure = hns3_pci_sriov_configure,
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
int ret;
|
||||
|
||||
if (!h->ae_algo->ops->start)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = hns3_nic_reset_all_ring(h);
|
||||
if (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);
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns3_lp_down(struct net_device *ndev, enum hnae3_loop loop_mode)
|
||||
{
|
||||
struct hnae3_handle *h = hns3_get_handle(ndev);
|
||||
int ret;
|
||||
|
||||
if (!h->ae_algo->ops->stop)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = hns3_lp_setup(ndev, loop_mode, false);
|
||||
if (ret) {
|
||||
netdev_err(ndev, "lb_setup return error: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
h->ae_algo->ops->stop(h);
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
return 0;
|
||||
|
@ -152,6 +137,7 @@ static void hns3_lp_setup_skb(struct sk_buff *skb)
|
|||
packet = skb_put(skb, HNS3_NIC_LB_TEST_PACKET_SIZE);
|
||||
|
||||
memcpy(ethh->h_dest, ndev->dev_addr, ETH_ALEN);
|
||||
ethh->h_dest[5] += 0x1f;
|
||||
eth_zero_addr(ethh->h_source);
|
||||
ethh->h_proto = htons(ETH_P_ARP);
|
||||
skb_reset_mac_header(skb);
|
||||
|
@ -309,7 +295,7 @@ static void hns3_self_test(struct net_device *ndev,
|
|||
h->flags & HNAE3_SUPPORT_SERDES_LOOPBACK;
|
||||
|
||||
if (if_running)
|
||||
dev_close(ndev);
|
||||
ndev->netdev_ops->ndo_stop(ndev);
|
||||
|
||||
#if IS_ENABLED(CONFIG_VLAN_8021Q)
|
||||
/* Disable the vlan filter for selftest does not support it */
|
||||
|
@ -347,7 +333,7 @@ static void hns3_self_test(struct net_device *ndev,
|
|||
#endif
|
||||
|
||||
if (if_running)
|
||||
dev_open(ndev);
|
||||
ndev->netdev_ops->ndo_open(ndev);
|
||||
}
|
||||
|
||||
static int hns3_get_sset_count(struct net_device *netdev, int stringset)
|
||||
|
@ -560,26 +546,56 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
|
|||
struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
struct hnae3_handle *h = hns3_get_handle(netdev);
|
||||
u32 flowctrl_adv = 0;
|
||||
const struct hnae3_ae_ops *ops;
|
||||
u8 link_stat;
|
||||
|
||||
if (!h->ae_algo || !h->ae_algo->ops)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* 1.auto_neg & speed & duplex from cmd */
|
||||
if (netdev->phydev) {
|
||||
ops = h->ae_algo->ops;
|
||||
if (ops->get_port_type)
|
||||
ops->get_port_type(h, &cmd->base.port);
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (cmd->base.port) {
|
||||
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.speed,
|
||||
&cmd->base.duplex);
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* 2.get link mode*/
|
||||
if (ops->get_link_mode)
|
||||
ops->get_link_mode(h,
|
||||
cmd->link_modes.supported,
|
||||
cmd->link_modes.advertising);
|
||||
|
||||
/* 3.mdix_ctrl&mdix get from phy reg */
|
||||
if (ops->get_mdix_mode)
|
||||
ops->get_mdix_mode(h, &cmd->base.eth_tp_mdix_ctrl,
|
||||
&cmd->base.eth_tp_mdix);
|
||||
|
||||
break;
|
||||
case PORT_TP:
|
||||
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 (h->ae_algo->ops->get_ksettings_an_result)
|
||||
h->ae_algo->ops->get_ksettings_an_result(h,
|
||||
&cmd->base.autoneg,
|
||||
&cmd->base.speed,
|
||||
&cmd->base.duplex);
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
/* mdio_support */
|
||||
cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C22;
|
||||
|
||||
link_stat = hns3_get_link(netdev);
|
||||
if (!link_stat) {
|
||||
|
@ -587,36 +603,6 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
|
|||
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.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 */
|
||||
if (h->ae_algo->ops->get_mdix_mode)
|
||||
h->ae_algo->ops->get_mdix_mode(h, &cmd->base.eth_tp_mdix_ctrl,
|
||||
&cmd->base.eth_tp_mdix);
|
||||
/* 4.mdio_support */
|
||||
cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C22;
|
||||
|
||||
/* 5.get flow control setttings */
|
||||
if (h->ae_algo->ops->get_flowctrl_adv)
|
||||
h->ae_algo->ops->get_flowctrl_adv(h, &flowctrl_adv);
|
||||
|
||||
if (flowctrl_adv & ADVERTISED_Pause)
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
Pause);
|
||||
|
||||
if (flowctrl_adv & ADVERTISED_Asym_Pause)
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
Asym_Pause);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2066,19 +2066,17 @@ static int hclge_init_msi(struct hclge_dev *hdev)
|
|||
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))
|
||||
mac->duplex = (u8)duplex;
|
||||
else
|
||||
mac->duplex = HCLGE_MAC_FULL;
|
||||
if (!(speed == HCLGE_MAC_SPEED_10M || speed == HCLGE_MAC_SPEED_100M))
|
||||
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_desc desc;
|
||||
|
@ -2138,7 +2136,23 @@ int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex)
|
|||
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;
|
||||
}
|
||||
|
@ -2259,7 +2273,9 @@ static int hclge_mac_init(struct hclge_dev *hdev)
|
|||
int ret;
|
||||
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) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"Config mac speed dup fail ret=%d\n", ret);
|
||||
|
@ -2415,13 +2431,11 @@ static int hclge_update_speed_duplex(struct hclge_dev *hdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if ((mac.speed != speed) || (mac.duplex != duplex)) {
|
||||
ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"mac speed/duplex config failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"mac speed/duplex config failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -3659,6 +3673,8 @@ static int hclge_set_mac_loopback(struct hclge_dev *hdev, bool en)
|
|||
/* 2 Then setup the loopback flag */
|
||||
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_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);
|
||||
|
||||
|
@ -3719,33 +3735,10 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
hclge_cfg_mac_mode(hdev, en);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_set_loopback(struct hnae3_handle *handle,
|
||||
enum hnae3_loop loop_mode, bool en)
|
||||
{
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
int ret;
|
||||
|
||||
switch (loop_mode) {
|
||||
case HNAE3_MAC_INTER_LOOP_MAC:
|
||||
ret = hclge_set_mac_loopback(hdev, en);
|
||||
break;
|
||||
case HNAE3_MAC_INTER_LOOP_SERDES:
|
||||
ret = hclge_set_serdes_loopback(hdev, en);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTSUPP;
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"loop_mode %d is not supported\n", loop_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hclge_tqp_enable(struct hclge_dev *hdev, int tqp_id,
|
||||
int stream_id, bool enable)
|
||||
{
|
||||
|
@ -3766,6 +3759,36 @@ static int hclge_tqp_enable(struct hclge_dev *hdev, int tqp_id,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int hclge_set_loopback(struct hnae3_handle *handle,
|
||||
enum hnae3_loop loop_mode, bool en)
|
||||
{
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
int i, ret;
|
||||
|
||||
switch (loop_mode) {
|
||||
case HNAE3_MAC_INTER_LOOP_MAC:
|
||||
ret = hclge_set_mac_loopback(hdev, en);
|
||||
break;
|
||||
case HNAE3_MAC_INTER_LOOP_SERDES:
|
||||
ret = hclge_set_serdes_loopback(hdev, en);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTSUPP;
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"loop_mode %d is not supported\n", loop_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < vport->alloc_tqps; i++) {
|
||||
ret = hclge_tqp_enable(hdev, i, 0, en);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hclge_reset_tqp_stats(struct hnae3_handle *handle)
|
||||
{
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
|
@ -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.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.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);
|
||||
status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true);
|
||||
if (!status) {
|
||||
|
@ -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.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.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);
|
||||
status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true);
|
||||
if (!status) {
|
||||
|
@ -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",
|
||||
req0->resp_code);
|
||||
} else {
|
||||
#define HCLGE_VF_VLAN_DEL_NO_FOUND 1
|
||||
if (!req0->resp_code)
|
||||
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,
|
||||
"Kill vf vlan filter fail, ret =%d.\n",
|
||||
req0->resp_code);
|
||||
|
@ -4732,6 +4763,9 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
|
|||
u16 vport_idx, vport_num = 0;
|
||||
int ret;
|
||||
|
||||
if (is_kill && !vlan_id)
|
||||
return 0;
|
||||
|
||||
ret = hclge_set_vf_vlan_common(hdev, vport_id, is_kill, vlan_id,
|
||||
0, proto);
|
||||
if (ret) {
|
||||
|
@ -4761,7 +4795,7 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
|
|||
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++;
|
||||
|
||||
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)
|
|||
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)
|
||||
{
|
||||
struct phy_device *phydev = hdev->hw.mac.phydev;
|
||||
|
@ -6301,7 +6321,6 @@ static const struct hnae3_ae_ops hclge_ops = {
|
|||
.get_tqps_and_rss_info = hclge_get_tqps_and_rss_info,
|
||||
.set_channels = hclge_set_channels,
|
||||
.get_channels = hclge_get_channels,
|
||||
.get_flowctrl_adv = hclge_get_flowctrl_adv,
|
||||
.get_regs_len = hclge_get_regs_len,
|
||||
.get_regs = hclge_get_regs,
|
||||
.set_led_id = hclge_set_led_id,
|
||||
|
|
Loading…
Reference in New Issue