Commit 08c666b7 authored by David S. Miller's avatar David S. Miller

Merge branch 'hns3-next'

Huazhong Tan says:

====================
code optimizations & bugfixes for HNS3 driver

This patchset includes bugfixes and code optimizations for the HNS3
ethernet controller driver
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 45e8fddd f01f5559
......@@ -477,7 +477,6 @@ struct hnae3_dcb_ops {
u8 (*getdcbx)(struct hnae3_handle *);
u8 (*setdcbx)(struct hnae3_handle *, u8);
int (*map_update)(struct hnae3_handle *);
int (*setup_tc)(struct hnae3_handle *, u8, u8 *);
};
......
......@@ -348,6 +348,8 @@ static int hns3_nic_net_up(struct net_device *netdev)
return ret;
}
clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
/* enable the vectors */
for (i = 0; i < priv->vector_num; i++)
hns3_vector_enable(&priv->tqp_vector[i]);
......@@ -361,11 +363,10 @@ static int hns3_nic_net_up(struct net_device *netdev)
if (ret)
goto out_start_err;
clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
return 0;
out_start_err:
set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
while (j--)
hns3_tqp_disable(h->kinfo.tqp[j]);
......@@ -506,7 +507,7 @@ static u8 hns3_get_netdev_flags(struct net_device *netdev)
u8 flags = 0;
if (netdev->flags & IFF_PROMISC) {
flags = HNAE3_USER_UPE | HNAE3_USER_MPE;
flags = HNAE3_USER_UPE | HNAE3_USER_MPE | HNAE3_BPE;
} else {
flags |= HNAE3_VLAN_FLTR;
if (netdev->flags & IFF_ALLMULTI)
......@@ -541,13 +542,13 @@ static void hns3_nic_set_rx_mode(struct net_device *netdev)
}
}
hns3_update_promisc_mode(netdev, new_flags);
/* User mode Promisc mode enable and vlan filtering is disabled to
* let all packets in. MAC-VLAN Table overflow Promisc enabled and
* vlan fitering is enabled
*/
hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR);
h->netdev_flags = new_flags;
hns3_update_promisc_mode(netdev, new_flags);
}
int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
......@@ -1133,6 +1134,7 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
struct hns3_enet_ring *ring)
{
struct sk_buff *skb = *out_skb;
struct sk_buff *new_skb = NULL;
struct skb_frag_struct *frag;
int bdnum_for_frag;
int frag_num;
......@@ -1155,7 +1157,19 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
buf_num += bdnum_for_frag;
}
if (buf_num > ring_space(ring))
if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) {
buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
if (ring_space(ring) < buf_num)
return -EBUSY;
/* manual split the send packet */
new_skb = skb_copy(skb, GFP_ATOMIC);
if (!new_skb)
return -ENOMEM;
dev_kfree_skb_any(skb);
*out_skb = new_skb;
}
if (unlikely(ring_space(ring) < buf_num))
return -EBUSY;
*bnum = buf_num;
......@@ -1166,11 +1180,24 @@ static int hns3_nic_maybe_stop_tx(struct sk_buff **out_skb, int *bnum,
struct hns3_enet_ring *ring)
{
struct sk_buff *skb = *out_skb;
struct sk_buff *new_skb = NULL;
int buf_num;
/* No. of segments (plus a header) */
buf_num = skb_shinfo(skb)->nr_frags + 1;
if (unlikely(buf_num > HNS3_MAX_BD_PER_FRAG)) {
buf_num = (skb->len + HNS3_MAX_BD_SIZE - 1) / HNS3_MAX_BD_SIZE;
if (ring_space(ring) < buf_num)
return -EBUSY;
/* manual split the send packet */
new_skb = skb_copy(skb, GFP_ATOMIC);
if (!new_skb)
return -ENOMEM;
dev_kfree_skb_any(skb);
*out_skb = new_skb;
}
if (unlikely(ring_space(ring) < buf_num))
return -EBUSY;
......@@ -1425,9 +1452,7 @@ static void hns3_nic_get_stats64(struct net_device *netdev,
start = u64_stats_fetch_begin_irq(&ring->syncp);
tx_bytes += ring->stats.tx_bytes;
tx_pkts += ring->stats.tx_pkts;
tx_drop += ring->stats.tx_busy;
tx_drop += ring->stats.sw_err_cnt;
tx_errors += ring->stats.tx_busy;
tx_errors += ring->stats.sw_err_cnt;
} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
......@@ -1438,7 +1463,6 @@ static void hns3_nic_get_stats64(struct net_device *netdev,
rx_bytes += ring->stats.rx_bytes;
rx_pkts += ring->stats.rx_pkts;
rx_drop += ring->stats.non_vld_descs;
rx_drop += ring->stats.err_pkt_len;
rx_drop += ring->stats.l2_err;
rx_errors += ring->stats.non_vld_descs;
rx_errors += ring->stats.l2_err;
......@@ -1485,8 +1509,6 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data)
u8 tc = mqprio_qopt->qopt.num_tc;
u16 mode = mqprio_qopt->mode;
u8 hw = mqprio_qopt->qopt.hw;
bool if_running;
int ret;
if (!((hw == TC_MQPRIO_HW_OFFLOAD_TCS &&
mode == TC_MQPRIO_MODE_CHANNEL) || (!hw && tc == 0)))
......@@ -1498,24 +1520,8 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data)
if (!netdev)
return -EINVAL;
if_running = netif_running(netdev);
if (if_running) {
hns3_nic_net_stop(netdev);
msleep(100);
}
ret = (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ?
return (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ?
kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : -EOPNOTSUPP;
if (ret)
goto out;
ret = hns3_nic_set_real_num_queue(netdev);
out:
if (if_running)
hns3_nic_net_open(netdev);
return ret;
}
static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type,
......@@ -1784,6 +1790,7 @@ static void hns3_remove(struct pci_dev *pdev)
hns3_disable_sriov(pdev);
hnae3_unregister_ae_dev(ae_dev);
pci_set_drvdata(pdev, NULL);
}
/**
......@@ -3608,6 +3615,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
priv->netdev = netdev;
priv->ae_handle = handle;
priv->tx_timeout_count = 0;
set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
handle->kinfo.netdev = netdev;
handle->priv = (void *)priv;
......@@ -3752,7 +3760,6 @@ static int hns3_client_setup_tc(struct hnae3_handle *handle, u8 tc)
{
struct hnae3_knic_private_info *kinfo = &handle->kinfo;
struct net_device *ndev = kinfo->netdev;
int ret;
if (tc > HNAE3_MAX_TC)
return -EINVAL;
......@@ -3760,14 +3767,7 @@ static int hns3_client_setup_tc(struct hnae3_handle *handle, u8 tc)
if (!ndev)
return -ENODEV;
ret = (kinfo->dcb_ops && kinfo->dcb_ops->map_update) ?
kinfo->dcb_ops->map_update(handle) : -EOPNOTSUPP;
if (ret)
return ret;
ret = hns3_nic_set_real_num_queue(ndev);
return ret;
return hns3_nic_set_real_num_queue(ndev);
}
static int hns3_recover_hw_addr(struct net_device *ndev)
......
......@@ -117,7 +117,7 @@ static int hns3_lp_up(struct net_device *ndev, enum hnae3_loop loop_mode)
ret = hns3_lp_setup(ndev, loop_mode, true);
usleep_range(10000, 20000);
return 0;
return ret;
}
static int hns3_lp_down(struct net_device *ndev, enum hnae3_loop loop_mode)
......@@ -334,10 +334,10 @@ static void hns3_self_test(struct net_device *ndev,
continue;
data[test_index] = hns3_lp_up(ndev, loop_type);
if (!data[test_index]) {
if (!data[test_index])
data[test_index] = hns3_lp_run_test(ndev, loop_type);
hns3_lp_down(ndev, loop_type);
}
hns3_lp_down(ndev, loop_type);
if (data[test_index])
eth_test->flags |= ETH_TEST_FL_FAILED;
......
......@@ -156,10 +156,8 @@ static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,
return 0;
}
static int hclge_map_update(struct hnae3_handle *h)
static int hclge_map_update(struct hclge_dev *hdev)
{
struct hclge_vport *vport = hclge_get_vport(h);
struct hclge_dev *hdev = vport->back;
int ret;
ret = hclge_tm_schd_setup_hw(hdev);
......@@ -232,12 +230,17 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets)
ret = hclge_ieee_ets_to_tm_info(hdev, ets);
if (ret)
return ret;
goto err_out;
if (map_changed) {
ret = hclge_map_update(hdev);
if (ret)
goto err_out;
ret = hclge_client_setup_tc(hdev);
if (ret)
return ret;
goto err_out;
ret = hclge_notify_client(hdev, HNAE3_INIT_CLIENT);
if (ret)
return ret;
......@@ -248,6 +251,16 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets)
}
return hclge_tm_dwrr_cfg(hdev);
err_out:
if (!map_changed)
return ret;
if (hclge_notify_client(hdev, HNAE3_INIT_CLIENT))
return ret;
hclge_notify_client(hdev, HNAE3_UP_CLIENT);
return ret;
}
static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
......@@ -359,12 +372,24 @@ static int hclge_setup_tc(struct hnae3_handle *h, u8 tc, u8 *prio_tc)
if (ret)
return -EINVAL;
ret = hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
if (ret)
return ret;
ret = hclge_notify_client(hdev, HNAE3_UNINIT_CLIENT);
if (ret)
return ret;
hclge_tm_schd_info_update(hdev, tc);
hclge_tm_prio_tc_info_update(hdev, prio_tc);
ret = hclge_tm_init_hw(hdev, false);
if (ret)
return ret;
goto err_out;
ret = hclge_client_setup_tc(hdev);
if (ret)
goto err_out;
hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
......@@ -373,7 +398,18 @@ static int hclge_setup_tc(struct hnae3_handle *h, u8 tc, u8 *prio_tc)
else
hdev->flag &= ~HCLGE_FLAG_MQPRIO_ENABLE;
return 0;
ret = hclge_notify_client(hdev, HNAE3_INIT_CLIENT);
if (ret)
return ret;
return hclge_notify_client(hdev, HNAE3_UP_CLIENT);
err_out:
if (hclge_notify_client(hdev, HNAE3_INIT_CLIENT))
return ret;
hclge_notify_client(hdev, HNAE3_UP_CLIENT);
return ret;
}
static const struct hnae3_dcb_ops hns3_dcb_ops = {
......@@ -383,7 +419,6 @@ static const struct hnae3_dcb_ops hns3_dcb_ops = {
.ieee_setpfc = hclge_ieee_setpfc,
.getdcbx = hclge_getdcbx,
.setdcbx = hclge_setdcbx,
.map_update = hclge_map_update,
.setup_tc = hclge_setup_tc,
};
......
......@@ -3843,8 +3843,16 @@ static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
struct hclge_promisc_param param;
bool en_bc_pmc = true;
hclge_promisc_param_init(&param, en_uc_pmc, en_mc_pmc, true,
/* For revision 0x20, if broadcast promisc enabled, vlan filter is
* always bypassed. So broadcast promisc should be disabled until
* user enable promisc mode
*/
if (handle->pdev->revision == 0x20)
en_bc_pmc = handle->netdev_flags & HNAE3_BPE ? true : false;
hclge_promisc_param_init(&param, en_uc_pmc, en_mc_pmc, en_bc_pmc,
vport->vport_id);
return hclge_cmd_set_promisc_mode(hdev, &param);
}
......@@ -5229,8 +5237,15 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en,
{
#define HCLGE_SERDES_RETRY_MS 10
#define HCLGE_SERDES_RETRY_NUM 100
#define HCLGE_MAC_LINK_STATUS_MS 20
#define HCLGE_MAC_LINK_STATUS_NUM 10
#define HCLGE_MAC_LINK_STATUS_DOWN 0
#define HCLGE_MAC_LINK_STATUS_UP 1
struct hclge_serdes_lb_cmd *req;
struct hclge_desc desc;
int mac_link_ret = 0;
int ret, i = 0;
u8 loop_mode_b;
......@@ -5253,8 +5268,10 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en,
if (en) {
req->enable = loop_mode_b;
req->mask = loop_mode_b;
mac_link_ret = HCLGE_MAC_LINK_STATUS_UP;
} else {
req->mask = loop_mode_b;
mac_link_ret = HCLGE_MAC_LINK_STATUS_DOWN;
}
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
......@@ -5286,7 +5303,19 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en,
}
hclge_cfg_mac_mode(hdev, en);
return 0;
i = 0;
do {
/* serdes Internal loopback, independent of the network cable.*/
msleep(HCLGE_MAC_LINK_STATUS_MS);
ret = hclge_get_mac_link_status(hdev);
if (ret == mac_link_ret)
return 0;
} while (++i < HCLGE_MAC_LINK_STATUS_NUM);
dev_err(&hdev->pdev->dev, "config mac mode timeout\n");
return -EBUSY;
}
static int hclge_tqp_enable(struct hclge_dev *hdev, int tqp_id,
......@@ -5332,6 +5361,9 @@ static int hclge_set_loopback(struct hnae3_handle *handle,
break;
}
if (ret)
return ret;
kinfo = &vport->nic.kinfo;
for (i = 0; i < kinfo->num_tqps; i++) {
ret = hclge_tqp_enable(hdev, i, 0, en);
......
......@@ -203,12 +203,11 @@ static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en,
static int hclge_set_vf_promisc_mode(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *req)
{
bool en_uc = req->msg[1] ? true : false;
bool en_mc = req->msg[2] ? true : false;
bool en_bc = req->msg[1] ? true : false;
struct hclge_promisc_param param;
/* always enable broadcast promisc bit */
hclge_promisc_param_init(&param, en_uc, en_mc, true, vport->vport_id);
/* vf is not allowed to enable unicast/multicast broadcast */
hclge_promisc_param_init(&param, false, false, en_bc, vport->vport_id);
return hclge_cmd_set_promisc_mode(vport->back, &param);
}
......
......@@ -969,33 +969,29 @@ static int hclgevf_put_vector(struct hnae3_handle *handle, int vector)
}
static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev,
bool en_uc_pmc, bool en_mc_pmc)
bool en_bc_pmc)
{
struct hclge_mbx_vf_to_pf_cmd *req;
struct hclgevf_desc desc;
int status;
int ret;
req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data;
hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false);
req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE;
req->msg[1] = en_uc_pmc ? 1 : 0;
req->msg[2] = en_mc_pmc ? 1 : 0;
req->msg[1] = en_bc_pmc ? 1 : 0;
status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
if (status)
ret = hclgevf_cmd_send(&hdev->hw, &desc, 1);
if (ret)
dev_err(&hdev->pdev->dev,
"Set promisc mode fail, status is %d.\n", status);
"Set promisc mode fail, status is %d.\n", ret);
return status;
return ret;
}
static int hclgevf_set_promisc_mode(struct hnae3_handle *handle,
bool en_uc_pmc, bool en_mc_pmc)
static int hclgevf_set_promisc_mode(struct hclgevf_dev *hdev, bool en_bc_pmc)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
return hclgevf_cmd_set_promisc_mode(hdev, en_uc_pmc, en_mc_pmc);
return hclgevf_cmd_set_promisc_mode(hdev, en_bc_pmc);
}
static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, int tqp_id,
......@@ -2382,6 +2378,15 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
if (ret)
goto err_config;
/* vf is not allowed to enable unicast/multicast promisc mode.
* For revision 0x20, default to disable broadcast promisc mode,
* firmware makes sure broadcast packets can be accepted.
* For revision 0x21, default to enable broadcast promisc mode.
*/
ret = hclgevf_set_promisc_mode(hdev, true);
if (ret)
goto err_config;
/* Initialize RSS for this VF */
ret = hclgevf_rss_init_hw(hdev);
if (ret) {
......@@ -2646,7 +2651,6 @@ static const struct hnae3_ae_ops hclgevf_ops = {
.get_vector = hclgevf_get_vector,
.put_vector = hclgevf_put_vector,
.reset_queue = hclgevf_reset_tqp,
.set_promisc_mode = hclgevf_set_promisc_mode,
.get_mac_addr = hclgevf_get_mac_addr,
.set_mac_addr = hclgevf_set_mac_addr,
.add_uc_addr = hclgevf_add_uc_addr,
......
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