staticint __fbnic_fw_enable_mbx(struct fbnic_dev *fbd, int vector)
{ int err;
/* Initialize mailbox and attempt to poll it into ready state */
fbnic_mbx_init(fbd);
err = fbnic_mbx_poll_tx_ready(fbd); if (err) {
dev_warn(fbd->dev, "FW mailbox did not enter ready state\n"); return err;
}
/* Enable interrupt and unmask the vector */
enable_irq(vector);
fbnic_wr32(fbd, FBNIC_INTR_MASK_CLEAR(0), 1u << FBNIC_FW_MSIX_ENTRY);
return 0;
}
/** * fbnic_fw_request_mbx - Configure and initialize Firmware Mailbox * @fbd: Pointer to device to initialize * * This function will allocate the IRQ and then reinitialize the mailbox * starting communication between the host and firmware. * * Return: non-zero on failure.
**/ int fbnic_fw_request_mbx(struct fbnic_dev *fbd)
{ struct pci_dev *pdev = to_pci_dev(fbd->dev); int vector, err;
WARN_ON(fbd->fw_msix_vector);
vector = pci_irq_vector(pdev, FBNIC_FW_MSIX_ENTRY); if (vector < 0) return vector;
/* Request the IRQ for FW Mailbox vector. */
err = request_threaded_irq(vector, NULL, &fbnic_fw_msix_intr,
IRQF_ONESHOT | IRQF_NO_AUTOEN,
dev_name(fbd->dev), fbd); if (err) return err;
/* Initialize mailbox and attempt to poll it into ready state */
err = __fbnic_fw_enable_mbx(fbd, vector); if (err)
free_irq(vector, fbd);
fbd->fw_msix_vector = vector;
return err;
}
/** * fbnic_fw_disable_mbx - Temporarily place mailbox in standby state * @fbd: Pointer to device * * Shutdown the mailbox by notifying the firmware to stop sending us logs, mask * and synchronize the IRQ, and then clean up the rings.
**/ staticvoid fbnic_fw_disable_mbx(struct fbnic_dev *fbd)
{ /* Disable interrupt and synchronize the IRQ */
disable_irq(fbd->fw_msix_vector);
/* Mask the vector */
fbnic_wr32(fbd, FBNIC_INTR_MASK_SET(0), 1u << FBNIC_FW_MSIX_ENTRY);
/* Make sure disabling logs message is sent, must be done here to * avoid risk of completing without a running interrupt.
*/
fbnic_mbx_flush_tx(fbd);
fbnic_mbx_clean(fbd);
}
/** * fbnic_fw_free_mbx - Disable mailbox and place it in standby state * @fbd: Pointer to device to disable * * This function will disable the mailbox interrupt, free any messages still * in the mailbox and place it into a disabled state. The firmware is * expected to see the update and assume that the host is in the reset state.
**/ void fbnic_fw_free_mbx(struct fbnic_dev *fbd)
{ /* Vector has already been freed */ if (!fbd->fw_msix_vector) return;
/** * fbnic_pcs_request_irq - Configure the PCS to enable it to advertise link * @fbd: Pointer to device to initialize * * This function provides basic bringup for the MAC/PCS IRQ. For now the IRQ * will remain disabled until we start the MAC/PCS/PHY logic via phylink. * * Return: non-zero on failure.
**/ int fbnic_pcs_request_irq(struct fbnic_dev *fbd)
{ struct pci_dev *pdev = to_pci_dev(fbd->dev); int vector, err;
WARN_ON(fbd->pcs_msix_vector);
vector = pci_irq_vector(pdev, FBNIC_PCS_MSIX_ENTRY); if (vector < 0) return vector;
/* Request the IRQ for PCS link vector. * Map PCS cause to it, and unmask it
*/
err = request_irq(vector, &fbnic_pcs_msix_intr, 0,
fbd->netdev->name, fbd); if (err) return err;
/* Map and enable interrupt, unmask vector after link is configured */
fbnic_wr32(fbd, FBNIC_INTR_MSIX_CTRL(FBNIC_INTR_MSIX_CTRL_PCS_IDX),
FBNIC_PCS_MSIX_ENTRY | FBNIC_INTR_MSIX_CTRL_ENABLE);
fbd->pcs_msix_vector = vector;
return 0;
}
/** * fbnic_pcs_free_irq - Teardown the PCS IRQ to prepare for stopping * @fbd: Pointer to device that is stopping * * This function undoes the work done in fbnic_pcs_request_irq and prepares * the device to no longer receive traffic on the host interface.
**/ void fbnic_pcs_free_irq(struct fbnic_dev *fbd)
{ /* Vector has already been freed */ if (!fbd->pcs_msix_vector) return;
for (i = 0; i < ARRAY_SIZE(fbd->napi_irq); i++)
snprintf(fbd->napi_irq[i].name, sizeof(fbd->napi_irq[i].name), "%s-TxRx-%u", fbd->netdev->name, i);
}
int fbnic_napi_request_irq(struct fbnic_dev *fbd, struct fbnic_napi_vector *nv)
{ struct fbnic_net *fbn = netdev_priv(fbd->netdev); int i = fbnic_napi_idx(nv); int err;
if (!fbd->napi_irq[i].users) {
err = fbnic_request_irq(fbd, nv->v_idx,
fbnic_msix_clean_rings, 0,
fbd->napi_irq[i].name,
&fbn->napi[i]); if (err) return err;
}
fbd->napi_irq[i].users++; return 0;
}
void fbnic_napi_free_irq(struct fbnic_dev *fbd, struct fbnic_napi_vector *nv)
{ struct fbnic_net *fbn = netdev_priv(fbd->netdev); int i = fbnic_napi_idx(nv);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.