#include "hinic_pmd_hwdev.h"
#include "hinic_pmd_hwif.h"
#include "hinic_pmd_mgmt.h"
+#include "hinic_pmd_mbox.h"
#define BUF_OUT_DEFAULT_SIZE 1
* mgmt_msg_len - calculate the total message length
* @msg_data_len: the length of the message data
* Return: the total message length
- **/
+ */
static u16 mgmt_msg_len(u16 msg_data_len)
{
/* u64 - the size of the header */
* @direction: the direction of the original message
* @cmd: the command to do
* @msg_id: message id
- **/
+ */
static void prepare_header(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
u64 *header, int msg_len, enum hinic_mod_type mod,
enum hinic_msg_ack_type ack_type,
* @header: pointer of the header to prepare
* @msg: the data of the message
* @msg_len: the length of the message
- **/
+ */
static void prepare_mgmt_cmd(u8 *mgmt_cmd, u64 *header, void *msg,
int msg_len)
{
* alloc_recv_msg - allocate received message memory
* @recv_msg: pointer that will hold the allocated data
* Return: 0 - success, negative - failure
- **/
+ */
static int alloc_recv_msg(struct hinic_recv_msg *recv_msg)
{
int err;
/**
* free_recv_msg - free received message memory
* @recv_msg: pointer that holds the allocated data
- **/
+ */
static void free_recv_msg(struct hinic_recv_msg *recv_msg)
{
kfree(recv_msg->buf_out);
* alloc_msg_buf - allocate all the message buffers of PF to MGMT channel
* @pf_to_mgmt: PF to MGMT channel
* Return: 0 - success, negative - failure
- **/
+ */
static int alloc_msg_buf(struct hinic_msg_pf_to_mgmt *pf_to_mgmt)
{
int err;
* free_msg_buf - free all the message buffers of PF to MGMT channel
* @pf_to_mgmt: PF to MGMT channel
* Return: 0 - success, negative - failure
- **/
+ */
static void free_msg_buf(struct hinic_msg_pf_to_mgmt *pf_to_mgmt)
{
kfree(pf_to_mgmt->sync_msg_buf);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
}
+static int hinic_get_mgmt_channel_status(void *hwdev)
+{
+ struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;
+ u32 val;
+
+ if (hinic_func_type((struct hinic_hwdev *)hwdev) == TYPE_VF)
+ return false;
+
+ val = hinic_hwif_read_reg(hwif, HINIC_ICPL_RESERVD_ADDR);
+
+ return HINIC_GET_MGMT_CHANNEL_STATUS(val, MGMT_CHANNEL_STATUS);
+}
+
/**
* send_msg_to_mgmt_async - send async message
* @pf_to_mgmt: PF to MGMT channel
* @direction: the direction of the original message
* @resp_msg_id: message id of response
* Return: 0 - success, negative - failure
- **/
+ */
static int send_msg_to_mgmt_async(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
enum hinic_mod_type mod, u8 cmd,
void *msg, u16 msg_len,
* @direction: the direction of the original message
* @resp_msg_id: msg id to response for
* Return: 0 - success, negative - failure
- **/
+ */
static int send_msg_to_mgmt_sync(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
enum hinic_mod_type mod, u8 cmd,
void *msg, u16 msg_len,
u64 header;
u16 cmd_size = mgmt_msg_len(msg_len);
+ /* If fw is hot active, return failed */
+ if (hinic_get_mgmt_channel_status(pf_to_mgmt->hwdev)) {
+ if (mod == HINIC_MOD_COMM || mod == HINIC_MOD_L2NIC)
+ return HINIC_DEV_BUSY_ACTIVE_FW;
+ else
+ return -EBUSY;
+ }
+
if (direction == HINIC_MSG_RESPONSE)
prepare_header(pf_to_mgmt, &header, msg_len, mod, ack_type,
direction, cmd, resp_msg_id);
* hinic_pf_to_mgmt_init - initialize PF to MGMT channel
* @hwdev: the pointer to the private hardware device object
* Return: 0 - success, negative - failure
- **/
+ */
static int hinic_pf_to_mgmt_init(struct hinic_hwdev *hwdev)
{
struct hinic_msg_pf_to_mgmt *pf_to_mgmt;
hwdev->pf_to_mgmt = pf_to_mgmt;
pf_to_mgmt->hwdev = hwdev;
- err = hinic_mutex_init(&pf_to_mgmt->sync_msg_lock, NULL);
+ err = hinic_mutex_init(&pf_to_mgmt->sync_msg_mutex, NULL);
if (err)
goto mutex_init_err;
free_msg_buf(pf_to_mgmt);
alloc_msg_buf_err:
- hinic_mutex_destroy(&pf_to_mgmt->sync_msg_lock);
+ hinic_mutex_destroy(&pf_to_mgmt->sync_msg_mutex);
mutex_init_err:
kfree(pf_to_mgmt);
/**
* hinic_pf_to_mgmt_free - free PF to MGMT channel
* @hwdev: the pointer to the private hardware device object
- **/
+ */
static void hinic_pf_to_mgmt_free(struct hinic_hwdev *hwdev)
{
struct hinic_msg_pf_to_mgmt *pf_to_mgmt = hwdev->pf_to_mgmt;
hinic_api_cmd_free(pf_to_mgmt->cmd_chain);
free_msg_buf(pf_to_mgmt);
- hinic_mutex_destroy(&pf_to_mgmt->sync_msg_lock);
+ hinic_mutex_destroy(&pf_to_mgmt->sync_msg_mutex);
kfree(pf_to_mgmt);
}
u32 timeo;
int err, i;
- pthread_mutex_lock(&pf_to_mgmt->sync_msg_lock);
+ err = hinic_mutex_lock(&pf_to_mgmt->sync_msg_mutex);
+ if (err)
+ return err;
SYNC_MSG_ID_INC(pf_to_mgmt);
recv_msg = &pf_to_mgmt->recv_resp_msg_from_mgmt;
recv_msg->msg_len);
*out_size = recv_msg->msg_len;
} else {
- PMD_DRV_LOG(ERR, "Mgmt rsp's msg len:%u overflow.",
+ PMD_DRV_LOG(ERR, "Mgmt rsp's msg len: %u overflow.",
recv_msg->msg_len);
err = -ERANGE;
}
unlock_sync_msg:
if (err && out_size)
*out_size = 0;
- pthread_mutex_unlock(&pf_to_mgmt->sync_msg_lock);
+ (void)hinic_mutex_unlock(&pf_to_mgmt->sync_msg_mutex);
return err;
}
-static int hinic_get_mgmt_channel_status(void *hwdev)
-{
- struct hinic_hwif *hwif = ((struct hinic_hwdev *)hwdev)->hwif;
- u32 val;
-
- val = hinic_hwif_read_reg(hwif, HINIC_ICPL_RESERVD_ADDR);
-
- return HINIC_GET_MGMT_CHANNEL_STATUS(val, MGMT_CHANNEL_STATUS);
-}
-
int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size, u32 timeout)
if (!hwdev || in_size > HINIC_MSG_TO_MGMT_MAX_LEN)
return -EINVAL;
- /* If status is hot upgrading, don't send message to mgmt */
- if (hinic_get_mgmt_channel_status(hwdev))
- return -EPERM;
-
- rc = hinic_pf_to_mgmt_sync(hwdev, mod, cmd, buf_in,
- in_size, buf_out, out_size,
- timeout);
+ if (hinic_func_type(hwdev) == TYPE_VF) {
+ rc = hinic_mbox_to_pf(hwdev, mod, cmd, buf_in, in_size,
+ buf_out, out_size, timeout);
+ } else {
+ rc = hinic_pf_to_mgmt_sync(hwdev, mod, cmd, buf_in, in_size,
+ buf_out, out_size, timeout);
+ }
return rc;
}
int hinic_msg_to_mgmt_no_ack(void *hwdev, enum hinic_mod_type mod, u8 cmd,
- void *buf_in, u16 in_size, __rte_unused void *buf_out,
- __rte_unused u16 *out_size)
+ void *buf_in, u16 in_size)
{
struct hinic_msg_pf_to_mgmt *pf_to_mgmt =
((struct hinic_hwdev *)hwdev)->pf_to_mgmt;
return err;
}
- pthread_mutex_lock(&pf_to_mgmt->sync_msg_lock);
+ err = hinic_mutex_lock(&pf_to_mgmt->sync_msg_mutex);
+ if (err)
+ return err;
err = send_msg_to_mgmt_sync(pf_to_mgmt, mod, cmd, buf_in, in_size,
HINIC_MSG_NO_ACK, HINIC_MSG_DIRECT_SEND,
MSG_NO_RESP);
- pthread_mutex_unlock(&pf_to_mgmt->sync_msg_lock);
+ (void)hinic_mutex_unlock(&pf_to_mgmt->sync_msg_mutex);
return err;
}
* @pf_to_mgmt: PF to MGMT channel
* @recv_msg: received message details
* @param: customized parameter
- **/
+ */
static void hinic_mgmt_recv_msg_handler(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
struct hinic_recv_msg *recv_msg,
void *param)
buf_out, &out_size);
break;
default:
- PMD_DRV_LOG(ERR, "No handler, mod = %d", recv_msg->mod);
+ PMD_DRV_LOG(ERR, "No handler, mod: %d", recv_msg->mod);
break;
}
* @param: customized parameter
* Return: 0 when aeq is response message, -1 default result,
* and when wrong message or not last message
- **/
+ */
static int recv_mgmt_msg_handler(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
u8 *header, struct hinic_recv_msg *recv_msg,
void *param)
if (!check_mgmt_seq_id_and_seg_len(recv_msg, seq_id, seq_len)) {
PMD_DRV_LOG(ERR,
- "Mgmt msg sequence and segment check fail, "
+ "Mgmt msg sequence and segment check failed, "
"func id: 0x%x, front id: 0x%x, current id: 0x%x, seg len: 0x%x",
hinic_global_func_id(pf_to_mgmt->hwdev),
recv_msg->sed_id, seq_id, seq_len);
- return HINIC_RECV_NEXT_AEQE;
+ return HINIC_ERROR;
}
dest_msg = (u8 *)recv_msg->msg + seq_id * HINIC_MSG_SEG_LEN;
memcpy(dest_msg, msg_body, seq_len);
if (!HINIC_MSG_HEADER_GET(msg_header, LAST))
- return HINIC_RECV_NEXT_AEQE;
+ return HINIC_ERROR;
recv_msg->cmd = HINIC_MSG_HEADER_GET(msg_header, CMD);
recv_msg->mod = HINIC_MSG_HEADER_GET(msg_header, MODULE);
recv_msg->msg_id = HINIC_MSG_HEADER_GET(msg_header, MSG_ID);
if (HINIC_MSG_HEADER_GET(msg_header, DIRECTION) == HINIC_MSG_RESPONSE)
- return HINIC_RECV_DONE;
+ return HINIC_OK;
hinic_mgmt_recv_msg_handler(pf_to_mgmt, recv_msg, param);
- return HINIC_RECV_NEXT_AEQE;
+ return HINIC_ERROR;
}
/**
* @param: customized parameter
* Return: 0 when aeq is response message,
* -1 default result, and when wrong message or not last message
- **/
+ */
static int hinic_mgmt_msg_aeqe_handler(void *hwdev, u8 *header,
__rte_unused u8 size, void *param)
{
case HINIC_MSG_FROM_MGMT_CPU:
rc = hinic_mgmt_msg_aeqe_handler(handle, data, size, param);
break;
+ case HINIC_MBX_FROM_FUNC:
+ rc = hinic_mbox_func_aeqe_handler(handle, data, size, param);
+ break;
default:
PMD_DRV_LOG(ERR, "Unknown event type: 0x%x, size: %d",
event, size);
- rc = HINIC_RECV_NEXT_AEQE;
+ rc = HINIC_ERROR;
break;
}
* used in polling mode.
* @param: customized parameter
* Return: 0 - Success, EIO - poll timeout, ENODEV - swe not support
- **/
+ */
int hinic_aeq_poll_msg(struct hinic_eq *eq, u32 timeout, void *param)
{
struct hinic_aeq_elem *aeqe_pos;
event = EQ_ELEM_DESC_GET(aeqe_desc, TYPE);
if (EQ_ELEM_DESC_GET(aeqe_desc, SRC)) {
- PMD_DRV_LOG(ERR, "AEQ sw event not support %d",
- event);
+ PMD_DRV_LOG(ERR, "AEQ sw event not support %d", event);
return -ENODEV;
} else {
{
int rc;
+ /* VF do not support send msg to mgmt directly */
+ if (hinic_func_type(hwdev) == TYPE_VF)
+ return 0;
+
rc = hinic_pf_to_mgmt_init(hwdev);
if (rc)
return rc;
void hinic_comm_pf_to_mgmt_free(struct hinic_hwdev *hwdev)
{
+ /* VF do not support send msg to mgmt directly */
+ if (hinic_func_type(hwdev) == TYPE_VF)
+ return;
+
hinic_pf_to_mgmt_free(hwdev);
}