mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
673184a2a5
GEN2 devices use a single CSR for PFVF messages, which leaves up to 10 bits of payload per single message. While such amount is sufficient for the currently defined messages, the transfer of bigger and more complex data streams from the PF to the VF requires a new mechanism that extends the protocol. This patch adds a new layer on top of the basic PFVF messaging, called Block Messages, to encapsulate up to 126 bytes of data in a single logical message across multiple PFVF messages of new types (SMALL, MEDIUM and LARGE BLOCK), including (sub)types (BLKMSG_TYPE) to carry the information about the actual Block Message. Regardless of the size, each Block Message uses a two bytes header, containing the version and size, to allow for extension while maintaining compatibility. The size and the types of Block Messages are defined as follow: - small block messages: up to 16 BLKMSG types of up to 30 bytes - medium block messages: up to 8 BLKMSG types of up to 62 bytes - large block messages: up to 4 BLKMSG types of up to 126 bytes It effectively works as reading a byte at a time from a block device and for each of these new Block Messages: - the requestor (always a VF) can either request a specific byte of the larger message, in order to retrieve the full message, or request the value of the CRC calculated for a specific message up to the provided size (to allow for messages to grow while maintaining forward compatibility) - the responder (always the PF) will either return a single data or CRC byte, along with the indication of response type (or error). This patch provides the basic infrastructure to perform the above operations, without defining any new message. As CRCs are required, this code now depends on the CRC8 module. Note: as a consequence of the Block Messages design, sending multiple PFVF messages in bursts, the interrupt rate limiting values on the PF are increased. Signed-off-by: Marco Chiappero <marco.chiappero@intel.com> Co-developed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com> Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com> Reviewed-by: Fiona Trahe <fiona.trahe@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
65 lines
1.7 KiB
C
65 lines
1.7 KiB
C
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
|
|
/* Copyright(c) 2021 Intel Corporation */
|
|
#include <linux/crc8.h>
|
|
#include <linux/pci.h>
|
|
#include <linux/types.h>
|
|
#include "adf_accel_devices.h"
|
|
#include "adf_pfvf_msg.h"
|
|
#include "adf_pfvf_utils.h"
|
|
|
|
/* CRC Calculation */
|
|
DECLARE_CRC8_TABLE(pfvf_crc8_table);
|
|
#define ADF_PFVF_CRC8_POLYNOMIAL 0x97
|
|
|
|
void adf_pfvf_crc_init(void)
|
|
{
|
|
crc8_populate_msb(pfvf_crc8_table, ADF_PFVF_CRC8_POLYNOMIAL);
|
|
}
|
|
|
|
u8 adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len)
|
|
{
|
|
return crc8(pfvf_crc8_table, buf, buf_len, CRC8_INIT_VALUE);
|
|
}
|
|
|
|
static bool set_value_on_csr_msg(struct adf_accel_dev *accel_dev, u32 *csr_msg,
|
|
u32 value, const struct pfvf_field_format *fmt)
|
|
{
|
|
if (unlikely((value & fmt->mask) != value)) {
|
|
dev_err(&GET_DEV(accel_dev),
|
|
"PFVF message value 0x%X out of range, %u max allowed\n",
|
|
value, fmt->mask);
|
|
return false;
|
|
}
|
|
|
|
*csr_msg |= value << fmt->offset;
|
|
|
|
return true;
|
|
}
|
|
|
|
u32 adf_pfvf_csr_msg_of(struct adf_accel_dev *accel_dev,
|
|
struct pfvf_message msg,
|
|
const struct pfvf_csr_format *fmt)
|
|
{
|
|
u32 csr_msg = 0;
|
|
|
|
if (!set_value_on_csr_msg(accel_dev, &csr_msg, msg.type, &fmt->type) ||
|
|
!set_value_on_csr_msg(accel_dev, &csr_msg, msg.data, &fmt->data))
|
|
return 0;
|
|
|
|
return csr_msg | ADF_PFVF_MSGORIGIN_SYSTEM;
|
|
}
|
|
|
|
struct pfvf_message adf_pfvf_message_of(struct adf_accel_dev *accel_dev, u32 csr_msg,
|
|
const struct pfvf_csr_format *fmt)
|
|
{
|
|
struct pfvf_message msg = { 0 };
|
|
|
|
msg.type = (csr_msg >> fmt->type.offset) & fmt->type.mask;
|
|
msg.data = (csr_msg >> fmt->data.offset) & fmt->data.mask;
|
|
|
|
if (unlikely(!msg.type))
|
|
dev_err(&GET_DEV(accel_dev),
|
|
"Invalid PFVF msg with no type received\n");
|
|
|
|
return msg;
|
|
}
|