Commit 18838d0c authored by Fuyun Liang's avatar Fuyun Liang Committed by David S. Miller

net: hns3: fix for not setting pause parameters

Pause parameters include source address, transmit gap and pause time.
The default value of the pause source address is zero in the hardware.
Default pause parameters need to be set to the hardware. Also, when
setting new mac address, the pause source address need to be updated.

Fixes: 9dc2145d ("net: hns3: Add support for PFC setting in TM module")
Signed-off-by: default avatarFuyun Liang <liangfuyun1@huawei.com>
Signed-off-by: default avatarPeng Li <lipeng321@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f9fd82a9
......@@ -4225,6 +4225,7 @@ static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p)
const unsigned char *new_addr = (const unsigned char *)p;
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
int ret;
/* mac addr check */
if (is_zero_ether_addr(new_addr) ||
......@@ -4236,14 +4237,39 @@ static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p)
return -EINVAL;
}
hclge_rm_uc_addr(handle, hdev->hw.mac.mac_addr);
ret = hclge_rm_uc_addr(handle, hdev->hw.mac.mac_addr);
if (ret)
dev_warn(&hdev->pdev->dev,
"remove old uc mac address fail, ret =%d.\n",
ret);
if (!hclge_add_uc_addr(handle, new_addr)) {
ether_addr_copy(hdev->hw.mac.mac_addr, new_addr);
return 0;
ret = hclge_add_uc_addr(handle, new_addr);
if (ret) {
dev_err(&hdev->pdev->dev,
"add uc mac address fail, ret =%d.\n",
ret);
ret = hclge_add_uc_addr(handle, hdev->hw.mac.mac_addr);
if (ret) {
dev_err(&hdev->pdev->dev,
"restore uc mac address fail, ret =%d.\n",
ret);
}
return -EIO;
}
return -EIO;
ret = hclge_mac_pause_addr_cfg(hdev, new_addr);
if (ret) {
dev_err(&hdev->pdev->dev,
"configure mac pause address fail, ret =%d.\n",
ret);
return -EIO;
}
ether_addr_copy(hdev->hw.mac.mac_addr, new_addr);
return 0;
}
static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type,
......
......@@ -138,6 +138,46 @@ static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
return hclge_cmd_send(&hdev->hw, &desc, 1);
}
static int hclge_mac_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr,
u8 pause_trans_gap, u16 pause_trans_time)
{
struct hclge_cfg_pause_param_cmd *pause_param;
struct hclge_desc desc;
pause_param = (struct hclge_cfg_pause_param_cmd *)&desc.data;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, false);
ether_addr_copy(pause_param->mac_addr, addr);
pause_param->pause_trans_gap = pause_trans_gap;
pause_param->pause_trans_time = cpu_to_le16(pause_trans_time);
return hclge_cmd_send(&hdev->hw, &desc, 1);
}
int hclge_mac_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr)
{
struct hclge_cfg_pause_param_cmd *pause_param;
struct hclge_desc desc;
u16 trans_time;
u8 trans_gap;
int ret;
pause_param = (struct hclge_cfg_pause_param_cmd *)&desc.data;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, true);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret)
return ret;
trans_gap = pause_param->pause_trans_gap;
trans_time = le16_to_cpu(pause_param->pause_trans_time);
return hclge_mac_pause_param_cfg(hdev, mac_addr, trans_gap,
trans_time);
}
static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id)
{
u8 tc;
......@@ -1056,6 +1096,15 @@ static int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
return hclge_tm_schd_mode_hw(hdev);
}
static int hclge_mac_pause_param_setup_hw(struct hclge_dev *hdev)
{
struct hclge_mac *mac = &hdev->hw.mac;
return hclge_mac_pause_param_cfg(hdev, mac->mac_addr,
HCLGE_DEFAULT_PAUSE_TRANS_GAP,
HCLGE_DEFAULT_PAUSE_TRANS_TIME);
}
static int hclge_pfc_setup_hw(struct hclge_dev *hdev)
{
u8 enable_bitmap = 0;
......@@ -1102,8 +1151,13 @@ int hclge_pause_setup_hw(struct hclge_dev *hdev)
int ret;
u8 i;
if (hdev->tm_info.fc_mode != HCLGE_FC_PFC)
return hclge_mac_pause_setup_hw(hdev);
if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) {
ret = hclge_mac_pause_setup_hw(hdev);
if (ret)
return ret;
return hclge_mac_pause_param_setup_hw(hdev);
}
/* Only DCB-supported dev supports qset back pressure and pfc cmd */
if (!hnae3_dev_dcb_supported(hdev))
......
......@@ -18,6 +18,9 @@
#define HCLGE_TM_PORT_BASE_MODE_MSK BIT(0)
#define HCLGE_DEFAULT_PAUSE_TRANS_GAP 0xFF
#define HCLGE_DEFAULT_PAUSE_TRANS_TIME 0xFFFF
/* SP or DWRR */
#define HCLGE_TM_TX_SCHD_DWRR_MSK BIT(0)
#define HCLGE_TM_TX_SCHD_SP_MSK (0xFE)
......@@ -99,6 +102,13 @@ struct hclge_pfc_en_cmd {
u8 pri_en_bitmap;
};
struct hclge_cfg_pause_param_cmd {
u8 mac_addr[ETH_ALEN];
u8 pause_trans_gap;
u8 rsvd;
__le16 pause_trans_time;
};
struct hclge_port_shapping_cmd {
__le32 port_shapping_para;
};
......@@ -119,4 +129,5 @@ int hclge_tm_dwrr_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_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);
#endif
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