forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/ethernet/cavium/thunder/nic_main.c
....@@ -1,9 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2015 Cavium, Inc.
3
- *
4
- * This program is free software; you can redistribute it and/or modify it
5
- * under the terms of version 2 of the GNU General Public License
6
- * as published by the Free Software Foundation.
74 */
85
96 #include <linux/module.h>
....@@ -57,14 +54,8 @@
5754 #define NIC_GET_BGX_FROM_VF_LMAC_MAP(map) ((map >> 4) & 0xF)
5855 #define NIC_GET_LMAC_FROM_VF_LMAC_MAP(map) (map & 0xF)
5956 u8 *vf_lmac_map;
60
- struct delayed_work dwork;
61
- struct workqueue_struct *check_link;
62
- u8 *link;
63
- u8 *duplex;
64
- u32 *speed;
6557 u16 cpi_base[MAX_NUM_VFS_SUPPORTED];
6658 u16 rssi_base[MAX_NUM_VFS_SUPPORTED];
67
- bool mbx_lock[MAX_NUM_VFS_SUPPORTED];
6859
6960 /* MSI-X */
7061 u8 num_vec;
....@@ -929,6 +920,35 @@
929920 nic_reg_write(nic, NIC_PF_PKIND_0_15_CFG | (pkind_idx << 3), pkind_val);
930921 }
931922
923
+/* Get BGX LMAC link status and update corresponding VF
924
+ * if there is a change, valid only if internal L2 switch
925
+ * is not present otherwise VF link is always treated as up
926
+ */
927
+static void nic_link_status_get(struct nicpf *nic, u8 vf)
928
+{
929
+ union nic_mbx mbx = {};
930
+ struct bgx_link_status link;
931
+ u8 bgx, lmac;
932
+
933
+ mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE;
934
+
935
+ /* Get BGX, LMAC indices for the VF */
936
+ bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
937
+ lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
938
+
939
+ /* Get interface link status */
940
+ bgx_get_lmac_link_state(nic->node, bgx, lmac, &link);
941
+
942
+ /* Send a mbox message to VF with current link status */
943
+ mbx.link_status.link_up = link.link_up;
944
+ mbx.link_status.duplex = link.duplex;
945
+ mbx.link_status.speed = link.speed;
946
+ mbx.link_status.mac_type = link.mac_type;
947
+
948
+ /* reply with link status */
949
+ nic_send_msg_to_vf(nic, vf, &mbx);
950
+}
951
+
932952 /* Interrupt handler to handle mailbox messages from VFs */
933953 static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
934954 {
....@@ -940,8 +960,6 @@
940960 int bgx, lmac;
941961 int i;
942962 int ret = 0;
943
-
944
- nic->mbx_lock[vf] = true;
945963
946964 mbx_addr = nic_get_mbx_addr(vf);
947965 mbx_data = (u64 *)&mbx;
....@@ -957,12 +975,7 @@
957975 switch (mbx.msg.msg) {
958976 case NIC_MBOX_MSG_READY:
959977 nic_mbx_send_ready(nic, vf);
960
- if (vf < nic->num_vf_en) {
961
- nic->link[vf] = 0;
962
- nic->duplex[vf] = 0;
963
- nic->speed[vf] = 0;
964
- }
965
- goto unlock;
978
+ return;
966979 case NIC_MBOX_MSG_QS_CFG:
967980 reg_addr = NIC_PF_QSET_0_127_CFG |
968981 (mbx.qs.num << NIC_QS_ID_SHIFT);
....@@ -1031,7 +1044,7 @@
10311044 break;
10321045 case NIC_MBOX_MSG_RSS_SIZE:
10331046 nic_send_rss_size(nic, vf);
1034
- goto unlock;
1047
+ return;
10351048 case NIC_MBOX_MSG_RSS_CFG:
10361049 case NIC_MBOX_MSG_RSS_CFG_CONT:
10371050 nic_config_rss(nic, &mbx.rss_cfg);
....@@ -1049,19 +1062,19 @@
10491062 break;
10501063 case NIC_MBOX_MSG_ALLOC_SQS:
10511064 nic_alloc_sqs(nic, &mbx.sqs_alloc);
1052
- goto unlock;
1065
+ return;
10531066 case NIC_MBOX_MSG_NICVF_PTR:
10541067 nic->nicvf[vf] = mbx.nicvf.nicvf;
10551068 break;
10561069 case NIC_MBOX_MSG_PNICVF_PTR:
10571070 nic_send_pnicvf(nic, vf);
1058
- goto unlock;
1071
+ return;
10591072 case NIC_MBOX_MSG_SNICVF_PTR:
10601073 nic_send_snicvf(nic, &mbx.nicvf);
1061
- goto unlock;
1074
+ return;
10621075 case NIC_MBOX_MSG_BGX_STATS:
10631076 nic_get_bgx_stats(nic, &mbx.bgx_stats);
1064
- goto unlock;
1077
+ return;
10651078 case NIC_MBOX_MSG_LOOPBACK:
10661079 ret = nic_config_loopback(nic, &mbx.lbk);
10671080 break;
....@@ -1070,7 +1083,7 @@
10701083 break;
10711084 case NIC_MBOX_MSG_PFC:
10721085 nic_pause_frame(nic, vf, &mbx.pfc);
1073
- goto unlock;
1086
+ return;
10741087 case NIC_MBOX_MSG_PTP_CFG:
10751088 nic_config_timestamp(nic, vf, &mbx.ptp);
10761089 break;
....@@ -1094,7 +1107,7 @@
10941107 bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
10951108 lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
10961109 bgx_set_dmac_cam_filter(nic->node, bgx, lmac,
1097
- mbx.xcast.data.mac,
1110
+ mbx.xcast.mac,
10981111 vf < NIC_VF_PER_MBX_REG ? vf :
10991112 vf - NIC_VF_PER_MBX_REG);
11001113 break;
....@@ -1106,8 +1119,15 @@
11061119 }
11071120 bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
11081121 lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
1109
- bgx_set_xcast_mode(nic->node, bgx, lmac, mbx.xcast.data.mode);
1122
+ bgx_set_xcast_mode(nic->node, bgx, lmac, mbx.xcast.mode);
11101123 break;
1124
+ case NIC_MBOX_MSG_BGX_LINK_CHANGE:
1125
+ if (vf >= nic->num_vf_en) {
1126
+ ret = -1; /* NACK */
1127
+ break;
1128
+ }
1129
+ nic_link_status_get(nic, vf);
1130
+ return;
11111131 default:
11121132 dev_err(&nic->pdev->dev,
11131133 "Invalid msg from VF%d, msg 0x%x\n", vf, mbx.msg.msg);
....@@ -1121,8 +1141,6 @@
11211141 mbx.msg.msg, vf);
11221142 nic_mbx_send_nack(nic, vf);
11231143 }
1124
-unlock:
1125
- nic->mbx_lock[vf] = false;
11261144 }
11271145
11281146 static irqreturn_t nic_mbx_intr_handler(int irq, void *nic_irq)
....@@ -1270,52 +1288,6 @@
12701288 return 0;
12711289 }
12721290
1273
-/* Poll for BGX LMAC link status and update corresponding VF
1274
- * if there is a change, valid only if internal L2 switch
1275
- * is not present otherwise VF link is always treated as up
1276
- */
1277
-static void nic_poll_for_link(struct work_struct *work)
1278
-{
1279
- union nic_mbx mbx = {};
1280
- struct nicpf *nic;
1281
- struct bgx_link_status link;
1282
- u8 vf, bgx, lmac;
1283
-
1284
- nic = container_of(work, struct nicpf, dwork.work);
1285
-
1286
- mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE;
1287
-
1288
- for (vf = 0; vf < nic->num_vf_en; vf++) {
1289
- /* Poll only if VF is UP */
1290
- if (!nic->vf_enabled[vf])
1291
- continue;
1292
-
1293
- /* Get BGX, LMAC indices for the VF */
1294
- bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
1295
- lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
1296
- /* Get interface link status */
1297
- bgx_get_lmac_link_state(nic->node, bgx, lmac, &link);
1298
-
1299
- /* Inform VF only if link status changed */
1300
- if (nic->link[vf] == link.link_up)
1301
- continue;
1302
-
1303
- if (!nic->mbx_lock[vf]) {
1304
- nic->link[vf] = link.link_up;
1305
- nic->duplex[vf] = link.duplex;
1306
- nic->speed[vf] = link.speed;
1307
-
1308
- /* Send a mbox message to VF with current link status */
1309
- mbx.link_status.link_up = link.link_up;
1310
- mbx.link_status.duplex = link.duplex;
1311
- mbx.link_status.speed = link.speed;
1312
- mbx.link_status.mac_type = link.mac_type;
1313
- nic_send_msg_to_vf(nic, vf, &mbx);
1314
- }
1315
- }
1316
- queue_delayed_work(nic->check_link, &nic->dwork, HZ * 2);
1317
-}
1318
-
13191291 static int nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
13201292 {
13211293 struct device *dev = &pdev->dev;
....@@ -1384,18 +1356,6 @@
13841356 if (!nic->vf_lmac_map)
13851357 goto err_release_regions;
13861358
1387
- nic->link = devm_kmalloc_array(dev, max_lmac, sizeof(u8), GFP_KERNEL);
1388
- if (!nic->link)
1389
- goto err_release_regions;
1390
-
1391
- nic->duplex = devm_kmalloc_array(dev, max_lmac, sizeof(u8), GFP_KERNEL);
1392
- if (!nic->duplex)
1393
- goto err_release_regions;
1394
-
1395
- nic->speed = devm_kmalloc_array(dev, max_lmac, sizeof(u32), GFP_KERNEL);
1396
- if (!nic->speed)
1397
- goto err_release_regions;
1398
-
13991359 /* Initialize hardware */
14001360 nic_init_hw(nic);
14011361
....@@ -1411,22 +1371,8 @@
14111371 if (err)
14121372 goto err_unregister_interrupts;
14131373
1414
- /* Register a physical link status poll fn() */
1415
- nic->check_link = alloc_workqueue("check_link_status",
1416
- WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
1417
- if (!nic->check_link) {
1418
- err = -ENOMEM;
1419
- goto err_disable_sriov;
1420
- }
1421
-
1422
- INIT_DELAYED_WORK(&nic->dwork, nic_poll_for_link);
1423
- queue_delayed_work(nic->check_link, &nic->dwork, 0);
1424
-
14251374 return 0;
14261375
1427
-err_disable_sriov:
1428
- if (nic->flags & NIC_SRIOV_ENABLED)
1429
- pci_disable_sriov(pdev);
14301376 err_unregister_interrupts:
14311377 nic_unregister_interrupts(nic);
14321378 err_release_regions:
....@@ -1446,12 +1392,6 @@
14461392
14471393 if (nic->flags & NIC_SRIOV_ENABLED)
14481394 pci_disable_sriov(pdev);
1449
-
1450
- if (nic->check_link) {
1451
- /* Destroy work Queue */
1452
- cancel_delayed_work_sync(&nic->dwork);
1453
- destroy_workqueue(nic->check_link);
1454
- }
14551395
14561396 nic_unregister_interrupts(nic);
14571397 pci_release_regions(pdev);