|author||Andrew Donnellan <email@example.com>||2016-07-14 07:17:14 +1000|
|committer||Michael Ellerman <firstname.lastname@example.org>||2016-07-14 20:28:11 +1000|
|parent||PCI/hotplug: pnv_php: handle OPAL_PCI_SLOT_OFFLINE power state (diff)|
cxl: Add cxl_check_and_switch_mode() API to switch bi-modal cards
Add a new API, cxl_check_and_switch_mode() to allow for switching of bi-modal CAPI cards, such as the Mellanox CX-4 network card. When a driver requests to switch a card to CAPI mode, use PCI hotplug infrastructure to remove all PCI devices underneath the slot. We then write an updated mode control register to the CAPI VSEC, hot reset the card, and reprobe the card. As the card may present a different set of PCI devices after the mode switch, use the infrastructure provided by the pnv_php driver and the OPAL PCI slot management facilities to ensure that: * the old devices are removed from both the OPAL and Linux device trees * the new devices are probed by OPAL and added to the OPAL device tree * the new devices are added to the Linux device tree and probed through the regular PCI device probe path As such, introduce a new option, CONFIG_CXL_BIMODAL, with a dependency on the pnv_php driver. Refactor existing code that touches the mode control register in the regular single mode case into a new function, setup_cxl_protocol_area(). Co-authored-by: Ian Munsie <email@example.com> Cc: Gavin Shan <firstname.lastname@example.org> Signed-off-by: Andrew Donnellan <email@example.com> Signed-off-by: Ian Munsie <firstname.lastname@example.org> Reviewed-by: Gavin Shan <email@example.com> Signed-off-by: Michael Ellerman <firstname.lastname@example.org>
Diffstat (limited to 'include/misc')
1 files changed, 25 insertions, 0 deletions
diff --git a/include/misc/cxl.h b/include/misc/cxl.h
index 6c52cbcdfd79..480d50a0b8ba 100644
@@ -39,6 +39,31 @@
bool cxl_slot_is_supported(struct pci_dev *dev, int flags);
+#define CXL_BIMODE_CXL 1
+#define CXL_BIMODE_PCI 2
+ * Check the mode that the given bi-modal CXL adapter is currently in and
+ * change it if necessary. This does not apply to AFU drivers.
+ * If the mode matches the requested mode this function will return 0 - if the
+ * driver was expecting the generic CXL driver to have bound to the adapter and
+ * it gets this return value it should fail the probe function to give the CXL
+ * driver a chance to probe it.
+ * If the mode does not match it will start a background task to unplug the
+ * device from Linux and switch its mode, and will return -EBUSY. At this
+ * point the calling driver should make sure it has released the device and
+ * fail its probe function.
+ * The offset of the CXL VSEC can be provided to this function. If 0 is passed,
+ * this function will search for a CXL VSEC with ID 0x1280 and return -ENODEV
+ * if it is not found.
+int cxl_check_and_switch_mode(struct pci_dev *dev, int mode, int vsec);
/* Get the AFU associated with a pci_dev */
struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev);