Message ID | 1502303377-28407-2-git-send-email-arbab@linux.vnet.ibm.com |
---|---|
State | Accepted |
Headers | show |
On 10/08/17 04:29, Reza Arbab wrote: > Add basic handling of FLR (function level reset) by porting the changes > from commit b74841db759d ("npu: Implement FLR") to npu2. > > The only difference for npu2 is that we track the reset state explicitly > with a link flag instead of inferring it from > dev->procedure_{status,number,step,data}. Sounds like a reasonable thing to do for NPU too. > Signed-off-by: Reza Arbab <arbab@linux.vnet.ibm.com> > Cc: Alexey Kardashevskiy <aik@ozlabs.ru> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Also, please, when you post a patchset, cc: everyone in every patch, I had to dig for 1/2. Thanks. > --- > hw/npu2-hw-procedures.c | 5 +++++ > hw/npu2.c | 29 ++++++++++++++++++++++++++++- > include/npu2.h | 1 + > 3 files changed, 34 insertions(+), 1 deletion(-) > > diff --git a/hw/npu2-hw-procedures.c b/hw/npu2-hw-procedures.c > index 71af3e7..1a990f2 100644 > --- a/hw/npu2-hw-procedures.c > +++ b/hw/npu2-hw-procedures.c > @@ -719,3 +719,8 @@ int64_t npu2_dev_procedure(void *dev, struct pci_cfg_reg_filter *pcrf, > > return npu_dev_procedure_read(ndev, offset - pcrf->start, len, data); > } > + > +void npu2_dev_procedure_reset(struct npu2_dev *dev) > +{ > + npu2_clear_link_flag(dev, NPU2_DEV_DL_RESET); > +} > diff --git a/hw/npu2.c b/hw/npu2.c > index 807c78d..87f52e2 100644 > --- a/hw/npu2.c > +++ b/hw/npu2.c > @@ -405,6 +405,29 @@ static int64_t npu2_dev_cfg_bar(void *dev, struct pci_cfg_reg_filter *pcrf, > return npu2_cfg_read_bar(ndev, pcrf, offset, len, data); > } > > +static int64_t npu2_dev_cfg_exp_devcap(void *dev, > + struct pci_cfg_reg_filter *pcrf __unused, > + uint32_t offset, uint32_t size, > + uint32_t *data, bool write) > +{ > + struct pci_virt_device *pvd = dev; > + struct npu2_dev *ndev = pvd->data; > + > + assert(write); > + > + if ((size != 2) || (offset & 1)) { > + /* Short config writes are not supported */ > + prlog(PR_ERR, "NPU%d: Unsupported write to pcie control register\n", > + ndev->phb->opal_id); > + return OPAL_PARAMETER; > + } > + > + if (*data & PCICAP_EXP_DEVCTL_FUNC_RESET) > + npu2_dev_procedure_reset(ndev); > + > + return OPAL_PARTIAL; > +} > + > #define NPU2_CFG_READ(size, type) \ > static int64_t npu2_cfg_read##size(struct phb *phb, uint32_t bdfn, \ > uint32_t offset, type *data) \ > @@ -1336,7 +1359,7 @@ static uint32_t npu2_populate_pcie_cap(struct npu2_dev *dev, > > /* 0x04 - Device capability > * > - * We should support FLR. Oterwhsie, it might have > + * We should support FLR. Otherwise, it might have > * problem passing it through to userland via Linux > * VFIO infrastructure > */ > @@ -1347,6 +1370,10 @@ static uint32_t npu2_populate_pcie_cap(struct npu2_dev *dev, > (PCICAP_EXP_DEVCAP_FUNC_RESET)); > PCI_VIRT_CFG_INIT_RO(pvd, start + PCICAP_EXP_DEVCAP, 4, val); > > + pci_virt_add_filter(pvd, start + PCICAP_EXP_DEVCTL, 2, > + PCI_REG_FLAG_WRITE, > + npu2_dev_cfg_exp_devcap, NULL); > + > /* 0x08 - Device control and status */ > PCI_VIRT_CFG_INIT(pvd, start + PCICAP_EXP_DEVCTL, 4, 0x00002810, > 0xffff0000, 0x000f0000); > diff --git a/include/npu2.h b/include/npu2.h > index ef05f46..f11a13a 100644 > --- a/include/npu2.h > +++ b/include/npu2.h > @@ -155,6 +155,7 @@ void npu2_write_mask(struct npu2 *p, uint64_t reg, uint64_t val, uint64_t mask); > int64_t npu2_dev_procedure(void *dev, struct pci_cfg_reg_filter *pcrf, > uint32_t offset, uint32_t len, uint32_t *data, > bool write); > +void npu2_dev_procedure_reset(struct npu2_dev *dev); > void npu2_set_link_flag(struct npu2_dev *ndev, uint8_t flag); > void npu2_clear_link_flag(struct npu2_dev *ndev, uint8_t flag); > extern int nv_zcal_nominal; >
diff --git a/hw/npu2-hw-procedures.c b/hw/npu2-hw-procedures.c index 71af3e7..1a990f2 100644 --- a/hw/npu2-hw-procedures.c +++ b/hw/npu2-hw-procedures.c @@ -719,3 +719,8 @@ int64_t npu2_dev_procedure(void *dev, struct pci_cfg_reg_filter *pcrf, return npu_dev_procedure_read(ndev, offset - pcrf->start, len, data); } + +void npu2_dev_procedure_reset(struct npu2_dev *dev) +{ + npu2_clear_link_flag(dev, NPU2_DEV_DL_RESET); +} diff --git a/hw/npu2.c b/hw/npu2.c index 807c78d..87f52e2 100644 --- a/hw/npu2.c +++ b/hw/npu2.c @@ -405,6 +405,29 @@ static int64_t npu2_dev_cfg_bar(void *dev, struct pci_cfg_reg_filter *pcrf, return npu2_cfg_read_bar(ndev, pcrf, offset, len, data); } +static int64_t npu2_dev_cfg_exp_devcap(void *dev, + struct pci_cfg_reg_filter *pcrf __unused, + uint32_t offset, uint32_t size, + uint32_t *data, bool write) +{ + struct pci_virt_device *pvd = dev; + struct npu2_dev *ndev = pvd->data; + + assert(write); + + if ((size != 2) || (offset & 1)) { + /* Short config writes are not supported */ + prlog(PR_ERR, "NPU%d: Unsupported write to pcie control register\n", + ndev->phb->opal_id); + return OPAL_PARAMETER; + } + + if (*data & PCICAP_EXP_DEVCTL_FUNC_RESET) + npu2_dev_procedure_reset(ndev); + + return OPAL_PARTIAL; +} + #define NPU2_CFG_READ(size, type) \ static int64_t npu2_cfg_read##size(struct phb *phb, uint32_t bdfn, \ uint32_t offset, type *data) \ @@ -1336,7 +1359,7 @@ static uint32_t npu2_populate_pcie_cap(struct npu2_dev *dev, /* 0x04 - Device capability * - * We should support FLR. Oterwhsie, it might have + * We should support FLR. Otherwise, it might have * problem passing it through to userland via Linux * VFIO infrastructure */ @@ -1347,6 +1370,10 @@ static uint32_t npu2_populate_pcie_cap(struct npu2_dev *dev, (PCICAP_EXP_DEVCAP_FUNC_RESET)); PCI_VIRT_CFG_INIT_RO(pvd, start + PCICAP_EXP_DEVCAP, 4, val); + pci_virt_add_filter(pvd, start + PCICAP_EXP_DEVCTL, 2, + PCI_REG_FLAG_WRITE, + npu2_dev_cfg_exp_devcap, NULL); + /* 0x08 - Device control and status */ PCI_VIRT_CFG_INIT(pvd, start + PCICAP_EXP_DEVCTL, 4, 0x00002810, 0xffff0000, 0x000f0000); diff --git a/include/npu2.h b/include/npu2.h index ef05f46..f11a13a 100644 --- a/include/npu2.h +++ b/include/npu2.h @@ -155,6 +155,7 @@ void npu2_write_mask(struct npu2 *p, uint64_t reg, uint64_t val, uint64_t mask); int64_t npu2_dev_procedure(void *dev, struct pci_cfg_reg_filter *pcrf, uint32_t offset, uint32_t len, uint32_t *data, bool write); +void npu2_dev_procedure_reset(struct npu2_dev *dev); void npu2_set_link_flag(struct npu2_dev *ndev, uint8_t flag); void npu2_clear_link_flag(struct npu2_dev *ndev, uint8_t flag); extern int nv_zcal_nominal;
Add basic handling of FLR (function level reset) by porting the changes from commit b74841db759d ("npu: Implement FLR") to npu2. The only difference for npu2 is that we track the reset state explicitly with a link flag instead of inferring it from dev->procedure_{status,number,step,data}. Signed-off-by: Reza Arbab <arbab@linux.vnet.ibm.com> Cc: Alexey Kardashevskiy <aik@ozlabs.ru> --- hw/npu2-hw-procedures.c | 5 +++++ hw/npu2.c | 29 ++++++++++++++++++++++++++++- include/npu2.h | 1 + 3 files changed, 34 insertions(+), 1 deletion(-)