Skip to content

Commit

Permalink
NTB: Fix access to link status and control register
Browse files Browse the repository at this point in the history
The design of AMD NTB implementation is such that
NTB primary acts as an endpoint device and NTB
secondary is an endpoint device behind a combination
of Switch Upstream and Switch Downstream. Considering
that, the link status and control register needs to
be accessed differently based on the NTB topology.

So in the case of NTB secondary, we first get the
pointer to the Switch Downstream device for the NTB
device. Then we get the pointer to the Switch Upstream
device. Once we have that, we read the Link Status
and Control register to get the correct status of
link at the secondary.

In the case of NTB primary, simply reading the Link
Status and Control register of the NTB device itself
will suffice.

Suggested-by: Jiasen Lin <linjiasen@hygon.cn>
Signed-off-by: Arindam Nath <arindam.nath@amd.com>
Signed-off-by: Jon Mason <jdmason@kudzu.us>
  • Loading branch information
Arindam Nath authored and Jon Mason committed Mar 13, 2020
1 parent 8ad1a2f commit cb004c2
Showing 1 changed file with 37 additions and 3 deletions.
40 changes: 37 additions & 3 deletions drivers/ntb/hw/amd/ntb_hw_amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,9 @@ static inline void ndev_init_struct(struct amd_ntb_dev *ndev,
static int amd_poll_link(struct amd_ntb_dev *ndev)
{
void __iomem *mmio = ndev->peer_mmio;
struct pci_dev *pdev = NULL;
struct pci_dev *pci_swds = NULL;
struct pci_dev *pci_swus = NULL;
u32 reg, stat;
int rc;

Expand All @@ -855,10 +858,41 @@ static int amd_poll_link(struct amd_ntb_dev *ndev)

ndev->cntl_sta = reg;

rc = pcie_capability_read_dword(ndev->ntb.pdev,
PCI_EXP_LNKCTL, &stat);
if (rc)
if (ndev->ntb.topo == NTB_TOPO_SEC) {
/* Locate the pointer to Downstream Switch for this device */
pci_swds = pci_upstream_bridge(ndev->ntb.pdev);
if (pci_swds) {
/*
* Locate the pointer to Upstream Switch for
* the Downstream Switch.
*/
pci_swus = pci_upstream_bridge(pci_swds);
if (pci_swus) {
rc = pcie_capability_read_dword(pci_swus,
PCI_EXP_LNKCTL,
&stat);
if (rc)
return 0;
} else {
return 0;
}
} else {
return 0;
}
} else if (ndev->ntb.topo == NTB_TOPO_PRI) {
/*
* For NTB primary, we simply read the Link Status and control
* register of the NTB device itself.
*/
pdev = ndev->ntb.pdev;
rc = pcie_capability_read_dword(pdev, PCI_EXP_LNKCTL, &stat);
if (rc)
return 0;
} else {
/* Catch all for everything else */
return 0;
}

ndev->lnk_sta = stat;

return 1;
Expand Down

0 comments on commit cb004c2

Please sign in to comment.