Commit 8b4c6ed2 authored by David S. Miller's avatar David S. Miller

Merge branch 'hns3-next'

Peng Li says:

====================
fix some bugs for HNS3 driver

This patchset fixes some bugs for HNS3 driver:
[Patch 1/12 - Patch 8/12] fix various bugs for PF driver.
[Patch 9/12 - Patch 12/12] fix issues when change the us mac address of
PF/VF device to an existent one in the mac_vlan table.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents daa13701 2097fdef
...@@ -57,6 +57,8 @@ enum hclge_mbx_vlan_cfg_subcode { ...@@ -57,6 +57,8 @@ enum hclge_mbx_vlan_cfg_subcode {
#define HCLGE_MBX_MAX_MSG_SIZE 16 #define HCLGE_MBX_MAX_MSG_SIZE 16
#define HCLGE_MBX_MAX_RESP_DATA_SIZE 8 #define HCLGE_MBX_MAX_RESP_DATA_SIZE 8
#define HCLGE_MBX_RING_MAP_BASIC_MSG_NUM 3
#define HCLGE_MBX_RING_NODE_VARIABLE_NUM 3
struct hclgevf_mbx_resp_status { struct hclgevf_mbx_resp_status {
struct mutex mbx_mutex; /* protects against contending sync cmd resp */ struct mutex mbx_mutex; /* protects against contending sync cmd resp */
......
...@@ -338,7 +338,8 @@ struct hnae3_ae_ops { ...@@ -338,7 +338,8 @@ struct hnae3_ae_ops {
u32 *tx_usecs_high, u32 *rx_usecs_high); u32 *tx_usecs_high, u32 *rx_usecs_high);
void (*get_mac_addr)(struct hnae3_handle *handle, u8 *p); void (*get_mac_addr)(struct hnae3_handle *handle, u8 *p);
int (*set_mac_addr)(struct hnae3_handle *handle, void *p); int (*set_mac_addr)(struct hnae3_handle *handle, void *p,
bool is_first);
int (*add_uc_addr)(struct hnae3_handle *handle, int (*add_uc_addr)(struct hnae3_handle *handle,
const unsigned char *addr); const unsigned char *addr);
int (*rm_uc_addr)(struct hnae3_handle *handle, int (*rm_uc_addr)(struct hnae3_handle *handle,
......
...@@ -1120,7 +1120,7 @@ static int hns3_nic_net_set_mac_address(struct net_device *netdev, void *p) ...@@ -1120,7 +1120,7 @@ static int hns3_nic_net_set_mac_address(struct net_device *netdev, void *p)
if (!mac_addr || !is_valid_ether_addr((const u8 *)mac_addr->sa_data)) if (!mac_addr || !is_valid_ether_addr((const u8 *)mac_addr->sa_data))
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
ret = h->ae_algo->ops->set_mac_addr(h, mac_addr->sa_data); ret = h->ae_algo->ops->set_mac_addr(h, mac_addr->sa_data, false);
if (ret) { if (ret) {
netdev_err(netdev, "set_mac_address fail, ret=%d!\n", ret); netdev_err(netdev, "set_mac_address fail, ret=%d!\n", ret);
return ret; return ret;
...@@ -2080,15 +2080,13 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i, ...@@ -2080,15 +2080,13 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i,
desc = &ring->desc[ring->next_to_clean]; desc = &ring->desc[ring->next_to_clean];
size = le16_to_cpu(desc->rx.size); size = le16_to_cpu(desc->rx.size);
if (twobufs) { truesize = hnae_buf_size(ring);
truesize = hnae_buf_size(ring);
} else { if (!twobufs)
truesize = ALIGN(size, L1_CACHE_BYTES);
last_offset = hnae_page_size(ring) - hnae_buf_size(ring); last_offset = hnae_page_size(ring) - hnae_buf_size(ring);
}
skb_add_rx_frag(skb, i, desc_cb->priv, desc_cb->page_offset + pull_len, skb_add_rx_frag(skb, i, desc_cb->priv, desc_cb->page_offset + pull_len,
size - pull_len, truesize - pull_len); size - pull_len, truesize);
/* Avoid re-using remote pages,flag default unreuse */ /* Avoid re-using remote pages,flag default unreuse */
if (unlikely(page_to_nid(desc_cb->priv) != numa_node_id())) if (unlikely(page_to_nid(desc_cb->priv) != numa_node_id()))
...@@ -3048,7 +3046,7 @@ static void hns3_init_mac_addr(struct net_device *netdev) ...@@ -3048,7 +3046,7 @@ static void hns3_init_mac_addr(struct net_device *netdev)
} }
if (h->ae_algo->ops->set_mac_addr) if (h->ae_algo->ops->set_mac_addr)
h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr); h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr, true);
} }
...@@ -3503,7 +3501,7 @@ int hns3_set_channels(struct net_device *netdev, ...@@ -3503,7 +3501,7 @@ int hns3_set_channels(struct net_device *netdev,
return 0; return 0;
if (if_running) if (if_running)
dev_close(netdev); hns3_nic_net_stop(netdev);
hns3_clear_all_ring(h); hns3_clear_all_ring(h);
...@@ -3546,7 +3544,7 @@ int hns3_set_channels(struct net_device *netdev, ...@@ -3546,7 +3544,7 @@ int hns3_set_channels(struct net_device *netdev,
open_netdev: open_netdev:
if (if_running) if (if_running)
dev_open(netdev); hns3_nic_net_open(netdev);
return ret; return ret;
} }
......
...@@ -309,6 +309,9 @@ static void hns3_self_test(struct net_device *ndev, ...@@ -309,6 +309,9 @@ static void hns3_self_test(struct net_device *ndev,
struct hnae3_handle *h = priv->ae_handle; struct hnae3_handle *h = priv->ae_handle;
int st_param[HNS3_SELF_TEST_TPYE_NUM][2]; int st_param[HNS3_SELF_TEST_TPYE_NUM][2];
bool if_running = netif_running(ndev); bool if_running = netif_running(ndev);
#if IS_ENABLED(CONFIG_VLAN_8021Q)
bool dis_vlan_filter;
#endif
int test_index = 0; int test_index = 0;
u32 i; u32 i;
...@@ -323,6 +326,14 @@ static void hns3_self_test(struct net_device *ndev, ...@@ -323,6 +326,14 @@ static void hns3_self_test(struct net_device *ndev,
if (if_running) if (if_running)
dev_close(ndev); dev_close(ndev);
#if IS_ENABLED(CONFIG_VLAN_8021Q)
/* Disable the vlan filter for selftest does not support it */
dis_vlan_filter = (ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
h->ae_algo->ops->enable_vlan_filter;
if (dis_vlan_filter)
h->ae_algo->ops->enable_vlan_filter(h, false);
#endif
set_bit(HNS3_NIC_STATE_TESTING, &priv->state); set_bit(HNS3_NIC_STATE_TESTING, &priv->state);
for (i = 0; i < HNS3_SELF_TEST_TPYE_NUM; i++) { for (i = 0; i < HNS3_SELF_TEST_TPYE_NUM; i++) {
...@@ -345,6 +356,11 @@ static void hns3_self_test(struct net_device *ndev, ...@@ -345,6 +356,11 @@ static void hns3_self_test(struct net_device *ndev,
clear_bit(HNS3_NIC_STATE_TESTING, &priv->state); clear_bit(HNS3_NIC_STATE_TESTING, &priv->state);
#if IS_ENABLED(CONFIG_VLAN_8021Q)
if (dis_vlan_filter)
h->ae_algo->ops->enable_vlan_filter(h, true);
#endif
if (if_running) if (if_running)
dev_open(ndev); dev_open(ndev);
} }
......
...@@ -205,9 +205,11 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets) ...@@ -205,9 +205,11 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets)
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)
{ {
u64 requests[HNAE3_MAX_TC], indications[HNAE3_MAX_TC];
struct hclge_vport *vport = hclge_get_vport(h); struct hclge_vport *vport = hclge_get_vport(h);
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
u8 i, j, pfc_map, *prio_tc; u8 i, j, pfc_map, *prio_tc;
int ret;
memset(pfc, 0, sizeof(*pfc)); memset(pfc, 0, sizeof(*pfc));
pfc->pfc_cap = hdev->pfc_max; pfc->pfc_cap = hdev->pfc_max;
...@@ -222,6 +224,18 @@ static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc) ...@@ -222,6 +224,18 @@ static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
} }
} }
ret = hclge_pfc_tx_stats_get(hdev, requests);
if (ret)
return ret;
ret = hclge_pfc_rx_stats_get(hdev, indications);
if (ret)
return ret;
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
pfc->requests[i] = requests[i];
pfc->indications[i] = indications[i];
}
return 0; return 0;
} }
......
...@@ -3756,6 +3756,9 @@ static void hclge_ae_stop(struct hnae3_handle *handle) ...@@ -3756,6 +3756,9 @@ static void hclge_ae_stop(struct hnae3_handle *handle)
/* reset tqp stats */ /* reset tqp stats */
hclge_reset_tqp_stats(handle); hclge_reset_tqp_stats(handle);
del_timer_sync(&hdev->service_timer);
cancel_work_sync(&hdev->service_task);
hclge_update_link_status(hdev);
} }
static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport, static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
...@@ -3776,11 +3779,11 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport, ...@@ -3776,11 +3779,11 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
if ((!resp_code) || (resp_code == 1)) { if ((!resp_code) || (resp_code == 1)) {
return_status = 0; return_status = 0;
} else if (resp_code == 2) { } else if (resp_code == 2) {
return_status = -EIO; return_status = -ENOSPC;
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"add mac addr failed for uc_overflow.\n"); "add mac addr failed for uc_overflow.\n");
} else if (resp_code == 3) { } else if (resp_code == 3) {
return_status = -EIO; return_status = -ENOSPC;
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"add mac addr failed for mc_overflow.\n"); "add mac addr failed for mc_overflow.\n");
} else { } else {
...@@ -3792,7 +3795,7 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport, ...@@ -3792,7 +3795,7 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
if (!resp_code) { if (!resp_code) {
return_status = 0; return_status = 0;
} else if (resp_code == 1) { } else if (resp_code == 1) {
return_status = -EIO; return_status = -ENOENT;
dev_dbg(&hdev->pdev->dev, dev_dbg(&hdev->pdev->dev,
"remove mac addr failed for miss.\n"); "remove mac addr failed for miss.\n");
} else { } else {
...@@ -3804,7 +3807,7 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport, ...@@ -3804,7 +3807,7 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
if (!resp_code) { if (!resp_code) {
return_status = 0; return_status = 0;
} else if (resp_code == 1) { } else if (resp_code == 1) {
return_status = -EIO; return_status = -ENOENT;
dev_dbg(&hdev->pdev->dev, dev_dbg(&hdev->pdev->dev,
"lookup mac addr failed for miss.\n"); "lookup mac addr failed for miss.\n");
} else { } else {
...@@ -3813,7 +3816,7 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport, ...@@ -3813,7 +3816,7 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
resp_code); resp_code);
} }
} else { } else {
return_status = -EIO; return_status = -EINVAL;
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"unknown opcode for get_mac_vlan_cmd_status,opcode=%d.\n", "unknown opcode for get_mac_vlan_cmd_status,opcode=%d.\n",
op); op);
...@@ -4104,8 +4107,9 @@ int hclge_add_uc_addr_common(struct hclge_vport *vport, ...@@ -4104,8 +4107,9 @@ int hclge_add_uc_addr_common(struct hclge_vport *vport,
{ {
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
struct hclge_mac_vlan_tbl_entry_cmd req; struct hclge_mac_vlan_tbl_entry_cmd req;
enum hclge_cmd_status status; struct hclge_desc desc;
u16 egress_port = 0; u16 egress_port = 0;
int ret;
/* mac addr check */ /* mac addr check */
if (is_zero_ether_addr(addr) || if (is_zero_ether_addr(addr) ||
...@@ -4137,9 +4141,23 @@ int hclge_add_uc_addr_common(struct hclge_vport *vport, ...@@ -4137,9 +4141,23 @@ int hclge_add_uc_addr_common(struct hclge_vport *vport,
hclge_prepare_mac_addr(&req, addr); hclge_prepare_mac_addr(&req, addr);
status = hclge_add_mac_vlan_tbl(vport, &req, NULL); /* Lookup the mac address in the mac_vlan table, and add
* it if the entry is inexistent. Repeated unicast entry
* is not allowed in the mac vlan table.
*/
ret = hclge_lookup_mac_vlan_tbl(vport, &req, &desc, false);
if (ret == -ENOENT)
return hclge_add_mac_vlan_tbl(vport, &req, NULL);
return status; /* check if we just hit the duplicate */
if (!ret)
ret = -EINVAL;
dev_err(&hdev->pdev->dev,
"PF failed to add unicast entry(%pM) in the MAC table\n",
addr);
return ret;
} }
static int hclge_rm_uc_addr(struct hnae3_handle *handle, static int hclge_rm_uc_addr(struct hnae3_handle *handle,
...@@ -4155,7 +4173,7 @@ int hclge_rm_uc_addr_common(struct hclge_vport *vport, ...@@ -4155,7 +4173,7 @@ int hclge_rm_uc_addr_common(struct hclge_vport *vport,
{ {
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
struct hclge_mac_vlan_tbl_entry_cmd req; struct hclge_mac_vlan_tbl_entry_cmd req;
enum hclge_cmd_status status; int ret;
/* mac addr check */ /* mac addr check */
if (is_zero_ether_addr(addr) || if (is_zero_ether_addr(addr) ||
...@@ -4171,9 +4189,9 @@ int hclge_rm_uc_addr_common(struct hclge_vport *vport, ...@@ -4171,9 +4189,9 @@ int hclge_rm_uc_addr_common(struct hclge_vport *vport,
hnae_set_bit(req.flags, HCLGE_MAC_VLAN_BIT0_EN_B, 1); hnae_set_bit(req.flags, HCLGE_MAC_VLAN_BIT0_EN_B, 1);
hnae_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0); hnae_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0);
hclge_prepare_mac_addr(&req, addr); hclge_prepare_mac_addr(&req, addr);
status = hclge_remove_mac_vlan_tbl(vport, &req); ret = hclge_remove_mac_vlan_tbl(vport, &req);
return status; return ret;
} }
static int hclge_add_mc_addr(struct hnae3_handle *handle, static int hclge_add_mc_addr(struct hnae3_handle *handle,
...@@ -4378,7 +4396,8 @@ static void hclge_get_mac_addr(struct hnae3_handle *handle, u8 *p) ...@@ -4378,7 +4396,8 @@ static void hclge_get_mac_addr(struct hnae3_handle *handle, u8 *p)
ether_addr_copy(p, hdev->hw.mac.mac_addr); ether_addr_copy(p, hdev->hw.mac.mac_addr);
} }
static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p) static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p,
bool is_first)
{ {
const unsigned char *new_addr = (const unsigned char *)p; const unsigned char *new_addr = (const unsigned char *)p;
struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_vport *vport = hclge_get_vport(handle);
...@@ -4395,11 +4414,9 @@ static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p) ...@@ -4395,11 +4414,9 @@ static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p)
return -EINVAL; return -EINVAL;
} }
ret = hclge_rm_uc_addr(handle, hdev->hw.mac.mac_addr); if (!is_first && hclge_rm_uc_addr(handle, hdev->hw.mac.mac_addr))
if (ret)
dev_warn(&hdev->pdev->dev, dev_warn(&hdev->pdev->dev,
"remove old uc mac address fail, ret =%d.\n", "remove old uc mac address fail.\n");
ret);
ret = hclge_add_uc_addr(handle, new_addr); ret = hclge_add_uc_addr(handle, new_addr);
if (ret) { if (ret) {
...@@ -4407,17 +4424,15 @@ static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p) ...@@ -4407,17 +4424,15 @@ static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p)
"add uc mac address fail, ret =%d.\n", "add uc mac address fail, ret =%d.\n",
ret); ret);
ret = hclge_add_uc_addr(handle, hdev->hw.mac.mac_addr); if (!is_first &&
if (ret) { hclge_add_uc_addr(handle, hdev->hw.mac.mac_addr))
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"restore uc mac address fail, ret =%d.\n", "restore uc mac address fail.\n");
ret);
}
return -EIO; return -EIO;
} }
ret = hclge_mac_pause_addr_cfg(hdev, new_addr); ret = hclge_pause_addr_cfg(hdev, new_addr);
if (ret) { if (ret) {
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"configure mac pause address fail, ret =%d.\n", "configure mac pause address fail, ret =%d.\n",
......
...@@ -105,14 +105,17 @@ static int hclge_get_ring_chain_from_mbx( ...@@ -105,14 +105,17 @@ static int hclge_get_ring_chain_from_mbx(
struct hnae3_ring_chain_node *ring_chain, struct hnae3_ring_chain_node *ring_chain,
struct hclge_vport *vport) struct hclge_vport *vport)
{ {
#define HCLGE_RING_NODE_VARIABLE_NUM 3
#define HCLGE_RING_MAP_MBX_BASIC_MSG_NUM 3
struct hnae3_ring_chain_node *cur_chain, *new_chain; struct hnae3_ring_chain_node *cur_chain, *new_chain;
int ring_num; int ring_num;
int i; int i;
ring_num = req->msg[2]; ring_num = req->msg[2];
if (ring_num > ((HCLGE_MBX_VF_MSG_DATA_NUM -
HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) /
HCLGE_MBX_RING_NODE_VARIABLE_NUM))
return -ENOMEM;
hnae_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, req->msg[3]); hnae_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, req->msg[3]);
ring_chain->tqp_index = ring_chain->tqp_index =
hclge_get_queue_id(vport->nic.kinfo.tqp[req->msg[4]]); hclge_get_queue_id(vport->nic.kinfo.tqp[req->msg[4]]);
...@@ -128,18 +131,18 @@ static int hclge_get_ring_chain_from_mbx( ...@@ -128,18 +131,18 @@ static int hclge_get_ring_chain_from_mbx(
goto err; goto err;
hnae_set_bit(new_chain->flag, HNAE3_RING_TYPE_B, hnae_set_bit(new_chain->flag, HNAE3_RING_TYPE_B,
req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i + req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i +
HCLGE_RING_MAP_MBX_BASIC_MSG_NUM]); HCLGE_MBX_RING_MAP_BASIC_MSG_NUM]);
new_chain->tqp_index = new_chain->tqp_index =
hclge_get_queue_id(vport->nic.kinfo.tqp hclge_get_queue_id(vport->nic.kinfo.tqp
[req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i + [req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i +
HCLGE_RING_MAP_MBX_BASIC_MSG_NUM + 1]]); HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 1]]);
hnae_set_field(new_chain->int_gl_idx, HCLGE_INT_GL_IDX_M, hnae_set_field(new_chain->int_gl_idx, HCLGE_INT_GL_IDX_M,
HCLGE_INT_GL_IDX_S, HCLGE_INT_GL_IDX_S,
req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i + req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i +
HCLGE_RING_MAP_MBX_BASIC_MSG_NUM + 2]); HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 2]);
cur_chain->next = new_chain; cur_chain->next = new_chain;
cur_chain = new_chain; cur_chain = new_chain;
...@@ -196,6 +199,8 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, ...@@ -196,6 +199,8 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport,
hclge_rm_uc_addr_common(vport, old_addr); hclge_rm_uc_addr_common(vport, old_addr);
status = hclge_add_uc_addr_common(vport, mac_addr); status = hclge_add_uc_addr_common(vport, mac_addr);
if (status)
hclge_add_uc_addr_common(vport, old_addr);
} else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_ADD) { } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_ADD) {
status = hclge_add_uc_addr_common(vport, mac_addr); status = hclge_add_uc_addr_common(vport, mac_addr);
} else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_REMOVE) { } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_REMOVE) {
...@@ -360,7 +365,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev) ...@@ -360,7 +365,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
ret); ret);
break; break;
case HCLGE_MBX_SET_UNICAST: case HCLGE_MBX_SET_UNICAST:
ret = hclge_set_vf_uc_mac_addr(vport, req, false); ret = hclge_set_vf_uc_mac_addr(vport, req, true);
if (ret) if (ret)
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"PF fail(%d) to set VF UC MAC Addr\n", "PF fail(%d) to set VF UC MAC Addr\n",
......
...@@ -23,6 +23,9 @@ enum hclge_shaper_level { ...@@ -23,6 +23,9 @@ enum hclge_shaper_level {
HCLGE_SHAPER_LVL_PF = 1, HCLGE_SHAPER_LVL_PF = 1,
}; };
#define HCLGE_TM_PFC_PKT_GET_CMD_NUM 3
#define HCLGE_TM_PFC_NUM_GET_PER_CMD 3
#define HCLGE_SHAPER_BS_U_DEF 5 #define HCLGE_SHAPER_BS_U_DEF 5
#define HCLGE_SHAPER_BS_S_DEF 20 #define HCLGE_SHAPER_BS_S_DEF 20
...@@ -112,6 +115,56 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, ...@@ -112,6 +115,56 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level,
return 0; return 0;
} }
static int hclge_pfc_stats_get(struct hclge_dev *hdev,
enum hclge_opcode_type opcode, u64 *stats)
{
struct hclge_desc desc[HCLGE_TM_PFC_PKT_GET_CMD_NUM];
int ret, i, j;
if (!(opcode == HCLGE_OPC_QUERY_PFC_RX_PKT_CNT ||
opcode == HCLGE_OPC_QUERY_PFC_TX_PKT_CNT))
return -EINVAL;
for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) {
hclge_cmd_setup_basic_desc(&desc[i], opcode, true);
if (i != (HCLGE_TM_PFC_PKT_GET_CMD_NUM - 1))
desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
else
desc[i].flag &= ~cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
}
ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_TM_PFC_PKT_GET_CMD_NUM);
if (ret) {
dev_err(&hdev->pdev->dev,
"Get pfc pause stats fail, ret = %d.\n", ret);
return ret;
}
for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) {
struct hclge_pfc_stats_cmd *pfc_stats =
(struct hclge_pfc_stats_cmd *)desc[i].data;
for (j = 0; j < HCLGE_TM_PFC_NUM_GET_PER_CMD; j++) {
u32 index = i * HCLGE_TM_PFC_PKT_GET_CMD_NUM + j;
if (index < HCLGE_MAX_TC_NUM)
stats[index] =
le64_to_cpu(pfc_stats->pkt_num[j]);
}
}
return 0;
}
int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats)
{
return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_RX_PKT_CNT, stats);
}
int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats)
{
return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_TX_PKT_CNT, stats);
}
int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx) int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)
{ {
struct hclge_desc desc; struct hclge_desc desc;
...@@ -138,8 +191,8 @@ static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, ...@@ -138,8 +191,8 @@ static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
return hclge_cmd_send(&hdev->hw, &desc, 1); return hclge_cmd_send(&hdev->hw, &desc, 1);
} }
static int hclge_mac_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr, static int hclge_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr,
u8 pause_trans_gap, u16 pause_trans_time) u8 pause_trans_gap, u16 pause_trans_time)
{ {
struct hclge_cfg_pause_param_cmd *pause_param; struct hclge_cfg_pause_param_cmd *pause_param;
struct hclge_desc desc; struct hclge_desc desc;
...@@ -155,7 +208,7 @@ static int hclge_mac_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr, ...@@ -155,7 +208,7 @@ static int hclge_mac_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr,
return hclge_cmd_send(&hdev->hw, &desc, 1); return hclge_cmd_send(&hdev->hw, &desc, 1);
} }
int hclge_mac_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr) int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr)
{ {
struct hclge_cfg_pause_param_cmd *pause_param; struct hclge_cfg_pause_param_cmd *pause_param;
struct hclge_desc desc; struct hclge_desc desc;
...@@ -174,7 +227,7 @@ int hclge_mac_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr) ...@@ -174,7 +227,7 @@ int hclge_mac_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr)
trans_gap = pause_param->pause_trans_gap; trans_gap = pause_param->pause_trans_gap;
trans_time = le16_to_cpu(pause_param->pause_trans_time); trans_time = le16_to_cpu(pause_param->pause_trans_time);
return hclge_mac_pause_param_cfg(hdev, mac_addr, trans_gap, return hclge_pause_param_cfg(hdev, mac_addr, trans_gap,
trans_time); trans_time);
} }
...@@ -1096,11 +1149,11 @@ static int hclge_tm_schd_setup_hw(struct hclge_dev *hdev) ...@@ -1096,11 +1149,11 @@ static int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
return hclge_tm_schd_mode_hw(hdev); return hclge_tm_schd_mode_hw(hdev);
} }
static int hclge_mac_pause_param_setup_hw(struct hclge_dev *hdev) static int hclge_pause_param_setup_hw(struct hclge_dev *hdev)
{ {
struct hclge_mac *mac = &hdev->hw.mac; struct hclge_mac *mac = &hdev->hw.mac;
return hclge_mac_pause_param_cfg(hdev, mac->mac_addr, return hclge_pause_param_cfg(hdev, mac->mac_addr,
HCLGE_DEFAULT_PAUSE_TRANS_GAP, HCLGE_DEFAULT_PAUSE_TRANS_GAP,
HCLGE_DEFAULT_PAUSE_TRANS_TIME); HCLGE_DEFAULT_PAUSE_TRANS_TIME);
} }
...@@ -1151,13 +1204,12 @@ int hclge_pause_setup_hw(struct hclge_dev *hdev) ...@@ -1151,13 +1204,12 @@ int hclge_pause_setup_hw(struct hclge_dev *hdev)
int ret; int ret;
u8 i; u8 i;
if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) { ret = hclge_pause_param_setup_hw(hdev);
ret = hclge_mac_pause_setup_hw(hdev); if (ret)
if (ret) return ret;
return ret;
return hclge_mac_pause_param_setup_hw(hdev); if (hdev->tm_info.fc_mode != HCLGE_FC_PFC)
} return hclge_mac_pause_setup_hw(hdev);
/* Only DCB-supported dev supports qset back pressure and pfc cmd */ /* Only DCB-supported dev supports qset back pressure and pfc cmd */
if (!hnae3_dev_dcb_supported(hdev)) if (!hnae3_dev_dcb_supported(hdev))
......
...@@ -109,6 +109,10 @@ struct hclge_cfg_pause_param_cmd { ...@@ -109,6 +109,10 @@ struct hclge_cfg_pause_param_cmd {
__le16 pause_trans_time; __le16 pause_trans_time;
}; };
struct hclge_pfc_stats_cmd {
__le64 pkt_num[3];
};
struct hclge_port_shapping_cmd { struct hclge_port_shapping_cmd {
__le32 port_shapping_para; __le32 port_shapping_para;
}; };
...@@ -129,5 +133,7 @@ int hclge_tm_dwrr_cfg(struct hclge_dev *hdev); ...@@ -129,5 +133,7 @@ int hclge_tm_dwrr_cfg(struct hclge_dev *hdev);
int hclge_tm_map_cfg(struct hclge_dev *hdev); int hclge_tm_map_cfg(struct hclge_dev *hdev);
int hclge_tm_init_hw(struct hclge_dev *hdev); int hclge_tm_init_hw(struct hclge_dev *hdev);
int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx); int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx);
int hclge_mac_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr);
int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats);
int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats);
#endif #endif
...@@ -533,13 +533,11 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en, ...@@ -533,13 +533,11 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
int vector, int vector,
struct hnae3_ring_chain_node *ring_chain) struct hnae3_ring_chain_node *ring_chain)
{ {
#define HCLGEVF_RING_NODE_VARIABLE_NUM 3
#define HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM 3
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
struct hnae3_ring_chain_node *node; struct hnae3_ring_chain_node *node;
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 i, vector_id; int i = 0, vector_id;
int status; int status;
u8 type; u8 type;
...@@ -551,28 +549,33 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en, ...@@ -551,28 +549,33 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
return vector_id; return vector_id;
} }
hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false);
type = en ?
HCLGE_MBX_MAP_RING_TO_VECTOR : HCLGE_MBX_UNMAP_RING_TO_VECTOR;
req->msg[0] = type;
req->msg[1] = vector_id; /* vector_id should be id in VF */
i = 0;
for (node = ring_chain; node; node = node->next) { for (node = ring_chain; node; node = node->next) {
i++; int idx_offset = HCLGE_MBX_RING_MAP_BASIC_MSG_NUM +
/* msg[2] is cause num */ HCLGE_MBX_RING_NODE_VARIABLE_NUM * i;
req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i] =
if (i == 0) {
hclgevf_cmd_setup_basic_desc(&desc,
HCLGEVF_OPC_MBX_VF_TO_PF,
false);
type = en ?
HCLGE_MBX_MAP_RING_TO_VECTOR :
HCLGE_MBX_UNMAP_RING_TO_VECTOR;
req->msg[0] = type;
req->msg[1] = vector_id;
}
req->msg[idx_offset] =
hnae_get_bit(node->flag, HNAE3_RING_TYPE_B); hnae_get_bit(node->flag, HNAE3_RING_TYPE_B);
req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i + 1] = req->msg[idx_offset + 1] = node->tqp_index;
node->tqp_index; req->msg[idx_offset + 2] = hnae_get_field(node->int_gl_idx,
req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i + 2] = HNAE3_RING_GL_IDX_M,
hnae_get_field(node->int_gl_idx, HNAE3_RING_GL_IDX_S);
HNAE3_RING_GL_IDX_M,
HNAE3_RING_GL_IDX_S); i++;
if ((i == (HCLGE_MBX_VF_MSG_DATA_NUM -
if (i == (HCLGE_MBX_VF_MSG_DATA_NUM - HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) /
HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM) / HCLGE_MBX_RING_NODE_VARIABLE_NUM) ||
HCLGEVF_RING_NODE_VARIABLE_NUM) { !node->next) {
req->msg[2] = i; req->msg[2] = i;
status = hclgevf_cmd_send(&hdev->hw, &desc, 1); status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
...@@ -591,17 +594,6 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en, ...@@ -591,17 +594,6 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
} }
} }
if (i > 0) {
req->msg[2] = i;
status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
if (status) {
dev_err(&hdev->pdev->dev,
"Map TQP fail, status is %d.\n", status);
return status;
}
}
return 0; return 0;
} }
...@@ -734,21 +726,25 @@ static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p) ...@@ -734,21 +726,25 @@ static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p)
ether_addr_copy(p, hdev->hw.mac.mac_addr); ether_addr_copy(p, hdev->hw.mac.mac_addr);
} }
static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p) static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p,
bool is_first)
{ {
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr; u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr;
u8 *new_mac_addr = (u8 *)p; u8 *new_mac_addr = (u8 *)p;
u8 msg_data[ETH_ALEN * 2]; u8 msg_data[ETH_ALEN * 2];
u16 subcode;
int status; int status;
ether_addr_copy(msg_data, new_mac_addr); ether_addr_copy(msg_data, new_mac_addr);
ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr); ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr);
subcode = is_first ? HCLGE_MBX_MAC_VLAN_UC_ADD :
HCLGE_MBX_MAC_VLAN_UC_MODIFY;
status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST,
HCLGE_MBX_MAC_VLAN_UC_MODIFY, subcode, msg_data, ETH_ALEN * 2,
msg_data, ETH_ALEN * 2, true, NULL, 0);
false, NULL, 0);
if (!status) if (!status)
ether_addr_copy(hdev->hw.mac.mac_addr, new_mac_addr); ether_addr_copy(hdev->hw.mac.mac_addr, new_mac_addr);
...@@ -1062,6 +1058,9 @@ static void hclgevf_ae_stop(struct hnae3_handle *handle) ...@@ -1062,6 +1058,9 @@ static void hclgevf_ae_stop(struct hnae3_handle *handle)
/* reset tqp stats */ /* reset tqp stats */
hclgevf_reset_tqp_stats(handle); hclgevf_reset_tqp_stats(handle);
del_timer_sync(&hdev->service_timer);
cancel_work_sync(&hdev->service_task);
hclgevf_update_link_status(hdev, 0);
} }
static void hclgevf_state_init(struct hclgevf_dev *hdev) static void hclgevf_state_init(struct hclgevf_dev *hdev)
......
...@@ -54,6 +54,10 @@ static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1, ...@@ -54,6 +54,10 @@ static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1,
mbx_resp = &hdev->mbx_resp; mbx_resp = &hdev->mbx_resp;
r_code0 = (u16)(mbx_resp->origin_mbx_msg >> 16); r_code0 = (u16)(mbx_resp->origin_mbx_msg >> 16);
r_code1 = (u16)(mbx_resp->origin_mbx_msg & 0xff); r_code1 = (u16)(mbx_resp->origin_mbx_msg & 0xff);
if (mbx_resp->resp_status)
return mbx_resp->resp_status;
if (resp_data) if (resp_data)
memcpy(resp_data, &mbx_resp->additional_info[0], resp_len); memcpy(resp_data, &mbx_resp->additional_info[0], resp_len);
......
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