X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Ffm10k%2Fbase%2Ffm10k_mbx.c;h=3c9ab3a535e27c9aa4aac6f0cbfc4611f76808ee;hb=43254a336780a7d21c525097794a70a21a7fa2c4;hp=20814140878feb0076ddd8ca211e6da13d64381e;hpb=637bb7694d6aedbbf1830a12d0bd0e582a3a18a5;p=dpdk.git diff --git a/drivers/net/fm10k/base/fm10k_mbx.c b/drivers/net/fm10k/base/fm10k_mbx.c index 2081414087..3c9ab3a535 100644 --- a/drivers/net/fm10k/base/fm10k_mbx.c +++ b/drivers/net/fm10k/base/fm10k_mbx.c @@ -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 */ @@ -343,8 +355,7 @@ STATIC u16 fm10k_mbx_validate_msg_size(struct fm10k_mbx_info *mbx, u16 len) * fm10k_mbx_write_copy - pulls data off of Tx FIFO and places it in mbmem * @mbx: pointer to mailbox * - * This function will take a section of the Rx FIFO and copy it into the - mbx->tail--; + * This function will take a section of the Tx FIFO and copy it into the * mailbox memory. The offset in mbmem is based on the lower bits of the * tail and len determines the length to copy. **/ @@ -383,6 +394,8 @@ STATIC void fm10k_mbx_write_copy(struct fm10k_hw *hw, if (!tail) tail++; + mbx->tx_mbmem_pulled++; + /* write message to hardware FIFO */ FM10K_WRITE_MBX(hw, mbmem + tail++, *(head++)); } while (--len && --end); @@ -469,6 +482,8 @@ STATIC void fm10k_mbx_read_copy(struct fm10k_hw *hw, if (!head) head++; + mbx->rx_mbmem_pushed++; + /* read message from hardware FIFO */ *(tail++) = FM10K_READ_MBX(hw, mbmem + head++); } while (--len && --end); @@ -914,6 +929,27 @@ STATIC void fm10k_mbx_create_disconnect_hdr(struct fm10k_mbx_info *mbx) mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC); } +/** + * fm10k_mbx_create_fake_disconnect_hdr - Generate a false disconnect mailbox header + * @mbx: pointer to mailbox + * + * This function creates a fake disconnect header for loading into remote + * mailbox header. The primary purpose is to prevent errors on immediate + * start up after mbx->connect. + **/ +STATIC void fm10k_mbx_create_fake_disconnect_hdr(struct fm10k_mbx_info *mbx) +{ + u32 hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_DISCONNECT, TYPE) | + FM10K_MSG_HDR_FIELD_SET(mbx->head, TAIL) | + FM10K_MSG_HDR_FIELD_SET(mbx->tail, HEAD); + u16 crc = fm10k_crc_16b(&hdr, mbx->local, 1); + + mbx->mbx_lock |= FM10K_MBX_ACK; + + /* load header to memory to be written */ + mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC); +} + /** * fm10k_mbx_create_error_msg - Generate a error message * @mbx: pointer to mailbox @@ -1064,9 +1100,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; @@ -1077,12 +1130,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) { @@ -1278,16 +1334,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: @@ -1408,9 +1459,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); } @@ -1446,8 +1499,9 @@ STATIC s32 fm10k_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) /* Place mbx in ready to connect state */ mbx->state = FM10K_STATE_CONNECT; - /* initialize header of remote mailbox */ - fm10k_mbx_create_disconnect_hdr(mbx); + fm10k_mbx_reset_work(mbx); + + fm10k_mbx_create_fake_disconnect_hdr(mbx); FM10K_WRITE_MBX(hw, mbx->mbmem_reg ^ mbx->mbmem_len, mbx->mbx_hdr); /* enable interrupt and notify other party of new message */ @@ -1763,7 +1817,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); }