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: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
a68a848135
|
@ -40,6 +40,8 @@ enum HCLGE_MBX_OPCODE {
|
|||
HCLGE_MBX_SET_ALIVE, /* (VF -> PF) set alive state */
|
||||
HCLGE_MBX_SET_MTU, /* (VF -> PF) set mtu */
|
||||
HCLGE_MBX_GET_QID_IN_PF, /* (VF -> PF) get queue id in pf */
|
||||
HCLGE_MBX_LINK_STAT_MODE, /* (PF -> VF) link mode has changed */
|
||||
HCLGE_MBX_GET_LINK_MODE, /* (VF -> PF) get the link mode of pf */
|
||||
};
|
||||
|
||||
/* below are per-VF mac-vlan subcodes */
|
||||
|
@ -60,7 +62,7 @@ enum hclge_mbx_vlan_cfg_subcode {
|
|||
};
|
||||
|
||||
#define HCLGE_MBX_MAX_MSG_SIZE 16
|
||||
#define HCLGE_MBX_MAX_RESP_DATA_SIZE 8
|
||||
#define HCLGE_MBX_MAX_RESP_DATA_SIZE 16
|
||||
#define HCLGE_MBX_RING_MAP_BASIC_MSG_NUM 3
|
||||
#define HCLGE_MBX_RING_NODE_VARIABLE_NUM 3
|
||||
|
||||
|
|
|
@ -461,7 +461,7 @@ struct hnae3_ae_ops {
|
|||
bool (*get_hw_reset_stat)(struct hnae3_handle *handle);
|
||||
bool (*ae_dev_resetting)(struct hnae3_handle *handle);
|
||||
unsigned long (*ae_dev_reset_cnt)(struct hnae3_handle *handle);
|
||||
int (*set_gro_en)(struct hnae3_handle *handle, int enable);
|
||||
int (*set_gro_en)(struct hnae3_handle *handle, bool enable);
|
||||
u16 (*get_global_queue_id)(struct hnae3_handle *handle, u16 queue_id);
|
||||
void (*set_timer_task)(struct hnae3_handle *handle, bool enable);
|
||||
int (*mac_connect_phy)(struct hnae3_handle *handle);
|
||||
|
|
|
@ -1349,6 +1349,7 @@ static int hns3_nic_set_features(struct net_device *netdev,
|
|||
netdev_features_t changed = netdev->features ^ features;
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
bool enable;
|
||||
int ret;
|
||||
|
||||
if (changed & (NETIF_F_TSO | NETIF_F_TSO6)) {
|
||||
|
@ -1359,38 +1360,29 @@ static int hns3_nic_set_features(struct net_device *netdev,
|
|||
}
|
||||
|
||||
if (changed & (NETIF_F_GRO_HW) && h->ae_algo->ops->set_gro_en) {
|
||||
if (features & NETIF_F_GRO_HW)
|
||||
ret = h->ae_algo->ops->set_gro_en(h, true);
|
||||
else
|
||||
ret = h->ae_algo->ops->set_gro_en(h, false);
|
||||
enable = !!(features & NETIF_F_GRO_HW);
|
||||
ret = h->ae_algo->ops->set_gro_en(h, enable);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_HW_VLAN_CTAG_FILTER) &&
|
||||
h->ae_algo->ops->enable_vlan_filter) {
|
||||
if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
|
||||
h->ae_algo->ops->enable_vlan_filter(h, true);
|
||||
else
|
||||
h->ae_algo->ops->enable_vlan_filter(h, false);
|
||||
enable = !!(features & NETIF_F_HW_VLAN_CTAG_FILTER);
|
||||
h->ae_algo->ops->enable_vlan_filter(h, enable);
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_HW_VLAN_CTAG_RX) &&
|
||||
h->ae_algo->ops->enable_hw_strip_rxvtag) {
|
||||
if (features & NETIF_F_HW_VLAN_CTAG_RX)
|
||||
ret = h->ae_algo->ops->enable_hw_strip_rxvtag(h, true);
|
||||
else
|
||||
ret = h->ae_algo->ops->enable_hw_strip_rxvtag(h, false);
|
||||
|
||||
enable = !!(features & NETIF_F_HW_VLAN_CTAG_RX);
|
||||
ret = h->ae_algo->ops->enable_hw_strip_rxvtag(h, enable);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((changed & NETIF_F_NTUPLE) && h->ae_algo->ops->enable_fd) {
|
||||
if (features & NETIF_F_NTUPLE)
|
||||
h->ae_algo->ops->enable_fd(h, true);
|
||||
else
|
||||
h->ae_algo->ops->enable_fd(h, false);
|
||||
enable = !!(features & NETIF_F_NTUPLE);
|
||||
h->ae_algo->ops->enable_fd(h, enable);
|
||||
}
|
||||
|
||||
netdev->features = features;
|
||||
|
@ -1937,8 +1929,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
|
|||
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC;
|
||||
|
||||
if (pdev->revision >= 0x21) {
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER |
|
||||
NETIF_F_GRO_HW;
|
||||
netdev->hw_features |= NETIF_F_GRO_HW;
|
||||
netdev->features |= NETIF_F_GRO_HW;
|
||||
|
||||
if (!(h->flags & HNAE3_SUPPORT_VF)) {
|
||||
|
@ -2777,7 +2768,7 @@ static bool hns3_get_new_int_gl(struct hns3_enet_ring_group *ring_group)
|
|||
u32 time_passed_ms;
|
||||
u16 new_int_gl;
|
||||
|
||||
if (!ring_group->coal.int_gl || !tqp_vector->last_jiffies)
|
||||
if (!tqp_vector->last_jiffies)
|
||||
return false;
|
||||
|
||||
if (ring_group->total_packets == 0) {
|
||||
|
@ -2880,7 +2871,7 @@ static void hns3_update_new_int_gl(struct hns3_enet_tqp_vector *tqp_vector)
|
|||
}
|
||||
|
||||
if (tx_group->coal.gl_adapt_enable) {
|
||||
tx_update = hns3_get_new_int_gl(&tqp_vector->tx_group);
|
||||
tx_update = hns3_get_new_int_gl(tx_group);
|
||||
if (tx_update)
|
||||
hns3_set_vector_coalesce_tx_gl(tqp_vector,
|
||||
tx_group->coal.int_gl);
|
||||
|
|
|
@ -186,6 +186,38 @@ static bool hclge_is_special_opcode(u16 opcode)
|
|||
return false;
|
||||
}
|
||||
|
||||
static int hclge_cmd_check_retval(struct hclge_hw *hw, struct hclge_desc *desc,
|
||||
int num, int ntc)
|
||||
{
|
||||
u16 opcode, desc_ret;
|
||||
int handle;
|
||||
int retval;
|
||||
|
||||
opcode = le16_to_cpu(desc[0].opcode);
|
||||
for (handle = 0; handle < num; handle++) {
|
||||
desc[handle] = hw->cmq.csq.desc[ntc];
|
||||
ntc++;
|
||||
if (ntc >= hw->cmq.csq.desc_num)
|
||||
ntc = 0;
|
||||
}
|
||||
if (likely(!hclge_is_special_opcode(opcode)))
|
||||
desc_ret = le16_to_cpu(desc[num - 1].retval);
|
||||
else
|
||||
desc_ret = le16_to_cpu(desc[0].retval);
|
||||
|
||||
if (desc_ret == HCLGE_CMD_EXEC_SUCCESS)
|
||||
retval = 0;
|
||||
else if (desc_ret == HCLGE_CMD_NO_AUTH)
|
||||
retval = -EPERM;
|
||||
else if (desc_ret == HCLGE_CMD_NOT_SUPPORTED)
|
||||
retval = -EOPNOTSUPP;
|
||||
else
|
||||
retval = -EIO;
|
||||
hw->cmq.last_status = desc_ret;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* hclge_cmd_send - send command to command queue
|
||||
* @hw: pointer to the hw struct
|
||||
|
@ -203,7 +235,6 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num)
|
|||
u32 timeout = 0;
|
||||
int handle = 0;
|
||||
int retval = 0;
|
||||
u16 opcode, desc_ret;
|
||||
int ntc;
|
||||
|
||||
spin_lock_bh(&hw->cmq.csq.lock);
|
||||
|
@ -219,12 +250,11 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num)
|
|||
* which will be use for hardware to write back
|
||||
*/
|
||||
ntc = hw->cmq.csq.next_to_use;
|
||||
opcode = le16_to_cpu(desc[0].opcode);
|
||||
while (handle < num) {
|
||||
desc_to_use = &hw->cmq.csq.desc[hw->cmq.csq.next_to_use];
|
||||
*desc_to_use = desc[handle];
|
||||
(hw->cmq.csq.next_to_use)++;
|
||||
if (hw->cmq.csq.next_to_use == hw->cmq.csq.desc_num)
|
||||
if (hw->cmq.csq.next_to_use >= hw->cmq.csq.desc_num)
|
||||
hw->cmq.csq.next_to_use = 0;
|
||||
handle++;
|
||||
}
|
||||
|
@ -250,31 +280,7 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num)
|
|||
if (!complete) {
|
||||
retval = -EAGAIN;
|
||||
} else {
|
||||
handle = 0;
|
||||
while (handle < num) {
|
||||
/* Get the result of hardware write back */
|
||||
desc_to_use = &hw->cmq.csq.desc[ntc];
|
||||
desc[handle] = *desc_to_use;
|
||||
|
||||
if (likely(!hclge_is_special_opcode(opcode)))
|
||||
desc_ret = le16_to_cpu(desc[handle].retval);
|
||||
else
|
||||
desc_ret = le16_to_cpu(desc[0].retval);
|
||||
|
||||
if (desc_ret == HCLGE_CMD_EXEC_SUCCESS)
|
||||
retval = 0;
|
||||
else if (desc_ret == HCLGE_CMD_NO_AUTH)
|
||||
retval = -EPERM;
|
||||
else if (desc_ret == HCLGE_CMD_NOT_SUPPORTED)
|
||||
retval = -EOPNOTSUPP;
|
||||
else
|
||||
retval = -EIO;
|
||||
hw->cmq.last_status = desc_ret;
|
||||
ntc++;
|
||||
handle++;
|
||||
if (ntc == hw->cmq.csq.desc_num)
|
||||
ntc = 0;
|
||||
}
|
||||
retval = hclge_cmd_check_retval(hw, desc, num, ntc);
|
||||
}
|
||||
|
||||
/* Clean the command send queue */
|
||||
|
|
|
@ -312,16 +312,16 @@ struct hclge_ctrl_vector_chain_cmd {
|
|||
u8 rsv;
|
||||
};
|
||||
|
||||
#define HCLGE_TC_NUM 8
|
||||
#define HCLGE_MAX_TC_NUM 8
|
||||
#define HCLGE_TC0_PRI_BUF_EN_B 15 /* Bit 15 indicate enable or not */
|
||||
#define HCLGE_BUF_UNIT_S 7 /* Buf size is united by 128 bytes */
|
||||
struct hclge_tx_buff_alloc_cmd {
|
||||
__le16 tx_pkt_buff[HCLGE_TC_NUM];
|
||||
__le16 tx_pkt_buff[HCLGE_MAX_TC_NUM];
|
||||
u8 tx_buff_rsv[8];
|
||||
};
|
||||
|
||||
struct hclge_rx_priv_buff_cmd {
|
||||
__le16 buf_num[HCLGE_TC_NUM];
|
||||
__le16 buf_num[HCLGE_MAX_TC_NUM];
|
||||
__le16 shared_buf;
|
||||
u8 rsv[6];
|
||||
};
|
||||
|
@ -367,7 +367,6 @@ struct hclge_priv_buf {
|
|||
u32 enable; /* Enable TC private buffer or not */
|
||||
};
|
||||
|
||||
#define HCLGE_MAX_TC_NUM 8
|
||||
struct hclge_shared_buf {
|
||||
struct hclge_waterline self;
|
||||
struct hclge_tc_thrd tc_thrd[HCLGE_MAX_TC_NUM];
|
||||
|
|
|
@ -691,7 +691,7 @@ static void hclge_dbg_dump_qos_buf_cfg(struct hclge_dev *hdev)
|
|||
dev_info(&hdev->pdev->dev, "dump qos buf cfg\n");
|
||||
|
||||
tx_buf_cmd = (struct hclge_tx_buff_alloc_cmd *)desc[0].data;
|
||||
for (i = 0; i < HCLGE_TC_NUM; i++)
|
||||
for (i = 0; i < HCLGE_MAX_TC_NUM; i++)
|
||||
dev_info(&hdev->pdev->dev, "tx_packet_buf_tc_%d: 0x%x\n", i,
|
||||
tx_buf_cmd->tx_pkt_buff[i]);
|
||||
|
||||
|
@ -703,7 +703,7 @@ static void hclge_dbg_dump_qos_buf_cfg(struct hclge_dev *hdev)
|
|||
|
||||
dev_info(&hdev->pdev->dev, "\n");
|
||||
rx_buf_cmd = (struct hclge_rx_priv_buff_cmd *)desc[0].data;
|
||||
for (i = 0; i < HCLGE_TC_NUM; i++)
|
||||
for (i = 0; i < HCLGE_MAX_TC_NUM; i++)
|
||||
dev_info(&hdev->pdev->dev, "rx_packet_buf_tc_%d: 0x%x\n", i,
|
||||
rx_buf_cmd->buf_num[i]);
|
||||
|
||||
|
|
|
@ -1331,7 +1331,7 @@ static int hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev,
|
|||
req = (struct hclge_tx_buff_alloc_cmd *)desc.data;
|
||||
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TX_BUFF_ALLOC, 0);
|
||||
for (i = 0; i < HCLGE_TC_NUM; i++) {
|
||||
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
|
||||
u32 buf_size = buf_alloc->priv_buf[i].tx_buf_size;
|
||||
|
||||
req->tx_pkt_buff[i] =
|
||||
|
@ -1506,13 +1506,14 @@ static int hclge_tx_buffer_calc(struct hclge_dev *hdev,
|
|||
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
|
||||
struct hclge_priv_buf *priv = &buf_alloc->priv_buf[i];
|
||||
|
||||
if (total_size < hdev->tx_buf_size)
|
||||
return -ENOMEM;
|
||||
if (hdev->hw_tc_map & BIT(i)) {
|
||||
if (total_size < hdev->tx_buf_size)
|
||||
return -ENOMEM;
|
||||
|
||||
if (hdev->hw_tc_map & BIT(i))
|
||||
priv->tx_buf_size = hdev->tx_buf_size;
|
||||
else
|
||||
} else {
|
||||
priv->tx_buf_size = 0;
|
||||
}
|
||||
|
||||
total_size -= priv->tx_buf_size;
|
||||
}
|
||||
|
@ -1520,66 +1521,15 @@ static int hclge_tx_buffer_calc(struct hclge_dev *hdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* hclge_rx_buffer_calc: calculate the rx private buffer size for all TCs
|
||||
* @hdev: pointer to struct hclge_dev
|
||||
* @buf_alloc: pointer to buffer calculation data
|
||||
* @return: 0: calculate sucessful, negative: fail
|
||||
*/
|
||||
static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
|
||||
struct hclge_pkt_buf_alloc *buf_alloc)
|
||||
static bool hclge_rx_buf_calc_all(struct hclge_dev *hdev, bool max,
|
||||
struct hclge_pkt_buf_alloc *buf_alloc)
|
||||
{
|
||||
u32 rx_all = hdev->pkt_buf_size, aligned_mps;
|
||||
int no_pfc_priv_num, pfc_priv_num;
|
||||
struct hclge_priv_buf *priv;
|
||||
u32 rx_all = hdev->pkt_buf_size - hclge_get_tx_buff_alloced(buf_alloc);
|
||||
u32 aligned_mps = round_up(hdev->mps, HCLGE_BUF_SIZE_UNIT);
|
||||
int i;
|
||||
|
||||
aligned_mps = round_up(hdev->mps, HCLGE_BUF_SIZE_UNIT);
|
||||
rx_all -= hclge_get_tx_buff_alloced(buf_alloc);
|
||||
|
||||
/* When DCB is not supported, rx private
|
||||
* buffer is not allocated.
|
||||
*/
|
||||
if (!hnae3_dev_dcb_supported(hdev)) {
|
||||
if (!hclge_is_rx_buf_ok(hdev, buf_alloc, rx_all))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* step 1, try to alloc private buffer for all enabled tc */
|
||||
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
|
||||
priv = &buf_alloc->priv_buf[i];
|
||||
if (hdev->hw_tc_map & BIT(i)) {
|
||||
priv->enable = 1;
|
||||
if (hdev->tm_info.hw_pfc_map & BIT(i)) {
|
||||
priv->wl.low = aligned_mps;
|
||||
priv->wl.high =
|
||||
roundup(priv->wl.low + aligned_mps,
|
||||
HCLGE_BUF_SIZE_UNIT);
|
||||
priv->buf_size = priv->wl.high +
|
||||
hdev->dv_buf_size;
|
||||
} else {
|
||||
priv->wl.low = 0;
|
||||
priv->wl.high = 2 * aligned_mps;
|
||||
priv->buf_size = priv->wl.high +
|
||||
hdev->dv_buf_size;
|
||||
}
|
||||
} else {
|
||||
priv->enable = 0;
|
||||
priv->wl.low = 0;
|
||||
priv->wl.high = 0;
|
||||
priv->buf_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (hclge_is_rx_buf_ok(hdev, buf_alloc, rx_all))
|
||||
return 0;
|
||||
|
||||
/* step 2, try to decrease the buffer size of
|
||||
* no pfc TC's private buffer
|
||||
*/
|
||||
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
|
||||
priv = &buf_alloc->priv_buf[i];
|
||||
struct hclge_priv_buf *priv = &buf_alloc->priv_buf[i];
|
||||
|
||||
priv->enable = 0;
|
||||
priv->wl.low = 0;
|
||||
|
@ -1592,28 +1542,30 @@ static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
|
|||
priv->enable = 1;
|
||||
|
||||
if (hdev->tm_info.hw_pfc_map & BIT(i)) {
|
||||
priv->wl.low = 256;
|
||||
priv->wl.high = priv->wl.low + aligned_mps;
|
||||
priv->buf_size = priv->wl.high + hdev->dv_buf_size;
|
||||
priv->wl.low = max ? aligned_mps : 256;
|
||||
priv->wl.high = roundup(priv->wl.low + aligned_mps,
|
||||
HCLGE_BUF_SIZE_UNIT);
|
||||
} else {
|
||||
priv->wl.low = 0;
|
||||
priv->wl.high = aligned_mps;
|
||||
priv->buf_size = priv->wl.high + hdev->dv_buf_size;
|
||||
priv->wl.high = max ? (aligned_mps * 2) : aligned_mps;
|
||||
}
|
||||
|
||||
priv->buf_size = priv->wl.high + hdev->dv_buf_size;
|
||||
}
|
||||
|
||||
if (hclge_is_rx_buf_ok(hdev, buf_alloc, rx_all))
|
||||
return 0;
|
||||
return hclge_is_rx_buf_ok(hdev, buf_alloc, rx_all);
|
||||
}
|
||||
|
||||
/* step 3, try to reduce the number of pfc disabled TCs,
|
||||
* which have private buffer
|
||||
*/
|
||||
/* get the total no pfc enable TC number, which have private buffer */
|
||||
no_pfc_priv_num = hclge_get_no_pfc_priv_num(hdev, buf_alloc);
|
||||
static bool hclge_drop_nopfc_buf_till_fit(struct hclge_dev *hdev,
|
||||
struct hclge_pkt_buf_alloc *buf_alloc)
|
||||
{
|
||||
u32 rx_all = hdev->pkt_buf_size - hclge_get_tx_buff_alloced(buf_alloc);
|
||||
int no_pfc_priv_num = hclge_get_no_pfc_priv_num(hdev, buf_alloc);
|
||||
int i;
|
||||
|
||||
/* let the last to be cleared first */
|
||||
for (i = HCLGE_MAX_TC_NUM - 1; i >= 0; i--) {
|
||||
priv = &buf_alloc->priv_buf[i];
|
||||
struct hclge_priv_buf *priv = &buf_alloc->priv_buf[i];
|
||||
|
||||
if (hdev->hw_tc_map & BIT(i) &&
|
||||
!(hdev->tm_info.hw_pfc_map & BIT(i))) {
|
||||
|
@ -1630,17 +1582,19 @@ static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
|
|||
break;
|
||||
}
|
||||
|
||||
if (hclge_is_rx_buf_ok(hdev, buf_alloc, rx_all))
|
||||
return 0;
|
||||
return hclge_is_rx_buf_ok(hdev, buf_alloc, rx_all);
|
||||
}
|
||||
|
||||
/* step 4, try to reduce the number of pfc enabled TCs
|
||||
* which have private buffer.
|
||||
*/
|
||||
pfc_priv_num = hclge_get_pfc_priv_num(hdev, buf_alloc);
|
||||
static bool hclge_drop_pfc_buf_till_fit(struct hclge_dev *hdev,
|
||||
struct hclge_pkt_buf_alloc *buf_alloc)
|
||||
{
|
||||
u32 rx_all = hdev->pkt_buf_size - hclge_get_tx_buff_alloced(buf_alloc);
|
||||
int pfc_priv_num = hclge_get_pfc_priv_num(hdev, buf_alloc);
|
||||
int i;
|
||||
|
||||
/* let the last to be cleared first */
|
||||
for (i = HCLGE_MAX_TC_NUM - 1; i >= 0; i--) {
|
||||
priv = &buf_alloc->priv_buf[i];
|
||||
struct hclge_priv_buf *priv = &buf_alloc->priv_buf[i];
|
||||
|
||||
if (hdev->hw_tc_map & BIT(i) &&
|
||||
hdev->tm_info.hw_pfc_map & BIT(i)) {
|
||||
|
@ -1656,7 +1610,40 @@ static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
|
|||
pfc_priv_num == 0)
|
||||
break;
|
||||
}
|
||||
if (hclge_is_rx_buf_ok(hdev, buf_alloc, rx_all))
|
||||
|
||||
return hclge_is_rx_buf_ok(hdev, buf_alloc, rx_all);
|
||||
}
|
||||
|
||||
/* hclge_rx_buffer_calc: calculate the rx private buffer size for all TCs
|
||||
* @hdev: pointer to struct hclge_dev
|
||||
* @buf_alloc: pointer to buffer calculation data
|
||||
* @return: 0: calculate sucessful, negative: fail
|
||||
*/
|
||||
static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
|
||||
struct hclge_pkt_buf_alloc *buf_alloc)
|
||||
{
|
||||
/* When DCB is not supported, rx private buffer is not allocated. */
|
||||
if (!hnae3_dev_dcb_supported(hdev)) {
|
||||
u32 rx_all = hdev->pkt_buf_size;
|
||||
|
||||
rx_all -= hclge_get_tx_buff_alloced(buf_alloc);
|
||||
if (!hclge_is_rx_buf_ok(hdev, buf_alloc, rx_all))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hclge_rx_buf_calc_all(hdev, true, buf_alloc))
|
||||
return 0;
|
||||
|
||||
/* try to decrease the buffer size */
|
||||
if (hclge_rx_buf_calc_all(hdev, false, buf_alloc))
|
||||
return 0;
|
||||
|
||||
if (hclge_drop_nopfc_buf_till_fit(hdev, buf_alloc))
|
||||
return 0;
|
||||
|
||||
if (hclge_drop_pfc_buf_till_fit(hdev, buf_alloc))
|
||||
return 0;
|
||||
|
||||
return -ENOMEM;
|
||||
|
@ -5600,13 +5587,19 @@ static bool hclge_is_all_function_id_zero(struct hclge_desc *desc)
|
|||
}
|
||||
|
||||
static void hclge_prepare_mac_addr(struct hclge_mac_vlan_tbl_entry_cmd *new_req,
|
||||
const u8 *addr)
|
||||
const u8 *addr, bool is_mc)
|
||||
{
|
||||
const unsigned char *mac_addr = addr;
|
||||
u32 high_val = mac_addr[2] << 16 | (mac_addr[3] << 24) |
|
||||
(mac_addr[0]) | (mac_addr[1] << 8);
|
||||
u32 low_val = mac_addr[4] | (mac_addr[5] << 8);
|
||||
|
||||
hnae3_set_bit(new_req->flags, HCLGE_MAC_VLAN_BIT0_EN_B, 1);
|
||||
if (is_mc) {
|
||||
hnae3_set_bit(new_req->entry_type, HCLGE_MAC_VLAN_BIT1_EN_B, 1);
|
||||
hnae3_set_bit(new_req->mc_mac_en, HCLGE_MAC_VLAN_BIT0_EN_B, 1);
|
||||
}
|
||||
|
||||
new_req->mac_addr_hi32 = cpu_to_le32(high_val);
|
||||
new_req->mac_addr_lo16 = cpu_to_le16(low_val & 0xffff);
|
||||
}
|
||||
|
@ -5837,9 +5830,12 @@ static void hclge_update_umv_space(struct hclge_vport *vport, bool is_free)
|
|||
if (is_free) {
|
||||
if (vport->used_umv_num > hdev->priv_umv_size)
|
||||
hdev->share_umv_size++;
|
||||
vport->used_umv_num--;
|
||||
|
||||
if (vport->used_umv_num > 0)
|
||||
vport->used_umv_num--;
|
||||
} else {
|
||||
if (vport->used_umv_num >= hdev->priv_umv_size)
|
||||
if (vport->used_umv_num >= hdev->priv_umv_size &&
|
||||
hdev->share_umv_size > 0)
|
||||
hdev->share_umv_size--;
|
||||
vport->used_umv_num++;
|
||||
}
|
||||
|
@ -5877,14 +5873,13 @@ int hclge_add_uc_addr_common(struct hclge_vport *vport,
|
|||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
hnae3_set_bit(req.flags, HCLGE_MAC_VLAN_BIT0_EN_B, 1);
|
||||
|
||||
hnae3_set_field(egress_port, HCLGE_MAC_EPORT_VFID_M,
|
||||
HCLGE_MAC_EPORT_VFID_S, vport->vport_id);
|
||||
|
||||
req.egress_port = cpu_to_le16(egress_port);
|
||||
|
||||
hclge_prepare_mac_addr(&req, addr);
|
||||
hclge_prepare_mac_addr(&req, addr, false);
|
||||
|
||||
/* Lookup the mac address in the mac_vlan table, and add
|
||||
* it if the entry is inexistent. Repeated unicast entry
|
||||
|
@ -5942,9 +5937,8 @@ int hclge_rm_uc_addr_common(struct hclge_vport *vport,
|
|||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
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);
|
||||
hclge_prepare_mac_addr(&req, addr);
|
||||
hclge_prepare_mac_addr(&req, addr, false);
|
||||
ret = hclge_remove_mac_vlan_tbl(vport, &req);
|
||||
if (!ret)
|
||||
hclge_update_umv_space(vport, true);
|
||||
|
@ -5976,11 +5970,8 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport,
|
|||
return -EINVAL;
|
||||
}
|
||||
memset(&req, 0, sizeof(req));
|
||||
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, 1);
|
||||
hclge_prepare_mac_addr(&req, addr);
|
||||
hclge_prepare_mac_addr(&req, addr, true);
|
||||
status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true);
|
||||
if (!status) {
|
||||
/* This mac addr exist, update VFID for it */
|
||||
|
@ -6026,11 +6017,8 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport,
|
|||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
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, 1);
|
||||
hclge_prepare_mac_addr(&req, addr);
|
||||
hclge_prepare_mac_addr(&req, addr, true);
|
||||
status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true);
|
||||
if (!status) {
|
||||
/* This mac addr exist, remove this handle's VFID for it */
|
||||
|
@ -7989,7 +7977,7 @@ static void hclge_get_link_mode(struct hnae3_handle *handle,
|
|||
}
|
||||
}
|
||||
|
||||
static int hclge_gro_en(struct hnae3_handle *handle, int enable)
|
||||
static int hclge_gro_en(struct hnae3_handle *handle, bool enable)
|
||||
{
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
|
|
|
@ -355,16 +355,19 @@ static int hclge_get_link_info(struct hclge_vport *vport,
|
|||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
u16 link_status;
|
||||
u8 msg_data[8];
|
||||
u8 msg_data[10];
|
||||
u16 media_type;
|
||||
u8 dest_vfid;
|
||||
u16 duplex;
|
||||
|
||||
/* mac.link can only be 0 or 1 */
|
||||
link_status = (u16)hdev->hw.mac.link;
|
||||
duplex = hdev->hw.mac.duplex;
|
||||
media_type = hdev->hw.mac.media_type;
|
||||
memcpy(&msg_data[0], &link_status, sizeof(u16));
|
||||
memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32));
|
||||
memcpy(&msg_data[6], &duplex, sizeof(u16));
|
||||
memcpy(&msg_data[8], &media_type, sizeof(u16));
|
||||
dest_vfid = mbx_req->mbx_src_vfid;
|
||||
|
||||
/* send this requested info to VF */
|
||||
|
@ -372,6 +375,29 @@ static int hclge_get_link_info(struct hclge_vport *vport,
|
|||
HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid);
|
||||
}
|
||||
|
||||
static void hclge_get_link_mode(struct hclge_vport *vport,
|
||||
struct hclge_mbx_vf_to_pf_cmd *mbx_req)
|
||||
{
|
||||
#define HCLGE_SUPPORTED 1
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
unsigned long advertising;
|
||||
unsigned long supported;
|
||||
unsigned long send_data;
|
||||
u8 msg_data[10];
|
||||
u8 dest_vfid;
|
||||
|
||||
advertising = hdev->hw.mac.advertising[0];
|
||||
supported = hdev->hw.mac.supported[0];
|
||||
dest_vfid = mbx_req->mbx_src_vfid;
|
||||
msg_data[0] = mbx_req->msg[2];
|
||||
|
||||
send_data = msg_data[0] == HCLGE_SUPPORTED ? supported : advertising;
|
||||
|
||||
memcpy(&msg_data[2], &send_data, sizeof(unsigned long));
|
||||
hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
|
||||
HCLGE_MBX_LINK_STAT_MODE, dest_vfid);
|
||||
}
|
||||
|
||||
static void hclge_mbx_reset_vf_queue(struct hclge_vport *vport,
|
||||
struct hclge_mbx_vf_to_pf_cmd *mbx_req)
|
||||
{
|
||||
|
@ -556,6 +582,9 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
|
|||
"PF failed(%d) to get qid for VF\n",
|
||||
ret);
|
||||
break;
|
||||
case HCLGE_MBX_GET_LINK_MODE:
|
||||
hclge_get_link_mode(vport, req);
|
||||
break;
|
||||
default:
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"un-supported mailbox message, code = %d\n",
|
||||
|
|
|
@ -381,6 +381,21 @@ void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state)
|
|||
}
|
||||
}
|
||||
|
||||
void hclgevf_update_link_mode(struct hclgevf_dev *hdev)
|
||||
{
|
||||
#define HCLGEVF_ADVERTISING 0
|
||||
#define HCLGEVF_SUPPORTED 1
|
||||
u8 send_msg;
|
||||
u8 resp_msg;
|
||||
|
||||
send_msg = HCLGEVF_ADVERTISING;
|
||||
hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_MODE, 0, &send_msg,
|
||||
sizeof(u8), false, &resp_msg, sizeof(u8));
|
||||
send_msg = HCLGEVF_SUPPORTED;
|
||||
hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_MODE, 0, &send_msg,
|
||||
sizeof(u8), false, &resp_msg, sizeof(u8));
|
||||
}
|
||||
|
||||
static int hclgevf_set_handle_info(struct hclgevf_dev *hdev)
|
||||
{
|
||||
struct hnae3_handle *nic = &hdev->nic;
|
||||
|
@ -1646,6 +1661,8 @@ static void hclgevf_service_task(struct work_struct *work)
|
|||
*/
|
||||
hclgevf_request_link_info(hdev);
|
||||
|
||||
hclgevf_update_link_mode(hdev);
|
||||
|
||||
hclgevf_deferred_task_schedule(hdev);
|
||||
|
||||
clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state);
|
||||
|
@ -1726,8 +1743,6 @@ static int hclgevf_configure(struct hclgevf_dev *hdev)
|
|||
{
|
||||
int ret;
|
||||
|
||||
hdev->hw.mac.media_type = HNAE3_MEDIA_TYPE_NONE;
|
||||
|
||||
/* get queue configuration from PF */
|
||||
ret = hclgevf_get_queue_info(hdev);
|
||||
if (ret)
|
||||
|
@ -1880,6 +1895,8 @@ static int hclgevf_ae_start(struct hnae3_handle *handle)
|
|||
|
||||
hclgevf_request_link_info(hdev);
|
||||
|
||||
hclgevf_update_link_mode(hdev);
|
||||
|
||||
clear_bit(HCLGEVF_STATE_DOWN, &hdev->state);
|
||||
|
||||
return 0;
|
||||
|
@ -2550,7 +2567,7 @@ void hclgevf_update_speed_duplex(struct hclgevf_dev *hdev, u32 speed,
|
|||
hdev->hw.mac.duplex = duplex;
|
||||
}
|
||||
|
||||
static int hclgevf_gro_en(struct hnae3_handle *handle, int enable)
|
||||
static int hclgevf_gro_en(struct hnae3_handle *handle, bool enable)
|
||||
{
|
||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
||||
|
||||
|
@ -2586,6 +2603,16 @@ static unsigned long hclgevf_ae_dev_reset_cnt(struct hnae3_handle *handle)
|
|||
return hdev->reset_count;
|
||||
}
|
||||
|
||||
static void hclgevf_get_link_mode(struct hnae3_handle *handle,
|
||||
unsigned long *supported,
|
||||
unsigned long *advertising)
|
||||
{
|
||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
||||
|
||||
*supported = hdev->hw.mac.supported;
|
||||
*advertising = hdev->hw.mac.advertising;
|
||||
}
|
||||
|
||||
#define MAX_SEPARATE_NUM 4
|
||||
#define SEPARATOR_VALUE 0xFFFFFFFF
|
||||
#define REG_NUM_PER_LINE 4
|
||||
|
@ -2704,6 +2731,7 @@ static const struct hnae3_ae_ops hclgevf_ops = {
|
|||
.set_mtu = hclgevf_set_mtu,
|
||||
.get_global_queue_id = hclgevf_get_qid_global,
|
||||
.set_timer_task = hclgevf_set_timer_task,
|
||||
.get_link_mode = hclgevf_get_link_mode,
|
||||
};
|
||||
|
||||
static struct hnae3_ae_algo ae_algovf = {
|
||||
|
|
|
@ -145,6 +145,8 @@ struct hclgevf_mac {
|
|||
int link;
|
||||
u8 duplex;
|
||||
u32 speed;
|
||||
u64 supported;
|
||||
u64 advertising;
|
||||
};
|
||||
|
||||
struct hclgevf_hw {
|
||||
|
|
|
@ -197,6 +197,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
|
|||
break;
|
||||
case HCLGE_MBX_LINK_STAT_CHANGE:
|
||||
case HCLGE_MBX_ASSERTING_RESET:
|
||||
case HCLGE_MBX_LINK_STAT_MODE:
|
||||
/* set this mbx event as pending. This is required as we
|
||||
* might loose interrupt event when mbx task is busy
|
||||
* handling. This shall be cleared when mbx task just
|
||||
|
@ -247,6 +248,7 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
|
|||
u8 duplex;
|
||||
u32 speed;
|
||||
u32 tail;
|
||||
u8 idx;
|
||||
|
||||
/* we can safely clear it now as we are at start of the async message
|
||||
* processing
|
||||
|
@ -270,12 +272,22 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
|
|||
link_status = le16_to_cpu(msg_q[1]);
|
||||
memcpy(&speed, &msg_q[2], sizeof(speed));
|
||||
duplex = (u8)le16_to_cpu(msg_q[4]);
|
||||
hdev->hw.mac.media_type = (u8)le16_to_cpu(msg_q[5]);
|
||||
|
||||
/* update upper layer with new link link status */
|
||||
hclgevf_update_link_status(hdev, link_status);
|
||||
hclgevf_update_speed_duplex(hdev, speed, duplex);
|
||||
|
||||
break;
|
||||
case HCLGE_MBX_LINK_STAT_MODE:
|
||||
idx = (u8)le16_to_cpu(msg_q[1]);
|
||||
if (idx)
|
||||
memcpy(&hdev->hw.mac.supported, &msg_q[2],
|
||||
sizeof(unsigned long));
|
||||
else
|
||||
memcpy(&hdev->hw.mac.advertising, &msg_q[2],
|
||||
sizeof(unsigned long));
|
||||
break;
|
||||
case HCLGE_MBX_ASSERTING_RESET:
|
||||
/* PF has asserted reset hence VF should go in pending
|
||||
* state and poll for the hardware reset status till it
|
||||
|
|
Загрузка…
Ссылка в новой задаче