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)
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,15 +3735,36 @@ 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_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,
enum hnae3_loop loop_mode, bool en)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
int ret;
int i, ret;
switch (loop_mode) {
case HNAE3_MAC_INTER_LOOP_MAC:
......@@ -3743,27 +3780,13 @@ static int hclge_set_loopback(struct hnae3_handle *handle,
break;
}
return ret;
}
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;
for (i = 0; i < vport->alloc_tqps; i++) {
ret = hclge_tqp_enable(hdev, i, 0, en);
if (ret)
return ret;
}
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret)
dev_err(&hdev->pdev->dev,
"Tqp enable fail, status =%d.\n", ret);
return ret;
return 0;
}
static void hclge_reset_tqp_stats(struct hnae3_handle *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,
......
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