mirror of
https://github.com/torvalds/linux.git
synced 2024-11-13 07:31:45 +00:00
Merge branch 'hns3-next'
Salil Mehta says: ==================== Misc bug fixes & small enhancements for HNS3 Driver This patch-set presents some bug fixes and minor enhancements to HNS3 Ethernet driver. Rework Summary: (*) Patch V1->V2 1. Fixed David S Miller's comments 2. Dropped patch 0005 "net: hns3: Fix for vf vlan delete failed problem" for now. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
ac272a3e9c
@ -1673,6 +1673,9 @@ static struct pci_driver hns3_driver = {
|
||||
/* set default feature to hns3 */
|
||||
static void hns3_set_default_feature(struct net_device *netdev)
|
||||
{
|
||||
struct hnae3_handle *h = hns3_get_handle(netdev);
|
||||
struct pci_dev *pdev = h->pdev;
|
||||
|
||||
netdev->priv_flags |= IFF_UNICAST_FLT;
|
||||
|
||||
netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
||||
@ -1706,6 +1709,9 @@ static void hns3_set_default_feature(struct net_device *netdev)
|
||||
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
||||
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
|
||||
if (pdev->revision != 0x20)
|
||||
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
||||
}
|
||||
|
||||
static int hns3_alloc_buffer(struct hns3_enet_ring *ring,
|
||||
@ -2969,13 +2975,33 @@ static void hns3_init_ring_hw(struct hns3_enet_ring *ring)
|
||||
hns3_write_dev(q, HNS3_RING_TX_RING_BASEADDR_H_REG,
|
||||
(u32)((dma >> 31) >> 1));
|
||||
|
||||
hns3_write_dev(q, HNS3_RING_TX_RING_BD_LEN_REG,
|
||||
hns3_buf_size2type(ring->buf_size));
|
||||
hns3_write_dev(q, HNS3_RING_TX_RING_BD_NUM_REG,
|
||||
ring->desc_num / 8 - 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void hns3_init_tx_ring_tc(struct hns3_nic_priv *priv)
|
||||
{
|
||||
struct hnae3_knic_private_info *kinfo = &priv->ae_handle->kinfo;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HNAE3_MAX_TC; i++) {
|
||||
struct hnae3_tc_info *tc_info = &kinfo->tc_info[i];
|
||||
int j;
|
||||
|
||||
if (!tc_info->enable)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < tc_info->tqp_count; j++) {
|
||||
struct hnae3_queue *q;
|
||||
|
||||
q = priv->ring_data[tc_info->tqp_offset + j].ring->tqp;
|
||||
hns3_write_dev(q, HNS3_RING_TX_RING_TC_REG,
|
||||
tc_info->tc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int hns3_init_all_ring(struct hns3_nic_priv *priv)
|
||||
{
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
@ -3387,6 +3413,8 @@ int hns3_nic_reset_all_ring(struct hnae3_handle *h)
|
||||
rx_ring->next_to_use = 0;
|
||||
}
|
||||
|
||||
hns3_init_tx_ring_tc(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ enum hns3_nic_state {
|
||||
#define HNS3_RING_TX_RING_BASEADDR_L_REG 0x00040
|
||||
#define HNS3_RING_TX_RING_BASEADDR_H_REG 0x00044
|
||||
#define HNS3_RING_TX_RING_BD_NUM_REG 0x00048
|
||||
#define HNS3_RING_TX_RING_BD_LEN_REG 0x0004C
|
||||
#define HNS3_RING_TX_RING_TC_REG 0x00050
|
||||
#define HNS3_RING_TX_RING_TAIL_REG 0x00058
|
||||
#define HNS3_RING_TX_RING_HEAD_REG 0x0005C
|
||||
#define HNS3_RING_TX_RING_FBDNUM_REG 0x00060
|
||||
|
@ -53,7 +53,7 @@ static const struct hns3_stats hns3_rxq_stats[] = {
|
||||
|
||||
#define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
|
||||
|
||||
#define HNS3_SELF_TEST_TPYE_NUM 1
|
||||
#define HNS3_SELF_TEST_TYPE_NUM 2
|
||||
#define HNS3_NIC_LB_TEST_PKT_NUM 1
|
||||
#define HNS3_NIC_LB_TEST_RING_ID 0
|
||||
#define HNS3_NIC_LB_TEST_PACKET_SIZE 128
|
||||
@ -78,6 +78,7 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (loop) {
|
||||
case HNAE3_MAC_INTER_LOOP_SERDES:
|
||||
case HNAE3_MAC_INTER_LOOP_MAC:
|
||||
ret = h->ae_algo->ops->set_loopback(h, loop, en);
|
||||
break;
|
||||
@ -287,7 +288,7 @@ static void hns3_self_test(struct net_device *ndev,
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(ndev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
int st_param[HNS3_SELF_TEST_TPYE_NUM][2];
|
||||
int st_param[HNS3_SELF_TEST_TYPE_NUM][2];
|
||||
bool if_running = netif_running(ndev);
|
||||
#if IS_ENABLED(CONFIG_VLAN_8021Q)
|
||||
bool dis_vlan_filter;
|
||||
@ -303,6 +304,10 @@ static void hns3_self_test(struct net_device *ndev,
|
||||
st_param[HNAE3_MAC_INTER_LOOP_MAC][1] =
|
||||
h->flags & HNAE3_SUPPORT_MAC_LOOPBACK;
|
||||
|
||||
st_param[HNAE3_MAC_INTER_LOOP_SERDES][0] = HNAE3_MAC_INTER_LOOP_SERDES;
|
||||
st_param[HNAE3_MAC_INTER_LOOP_SERDES][1] =
|
||||
h->flags & HNAE3_SUPPORT_SERDES_LOOPBACK;
|
||||
|
||||
if (if_running)
|
||||
dev_close(ndev);
|
||||
|
||||
@ -316,7 +321,7 @@ static void hns3_self_test(struct net_device *ndev,
|
||||
|
||||
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_TYPE_NUM; i++) {
|
||||
enum hnae3_loop loop_type = (enum hnae3_loop)st_param[i][0];
|
||||
|
||||
if (!st_param[i][1])
|
||||
|
@ -94,6 +94,7 @@ enum hclge_opcode_type {
|
||||
HCLGE_OPC_QUERY_LINK_STATUS = 0x0307,
|
||||
HCLGE_OPC_CONFIG_MAX_FRM_SIZE = 0x0308,
|
||||
HCLGE_OPC_CONFIG_SPEED_DUP = 0x0309,
|
||||
HCLGE_OPC_SERDES_LOOPBACK = 0x0315,
|
||||
|
||||
/* PFC/Pause commands */
|
||||
HCLGE_OPC_CFG_MAC_PAUSE_EN = 0x0701,
|
||||
@ -775,6 +776,17 @@ struct hclge_reset_cmd {
|
||||
u8 fun_reset_vfid;
|
||||
u8 rsv[22];
|
||||
};
|
||||
|
||||
#define HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B BIT(0)
|
||||
#define HCLGE_CMD_SERDES_DONE_B BIT(0)
|
||||
#define HCLGE_CMD_SERDES_SUCCESS_B BIT(1)
|
||||
struct hclge_serdes_lb_cmd {
|
||||
u8 mask;
|
||||
u8 enable;
|
||||
u8 result;
|
||||
u8 rsv[21];
|
||||
};
|
||||
|
||||
#define HCLGE_DEFAULT_TX_BUF 0x4000 /* 16k bytes */
|
||||
#define HCLGE_TOTAL_PKT_BUF 0x108000 /* 1.03125M bytes */
|
||||
#define HCLGE_DEFAULT_DV 0xA000 /* 40k byte */
|
||||
|
@ -787,9 +787,10 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset)
|
||||
hdev->hw.mac.speed == HCLGE_MAC_SPEED_1G) {
|
||||
count += 1;
|
||||
handle->flags |= HNAE3_SUPPORT_MAC_LOOPBACK;
|
||||
} else {
|
||||
count = -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
count++;
|
||||
handle->flags |= HNAE3_SUPPORT_SERDES_LOOPBACK;
|
||||
} else if (stringset == ETH_SS_STATS) {
|
||||
count = ARRAY_SIZE(g_mac_stats_string) +
|
||||
ARRAY_SIZE(g_all_32bit_stats_string) +
|
||||
@ -1266,35 +1267,37 @@ static int hclge_map_tqps_to_func(struct hclge_dev *hdev, u16 func_id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hclge_assign_tqp(struct hclge_vport *vport,
|
||||
struct hnae3_queue **tqp, u16 num_tqps)
|
||||
static int hclge_assign_tqp(struct hclge_vport *vport)
|
||||
{
|
||||
struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
int i, alloced;
|
||||
|
||||
for (i = 0, alloced = 0; i < hdev->num_tqps &&
|
||||
alloced < num_tqps; i++) {
|
||||
alloced < kinfo->num_tqps; i++) {
|
||||
if (!hdev->htqp[i].alloced) {
|
||||
hdev->htqp[i].q.handle = &vport->nic;
|
||||
hdev->htqp[i].q.tqp_index = alloced;
|
||||
tqp[alloced] = &hdev->htqp[i].q;
|
||||
hdev->htqp[i].q.desc_num = kinfo->num_desc;
|
||||
kinfo->tqp[alloced] = &hdev->htqp[i].q;
|
||||
hdev->htqp[i].alloced = true;
|
||||
alloced++;
|
||||
}
|
||||
}
|
||||
vport->alloc_tqps = num_tqps;
|
||||
vport->alloc_tqps = kinfo->num_tqps;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_knic_setup(struct hclge_vport *vport, u16 num_tqps)
|
||||
static int hclge_knic_setup(struct hclge_vport *vport,
|
||||
u16 num_tqps, u16 num_desc)
|
||||
{
|
||||
struct hnae3_handle *nic = &vport->nic;
|
||||
struct hnae3_knic_private_info *kinfo = &nic->kinfo;
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
int i, ret;
|
||||
|
||||
kinfo->num_desc = hdev->num_desc;
|
||||
kinfo->num_desc = num_desc;
|
||||
kinfo->rx_buf_len = hdev->rx_buf_len;
|
||||
kinfo->num_tc = min_t(u16, num_tqps, hdev->tm_info.num_tc);
|
||||
kinfo->rss_size
|
||||
@ -1321,7 +1324,7 @@ static int hclge_knic_setup(struct hclge_vport *vport, u16 num_tqps)
|
||||
if (!kinfo->tqp)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = hclge_assign_tqp(vport, kinfo->tqp, kinfo->num_tqps);
|
||||
ret = hclge_assign_tqp(vport);
|
||||
if (ret)
|
||||
dev_err(&hdev->pdev->dev, "fail to assign TQPs %d.\n", ret);
|
||||
|
||||
@ -1387,7 +1390,7 @@ static int hclge_vport_setup(struct hclge_vport *vport, u16 num_tqps)
|
||||
nic->numa_node_mask = hdev->numa_node_mask;
|
||||
|
||||
if (hdev->ae_dev->dev_type == HNAE3_DEV_KNIC) {
|
||||
ret = hclge_knic_setup(vport, num_tqps);
|
||||
ret = hclge_knic_setup(vport, num_tqps, hdev->num_desc);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev, "knic setup failed %d\n",
|
||||
ret);
|
||||
@ -3670,6 +3673,55 @@ static int hclge_set_mac_loopback(struct hclge_dev *hdev, bool en)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hclge_set_serdes_loopback(struct hclge_dev *hdev, bool en)
|
||||
{
|
||||
#define HCLGE_SERDES_RETRY_MS 10
|
||||
#define HCLGE_SERDES_RETRY_NUM 100
|
||||
struct hclge_serdes_lb_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
int ret, i = 0;
|
||||
|
||||
req = (struct hclge_serdes_lb_cmd *)&desc.data[0];
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, false);
|
||||
|
||||
if (en) {
|
||||
req->enable = HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B;
|
||||
req->mask = HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B;
|
||||
} else {
|
||||
req->mask = HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B;
|
||||
}
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"serdes loopback set fail, ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
do {
|
||||
msleep(HCLGE_SERDES_RETRY_MS);
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK,
|
||||
true);
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"serdes loopback get, ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
} while (++i < HCLGE_SERDES_RETRY_NUM &&
|
||||
!(req->result & HCLGE_CMD_SERDES_DONE_B));
|
||||
|
||||
if (!(req->result & HCLGE_CMD_SERDES_DONE_B)) {
|
||||
dev_err(&hdev->pdev->dev, "serdes loopback set timeout\n");
|
||||
return -EBUSY;
|
||||
} else if (!(req->result & HCLGE_CMD_SERDES_SUCCESS_B)) {
|
||||
dev_err(&hdev->pdev->dev, "serdes loopback set failed in fw\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_set_loopback(struct hnae3_handle *handle,
|
||||
enum hnae3_loop loop_mode, bool en)
|
||||
{
|
||||
@ -3681,6 +3733,9 @@ static int hclge_set_loopback(struct hnae3_handle *handle,
|
||||
case HNAE3_MAC_INTER_LOOP_MAC:
|
||||
ret = hclge_set_mac_loopback(hdev, en);
|
||||
break;
|
||||
case HNAE3_MAC_INTER_LOOP_SERDES:
|
||||
ret = hclge_set_serdes_loopback(hdev, en);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTSUPP;
|
||||
dev_err(&hdev->pdev->dev,
|
||||
@ -3729,7 +3784,7 @@ static int hclge_ae_start(struct hnae3_handle *handle)
|
||||
{
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
int i, ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vport->alloc_tqps; i++)
|
||||
hclge_tqp_enable(hdev, i, 0, true);
|
||||
@ -3743,9 +3798,7 @@ static int hclge_ae_start(struct hnae3_handle *handle)
|
||||
/* reset tqp stats */
|
||||
hclge_reset_tqp_stats(handle);
|
||||
|
||||
ret = hclge_mac_start_phy(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
hclge_mac_start_phy(hdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3877,7 +3930,7 @@ static bool hclge_is_all_function_id_zero(struct hclge_desc *desc)
|
||||
#define HCLGE_FUNC_NUMBER_PER_DESC 6
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < HCLGE_DESC_NUMBER; i++)
|
||||
for (i = 1; i < HCLGE_DESC_NUMBER; i++)
|
||||
for (j = 0; j < HCLGE_FUNC_NUMBER_PER_DESC; j++)
|
||||
if (desc[i].data[j])
|
||||
return false;
|
||||
@ -5364,6 +5417,16 @@ static void hclge_get_mdix_mode(struct hnae3_handle *handle,
|
||||
*tp_mdix = ETH_TP_MDI;
|
||||
}
|
||||
|
||||
static int hclge_init_instance_hw(struct hclge_dev *hdev)
|
||||
{
|
||||
return hclge_mac_connect_phy(hdev);
|
||||
}
|
||||
|
||||
static void hclge_uninit_instance_hw(struct hclge_dev *hdev)
|
||||
{
|
||||
hclge_mac_disconnect_phy(hdev);
|
||||
}
|
||||
|
||||
static int hclge_init_client_instance(struct hnae3_client *client,
|
||||
struct hnae3_ae_dev *ae_dev)
|
||||
{
|
||||
@ -5383,6 +5446,13 @@ static int hclge_init_client_instance(struct hnae3_client *client,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = hclge_init_instance_hw(hdev);
|
||||
if (ret) {
|
||||
client->ops->uninit_instance(&vport->nic,
|
||||
0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (hdev->roce_client &&
|
||||
hnae3_dev_roce_supported(hdev)) {
|
||||
struct hnae3_client *rc = hdev->roce_client;
|
||||
@ -5445,6 +5515,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
|
||||
if (client->type == HNAE3_CLIENT_ROCE)
|
||||
return;
|
||||
if (client->ops->uninit_instance) {
|
||||
hclge_uninit_instance_hw(hdev);
|
||||
client->ops->uninit_instance(&vport->nic, 0);
|
||||
hdev->nic_client = NULL;
|
||||
vport->nic.client = NULL;
|
||||
@ -5867,7 +5938,7 @@ static int hclge_set_channels(struct hnae3_handle *handle, u32 new_tqps_num)
|
||||
/* Free old tqps, and reallocate with new tqp number when nic setup */
|
||||
hclge_release_tqp(vport);
|
||||
|
||||
ret = hclge_knic_setup(vport, new_tqps_num);
|
||||
ret = hclge_knic_setup(vport, new_tqps_num, kinfo->num_desc);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev, "setup nic fail, ret =%d\n", ret);
|
||||
return ret;
|
||||
|
@ -193,7 +193,7 @@ static void hclge_mac_adjust_link(struct net_device *netdev)
|
||||
netdev_err(netdev, "failed to configure flow control.\n");
|
||||
}
|
||||
|
||||
int hclge_mac_start_phy(struct hclge_dev *hdev)
|
||||
int hclge_mac_connect_phy(struct hclge_dev *hdev)
|
||||
{
|
||||
struct net_device *netdev = hdev->vport[0].nic.netdev;
|
||||
struct phy_device *phydev = hdev->hw.mac.phydev;
|
||||
@ -202,6 +202,8 @@ int hclge_mac_start_phy(struct hclge_dev *hdev)
|
||||
if (!phydev)
|
||||
return 0;
|
||||
|
||||
phydev->supported &= ~SUPPORTED_FIBRE;
|
||||
|
||||
ret = phy_connect_direct(netdev, phydev,
|
||||
hclge_mac_adjust_link,
|
||||
PHY_INTERFACE_MODE_SGMII);
|
||||
@ -213,11 +215,29 @@ int hclge_mac_start_phy(struct hclge_dev *hdev)
|
||||
phydev->supported &= HCLGE_PHY_SUPPORTED_FEATURES;
|
||||
phydev->advertising = phydev->supported;
|
||||
|
||||
phy_start(phydev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hclge_mac_disconnect_phy(struct hclge_dev *hdev)
|
||||
{
|
||||
struct phy_device *phydev = hdev->hw.mac.phydev;
|
||||
|
||||
if (!phydev)
|
||||
return;
|
||||
|
||||
phy_disconnect(phydev);
|
||||
}
|
||||
|
||||
void hclge_mac_start_phy(struct hclge_dev *hdev)
|
||||
{
|
||||
struct phy_device *phydev = hdev->hw.mac.phydev;
|
||||
|
||||
if (!phydev)
|
||||
return;
|
||||
|
||||
phy_start(phydev);
|
||||
}
|
||||
|
||||
void hclge_mac_stop_phy(struct hclge_dev *hdev)
|
||||
{
|
||||
struct net_device *netdev = hdev->vport[0].nic.netdev;
|
||||
@ -227,5 +247,4 @@ void hclge_mac_stop_phy(struct hclge_dev *hdev)
|
||||
return;
|
||||
|
||||
phy_stop(phydev);
|
||||
phy_disconnect(phydev);
|
||||
}
|
||||
|
@ -5,7 +5,9 @@
|
||||
#define __HCLGE_MDIO_H
|
||||
|
||||
int hclge_mac_mdio_config(struct hclge_dev *hdev);
|
||||
int hclge_mac_start_phy(struct hclge_dev *hdev);
|
||||
int hclge_mac_connect_phy(struct hclge_dev *hdev);
|
||||
void hclge_mac_disconnect_phy(struct hclge_dev *hdev);
|
||||
void hclge_mac_start_phy(struct hclge_dev *hdev);
|
||||
void hclge_mac_stop_phy(struct hclge_dev *hdev);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user