Skip to content

Commit c6e03db

Browse files
committed
Merge branch 'mana-misc'
Dexuan Cui says: ==================== net: mana: some misc patches Patch 1 is a small fix. Patch 2 reports OS info to the PF driver. Before the patch, the req fields were all zeros. Patch 3 fixes and cleans up the error handling of HWC creation failure. Patch 4 adds the callbacks for hibernation/kexec. It's based on patch 3. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 986d2e3 + 635096a commit c6e03db

File tree

4 files changed

+208
-97
lines changed

4 files changed

+208
-97
lines changed

drivers/net/ethernet/microsoft/mana/gdma_main.c

Lines changed: 117 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <linux/module.h>
55
#include <linux/pci.h>
6+
#include <linux/utsname.h>
7+
#include <linux/version.h>
68

79
#include "mana.h"
810

@@ -848,6 +850,15 @@ int mana_gd_verify_vf_version(struct pci_dev *pdev)
848850
req.gd_drv_cap_flags3 = GDMA_DRV_CAP_FLAGS3;
849851
req.gd_drv_cap_flags4 = GDMA_DRV_CAP_FLAGS4;
850852

853+
req.drv_ver = 0; /* Unused*/
854+
req.os_type = 0x10; /* Linux */
855+
req.os_ver_major = LINUX_VERSION_MAJOR;
856+
req.os_ver_minor = LINUX_VERSION_PATCHLEVEL;
857+
req.os_ver_build = LINUX_VERSION_SUBLEVEL;
858+
strscpy(req.os_ver_str1, utsname()->sysname, sizeof(req.os_ver_str1));
859+
strscpy(req.os_ver_str2, utsname()->release, sizeof(req.os_ver_str2));
860+
strscpy(req.os_ver_str3, utsname()->version, sizeof(req.os_ver_str3));
861+
851862
err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp);
852863
if (err || resp.hdr.status) {
853864
dev_err(gc->dev, "VfVerifyVersionOutput: %d, status=0x%x\n",
@@ -1247,6 +1258,52 @@ static void mana_gd_remove_irqs(struct pci_dev *pdev)
12471258
gc->irq_contexts = NULL;
12481259
}
12491260

1261+
static int mana_gd_setup(struct pci_dev *pdev)
1262+
{
1263+
struct gdma_context *gc = pci_get_drvdata(pdev);
1264+
int err;
1265+
1266+
mana_gd_init_registers(pdev);
1267+
mana_smc_init(&gc->shm_channel, gc->dev, gc->shm_base);
1268+
1269+
err = mana_gd_setup_irqs(pdev);
1270+
if (err)
1271+
return err;
1272+
1273+
err = mana_hwc_create_channel(gc);
1274+
if (err)
1275+
goto remove_irq;
1276+
1277+
err = mana_gd_verify_vf_version(pdev);
1278+
if (err)
1279+
goto destroy_hwc;
1280+
1281+
err = mana_gd_query_max_resources(pdev);
1282+
if (err)
1283+
goto destroy_hwc;
1284+
1285+
err = mana_gd_detect_devices(pdev);
1286+
if (err)
1287+
goto destroy_hwc;
1288+
1289+
return 0;
1290+
1291+
destroy_hwc:
1292+
mana_hwc_destroy_channel(gc);
1293+
remove_irq:
1294+
mana_gd_remove_irqs(pdev);
1295+
return err;
1296+
}
1297+
1298+
static void mana_gd_cleanup(struct pci_dev *pdev)
1299+
{
1300+
struct gdma_context *gc = pci_get_drvdata(pdev);
1301+
1302+
mana_hwc_destroy_channel(gc);
1303+
1304+
mana_gd_remove_irqs(pdev);
1305+
}
1306+
12501307
static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
12511308
{
12521309
struct gdma_context *gc;
@@ -1276,56 +1333,33 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
12761333
if (!gc)
12771334
goto release_region;
12781335

1336+
mutex_init(&gc->eq_test_event_mutex);
1337+
pci_set_drvdata(pdev, gc);
1338+
12791339
bar0_va = pci_iomap(pdev, bar, 0);
12801340
if (!bar0_va)
12811341
goto free_gc;
12821342

12831343
gc->bar0_va = bar0_va;
12841344
gc->dev = &pdev->dev;
12851345

1286-
pci_set_drvdata(pdev, gc);
12871346

1288-
mana_gd_init_registers(pdev);
1289-
1290-
mana_smc_init(&gc->shm_channel, gc->dev, gc->shm_base);
1291-
1292-
err = mana_gd_setup_irqs(pdev);
1347+
err = mana_gd_setup(pdev);
12931348
if (err)
12941349
goto unmap_bar;
12951350

1296-
mutex_init(&gc->eq_test_event_mutex);
1297-
1298-
err = mana_hwc_create_channel(gc);
1299-
if (err)
1300-
goto remove_irq;
1301-
1302-
err = mana_gd_verify_vf_version(pdev);
1303-
if (err)
1304-
goto remove_irq;
1305-
1306-
err = mana_gd_query_max_resources(pdev);
1307-
if (err)
1308-
goto remove_irq;
1309-
1310-
err = mana_gd_detect_devices(pdev);
1351+
err = mana_probe(&gc->mana, false);
13111352
if (err)
1312-
goto remove_irq;
1313-
1314-
err = mana_probe(&gc->mana);
1315-
if (err)
1316-
goto clean_up_gdma;
1353+
goto cleanup_gd;
13171354

13181355
return 0;
13191356

1320-
clean_up_gdma:
1321-
mana_hwc_destroy_channel(gc);
1322-
vfree(gc->cq_table);
1323-
gc->cq_table = NULL;
1324-
remove_irq:
1325-
mana_gd_remove_irqs(pdev);
1357+
cleanup_gd:
1358+
mana_gd_cleanup(pdev);
13261359
unmap_bar:
13271360
pci_iounmap(pdev, bar0_va);
13281361
free_gc:
1362+
pci_set_drvdata(pdev, NULL);
13291363
vfree(gc);
13301364
release_region:
13311365
pci_release_regions(pdev);
@@ -1340,13 +1374,9 @@ static void mana_gd_remove(struct pci_dev *pdev)
13401374
{
13411375
struct gdma_context *gc = pci_get_drvdata(pdev);
13421376

1343-
mana_remove(&gc->mana);
1377+
mana_remove(&gc->mana, false);
13441378

1345-
mana_hwc_destroy_channel(gc);
1346-
vfree(gc->cq_table);
1347-
gc->cq_table = NULL;
1348-
1349-
mana_gd_remove_irqs(pdev);
1379+
mana_gd_cleanup(pdev);
13501380

13511381
pci_iounmap(pdev, gc->bar0_va);
13521382

@@ -1357,6 +1387,52 @@ static void mana_gd_remove(struct pci_dev *pdev)
13571387
pci_disable_device(pdev);
13581388
}
13591389

1390+
/* The 'state' parameter is not used. */
1391+
static int mana_gd_suspend(struct pci_dev *pdev, pm_message_t state)
1392+
{
1393+
struct gdma_context *gc = pci_get_drvdata(pdev);
1394+
1395+
mana_remove(&gc->mana, true);
1396+
1397+
mana_gd_cleanup(pdev);
1398+
1399+
return 0;
1400+
}
1401+
1402+
/* In case the NIC hardware stops working, the suspend and resume callbacks will
1403+
* fail -- if this happens, it's safer to just report an error than try to undo
1404+
* what has been done.
1405+
*/
1406+
static int mana_gd_resume(struct pci_dev *pdev)
1407+
{
1408+
struct gdma_context *gc = pci_get_drvdata(pdev);
1409+
int err;
1410+
1411+
err = mana_gd_setup(pdev);
1412+
if (err)
1413+
return err;
1414+
1415+
err = mana_probe(&gc->mana, true);
1416+
if (err)
1417+
return err;
1418+
1419+
return 0;
1420+
}
1421+
1422+
/* Quiesce the device for kexec. This is also called upon reboot/shutdown. */
1423+
static void mana_gd_shutdown(struct pci_dev *pdev)
1424+
{
1425+
struct gdma_context *gc = pci_get_drvdata(pdev);
1426+
1427+
dev_info(&pdev->dev, "Shutdown was calledd\n");
1428+
1429+
mana_remove(&gc->mana, true);
1430+
1431+
mana_gd_cleanup(pdev);
1432+
1433+
pci_disable_device(pdev);
1434+
}
1435+
13601436
#ifndef PCI_VENDOR_ID_MICROSOFT
13611437
#define PCI_VENDOR_ID_MICROSOFT 0x1414
13621438
#endif
@@ -1371,6 +1447,9 @@ static struct pci_driver mana_driver = {
13711447
.id_table = mana_id_table,
13721448
.probe = mana_gd_probe,
13731449
.remove = mana_gd_remove,
1450+
.suspend = mana_gd_suspend,
1451+
.resume = mana_gd_resume,
1452+
.shutdown = mana_gd_shutdown,
13741453
};
13751454

13761455
module_pci_driver(mana_driver);

drivers/net/ethernet/microsoft/mana/hw_channel.c

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,6 @@ static void mana_hwc_comp_event(void *ctx, struct gdma_queue *q_self)
309309

310310
static void mana_hwc_destroy_cq(struct gdma_context *gc, struct hwc_cq *hwc_cq)
311311
{
312-
if (!hwc_cq)
313-
return;
314-
315312
kfree(hwc_cq->comp_buf);
316313

317314
if (hwc_cq->gdma_cq)
@@ -446,9 +443,6 @@ static void mana_hwc_dealloc_dma_buf(struct hw_channel_context *hwc,
446443
static void mana_hwc_destroy_wq(struct hw_channel_context *hwc,
447444
struct hwc_wq *hwc_wq)
448445
{
449-
if (!hwc_wq)
450-
return;
451-
452446
mana_hwc_dealloc_dma_buf(hwc, hwc_wq->msg_buf);
453447

454448
if (hwc_wq->gdma_wq)
@@ -621,6 +615,7 @@ static int mana_hwc_establish_channel(struct gdma_context *gc, u16 *q_depth,
621615
*max_req_msg_size = hwc->hwc_init_max_req_msg_size;
622616
*max_resp_msg_size = hwc->hwc_init_max_resp_msg_size;
623617

618+
/* Both were set in mana_hwc_init_event_handler(). */
624619
if (WARN_ON(cq->id >= gc->max_num_cqs))
625620
return -EPROTO;
626621

@@ -636,9 +631,6 @@ static int mana_hwc_establish_channel(struct gdma_context *gc, u16 *q_depth,
636631
static int mana_hwc_init_queues(struct hw_channel_context *hwc, u16 q_depth,
637632
u32 max_req_msg_size, u32 max_resp_msg_size)
638633
{
639-
struct hwc_wq *hwc_rxq = NULL;
640-
struct hwc_wq *hwc_txq = NULL;
641-
struct hwc_cq *hwc_cq = NULL;
642634
int err;
643635

644636
err = mana_hwc_init_inflight_msg(hwc, q_depth);
@@ -651,44 +643,32 @@ static int mana_hwc_init_queues(struct hw_channel_context *hwc, u16 q_depth,
651643
err = mana_hwc_create_cq(hwc, q_depth * 2,
652644
mana_hwc_init_event_handler, hwc,
653645
mana_hwc_rx_event_handler, hwc,
654-
mana_hwc_tx_event_handler, hwc, &hwc_cq);
646+
mana_hwc_tx_event_handler, hwc, &hwc->cq);
655647
if (err) {
656648
dev_err(hwc->dev, "Failed to create HWC CQ: %d\n", err);
657649
goto out;
658650
}
659-
hwc->cq = hwc_cq;
660651

661652
err = mana_hwc_create_wq(hwc, GDMA_RQ, q_depth, max_req_msg_size,
662-
hwc_cq, &hwc_rxq);
653+
hwc->cq, &hwc->rxq);
663654
if (err) {
664655
dev_err(hwc->dev, "Failed to create HWC RQ: %d\n", err);
665656
goto out;
666657
}
667-
hwc->rxq = hwc_rxq;
668658

669659
err = mana_hwc_create_wq(hwc, GDMA_SQ, q_depth, max_resp_msg_size,
670-
hwc_cq, &hwc_txq);
660+
hwc->cq, &hwc->txq);
671661
if (err) {
672662
dev_err(hwc->dev, "Failed to create HWC SQ: %d\n", err);
673663
goto out;
674664
}
675-
hwc->txq = hwc_txq;
676665

677666
hwc->num_inflight_msg = q_depth;
678667
hwc->max_req_msg_size = max_req_msg_size;
679668

680669
return 0;
681670
out:
682-
if (hwc_txq)
683-
mana_hwc_destroy_wq(hwc, hwc_txq);
684-
685-
if (hwc_rxq)
686-
mana_hwc_destroy_wq(hwc, hwc_rxq);
687-
688-
if (hwc_cq)
689-
mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc_cq);
690-
691-
mana_gd_free_res_map(&hwc->inflight_msg_res);
671+
/* mana_hwc_create_channel() will do the cleanup.*/
692672
return err;
693673
}
694674

@@ -716,6 +696,9 @@ int mana_hwc_create_channel(struct gdma_context *gc)
716696
gd->pdid = INVALID_PDID;
717697
gd->doorbell = INVALID_DOORBELL;
718698

699+
/* mana_hwc_init_queues() only creates the required data structures,
700+
* and doesn't touch the HWC device.
701+
*/
719702
err = mana_hwc_init_queues(hwc, HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH,
720703
HW_CHANNEL_MAX_REQUEST_SIZE,
721704
HW_CHANNEL_MAX_RESPONSE_SIZE);
@@ -741,42 +724,50 @@ int mana_hwc_create_channel(struct gdma_context *gc)
741724

742725
return 0;
743726
out:
744-
kfree(hwc);
727+
mana_hwc_destroy_channel(gc);
745728
return err;
746729
}
747730

748731
void mana_hwc_destroy_channel(struct gdma_context *gc)
749732
{
750733
struct hw_channel_context *hwc = gc->hwc.driver_data;
751-
struct hwc_caller_ctx *ctx;
752734

753-
mana_smc_teardown_hwc(&gc->shm_channel, false);
735+
if (!hwc)
736+
return;
737+
738+
/* gc->max_num_cqs is set in mana_hwc_init_event_handler(). If it's
739+
* non-zero, the HWC worked and we should tear down the HWC here.
740+
*/
741+
if (gc->max_num_cqs > 0) {
742+
mana_smc_teardown_hwc(&gc->shm_channel, false);
743+
gc->max_num_cqs = 0;
744+
}
754745

755-
ctx = hwc->caller_ctx;
756-
kfree(ctx);
746+
kfree(hwc->caller_ctx);
757747
hwc->caller_ctx = NULL;
758748

759-
mana_hwc_destroy_wq(hwc, hwc->txq);
760-
hwc->txq = NULL;
749+
if (hwc->txq)
750+
mana_hwc_destroy_wq(hwc, hwc->txq);
761751

762-
mana_hwc_destroy_wq(hwc, hwc->rxq);
763-
hwc->rxq = NULL;
752+
if (hwc->rxq)
753+
mana_hwc_destroy_wq(hwc, hwc->rxq);
764754

765-
mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq);
766-
hwc->cq = NULL;
755+
if (hwc->cq)
756+
mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq);
767757

768758
mana_gd_free_res_map(&hwc->inflight_msg_res);
769759

770760
hwc->num_inflight_msg = 0;
771761

772-
if (hwc->gdma_dev->pdid != INVALID_PDID) {
773-
hwc->gdma_dev->doorbell = INVALID_DOORBELL;
774-
hwc->gdma_dev->pdid = INVALID_PDID;
775-
}
762+
hwc->gdma_dev->doorbell = INVALID_DOORBELL;
763+
hwc->gdma_dev->pdid = INVALID_PDID;
776764

777765
kfree(hwc);
778766
gc->hwc.driver_data = NULL;
779767
gc->hwc.gdma_context = NULL;
768+
769+
vfree(gc->cq_table);
770+
gc->cq_table = NULL;
780771
}
781772

782773
int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,

drivers/net/ethernet/microsoft/mana/mana.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ int mana_alloc_queues(struct net_device *ndev);
374374
int mana_attach(struct net_device *ndev);
375375
int mana_detach(struct net_device *ndev, bool from_close);
376376

377-
int mana_probe(struct gdma_dev *gd);
378-
void mana_remove(struct gdma_dev *gd);
377+
int mana_probe(struct gdma_dev *gd, bool resuming);
378+
void mana_remove(struct gdma_dev *gd, bool suspending);
379379

380380
extern const struct ethtool_ops mana_ethtool_ops;
381381

0 commit comments

Comments
 (0)