net/iavf: fix mbuf leak
[dpdk.git] / drivers / net / hinic / base / hinic_pmd_mgmt.c
index addc9d2..9b39950 100644 (file)
@@ -248,6 +248,19 @@ static void free_msg_buf(struct hinic_msg_pf_to_mgmt *pf_to_mgmt)
        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
@@ -309,6 +322,14 @@ static int send_msg_to_mgmt_sync(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
        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);
@@ -462,19 +483,6 @@ unlock_sync_msg:
        return err;
 }
 
-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);
-}
-
 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)
@@ -484,10 +492,6 @@ int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,
        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;
-
        if (hinic_func_type(hwdev) == TYPE_VF) {
                rc = hinic_mbox_to_pf(hwdev, mod, cmd, buf_in, in_size,
                                        buf_out, out_size, timeout);
@@ -500,8 +504,7 @@ int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,
 }
 
 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;
@@ -526,19 +529,21 @@ int hinic_msg_to_mgmt_no_ack(void *hwdev, enum hinic_mod_type mod, u8 cmd,
 }
 
 static bool check_mgmt_seq_id_and_seg_len(struct hinic_recv_msg *recv_msg,
-                                         u8 seq_id, u8 seg_len)
+                                         u8 seq_id, u8 seg_len, u16 msg_id)
 {
        if (seq_id > HINIC_SEQ_ID_MAX_VAL || seg_len > HINIC_MSG_SEG_LEN)
                return false;
 
        if (seq_id == 0) {
-               recv_msg->sed_id = seq_id;
+               recv_msg->seq_id = seq_id;
+               recv_msg->msg_id = msg_id;
        } else {
-               if (seq_id != recv_msg->sed_id + 1) {
-                       recv_msg->sed_id = 0;
+               if ((seq_id != recv_msg->seq_id + 1) ||
+                       msg_id != recv_msg->msg_id) {
+                       recv_msg->seq_id = 0;
                        return false;
                }
-               recv_msg->sed_id = seq_id;
+               recv_msg->seq_id = seq_id;
        }
 
        return true;
@@ -611,16 +616,21 @@ static int recv_mgmt_msg_handler(struct hinic_msg_pf_to_mgmt *pf_to_mgmt,
        u8 *dest_msg;
        u8 seq_id, seq_len;
        u32 msg_buf_max = MAX_PF_MGMT_BUF_SIZE;
+       u8 front_id;
+       u16 msg_id;
 
        seq_id = HINIC_MSG_HEADER_GET(msg_header, SEQID);
        seq_len = HINIC_MSG_HEADER_GET(msg_header, SEG_LEN);
+       front_id = recv_msg->seq_id;
+       msg_id = HINIC_MSG_HEADER_GET(msg_header, MSG_ID);
 
-       if (!check_mgmt_seq_id_and_seg_len(recv_msg, seq_id, seq_len)) {
+       if (!check_mgmt_seq_id_and_seg_len(recv_msg, seq_id, seq_len, msg_id)) {
                PMD_DRV_LOG(ERR,
                        "Mgmt msg sequence and segment check failed, "
-                       "func id: 0x%x, front id: 0x%x, current id: 0x%x, seg len: 0x%x",
+                       "func id: 0x%x, front id: 0x%x, current id: 0x%x, seg len: 0x%x "
+                       "front msg_id: %d, cur msg_id: %d",
                        hinic_global_func_id(pf_to_mgmt->hwdev),
-                       recv_msg->sed_id, seq_id, seq_len);
+                       front_id, seq_id, seq_len, recv_msg->msg_id, msg_id);
                return HINIC_ERROR;
        }