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 { ...@@ -477,7 +477,6 @@ struct hnae3_dcb_ops {
u8 (*getdcbx)(struct hnae3_handle *); u8 (*getdcbx)(struct hnae3_handle *);
u8 (*setdcbx)(struct hnae3_handle *, u8); u8 (*setdcbx)(struct hnae3_handle *, u8);
int (*map_update)(struct hnae3_handle *);
int (*setup_tc)(struct hnae3_handle *, u8, u8 *); int (*setup_tc)(struct hnae3_handle *, u8, u8 *);
}; };
......
...@@ -348,6 +348,8 @@ static int hns3_nic_net_up(struct net_device *netdev) ...@@ -348,6 +348,8 @@ static int hns3_nic_net_up(struct net_device *netdev)
return ret; return ret;
} }
clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
/* enable the vectors */ /* enable the vectors */
for (i = 0; i < priv->vector_num; i++) for (i = 0; i < priv->vector_num; i++)
hns3_vector_enable(&priv->tqp_vector[i]); hns3_vector_enable(&priv->tqp_vector[i]);
...@@ -361,11 +363,10 @@ static int hns3_nic_net_up(struct net_device *netdev) ...@@ -361,11 +363,10 @@ static int hns3_nic_net_up(struct net_device *netdev)
if (ret) if (ret)
goto out_start_err; goto out_start_err;
clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
return 0; return 0;
out_start_err: out_start_err:
set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
while (j--) while (j--)
hns3_tqp_disable(h->kinfo.tqp[j]); hns3_tqp_disable(h->kinfo.tqp[j]);
...@@ -506,7 +507,7 @@ static u8 hns3_get_netdev_flags(struct net_device *netdev) ...@@ -506,7 +507,7 @@ static u8 hns3_get_netdev_flags(struct net_device *netdev)
u8 flags = 0; u8 flags = 0;
if (netdev->flags & IFF_PROMISC) { if (netdev->flags & IFF_PROMISC) {
flags = HNAE3_USER_UPE | HNAE3_USER_MPE; flags = HNAE3_USER_UPE | HNAE3_USER_MPE | HNAE3_BPE;
} else { } else {
flags |= HNAE3_VLAN_FLTR; flags |= HNAE3_VLAN_FLTR;
if (netdev->flags & IFF_ALLMULTI) if (netdev->flags & IFF_ALLMULTI)
...@@ -541,13 +542,13 @@ static void hns3_nic_set_rx_mode(struct net_device *netdev) ...@@ -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 /* User mode Promisc mode enable and vlan filtering is disabled to
* let all packets in. MAC-VLAN Table overflow Promisc enabled and * let all packets in. MAC-VLAN Table overflow Promisc enabled and
* vlan fitering is enabled * vlan fitering is enabled
*/ */
hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR); hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR);
h->netdev_flags = new_flags; h->netdev_flags = new_flags;
hns3_update_promisc_mode(netdev, new_flags);
} }
int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_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, ...@@ -1133,6 +1134,7 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
struct hns3_enet_ring *ring) struct hns3_enet_ring *ring)
{ {
struct sk_buff *skb = *out_skb; struct sk_buff *skb = *out_skb;
struct sk_buff *new_skb = NULL;
struct skb_frag_struct *frag; struct skb_frag_struct *frag;
int bdnum_for_frag; int bdnum_for_frag;
int frag_num; int frag_num;
...@@ -1155,7 +1157,19 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum, ...@@ -1155,7 +1157,19 @@ static int hns3_nic_maybe_stop_tso(struct sk_buff **out_skb, int *bnum,
buf_num += bdnum_for_frag; 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; return -EBUSY;
*bnum = buf_num; *bnum = buf_num;
...@@ -1166,11 +1180,24 @@ static int hns3_nic_maybe_stop_tx(struct sk_buff **out_skb, int *bnum, ...@@ -1166,11 +1180,24 @@ static int hns3_nic_maybe_stop_tx(struct sk_buff **out_skb, int *bnum,
struct hns3_enet_ring *ring) struct hns3_enet_ring *ring)
{ {
struct sk_buff *skb = *out_skb; struct sk_buff *skb = *out_skb;
struct sk_buff *new_skb = NULL;
int buf_num; int buf_num;
/* No. of segments (plus a header) */ /* No. of segments (plus a header) */
buf_num = skb_shinfo(skb)->nr_frags + 1; 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)) if (unlikely(ring_space(ring) < buf_num))
return -EBUSY; return -EBUSY;
...@@ -1425,9 +1452,7 @@ static void hns3_nic_get_stats64(struct net_device *netdev, ...@@ -1425,9 +1452,7 @@ static void hns3_nic_get_stats64(struct net_device *netdev,
start = u64_stats_fetch_begin_irq(&ring->syncp); start = u64_stats_fetch_begin_irq(&ring->syncp);
tx_bytes += ring->stats.tx_bytes; tx_bytes += ring->stats.tx_bytes;
tx_pkts += ring->stats.tx_pkts; tx_pkts += ring->stats.tx_pkts;
tx_drop += ring->stats.tx_busy;
tx_drop += ring->stats.sw_err_cnt; tx_drop += ring->stats.sw_err_cnt;
tx_errors += ring->stats.tx_busy;
tx_errors += ring->stats.sw_err_cnt; tx_errors += ring->stats.sw_err_cnt;
} while (u64_stats_fetch_retry_irq(&ring->syncp, start)); } while (u64_stats_fetch_retry_irq(&ring->syncp, start));
...@@ -1438,7 +1463,6 @@ static void hns3_nic_get_stats64(struct net_device *netdev, ...@@ -1438,7 +1463,6 @@ static void hns3_nic_get_stats64(struct net_device *netdev,
rx_bytes += ring->stats.rx_bytes; rx_bytes += ring->stats.rx_bytes;
rx_pkts += ring->stats.rx_pkts; rx_pkts += ring->stats.rx_pkts;
rx_drop += ring->stats.non_vld_descs; rx_drop += ring->stats.non_vld_descs;
rx_drop += ring->stats.err_pkt_len;
rx_drop += ring->stats.l2_err; rx_drop += ring->stats.l2_err;
rx_errors += ring->stats.non_vld_descs; rx_errors += ring->stats.non_vld_descs;
rx_errors += ring->stats.l2_err; rx_errors += ring->stats.l2_err;
...@@ -1485,8 +1509,6 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data) ...@@ -1485,8 +1509,6 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data)
u8 tc = mqprio_qopt->qopt.num_tc; u8 tc = mqprio_qopt->qopt.num_tc;
u16 mode = mqprio_qopt->mode; u16 mode = mqprio_qopt->mode;
u8 hw = mqprio_qopt->qopt.hw; u8 hw = mqprio_qopt->qopt.hw;
bool if_running;
int ret;
if (!((hw == TC_MQPRIO_HW_OFFLOAD_TCS && if (!((hw == TC_MQPRIO_HW_OFFLOAD_TCS &&
mode == TC_MQPRIO_MODE_CHANNEL) || (!hw && tc == 0))) mode == TC_MQPRIO_MODE_CHANNEL) || (!hw && tc == 0)))
...@@ -1498,24 +1520,8 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data) ...@@ -1498,24 +1520,8 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data)
if (!netdev) if (!netdev)
return -EINVAL; return -EINVAL;
if_running = netif_running(netdev); return (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ?
if (if_running) {
hns3_nic_net_stop(netdev);
msleep(100);
}
ret = (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ?
kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : -EOPNOTSUPP; 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, 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) ...@@ -1784,6 +1790,7 @@ static void hns3_remove(struct pci_dev *pdev)
hns3_disable_sriov(pdev); hns3_disable_sriov(pdev);
hnae3_unregister_ae_dev(ae_dev); hnae3_unregister_ae_dev(ae_dev);
pci_set_drvdata(pdev, NULL);
} }
/** /**
...@@ -3608,6 +3615,7 @@ static int hns3_client_init(struct hnae3_handle *handle) ...@@ -3608,6 +3615,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
priv->netdev = netdev; priv->netdev = netdev;
priv->ae_handle = handle; priv->ae_handle = handle;
priv->tx_timeout_count = 0; priv->tx_timeout_count = 0;
set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
handle->kinfo.netdev = netdev; handle->kinfo.netdev = netdev;
handle->priv = (void *)priv; handle->priv = (void *)priv;
...@@ -3752,7 +3760,6 @@ static int hns3_client_setup_tc(struct hnae3_handle *handle, u8 tc) ...@@ -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 hnae3_knic_private_info *kinfo = &handle->kinfo;
struct net_device *ndev = kinfo->netdev; struct net_device *ndev = kinfo->netdev;
int ret;
if (tc > HNAE3_MAX_TC) if (tc > HNAE3_MAX_TC)
return -EINVAL; return -EINVAL;
...@@ -3760,14 +3767,7 @@ static int hns3_client_setup_tc(struct hnae3_handle *handle, u8 tc) ...@@ -3760,14 +3767,7 @@ static int hns3_client_setup_tc(struct hnae3_handle *handle, u8 tc)
if (!ndev) if (!ndev)
return -ENODEV; return -ENODEV;
ret = (kinfo->dcb_ops && kinfo->dcb_ops->map_update) ? return hns3_nic_set_real_num_queue(ndev);
kinfo->dcb_ops->map_update(handle) : -EOPNOTSUPP;
if (ret)
return ret;
ret = hns3_nic_set_real_num_queue(ndev);
return ret;
} }
static int hns3_recover_hw_addr(struct net_device *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) ...@@ -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); ret = hns3_lp_setup(ndev, loop_mode, true);
usleep_range(10000, 20000); usleep_range(10000, 20000);
return 0; return ret;
} }
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)
...@@ -334,10 +334,10 @@ static void hns3_self_test(struct net_device *ndev, ...@@ -334,10 +334,10 @@ static void hns3_self_test(struct net_device *ndev,
continue; continue;
data[test_index] = hns3_lp_up(ndev, loop_type); 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); 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]) if (data[test_index])
eth_test->flags |= ETH_TEST_FL_FAILED; eth_test->flags |= ETH_TEST_FL_FAILED;
......
...@@ -156,10 +156,8 @@ static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets, ...@@ -156,10 +156,8 @@ static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,
return 0; 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; int ret;
ret = hclge_tm_schd_setup_hw(hdev); ret = hclge_tm_schd_setup_hw(hdev);
...@@ -232,12 +230,17 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets) ...@@ -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); ret = hclge_ieee_ets_to_tm_info(hdev, ets);
if (ret) if (ret)
return ret; goto err_out;
if (map_changed) { if (map_changed) {
ret = hclge_map_update(hdev);
if (ret)
goto err_out;
ret = hclge_client_setup_tc(hdev); ret = hclge_client_setup_tc(hdev);
if (ret) if (ret)
return ret; goto err_out;
ret = hclge_notify_client(hdev, HNAE3_INIT_CLIENT); ret = hclge_notify_client(hdev, HNAE3_INIT_CLIENT);
if (ret) if (ret)
return ret; return ret;
...@@ -248,6 +251,16 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets) ...@@ -248,6 +251,16 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets)
} }
return hclge_tm_dwrr_cfg(hdev); 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) 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) ...@@ -359,12 +372,24 @@ static int hclge_setup_tc(struct hnae3_handle *h, u8 tc, u8 *prio_tc)
if (ret) if (ret)
return -EINVAL; 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_schd_info_update(hdev, tc);
hclge_tm_prio_tc_info_update(hdev, prio_tc); hclge_tm_prio_tc_info_update(hdev, prio_tc);
ret = hclge_tm_init_hw(hdev, false); ret = hclge_tm_init_hw(hdev, false);
if (ret) if (ret)
return ret; goto err_out;
ret = hclge_client_setup_tc(hdev);
if (ret)
goto err_out;
hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE; hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
...@@ -373,7 +398,18 @@ static int hclge_setup_tc(struct hnae3_handle *h, u8 tc, u8 *prio_tc) ...@@ -373,7 +398,18 @@ static int hclge_setup_tc(struct hnae3_handle *h, u8 tc, u8 *prio_tc)
else else
hdev->flag &= ~HCLGE_FLAG_MQPRIO_ENABLE; 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 = { static const struct hnae3_dcb_ops hns3_dcb_ops = {
...@@ -383,7 +419,6 @@ 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, .ieee_setpfc = hclge_ieee_setpfc,
.getdcbx = hclge_getdcbx, .getdcbx = hclge_getdcbx,
.setdcbx = hclge_setdcbx, .setdcbx = hclge_setdcbx,
.map_update = hclge_map_update,
.setup_tc = hclge_setup_tc, .setup_tc = hclge_setup_tc,
}; };
......
...@@ -3843,8 +3843,16 @@ static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc, ...@@ -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_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
struct hclge_promisc_param param; 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); vport->vport_id);
return hclge_cmd_set_promisc_mode(hdev, &param); return hclge_cmd_set_promisc_mode(hdev, &param);
} }
...@@ -5229,8 +5237,15 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en, ...@@ -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_MS 10
#define HCLGE_SERDES_RETRY_NUM 100 #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_serdes_lb_cmd *req;
struct hclge_desc desc; struct hclge_desc desc;
int mac_link_ret = 0;
int ret, i = 0; int ret, i = 0;
u8 loop_mode_b; u8 loop_mode_b;
...@@ -5253,8 +5268,10 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en, ...@@ -5253,8 +5268,10 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en,
if (en) { if (en) {
req->enable = loop_mode_b; req->enable = loop_mode_b;
req->mask = loop_mode_b; req->mask = loop_mode_b;
mac_link_ret = HCLGE_MAC_LINK_STATUS_UP;
} else { } else {
req->mask = loop_mode_b; req->mask = loop_mode_b;
mac_link_ret = HCLGE_MAC_LINK_STATUS_DOWN;
} }
ret = hclge_cmd_send(&hdev->hw, &desc, 1); ret = hclge_cmd_send(&hdev->hw, &desc, 1);
...@@ -5286,7 +5303,19 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en, ...@@ -5286,7 +5303,19 @@ static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en,
} }
hclge_cfg_mac_mode(hdev, 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, 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, ...@@ -5332,6 +5361,9 @@ static int hclge_set_loopback(struct hnae3_handle *handle,
break; break;
} }
if (ret)
return ret;
kinfo = &vport->nic.kinfo; kinfo = &vport->nic.kinfo;
for (i = 0; i < kinfo->num_tqps; i++) { for (i = 0; i < kinfo->num_tqps; i++) {
ret = hclge_tqp_enable(hdev, i, 0, en); 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, ...@@ -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, static int hclge_set_vf_promisc_mode(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *req) struct hclge_mbx_vf_to_pf_cmd *req)
{ {
bool en_uc = req->msg[1] ? true : false; bool en_bc = req->msg[1] ? true : false;
bool en_mc = req->msg[2] ? true : false;
struct hclge_promisc_param param; struct hclge_promisc_param param;
/* always enable broadcast promisc bit */ /* vf is not allowed to enable unicast/multicast broadcast */
hclge_promisc_param_init(&param, en_uc, en_mc, true, vport->vport_id); hclge_promisc_param_init(&param, false, false, en_bc, vport->vport_id);
return hclge_cmd_set_promisc_mode(vport->back, &param); return hclge_cmd_set_promisc_mode(vport->back, &param);
} }
......
...@@ -969,33 +969,29 @@ static int hclgevf_put_vector(struct hnae3_handle *handle, int vector) ...@@ -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, 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 hclge_mbx_vf_to_pf_cmd *req;
struct hclgevf_desc desc; struct hclgevf_desc desc;
int status; int ret;
req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data;
hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false);
req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE; req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE;
req->msg[1] = en_uc_pmc ? 1 : 0; req->msg[1] = en_bc_pmc ? 1 : 0;
req->msg[2] = en_mc_pmc ? 1 : 0;
status = hclgevf_cmd_send(&hdev->hw, &desc, 1); ret = hclgevf_cmd_send(&hdev->hw, &desc, 1);
if (status) if (ret)
dev_err(&hdev->pdev->dev, 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, static int hclgevf_set_promisc_mode(struct hclgevf_dev *hdev, bool en_bc_pmc)
bool en_uc_pmc, bool en_mc_pmc)
{ {
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); return hclgevf_cmd_set_promisc_mode(hdev, en_bc_pmc);
return hclgevf_cmd_set_promisc_mode(hdev, en_uc_pmc, en_mc_pmc);
} }
static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, int tqp_id, 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) ...@@ -2382,6 +2378,15 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
if (ret) if (ret)
goto err_config; 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 */ /* Initialize RSS for this VF */
ret = hclgevf_rss_init_hw(hdev); ret = hclgevf_rss_init_hw(hdev);
if (ret) { if (ret) {
...@@ -2646,7 +2651,6 @@ static const struct hnae3_ae_ops hclgevf_ops = { ...@@ -2646,7 +2651,6 @@ static const struct hnae3_ae_ops hclgevf_ops = {
.get_vector = hclgevf_get_vector, .get_vector = hclgevf_get_vector,
.put_vector = hclgevf_put_vector, .put_vector = hclgevf_put_vector,
.reset_queue = hclgevf_reset_tqp, .reset_queue = hclgevf_reset_tqp,
.set_promisc_mode = hclgevf_set_promisc_mode,
.get_mac_addr = hclgevf_get_mac_addr, .get_mac_addr = hclgevf_get_mac_addr,
.set_mac_addr = hclgevf_set_mac_addr, .set_mac_addr = hclgevf_set_mac_addr,
.add_uc_addr = hclgevf_add_uc_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