|
|
|
@@ -1008,7 +1008,7 @@ static irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq)
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void otx2_disable_mbox_intr(struct otx2_nic *pf)
|
|
|
|
|
void otx2_disable_mbox_intr(struct otx2_nic *pf)
|
|
|
|
|
{
|
|
|
|
|
int vector = pci_irq_vector(pf->pdev, RVU_PF_INT_VEC_AFPF_MBOX);
|
|
|
|
|
|
|
|
|
@@ -1017,7 +1017,7 @@ static void otx2_disable_mbox_intr(struct otx2_nic *pf)
|
|
|
|
|
free_irq(vector, pf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int otx2_register_mbox_intr(struct otx2_nic *pf, bool probe_af)
|
|
|
|
|
int otx2_register_mbox_intr(struct otx2_nic *pf, bool probe_af)
|
|
|
|
|
{
|
|
|
|
|
struct otx2_hw *hw = &pf->hw;
|
|
|
|
|
struct msg_req *req;
|
|
|
|
@@ -1061,7 +1061,7 @@ static int otx2_register_mbox_intr(struct otx2_nic *pf, bool probe_af)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void otx2_pfaf_mbox_destroy(struct otx2_nic *pf)
|
|
|
|
|
void otx2_pfaf_mbox_destroy(struct otx2_nic *pf)
|
|
|
|
|
{
|
|
|
|
|
struct mbox *mbox = &pf->mbox;
|
|
|
|
|
|
|
|
|
@@ -1077,7 +1077,7 @@ static void otx2_pfaf_mbox_destroy(struct otx2_nic *pf)
|
|
|
|
|
otx2_mbox_destroy(&mbox->mbox_up);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int otx2_pfaf_mbox_init(struct otx2_nic *pf)
|
|
|
|
|
int otx2_pfaf_mbox_init(struct otx2_nic *pf)
|
|
|
|
|
{
|
|
|
|
|
struct mbox *mbox = &pf->mbox;
|
|
|
|
|
void __iomem *hwbase;
|
|
|
|
@@ -1379,7 +1379,7 @@ done:
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static irqreturn_t otx2_cq_intr_handler(int irq, void *cq_irq)
|
|
|
|
|
irqreturn_t otx2_cq_intr_handler(int irq, void *cq_irq)
|
|
|
|
|
{
|
|
|
|
|
struct otx2_cq_poll *cq_poll = (struct otx2_cq_poll *)cq_irq;
|
|
|
|
|
struct otx2_nic *pf = (struct otx2_nic *)cq_poll->dev;
|
|
|
|
@@ -1399,15 +1399,18 @@ static irqreturn_t otx2_cq_intr_handler(int irq, void *cq_irq)
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void otx2_disable_napi(struct otx2_nic *pf)
|
|
|
|
|
void otx2_disable_napi(struct otx2_nic *pf)
|
|
|
|
|
{
|
|
|
|
|
struct otx2_qset *qset = &pf->qset;
|
|
|
|
|
struct otx2_cq_poll *cq_poll;
|
|
|
|
|
struct work_struct *work;
|
|
|
|
|
int qidx;
|
|
|
|
|
|
|
|
|
|
for (qidx = 0; qidx < pf->hw.cint_cnt; qidx++) {
|
|
|
|
|
cq_poll = &qset->napi[qidx];
|
|
|
|
|
cancel_work_sync(&cq_poll->dim.work);
|
|
|
|
|
work = &cq_poll->dim.work;
|
|
|
|
|
if (work->func)
|
|
|
|
|
cancel_work_sync(work);
|
|
|
|
|
napi_disable(&cq_poll->napi);
|
|
|
|
|
netif_napi_del(&cq_poll->napi);
|
|
|
|
|
}
|
|
|
|
@@ -1477,7 +1480,7 @@ static int otx2_get_rbuf_size(struct otx2_nic *pf, int mtu)
|
|
|
|
|
return ALIGN(rbuf_size, 2048);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int otx2_init_hw_resources(struct otx2_nic *pf)
|
|
|
|
|
int otx2_init_hw_resources(struct otx2_nic *pf)
|
|
|
|
|
{
|
|
|
|
|
struct nix_lf_free_req *free_req;
|
|
|
|
|
struct mbox *mbox = &pf->mbox;
|
|
|
|
@@ -1602,7 +1605,7 @@ exit:
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void otx2_free_hw_resources(struct otx2_nic *pf)
|
|
|
|
|
void otx2_free_hw_resources(struct otx2_nic *pf)
|
|
|
|
|
{
|
|
|
|
|
struct otx2_qset *qset = &pf->qset;
|
|
|
|
|
struct nix_lf_free_req *free_req;
|
|
|
|
@@ -1770,15 +1773,23 @@ static void otx2_dim_work(struct work_struct *w)
|
|
|
|
|
dim->state = DIM_START_MEASURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int otx2_open(struct net_device *netdev)
|
|
|
|
|
void otx2_free_queue_mem(struct otx2_qset *qset)
|
|
|
|
|
{
|
|
|
|
|
struct otx2_nic *pf = netdev_priv(netdev);
|
|
|
|
|
struct otx2_cq_poll *cq_poll = NULL;
|
|
|
|
|
kfree(qset->sq);
|
|
|
|
|
qset->sq = NULL;
|
|
|
|
|
kfree(qset->cq);
|
|
|
|
|
qset->cq = NULL;
|
|
|
|
|
kfree(qset->rq);
|
|
|
|
|
qset->rq = NULL;
|
|
|
|
|
kfree(qset->napi);
|
|
|
|
|
qset->napi = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int otx2_alloc_queue_mem(struct otx2_nic *pf)
|
|
|
|
|
{
|
|
|
|
|
struct otx2_qset *qset = &pf->qset;
|
|
|
|
|
int err = 0, qidx, vec;
|
|
|
|
|
char *irq_name;
|
|
|
|
|
struct otx2_cq_poll *cq_poll;
|
|
|
|
|
|
|
|
|
|
netif_carrier_off(netdev);
|
|
|
|
|
|
|
|
|
|
/* RQ and SQs are mapped to different CQs,
|
|
|
|
|
* so find out max CQ IRQs (i.e CINTs) needed.
|
|
|
|
@@ -1798,7 +1809,6 @@ int otx2_open(struct net_device *netdev)
|
|
|
|
|
/* CQ size of SQ */
|
|
|
|
|
qset->sqe_cnt = qset->sqe_cnt ? qset->sqe_cnt : Q_COUNT(Q_SIZE_4K);
|
|
|
|
|
|
|
|
|
|
err = -ENOMEM;
|
|
|
|
|
qset->cq = kcalloc(pf->qset.cq_cnt,
|
|
|
|
|
sizeof(struct otx2_cq_queue), GFP_KERNEL);
|
|
|
|
|
if (!qset->cq)
|
|
|
|
@@ -1814,6 +1824,27 @@ int otx2_open(struct net_device *netdev)
|
|
|
|
|
if (!qset->rq)
|
|
|
|
|
goto err_free_mem;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_free_mem:
|
|
|
|
|
otx2_free_queue_mem(qset);
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int otx2_open(struct net_device *netdev)
|
|
|
|
|
{
|
|
|
|
|
struct otx2_nic *pf = netdev_priv(netdev);
|
|
|
|
|
struct otx2_cq_poll *cq_poll = NULL;
|
|
|
|
|
struct otx2_qset *qset = &pf->qset;
|
|
|
|
|
int err = 0, qidx, vec;
|
|
|
|
|
char *irq_name;
|
|
|
|
|
|
|
|
|
|
netif_carrier_off(netdev);
|
|
|
|
|
|
|
|
|
|
err = otx2_alloc_queue_mem(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
return err;
|
|
|
|
|
|
|
|
|
|
err = otx2_init_hw_resources(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_free_mem;
|
|
|
|
@@ -1979,10 +2010,7 @@ err_disable_napi:
|
|
|
|
|
otx2_disable_napi(pf);
|
|
|
|
|
otx2_free_hw_resources(pf);
|
|
|
|
|
err_free_mem:
|
|
|
|
|
kfree(qset->sq);
|
|
|
|
|
kfree(qset->cq);
|
|
|
|
|
kfree(qset->rq);
|
|
|
|
|
kfree(qset->napi);
|
|
|
|
|
otx2_free_queue_mem(qset);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
EXPORT_SYMBOL(otx2_open);
|
|
|
|
@@ -2047,11 +2075,7 @@ int otx2_stop(struct net_device *netdev)
|
|
|
|
|
for (qidx = 0; qidx < netdev->num_tx_queues; qidx++)
|
|
|
|
|
netdev_tx_reset_queue(netdev_get_tx_queue(netdev, qidx));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
kfree(qset->sq);
|
|
|
|
|
kfree(qset->cq);
|
|
|
|
|
kfree(qset->rq);
|
|
|
|
|
kfree(qset->napi);
|
|
|
|
|
otx2_free_queue_mem(qset);
|
|
|
|
|
/* Do not clear RQ/SQ ringsize settings */
|
|
|
|
|
memset_startat(qset, 0, sqe_cnt);
|
|
|
|
|
return 0;
|
|
|
|
@@ -2786,7 +2810,7 @@ static const struct net_device_ops otx2_netdev_ops = {
|
|
|
|
|
.ndo_set_vf_trust = otx2_ndo_set_vf_trust,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int otx2_wq_init(struct otx2_nic *pf)
|
|
|
|
|
int otx2_wq_init(struct otx2_nic *pf)
|
|
|
|
|
{
|
|
|
|
|
pf->otx2_wq = create_singlethread_workqueue("otx2_wq");
|
|
|
|
|
if (!pf->otx2_wq)
|
|
|
|
@@ -2797,7 +2821,7 @@ static int otx2_wq_init(struct otx2_nic *pf)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int otx2_check_pf_usable(struct otx2_nic *nic)
|
|
|
|
|
int otx2_check_pf_usable(struct otx2_nic *nic)
|
|
|
|
|
{
|
|
|
|
|
u64 rev;
|
|
|
|
|
|
|
|
|
@@ -2815,7 +2839,7 @@ static int otx2_check_pf_usable(struct otx2_nic *nic)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int otx2_realloc_msix_vectors(struct otx2_nic *pf)
|
|
|
|
|
int otx2_realloc_msix_vectors(struct otx2_nic *pf)
|
|
|
|
|
{
|
|
|
|
|
struct otx2_hw *hw = &pf->hw;
|
|
|
|
|
int num_vec, err;
|
|
|
|
@@ -2872,6 +2896,87 @@ static void otx2_sriov_vfcfg_cleanup(struct otx2_nic *pf)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int otx2_init_rsrc(struct pci_dev *pdev, struct otx2_nic *pf)
|
|
|
|
|
{
|
|
|
|
|
struct device *dev = &pdev->dev;
|
|
|
|
|
struct otx2_hw *hw = &pf->hw;
|
|
|
|
|
int num_vec, err;
|
|
|
|
|
|
|
|
|
|
num_vec = pci_msix_vec_count(pdev);
|
|
|
|
|
hw->irq_name = devm_kmalloc_array(&hw->pdev->dev, num_vec, NAME_SIZE,
|
|
|
|
|
GFP_KERNEL);
|
|
|
|
|
if (!hw->irq_name)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
hw->affinity_mask = devm_kcalloc(&hw->pdev->dev, num_vec,
|
|
|
|
|
sizeof(cpumask_var_t), GFP_KERNEL);
|
|
|
|
|
if (!hw->affinity_mask)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
/* Map CSRs */
|
|
|
|
|
pf->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
|
|
|
|
|
if (!pf->reg_base) {
|
|
|
|
|
dev_err(dev, "Unable to map physical function CSRs, aborting\n");
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = otx2_check_pf_usable(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
return err;
|
|
|
|
|
|
|
|
|
|
err = pci_alloc_irq_vectors(hw->pdev, RVU_PF_INT_VEC_CNT,
|
|
|
|
|
RVU_PF_INT_VEC_CNT, PCI_IRQ_MSIX);
|
|
|
|
|
if (err < 0) {
|
|
|
|
|
dev_err(dev, "%s: Failed to alloc %d IRQ vectors\n",
|
|
|
|
|
__func__, num_vec);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
otx2_setup_dev_hw_settings(pf);
|
|
|
|
|
|
|
|
|
|
/* Init PF <=> AF mailbox stuff */
|
|
|
|
|
err = otx2_pfaf_mbox_init(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_free_irq_vectors;
|
|
|
|
|
|
|
|
|
|
/* Register mailbox interrupt */
|
|
|
|
|
err = otx2_register_mbox_intr(pf, true);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_mbox_destroy;
|
|
|
|
|
|
|
|
|
|
/* Request AF to attach NPA and NIX LFs to this PF.
|
|
|
|
|
* NIX and NPA LFs are needed for this PF to function as a NIC.
|
|
|
|
|
*/
|
|
|
|
|
err = otx2_attach_npa_nix(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_disable_mbox_intr;
|
|
|
|
|
|
|
|
|
|
err = otx2_realloc_msix_vectors(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_detach_rsrc;
|
|
|
|
|
|
|
|
|
|
err = cn10k_lmtst_init(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_detach_rsrc;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_detach_rsrc:
|
|
|
|
|
if (pf->hw.lmt_info)
|
|
|
|
|
free_percpu(pf->hw.lmt_info);
|
|
|
|
|
if (test_bit(CN10K_LMTST, &pf->hw.cap_flag))
|
|
|
|
|
qmem_free(pf->dev, pf->dync_lmt);
|
|
|
|
|
otx2_detach_resources(&pf->mbox);
|
|
|
|
|
err_disable_mbox_intr:
|
|
|
|
|
otx2_disable_mbox_intr(pf);
|
|
|
|
|
err_mbox_destroy:
|
|
|
|
|
otx2_pfaf_mbox_destroy(pf);
|
|
|
|
|
err_free_irq_vectors:
|
|
|
|
|
pci_free_irq_vectors(hw->pdev);
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
|
|
{
|
|
|
|
|
struct device *dev = &pdev->dev;
|
|
|
|
@@ -2879,7 +2984,6 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
|
|
struct net_device *netdev;
|
|
|
|
|
struct otx2_nic *pf;
|
|
|
|
|
struct otx2_hw *hw;
|
|
|
|
|
int num_vec;
|
|
|
|
|
|
|
|
|
|
err = pcim_enable_device(pdev);
|
|
|
|
|
if (err) {
|
|
|
|
@@ -2930,72 +3034,14 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
|
|
/* Use CQE of 128 byte descriptor size by default */
|
|
|
|
|
hw->xqe_size = 128;
|
|
|
|
|
|
|
|
|
|
num_vec = pci_msix_vec_count(pdev);
|
|
|
|
|
hw->irq_name = devm_kmalloc_array(&hw->pdev->dev, num_vec, NAME_SIZE,
|
|
|
|
|
GFP_KERNEL);
|
|
|
|
|
if (!hw->irq_name) {
|
|
|
|
|
err = -ENOMEM;
|
|
|
|
|
goto err_free_netdev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hw->affinity_mask = devm_kcalloc(&hw->pdev->dev, num_vec,
|
|
|
|
|
sizeof(cpumask_var_t), GFP_KERNEL);
|
|
|
|
|
if (!hw->affinity_mask) {
|
|
|
|
|
err = -ENOMEM;
|
|
|
|
|
goto err_free_netdev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Map CSRs */
|
|
|
|
|
pf->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
|
|
|
|
|
if (!pf->reg_base) {
|
|
|
|
|
dev_err(dev, "Unable to map physical function CSRs, aborting\n");
|
|
|
|
|
err = -ENOMEM;
|
|
|
|
|
goto err_free_netdev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = otx2_check_pf_usable(pf);
|
|
|
|
|
err = otx2_init_rsrc(pdev, pf);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_free_netdev;
|
|
|
|
|
|
|
|
|
|
err = pci_alloc_irq_vectors(hw->pdev, RVU_PF_INT_VEC_CNT,
|
|
|
|
|
RVU_PF_INT_VEC_CNT, PCI_IRQ_MSIX);
|
|
|
|
|
if (err < 0) {
|
|
|
|
|
dev_err(dev, "%s: Failed to alloc %d IRQ vectors\n",
|
|
|
|
|
__func__, num_vec);
|
|
|
|
|
goto err_free_netdev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
otx2_setup_dev_hw_settings(pf);
|
|
|
|
|
|
|
|
|
|
/* Init PF <=> AF mailbox stuff */
|
|
|
|
|
err = otx2_pfaf_mbox_init(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_free_irq_vectors;
|
|
|
|
|
|
|
|
|
|
/* Register mailbox interrupt */
|
|
|
|
|
err = otx2_register_mbox_intr(pf, true);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_mbox_destroy;
|
|
|
|
|
|
|
|
|
|
/* Request AF to attach NPA and NIX LFs to this PF.
|
|
|
|
|
* NIX and NPA LFs are needed for this PF to function as a NIC.
|
|
|
|
|
*/
|
|
|
|
|
err = otx2_attach_npa_nix(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_disable_mbox_intr;
|
|
|
|
|
|
|
|
|
|
err = otx2_realloc_msix_vectors(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_detach_rsrc;
|
|
|
|
|
|
|
|
|
|
err = otx2_set_real_num_queues(netdev, hw->tx_queues, hw->rx_queues);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_detach_rsrc;
|
|
|
|
|
|
|
|
|
|
err = cn10k_lmtst_init(pf);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_detach_rsrc;
|
|
|
|
|
|
|
|
|
|
/* Assign default mac address */
|
|
|
|
|
otx2_get_mac_from_af(netdev);
|
|
|
|
|
|
|
|
|
@@ -3058,6 +3104,7 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
|
|
|
|
|
|
|
netdev->min_mtu = OTX2_MIN_MTU;
|
|
|
|
|
netdev->max_mtu = otx2_get_max_mtu(pf);
|
|
|
|
|
hw->max_mtu = netdev->max_mtu;
|
|
|
|
|
|
|
|
|
|
/* reset CGX/RPM MAC stats */
|
|
|
|
|
otx2_reset_mac_stats(pf);
|
|
|
|
@@ -3118,11 +3165,8 @@ err_detach_rsrc:
|
|
|
|
|
if (test_bit(CN10K_LMTST, &pf->hw.cap_flag))
|
|
|
|
|
qmem_free(pf->dev, pf->dync_lmt);
|
|
|
|
|
otx2_detach_resources(&pf->mbox);
|
|
|
|
|
err_disable_mbox_intr:
|
|
|
|
|
otx2_disable_mbox_intr(pf);
|
|
|
|
|
err_mbox_destroy:
|
|
|
|
|
otx2_pfaf_mbox_destroy(pf);
|
|
|
|
|
err_free_irq_vectors:
|
|
|
|
|
pci_free_irq_vectors(hw->pdev);
|
|
|
|
|
err_free_netdev:
|
|
|
|
|
pci_set_drvdata(pdev, NULL);
|
|
|
|
|