Commit b7c13ee4 authored by Marco Chiappero's avatar Marco Chiappero Committed by Herbert Xu

crypto: qat - move VF message handler to adf_vf2pf_msg.c

Move the reading and parsing of a PF2VF message from the bottom half
function in adf_vf_isr.c, adf_pf2vf_bh_handler(), to the PFVF protocol
file adf_vf2pf_msg.c, for better code organization.

The receive and handle logic has been moved to a new function called
adf_recv_and_handle_pf2vf_msg() which returns a boolean indicating if
interrupts need to be re-enabled or not.
A slight refactoring has been done to avoid calculating the PF2VF CSR
offset twice and repeating the clearing of the PF2VFINT bit.

The "PF restarting" logic, now defined in the function
adf_pf2vf_handle_pf_restaring(), has been kept in adf_vf_isr.c due to
the dependencies with the adf_vf_stop_wq workqueue.
Signed-off-by: default avatarMarco Chiappero <marco.chiappero@intel.com>
Co-developed-by: default avatarGiovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: default avatarGiovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 08ea97f4
...@@ -195,6 +195,8 @@ void adf_disable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, ...@@ -195,6 +195,8 @@ void adf_disable_vf2pf_interrupts(struct adf_accel_dev *accel_dev,
u32 vf_mask); u32 vf_mask);
void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev,
u32 vf_mask); u32 vf_mask);
bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev);
int adf_pf2vf_handle_pf_restarting(struct adf_accel_dev *accel_dev);
int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev); int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev);
void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev);
void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev);
......
...@@ -46,3 +46,62 @@ void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev) ...@@ -46,3 +46,62 @@ void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev)
"Failed to send Shutdown event to PF\n"); "Failed to send Shutdown event to PF\n");
} }
EXPORT_SYMBOL_GPL(adf_vf2pf_notify_shutdown); EXPORT_SYMBOL_GPL(adf_vf2pf_notify_shutdown);
bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev)
{
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
struct adf_bar *pmisc =
&GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
void __iomem *pmisc_bar_addr = pmisc->virt_addr;
u32 offset = hw_data->get_pf2vf_offset(0);
bool ret;
u32 msg;
/* Read the message from PF */
msg = ADF_CSR_RD(pmisc_bar_addr, offset);
if (!(msg & ADF_PF2VF_INT)) {
dev_info(&GET_DEV(accel_dev),
"Spurious PF2VF interrupt, msg %X. Ignored\n", msg);
return true;
}
if (!(msg & ADF_PF2VF_MSGORIGIN_SYSTEM))
/* Ignore legacy non-system (non-kernel) PF2VF messages */
goto err;
switch ((msg & ADF_PF2VF_MSGTYPE_MASK) >> ADF_PF2VF_MSGTYPE_SHIFT) {
case ADF_PF2VF_MSGTYPE_RESTARTING:
dev_dbg(&GET_DEV(accel_dev),
"Restarting msg received from PF 0x%x\n", msg);
adf_pf2vf_handle_pf_restarting(accel_dev);
ret = false;
break;
case ADF_PF2VF_MSGTYPE_VERSION_RESP:
dev_dbg(&GET_DEV(accel_dev),
"Version resp received from PF 0x%x\n", msg);
accel_dev->vf.pf_version =
(msg & ADF_PF2VF_VERSION_RESP_VERS_MASK) >>
ADF_PF2VF_VERSION_RESP_VERS_SHIFT;
accel_dev->vf.compatible =
(msg & ADF_PF2VF_VERSION_RESP_RESULT_MASK) >>
ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
complete(&accel_dev->vf.iov_msg_completion);
ret = true;
break;
default:
goto err;
}
/* To ack, clear the PF2VFINT bit */
msg &= ~ADF_PF2VF_INT;
ADF_CSR_WR(pmisc_bar_addr, offset, msg);
return ret;
err:
dev_err(&GET_DEV(accel_dev),
"Unknown message from PF (0x%x); leaving PF2VF ints disabled\n",
msg);
return false;
}
...@@ -85,78 +85,37 @@ static void adf_dev_stop_async(struct work_struct *work) ...@@ -85,78 +85,37 @@ static void adf_dev_stop_async(struct work_struct *work)
kfree(stop_data); kfree(stop_data);
} }
static void adf_pf2vf_bh_handler(void *data) int adf_pf2vf_handle_pf_restarting(struct adf_accel_dev *accel_dev)
{ {
struct adf_accel_dev *accel_dev = data; struct adf_vf_stop_data *stop_data;
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
struct adf_bar *pmisc =
&GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
void __iomem *pmisc_bar_addr = pmisc->virt_addr;
u32 msg;
/* Read the message from PF */
msg = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_pf2vf_offset(0));
if (!(msg & ADF_PF2VF_INT)) {
dev_info(&GET_DEV(accel_dev),
"Spurious PF2VF interrupt, msg %X. Ignored\n", msg);
goto out;
}
if (!(msg & ADF_PF2VF_MSGORIGIN_SYSTEM)) clear_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status);
/* Ignore legacy non-system (non-kernel) PF2VF messages */ stop_data = kzalloc(sizeof(*stop_data), GFP_ATOMIC);
goto err; if (!stop_data) {
dev_err(&GET_DEV(accel_dev),
switch ((msg & ADF_PF2VF_MSGTYPE_MASK) >> ADF_PF2VF_MSGTYPE_SHIFT) { "Couldn't schedule stop for vf_%d\n",
case ADF_PF2VF_MSGTYPE_RESTARTING: { accel_dev->accel_id);
struct adf_vf_stop_data *stop_data; return -ENOMEM;
dev_dbg(&GET_DEV(accel_dev),
"Restarting msg received from PF 0x%x\n", msg);
clear_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status);
stop_data = kzalloc(sizeof(*stop_data), GFP_ATOMIC);
if (!stop_data) {
dev_err(&GET_DEV(accel_dev),
"Couldn't schedule stop for vf_%d\n",
accel_dev->accel_id);
return;
}
stop_data->accel_dev = accel_dev;
INIT_WORK(&stop_data->work, adf_dev_stop_async);
queue_work(adf_vf_stop_wq, &stop_data->work);
/* To ack, clear the PF2VFINT bit */
msg &= ~ADF_PF2VF_INT;
ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg);
return;
}
case ADF_PF2VF_MSGTYPE_VERSION_RESP:
dev_dbg(&GET_DEV(accel_dev),
"Version resp received from PF 0x%x\n", msg);
accel_dev->vf.pf_version =
(msg & ADF_PF2VF_VERSION_RESP_VERS_MASK) >>
ADF_PF2VF_VERSION_RESP_VERS_SHIFT;
accel_dev->vf.compatible =
(msg & ADF_PF2VF_VERSION_RESP_RESULT_MASK) >>
ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
complete(&accel_dev->vf.iov_msg_completion);
break;
default:
goto err;
} }
stop_data->accel_dev = accel_dev;
INIT_WORK(&stop_data->work, adf_dev_stop_async);
queue_work(adf_vf_stop_wq, &stop_data->work);
/* To ack, clear the PF2VFINT bit */ return 0;
msg &= ~ADF_PF2VF_INT; }
ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg);
static void adf_pf2vf_bh_handler(void *data)
{
struct adf_accel_dev *accel_dev = data;
bool ret;
ret = adf_recv_and_handle_pf2vf_msg(accel_dev);
if (ret)
/* Re-enable PF2VF interrupts */
adf_enable_pf2vf_interrupts(accel_dev);
out:
/* Re-enable PF2VF interrupts */
adf_enable_pf2vf_interrupts(accel_dev);
return; return;
err:
dev_err(&GET_DEV(accel_dev),
"Unknown message from PF (0x%x); leaving PF2VF ints disabled\n",
msg);
} }
static int adf_setup_pf2vf_bh(struct adf_accel_dev *accel_dev) static int adf_setup_pf2vf_bh(struct adf_accel_dev *accel_dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment