Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pds_core: publish events to the clients

When the Core device gets an event from the device, or notices
the device FW to be up or down, it needs to send those events
on to the clients that have an event handler. Add the code to
pass along the events to the clients.

The entry points pdsc_register_notify() and pdsc_unregister_notify()
are EXPORTed for other drivers that want to listen for these events.

Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Shannon Nelson and committed by
David S. Miller
d24c2827 10659034

+39
+2
drivers/net/ethernet/amd/pds_core/adminq.c
··· 29 29 case PDS_EVENT_LINK_CHANGE: 30 30 dev_info(pdsc->dev, "NotifyQ LINK_CHANGE ecode %d eid %lld\n", 31 31 ecode, eid); 32 + pdsc_notify(PDS_EVENT_LINK_CHANGE, comp); 32 33 break; 33 34 34 35 case PDS_EVENT_RESET: 35 36 dev_info(pdsc->dev, "NotifyQ RESET ecode %d eid %lld\n", 36 37 ecode, eid); 38 + pdsc_notify(PDS_EVENT_RESET, comp); 37 39 break; 38 40 39 41 case PDS_EVENT_XCVR:
+32
drivers/net/ethernet/amd/pds_core/core.c
··· 6 6 7 7 #include "core.h" 8 8 9 + static BLOCKING_NOTIFIER_HEAD(pds_notify_chain); 10 + 11 + int pdsc_register_notify(struct notifier_block *nb) 12 + { 13 + return blocking_notifier_chain_register(&pds_notify_chain, nb); 14 + } 15 + EXPORT_SYMBOL_GPL(pdsc_register_notify); 16 + 17 + void pdsc_unregister_notify(struct notifier_block *nb) 18 + { 19 + blocking_notifier_chain_unregister(&pds_notify_chain, nb); 20 + } 21 + EXPORT_SYMBOL_GPL(pdsc_unregister_notify); 22 + 23 + void pdsc_notify(unsigned long event, void *data) 24 + { 25 + blocking_notifier_call_chain(&pds_notify_chain, event, data); 26 + } 27 + 9 28 void pdsc_intr_free(struct pdsc *pdsc, int index) 10 29 { 11 30 struct pdsc_intr_info *intr_info; ··· 513 494 514 495 static void pdsc_fw_down(struct pdsc *pdsc) 515 496 { 497 + union pds_core_notifyq_comp reset_event = { 498 + .reset.ecode = cpu_to_le16(PDS_EVENT_RESET), 499 + .reset.state = 0, 500 + }; 501 + 516 502 if (test_and_set_bit(PDSC_S_FW_DEAD, &pdsc->state)) { 517 503 dev_err(pdsc->dev, "%s: already happening\n", __func__); 518 504 return; 519 505 } 520 506 507 + /* Notify clients of fw_down */ 521 508 devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc); 509 + pdsc_notify(PDS_EVENT_RESET, &reset_event); 522 510 523 511 pdsc_stop(pdsc); 524 512 pdsc_teardown(pdsc, PDSC_TEARDOWN_RECOVERY); ··· 533 507 534 508 static void pdsc_fw_up(struct pdsc *pdsc) 535 509 { 510 + union pds_core_notifyq_comp reset_event = { 511 + .reset.ecode = cpu_to_le16(PDS_EVENT_RESET), 512 + .reset.state = 1, 513 + }; 536 514 int err; 537 515 538 516 if (!test_bit(PDSC_S_FW_DEAD, &pdsc->state)) { ··· 552 522 if (err) 553 523 goto err_out; 554 524 525 + /* Notify clients of fw_up */ 555 526 pdsc->fw_recoveries++; 556 527 devlink_health_reporter_state_update(pdsc->fw_reporter, 557 528 DEVLINK_HEALTH_REPORTER_STATE_HEALTHY); 529 + pdsc_notify(PDS_EVENT_RESET, &reset_event); 558 530 559 531 return; 560 532
+3
drivers/net/ethernet/amd/pds_core/core.h
··· 297 297 void pdsc_stop(struct pdsc *pdsc); 298 298 void pdsc_health_thread(struct work_struct *work); 299 299 300 + int pdsc_register_notify(struct notifier_block *nb); 301 + void pdsc_unregister_notify(struct notifier_block *nb); 302 + void pdsc_notify(unsigned long event, void *data); 300 303 int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf); 301 304 int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf); 302 305
+2
include/linux/pds/pds_common.h
··· 60 60 PDS_CORE_QTYPE_MAX = 16 /* don't change - used in struct size */ 61 61 }; 62 62 63 + int pdsc_register_notify(struct notifier_block *nb); 64 + void pdsc_unregister_notify(struct notifier_block *nb); 63 65 void *pdsc_get_pf_struct(struct pci_dev *vf_pdev); 64 66 int pds_client_register(struct pci_dev *pf_pdev, char *devname); 65 67 int pds_client_unregister(struct pci_dev *pf_pdev, u16 client_id);