fm10k/base: fix mailbox phantom messages
[dpdk.git] / drivers / net / fm10k / base / fm10k_mbx.c
index e6cf1c8..0df588a 100644 (file)
@@ -138,6 +138,18 @@ STATIC u16 fm10k_fifo_head_drop(struct fm10k_mbx_fifo *fifo)
        return len;
 }
 
+/**
+ *  fm10k_fifo_drop_all - Drop all messages in FIFO
+ *  @fifo: pointer to FIFO
+ *
+ *  This function resets the head pointer to drop all messages in the FIFO and
+ *  ensure the FIFO is empty.
+ **/
+STATIC void fm10k_fifo_drop_all(struct fm10k_mbx_fifo *fifo)
+{
+       fifo->head = fifo->tail;
+}
+
 /**
  *  fm10k_mbx_index_len - Convert a head/tail index into a length value
  *  @mbx: pointer to mailbox
@@ -332,7 +344,7 @@ STATIC u16 fm10k_mbx_validate_msg_size(struct fm10k_mbx_info *mbx, u16 len)
        } while (total_len < len);
 
        /* message extends out of pushed section, but fits in FIFO */
-       if ((len < total_len) && (msg_len <= mbx->rx.size))
+       if ((len < total_len) && (msg_len <= mbx->max_size))
                return 0;
 
        /* return length of invalid section */
@@ -1063,9 +1075,26 @@ STATIC s32 fm10k_mbx_create_reply(struct fm10k_hw *hw,
  **/
 STATIC void fm10k_mbx_reset_work(struct fm10k_mbx_info *mbx)
 {
+       u16 len, head, ack;
+
        /* reset our outgoing max size back to Rx limits */
        mbx->max_size = mbx->rx.size - 1;
 
+       /* update mbx->pulled to account for tail_len and ack */
+       head = FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, HEAD);
+       ack = fm10k_mbx_index_len(mbx, head, mbx->tail);
+       mbx->pulled += mbx->tail_len - ack;
+
+       /* now drop any messages which have started or finished transmitting */
+       while (fm10k_fifo_head_len(&mbx->tx) && mbx->pulled) {
+               len = fm10k_fifo_head_drop(&mbx->tx);
+               mbx->tx_dropped++;
+               if (mbx->pulled >= len)
+                       mbx->pulled -= len;
+               else
+                       mbx->pulled = 0;
+       }
+
        /* just do a quick resysnc to start of message */
        mbx->pushed = 0;
        mbx->pulled = 0;
@@ -1076,12 +1105,15 @@ STATIC void fm10k_mbx_reset_work(struct fm10k_mbx_info *mbx)
 }
 
 /**
- *  fm10k_mbx_update_max_size - Update the max_size and drop any large messages
+ *  fm10k_mbx_update_max_size - Update the max_size and drop large messages
  *  @mbx: pointer to mailbox
  *  @size: new value for max_size
  *
- *  This function will update the max_size value and drop any outgoing messages
- *  from the head of the Tx FIFO that are larger than max_size.
+ *  This function updates the max_size value and drops any outgoing messages
+ *  at the head of the Tx FIFO if they are larger than max_size. It does not
+ *  drop all messages, as this is too difficult to parse and remove them from
+ *  the FIFO. Instead, rely on the checking to ensure that messages larger
+ *  than max_size aren't pushed into the memory buffer.
  **/
 STATIC void fm10k_mbx_update_max_size(struct fm10k_mbx_info *mbx, u16 size)
 {
@@ -1277,16 +1309,11 @@ STATIC s32 fm10k_mbx_process_error(struct fm10k_hw *hw,
                                   struct fm10k_mbx_info *mbx)
 {
        const u32 *hdr = &mbx->mbx_hdr;
-       s32 err_no;
        u16 head;
 
        /* we will need to pull all of the fields for verification */
        head = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD);
 
-       /* we only have lower 10 bits of error number so add upper bits */
-       err_no = FM10K_MSG_HDR_FIELD_GET(*hdr, ERR_NO);
-       err_no |= ~FM10K_MSG_HDR_MASK(ERR_NO);
-
        switch (mbx->state) {
        case FM10K_STATE_OPEN:
        case FM10K_STATE_DISCONNECT:
@@ -1407,9 +1434,11 @@ STATIC void fm10k_mbx_disconnect(struct fm10k_hw *hw,
                timeout -= FM10K_MBX_POLL_DELAY;
        } while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED));
 
-       /* in case we didn't close just force the mailbox into shutdown */
+       /* in case we didn't close, just force the mailbox into shutdown and
+        * drop all left over messages in the FIFO.
+        */
        fm10k_mbx_connect_reset(mbx);
-       fm10k_mbx_update_max_size(mbx, 0);
+       fm10k_fifo_drop_all(&mbx->tx);
 
        FM10K_WRITE_MBX(hw, mbx->mbmem_reg, 0);
 }
@@ -1762,7 +1791,7 @@ STATIC void fm10k_sm_mbx_disconnect(struct fm10k_hw *hw,
        mbx->state = FM10K_STATE_CLOSED;
        mbx->remote = 0;
        fm10k_mbx_reset_work(mbx);
-       fm10k_mbx_update_max_size(mbx, 0);
+       fm10k_fifo_drop_all(&mbx->tx);
 
        FM10K_WRITE_REG(hw, mbx->mbmem_reg, 0);
 }