From owner-dev-commits-src-main@freebsd.org Fri Jun 18 21:49:06 2021 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 5DAAE64DC88; Fri, 18 Jun 2021 21:49:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4G6CHQ1Rrfz3MkY; Fri, 18 Jun 2021 21:49:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0BADB242D; Fri, 18 Jun 2021 21:49:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 15ILn5hZ069197; Fri, 18 Jun 2021 21:49:05 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 15ILn5MJ069196; Fri, 18 Jun 2021 21:49:05 GMT (envelope-from git) Date: Fri, 18 Jun 2021 21:49:05 GMT Message-Id: <202106182149.15ILn5MJ069196@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Bjoern A. Zeeb" Subject: git: 8e106c5230c1 - main - LinuxKPI: extend pci.h by various functions for wireless driver MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bz X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 8e106c5230c1f0683ffc473db5c2e0d01b2bfeea Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Jun 2021 21:49:06 -0000 The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=8e106c5230c1f0683ffc473db5c2e0d01b2bfeea commit 8e106c5230c1f0683ffc473db5c2e0d01b2bfeea Author: Bjoern A. Zeeb AuthorDate: 2021-05-28 11:16:12 +0000 Commit: Bjoern A. Zeeb CommitDate: 2021-06-18 21:20:09 +0000 LinuxKPI: extend pci.h by various functions for wireless driver Add dummy functions for dealing with "HotPlug" events which we currently do not support. Add pci_dev_get(), pci_find_ext_capability() and pci_pme_capable(). The added pcie_find_root_port() is a bit special as we need to create another linux pci device; for that make lkpinew_pci_dev() public which is also helpful for other cases when we want to use the Linux routines to check for device identifiers only and need a container for the "bsddev" to use natively. This has proven to avoid basic checking code for the sake of rewriting it to native field names elsewhere. Given we cache the newly created "root" we also need to make sure we clean it up. Sponsored by: The FreeBSD Foundation MFC after: 10 days Reviewed by: hselasky Differential Revision: https://reviews.freebsd.org/D30521 --- sys/compat/linuxkpi/common/include/linux/pci.h | 88 ++++++++++++++++++++++++++ sys/compat/linuxkpi/common/src/linux_pci.c | 6 +- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h index 36a82e81b4bc..b8a801ac9f70 100644 --- a/sys/compat/linuxkpi/common/include/linux/pci.h +++ b/sys/compat/linuxkpi/common/include/linux/pci.h @@ -221,6 +221,7 @@ struct pci_dev { struct list_head links; struct pci_driver *pdrv; struct pci_bus *bus; + struct pci_dev *root; uint16_t device; uint16_t vendor; uint16_t subsystem_vendor; @@ -236,6 +237,10 @@ struct pci_dev { TAILQ_HEAD(, pci_mmio_region) mmio; }; +/* Internal helper function(s). */ +struct pci_dev *lkpinew_pci_dev(device_t); + + static inline struct resource_list_entry * linux_pci_get_rle(struct pci_dev *pdev, int type, int rid) { @@ -327,6 +332,15 @@ pci_set_drvdata(struct pci_dev *pdev, void *data) dev_set_drvdata(&pdev->dev, data); } +static inline struct pci_dev * +pci_dev_get(struct pci_dev *pdev) +{ + + if (pdev != NULL) + get_device(&pdev->dev); + return (pdev); +} + static __inline void pci_dev_put(struct pci_dev *pdev) { @@ -496,6 +510,48 @@ static inline int pci_pcie_cap(struct pci_dev *dev) return pci_find_capability(dev, PCI_CAP_ID_EXP); } +static inline int +pci_find_ext_capability(struct pci_dev *pdev, int capid) +{ + int reg; + + if (pci_find_extcap(pdev->dev.bsddev, capid, ®)) + return (0); + return (reg); +} + +#define PCIM_PCAP_PME_SHIFT 11 +static __inline bool +pci_pme_capable(struct pci_dev *pdev, uint32_t flag) +{ + struct pci_devinfo *dinfo; + pcicfgregs *cfg; + + if (flag > (PCIM_PCAP_D3PME_COLD >> PCIM_PCAP_PME_SHIFT)) + return (false); + + dinfo = device_get_ivars(pdev->dev.bsddev); + cfg = &dinfo->cfg; + + if (cfg->pp.pp_cap == 0) + return (false); + + if ((cfg->pp.pp_cap & (1 << (PCIM_PCAP_PME_SHIFT + flag))) != 0) + return (true); + + return (false); +} + +static inline int +pci_disable_link_state(struct pci_dev *pdev, uint32_t flags) +{ + + if (!pci_enable_aspm) + return (-EPERM); + + return (-ENXIO); +} + static inline int pci_read_config_byte(struct pci_dev *pdev, int where, u8 *val) { @@ -1052,6 +1108,38 @@ pcie_bandwidth_available(struct pci_dev *pdev, return (nwidth * PCIE_SPEED2MBS_ENC(nspeed)); } +static inline struct pci_dev * +pcie_find_root_port(struct pci_dev *pdev) +{ + device_t root; + + if (pdev->root != NULL) + return (pdev->root); + + root = pci_find_pcie_root_port(pdev->dev.bsddev); + if (root == NULL) + return (NULL); + + pdev->root = lkpinew_pci_dev(root); + return (pdev->root); +} + +/* This is needed when people rip out the device "HotPlug". */ +static inline void +pci_lock_rescan_remove(void) +{ +} + +static inline void +pci_unlock_rescan_remove(void) +{ +} + +static __inline void +pci_stop_and_remove_bus_device(struct pci_dev *pdev) +{ +} + /* * The following functions can be used to attach/detach the LinuxKPI's * PCI device runtime. The pci_driver and pci_device_id pointer is diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c index 7aa159600faa..030951175a42 100644 --- a/sys/compat/linuxkpi/common/src/linux_pci.c +++ b/sys/compat/linuxkpi/common/src/linux_pci.c @@ -243,11 +243,13 @@ lkpinew_pci_dev_release(struct device *dev) struct pci_dev *pdev; pdev = to_pci_dev(dev); + if (pdev->root != NULL) + pci_dev_put(pdev->root); free(pdev->bus, M_DEVBUF); free(pdev, M_DEVBUF); } -static struct pci_dev * +struct pci_dev * lkpinew_pci_dev(device_t dev) { struct pci_dev *pdev; @@ -408,6 +410,8 @@ linux_pci_detach_device(struct pci_dev *pdev) if (pdev->pdrv != NULL) pdev->pdrv->remove(pdev); + if (pdev->root != NULL) + pci_dev_put(pdev->root); free(pdev->bus, M_DEVBUF); linux_pdev_dma_uninit(pdev);