Lines Matching refs:mbx
132 static u16 fm10k_mbx_index_len(struct fm10k_mbx_info *mbx, u16 head, u16 tail) in fm10k_mbx_index_len() argument
140 return len & ((mbx->mbmem_len << 1) - 1); in fm10k_mbx_index_len()
151 static u16 fm10k_mbx_tail_add(struct fm10k_mbx_info *mbx, u16 offset) in fm10k_mbx_tail_add() argument
153 u16 tail = (mbx->tail + offset + 1) & ((mbx->mbmem_len << 1) - 1); in fm10k_mbx_tail_add()
156 return (tail > mbx->tail) ? --tail : ++tail; in fm10k_mbx_tail_add()
167 static u16 fm10k_mbx_tail_sub(struct fm10k_mbx_info *mbx, u16 offset) in fm10k_mbx_tail_sub() argument
169 u16 tail = (mbx->tail - offset - 1) & ((mbx->mbmem_len << 1) - 1); in fm10k_mbx_tail_sub()
172 return (tail < mbx->tail) ? ++tail : --tail; in fm10k_mbx_tail_sub()
183 static u16 fm10k_mbx_head_add(struct fm10k_mbx_info *mbx, u16 offset) in fm10k_mbx_head_add() argument
185 u16 head = (mbx->head + offset + 1) & ((mbx->mbmem_len << 1) - 1); in fm10k_mbx_head_add()
188 return (head > mbx->head) ? --head : ++head; in fm10k_mbx_head_add()
199 static u16 fm10k_mbx_head_sub(struct fm10k_mbx_info *mbx, u16 offset) in fm10k_mbx_head_sub() argument
201 u16 head = (mbx->head - offset - 1) & ((mbx->mbmem_len << 1) - 1); in fm10k_mbx_head_sub()
204 return (head < mbx->head) ? ++head : --head; in fm10k_mbx_head_sub()
214 static u16 fm10k_mbx_pushed_tail_len(struct fm10k_mbx_info *mbx) in fm10k_mbx_pushed_tail_len() argument
216 u32 *tail = mbx->rx.buffer + fm10k_fifo_tail_offset(&mbx->rx, 0); in fm10k_mbx_pushed_tail_len()
219 if (!mbx->pushed) in fm10k_mbx_pushed_tail_len()
296 static u16 fm10k_mbx_validate_msg_size(struct fm10k_mbx_info *mbx, u16 len) in fm10k_mbx_validate_msg_size() argument
298 struct fm10k_mbx_fifo *fifo = &mbx->rx; in fm10k_mbx_validate_msg_size()
302 len += mbx->pushed; in fm10k_mbx_validate_msg_size()
314 if ((len < total_len) && (msg_len <= mbx->max_size)) in fm10k_mbx_validate_msg_size()
331 struct fm10k_mbx_info *mbx) in fm10k_mbx_write_copy() argument
333 struct fm10k_mbx_fifo *fifo = &mbx->tx; in fm10k_mbx_write_copy()
334 u32 mbmem = mbx->mbmem_reg; in fm10k_mbx_write_copy()
338 if (!mbx->tail_len) in fm10k_mbx_write_copy()
342 mask = mbx->mbmem_len - 1; in fm10k_mbx_write_copy()
343 len = mbx->tail_len; in fm10k_mbx_write_copy()
344 tail = fm10k_mbx_tail_sub(mbx, len); in fm10k_mbx_write_copy()
349 end = fm10k_fifo_head_offset(fifo, mbx->pulled); in fm10k_mbx_write_copy()
363 mbx->tx_mbmem_pulled++; in fm10k_mbx_write_copy()
383 struct fm10k_mbx_info *mbx, u16 head) in fm10k_mbx_pull_head() argument
385 u16 mbmem_len, len, ack = fm10k_mbx_index_len(mbx, head, mbx->tail); in fm10k_mbx_pull_head()
386 struct fm10k_mbx_fifo *fifo = &mbx->tx; in fm10k_mbx_pull_head()
389 mbx->pulled += mbx->tail_len - ack; in fm10k_mbx_pull_head()
392 mbmem_len = mbx->mbmem_len - 1; in fm10k_mbx_pull_head()
393 len = fm10k_fifo_used(fifo) - mbx->pulled; in fm10k_mbx_pull_head()
398 mbx->tail = fm10k_mbx_tail_add(mbx, len - ack); in fm10k_mbx_pull_head()
399 mbx->tail_len = len; in fm10k_mbx_pull_head()
403 len && (mbx->pulled >= len); in fm10k_mbx_pull_head()
405 mbx->pulled -= fm10k_fifo_head_drop(fifo); in fm10k_mbx_pull_head()
406 mbx->tx_messages++; in fm10k_mbx_pull_head()
407 mbx->tx_dwords += len; in fm10k_mbx_pull_head()
411 fm10k_mbx_write_copy(hw, mbx); in fm10k_mbx_pull_head()
424 struct fm10k_mbx_info *mbx) in fm10k_mbx_read_copy() argument
426 struct fm10k_mbx_fifo *fifo = &mbx->rx; in fm10k_mbx_read_copy()
427 u32 mbmem = mbx->mbmem_reg ^ mbx->mbmem_len; in fm10k_mbx_read_copy()
432 len = mbx->head_len; in fm10k_mbx_read_copy()
433 head = fm10k_mbx_head_sub(mbx, len); in fm10k_mbx_read_copy()
434 if (head >= mbx->mbmem_len) in fm10k_mbx_read_copy()
438 end = fm10k_fifo_tail_offset(fifo, mbx->pushed); in fm10k_mbx_read_copy()
445 head &= mbx->mbmem_len - 1; in fm10k_mbx_read_copy()
449 mbx->rx_mbmem_pushed++; in fm10k_mbx_read_copy()
472 struct fm10k_mbx_info *mbx, in fm10k_mbx_push_tail() argument
475 struct fm10k_mbx_fifo *fifo = &mbx->rx; in fm10k_mbx_push_tail()
476 u16 len, seq = fm10k_mbx_index_len(mbx, mbx->head, tail); in fm10k_mbx_push_tail()
479 len = fm10k_fifo_unused(fifo) - mbx->pushed; in fm10k_mbx_push_tail()
484 mbx->head = fm10k_mbx_head_add(mbx, len); in fm10k_mbx_push_tail()
485 mbx->head_len = len; in fm10k_mbx_push_tail()
492 fm10k_mbx_read_copy(hw, mbx); in fm10k_mbx_push_tail()
495 if (fm10k_mbx_validate_msg_size(mbx, len)) in fm10k_mbx_push_tail()
499 mbx->pushed += len; in fm10k_mbx_push_tail()
502 for (len = fm10k_mbx_pushed_tail_len(mbx); in fm10k_mbx_push_tail()
503 len && (mbx->pushed >= len); in fm10k_mbx_push_tail()
504 len = fm10k_mbx_pushed_tail_len(mbx)) { in fm10k_mbx_push_tail()
506 mbx->pushed -= len; in fm10k_mbx_push_tail()
507 mbx->rx_messages++; in fm10k_mbx_push_tail()
508 mbx->rx_dwords += len; in fm10k_mbx_push_tail()
617 static void fm10k_mbx_update_local_crc(struct fm10k_mbx_info *mbx, u16 head) in fm10k_mbx_update_local_crc() argument
619 u16 len = mbx->tail_len - fm10k_mbx_index_len(mbx, head, mbx->tail); in fm10k_mbx_update_local_crc()
622 head = fm10k_fifo_head_offset(&mbx->tx, mbx->pulled); in fm10k_mbx_update_local_crc()
625 mbx->local = fm10k_fifo_crc(&mbx->tx, head, len, mbx->local); in fm10k_mbx_update_local_crc()
638 static s32 fm10k_mbx_verify_remote_crc(struct fm10k_mbx_info *mbx) in fm10k_mbx_verify_remote_crc() argument
640 struct fm10k_mbx_fifo *fifo = &mbx->rx; in fm10k_mbx_verify_remote_crc()
641 u16 len = mbx->head_len; in fm10k_mbx_verify_remote_crc()
642 u16 offset = fm10k_fifo_tail_offset(fifo, mbx->pushed) - len; in fm10k_mbx_verify_remote_crc()
647 mbx->remote = fm10k_fifo_crc(fifo, offset, len, mbx->remote); in fm10k_mbx_verify_remote_crc()
650 crc = fm10k_crc_16b(&mbx->mbx_hdr, mbx->remote, 1); in fm10k_mbx_verify_remote_crc()
662 static bool fm10k_mbx_rx_ready(struct fm10k_mbx_info *mbx) in fm10k_mbx_rx_ready() argument
664 u16 msg_size = fm10k_fifo_head_len(&mbx->rx); in fm10k_mbx_rx_ready()
666 return msg_size && (fm10k_fifo_used(&mbx->rx) >= msg_size); in fm10k_mbx_rx_ready()
676 static bool fm10k_mbx_tx_ready(struct fm10k_mbx_info *mbx, u16 len) in fm10k_mbx_tx_ready() argument
678 u16 fifo_unused = fm10k_fifo_unused(&mbx->tx); in fm10k_mbx_tx_ready()
680 return (mbx->state == FM10K_STATE_OPEN) && (fifo_unused >= len); in fm10k_mbx_tx_ready()
689 static bool fm10k_mbx_tx_complete(struct fm10k_mbx_info *mbx) in fm10k_mbx_tx_complete() argument
691 return fm10k_fifo_empty(&mbx->tx); in fm10k_mbx_tx_complete()
703 struct fm10k_mbx_info *mbx) in fm10k_mbx_dequeue_rx() argument
705 struct fm10k_mbx_fifo *fifo = &mbx->rx; in fm10k_mbx_dequeue_rx()
712 mbx, mbx->msg_data); in fm10k_mbx_dequeue_rx()
714 mbx->rx_parse_err++; in fm10k_mbx_dequeue_rx()
720 memmove(fifo->buffer, fifo->buffer + fifo->tail, mbx->pushed << 2); in fm10k_mbx_dequeue_rx()
740 struct fm10k_mbx_info *mbx, const u32 *msg) in fm10k_mbx_enqueue_tx() argument
742 u32 countdown = mbx->timeout; in fm10k_mbx_enqueue_tx()
745 switch (mbx->state) { in fm10k_mbx_enqueue_tx()
754 err = fm10k_fifo_enqueue(&mbx->tx, msg); in fm10k_mbx_enqueue_tx()
759 udelay(mbx->udelay); in fm10k_mbx_enqueue_tx()
760 mbx->ops.process(hw, mbx); in fm10k_mbx_enqueue_tx()
761 err = fm10k_fifo_enqueue(&mbx->tx, msg); in fm10k_mbx_enqueue_tx()
766 mbx->timeout = 0; in fm10k_mbx_enqueue_tx()
767 mbx->tx_busy++; in fm10k_mbx_enqueue_tx()
774 if (!mbx->tail_len) in fm10k_mbx_enqueue_tx()
775 mbx->ops.process(hw, mbx); in fm10k_mbx_enqueue_tx()
787 static s32 fm10k_mbx_read(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) in fm10k_mbx_read() argument
790 if (mbx->mbx_hdr) in fm10k_mbx_read()
794 if (fm10k_read_reg(hw, mbx->mbx_reg) & FM10K_MBX_REQ_INTERRUPT) in fm10k_mbx_read()
795 mbx->mbx_lock = FM10K_MBX_ACK; in fm10k_mbx_read()
798 fm10k_write_reg(hw, mbx->mbx_reg, in fm10k_mbx_read()
802 mbx->mbx_hdr = fm10k_read_reg(hw, mbx->mbmem_reg ^ mbx->mbmem_len); in fm10k_mbx_read()
814 static void fm10k_mbx_write(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) in fm10k_mbx_write() argument
816 u32 mbmem = mbx->mbmem_reg; in fm10k_mbx_write()
819 fm10k_write_reg(hw, mbmem, mbx->mbx_hdr); in fm10k_mbx_write()
822 if (mbx->mbx_lock) in fm10k_mbx_write()
823 fm10k_write_reg(hw, mbx->mbx_reg, mbx->mbx_lock); in fm10k_mbx_write()
826 mbx->mbx_hdr = 0; in fm10k_mbx_write()
827 mbx->mbx_lock = 0; in fm10k_mbx_write()
836 static void fm10k_mbx_create_connect_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_create_connect_hdr() argument
838 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_mbx_create_connect_hdr()
840 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_CONNECT, TYPE) | in fm10k_mbx_create_connect_hdr()
841 FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD) | in fm10k_mbx_create_connect_hdr()
842 FM10K_MSG_HDR_FIELD_SET(mbx->rx.size - 1, CONNECT_SIZE); in fm10k_mbx_create_connect_hdr()
851 static void fm10k_mbx_create_data_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_create_data_hdr() argument
854 FM10K_MSG_HDR_FIELD_SET(mbx->tail, TAIL) | in fm10k_mbx_create_data_hdr()
855 FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD); in fm10k_mbx_create_data_hdr()
856 struct fm10k_mbx_fifo *fifo = &mbx->tx; in fm10k_mbx_create_data_hdr()
859 if (mbx->tail_len) in fm10k_mbx_create_data_hdr()
860 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_mbx_create_data_hdr()
863 crc = fm10k_fifo_crc(fifo, fm10k_fifo_head_offset(fifo, mbx->pulled), in fm10k_mbx_create_data_hdr()
864 mbx->tail_len, mbx->local); in fm10k_mbx_create_data_hdr()
868 mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC); in fm10k_mbx_create_data_hdr()
877 static void fm10k_mbx_create_disconnect_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_create_disconnect_hdr() argument
880 FM10K_MSG_HDR_FIELD_SET(mbx->tail, TAIL) | in fm10k_mbx_create_disconnect_hdr()
881 FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD); in fm10k_mbx_create_disconnect_hdr()
882 u16 crc = fm10k_crc_16b(&hdr, mbx->local, 1); in fm10k_mbx_create_disconnect_hdr()
884 mbx->mbx_lock |= FM10K_MBX_ACK; in fm10k_mbx_create_disconnect_hdr()
887 mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC); in fm10k_mbx_create_disconnect_hdr()
898 static void fm10k_mbx_create_fake_disconnect_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_create_fake_disconnect_hdr() argument
901 FM10K_MSG_HDR_FIELD_SET(mbx->head, TAIL) | in fm10k_mbx_create_fake_disconnect_hdr()
902 FM10K_MSG_HDR_FIELD_SET(mbx->tail, HEAD); in fm10k_mbx_create_fake_disconnect_hdr()
903 u16 crc = fm10k_crc_16b(&hdr, mbx->local, 1); in fm10k_mbx_create_fake_disconnect_hdr()
905 mbx->mbx_lock |= FM10K_MBX_ACK; in fm10k_mbx_create_fake_disconnect_hdr()
908 mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC); in fm10k_mbx_create_fake_disconnect_hdr()
920 static void fm10k_mbx_create_error_msg(struct fm10k_mbx_info *mbx, s32 err) in fm10k_mbx_create_error_msg() argument
935 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_mbx_create_error_msg()
937 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_ERROR, TYPE) | in fm10k_mbx_create_error_msg()
939 FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD); in fm10k_mbx_create_error_msg()
950 static s32 fm10k_mbx_validate_msg_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_validate_msg_hdr() argument
953 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_validate_msg_hdr()
967 if (tail != mbx->head) in fm10k_mbx_validate_msg_hdr()
975 if (fm10k_mbx_index_len(mbx, head, mbx->tail) > mbx->tail_len) in fm10k_mbx_validate_msg_hdr()
981 if (fm10k_mbx_index_len(mbx, mbx->head, tail) < mbx->mbmem_len) in fm10k_mbx_validate_msg_hdr()
1018 struct fm10k_mbx_info *mbx, u16 head) in fm10k_mbx_create_reply() argument
1020 switch (mbx->state) { in fm10k_mbx_create_reply()
1024 fm10k_mbx_update_local_crc(mbx, head); in fm10k_mbx_create_reply()
1027 fm10k_mbx_pull_head(hw, mbx, head); in fm10k_mbx_create_reply()
1030 if (mbx->tail_len || (mbx->state == FM10K_STATE_OPEN)) in fm10k_mbx_create_reply()
1031 fm10k_mbx_create_data_hdr(mbx); in fm10k_mbx_create_reply()
1033 fm10k_mbx_create_disconnect_hdr(mbx); in fm10k_mbx_create_reply()
1037 fm10k_mbx_create_connect_hdr(mbx); in fm10k_mbx_create_reply()
1041 fm10k_mbx_create_disconnect_hdr(mbx); in fm10k_mbx_create_reply()
1058 static void fm10k_mbx_reset_work(struct fm10k_mbx_info *mbx) in fm10k_mbx_reset_work() argument
1063 mbx->max_size = mbx->rx.size - 1; in fm10k_mbx_reset_work()
1066 head = FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, HEAD); in fm10k_mbx_reset_work()
1067 ack = fm10k_mbx_index_len(mbx, head, mbx->tail); in fm10k_mbx_reset_work()
1068 mbx->pulled += mbx->tail_len - ack; in fm10k_mbx_reset_work()
1071 while (fm10k_fifo_head_len(&mbx->tx) && mbx->pulled) { in fm10k_mbx_reset_work()
1072 len = fm10k_fifo_head_drop(&mbx->tx); in fm10k_mbx_reset_work()
1073 mbx->tx_dropped++; in fm10k_mbx_reset_work()
1074 if (mbx->pulled >= len) in fm10k_mbx_reset_work()
1075 mbx->pulled -= len; in fm10k_mbx_reset_work()
1077 mbx->pulled = 0; in fm10k_mbx_reset_work()
1081 mbx->pushed = 0; in fm10k_mbx_reset_work()
1082 mbx->pulled = 0; in fm10k_mbx_reset_work()
1083 mbx->tail_len = 0; in fm10k_mbx_reset_work()
1084 mbx->head_len = 0; in fm10k_mbx_reset_work()
1085 mbx->rx.tail = 0; in fm10k_mbx_reset_work()
1086 mbx->rx.head = 0; in fm10k_mbx_reset_work()
1100 static void fm10k_mbx_update_max_size(struct fm10k_mbx_info *mbx, u16 size) in fm10k_mbx_update_max_size() argument
1104 mbx->max_size = size; in fm10k_mbx_update_max_size()
1107 for (len = fm10k_fifo_head_len(&mbx->tx); in fm10k_mbx_update_max_size()
1109 len = fm10k_fifo_head_len(&mbx->tx)) { in fm10k_mbx_update_max_size()
1110 fm10k_fifo_head_drop(&mbx->tx); in fm10k_mbx_update_max_size()
1111 mbx->tx_dropped++; in fm10k_mbx_update_max_size()
1122 static void fm10k_mbx_connect_reset(struct fm10k_mbx_info *mbx) in fm10k_mbx_connect_reset() argument
1125 fm10k_mbx_reset_work(mbx); in fm10k_mbx_connect_reset()
1128 mbx->local = FM10K_MBX_CRC_SEED; in fm10k_mbx_connect_reset()
1129 mbx->remote = FM10K_MBX_CRC_SEED; in fm10k_mbx_connect_reset()
1132 if (mbx->state == FM10K_STATE_OPEN) in fm10k_mbx_connect_reset()
1133 mbx->state = FM10K_STATE_CONNECT; in fm10k_mbx_connect_reset()
1135 mbx->state = FM10K_STATE_CLOSED; in fm10k_mbx_connect_reset()
1148 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_connect() argument
1150 const enum fm10k_mbx_state state = mbx->state; in fm10k_mbx_process_connect()
1151 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_connect()
1162 fm10k_mbx_connect_reset(mbx); in fm10k_mbx_process_connect()
1166 if (size > mbx->rx.size) { in fm10k_mbx_process_connect()
1167 mbx->max_size = mbx->rx.size - 1; in fm10k_mbx_process_connect()
1170 mbx->state = FM10K_STATE_OPEN; in fm10k_mbx_process_connect()
1172 fm10k_mbx_update_max_size(mbx, size); in fm10k_mbx_process_connect()
1180 mbx->tail = head; in fm10k_mbx_process_connect()
1182 return fm10k_mbx_create_reply(hw, mbx, head); in fm10k_mbx_process_connect()
1195 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_data() argument
1197 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_data()
1206 if (mbx->state == FM10K_STATE_CONNECT) { in fm10k_mbx_process_data()
1207 mbx->tail = head; in fm10k_mbx_process_data()
1208 mbx->state = FM10K_STATE_OPEN; in fm10k_mbx_process_data()
1212 err = fm10k_mbx_push_tail(hw, mbx, tail); in fm10k_mbx_process_data()
1217 err = fm10k_mbx_verify_remote_crc(mbx); in fm10k_mbx_process_data()
1222 fm10k_mbx_dequeue_rx(hw, mbx); in fm10k_mbx_process_data()
1224 return fm10k_mbx_create_reply(hw, mbx, head); in fm10k_mbx_process_data()
1237 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_disconnect() argument
1239 const enum fm10k_mbx_state state = mbx->state; in fm10k_mbx_process_disconnect()
1240 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_disconnect()
1248 if (mbx->pushed) in fm10k_mbx_process_disconnect()
1252 mbx->head_len = 0; in fm10k_mbx_process_disconnect()
1255 err = fm10k_mbx_verify_remote_crc(mbx); in fm10k_mbx_process_disconnect()
1263 if (!fm10k_mbx_tx_complete(mbx)) in fm10k_mbx_process_disconnect()
1267 if (head != mbx->tail) in fm10k_mbx_process_disconnect()
1271 fm10k_mbx_connect_reset(mbx); in fm10k_mbx_process_disconnect()
1277 return fm10k_mbx_create_reply(hw, mbx, head); in fm10k_mbx_process_disconnect()
1290 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_error() argument
1292 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_error()
1298 switch (mbx->state) { in fm10k_mbx_process_error()
1302 fm10k_mbx_reset_work(mbx); in fm10k_mbx_process_error()
1305 mbx->local = FM10K_MBX_CRC_SEED; in fm10k_mbx_process_error()
1306 mbx->remote = FM10K_MBX_CRC_SEED; in fm10k_mbx_process_error()
1309 mbx->tail = head; in fm10k_mbx_process_error()
1312 if (mbx->state == FM10K_STATE_OPEN) { in fm10k_mbx_process_error()
1313 mbx->state = FM10K_STATE_CONNECT; in fm10k_mbx_process_error()
1318 fm10k_mbx_create_connect_hdr(mbx); in fm10k_mbx_process_error()
1324 return fm10k_mbx_create_reply(hw, mbx, mbx->tail); in fm10k_mbx_process_error()
1337 struct fm10k_mbx_info *mbx) in fm10k_mbx_process() argument
1342 if (mbx->state == FM10K_STATE_CLOSED) in fm10k_mbx_process()
1346 err = fm10k_mbx_read(hw, mbx); in fm10k_mbx_process()
1351 err = fm10k_mbx_validate_msg_hdr(mbx); in fm10k_mbx_process()
1355 switch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, TYPE)) { in fm10k_mbx_process()
1357 err = fm10k_mbx_process_connect(hw, mbx); in fm10k_mbx_process()
1360 err = fm10k_mbx_process_data(hw, mbx); in fm10k_mbx_process()
1363 err = fm10k_mbx_process_disconnect(hw, mbx); in fm10k_mbx_process()
1366 err = fm10k_mbx_process_error(hw, mbx); in fm10k_mbx_process()
1376 fm10k_mbx_create_error_msg(mbx, err); in fm10k_mbx_process()
1379 fm10k_mbx_write(hw, mbx); in fm10k_mbx_process()
1398 struct fm10k_mbx_info *mbx) in fm10k_mbx_disconnect() argument
1400 int timeout = mbx->timeout ? FM10K_MBX_DISCONNECT_TIMEOUT : 0; in fm10k_mbx_disconnect()
1403 mbx->state = FM10K_STATE_DISCONNECT; in fm10k_mbx_disconnect()
1406 fm10k_write_reg(hw, mbx->mbx_reg, FM10K_MBX_REQ | in fm10k_mbx_disconnect()
1410 mbx->ops.process(hw, mbx); in fm10k_mbx_disconnect()
1412 } while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED)); in fm10k_mbx_disconnect()
1417 fm10k_mbx_connect_reset(mbx); in fm10k_mbx_disconnect()
1418 fm10k_fifo_drop_all(&mbx->tx); in fm10k_mbx_disconnect()
1420 fm10k_write_reg(hw, mbx->mbmem_reg, 0); in fm10k_mbx_disconnect()
1436 static s32 fm10k_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) in fm10k_mbx_connect() argument
1439 if (!mbx->rx.buffer) in fm10k_mbx_connect()
1443 if (mbx->state != FM10K_STATE_CLOSED) in fm10k_mbx_connect()
1447 mbx->timeout = FM10K_MBX_INIT_TIMEOUT; in fm10k_mbx_connect()
1450 mbx->state = FM10K_STATE_CONNECT; in fm10k_mbx_connect()
1452 fm10k_mbx_reset_work(mbx); in fm10k_mbx_connect()
1455 fm10k_mbx_create_fake_disconnect_hdr(mbx); in fm10k_mbx_connect()
1456 fm10k_write_reg(hw, mbx->mbmem_reg ^ mbx->mbmem_len, mbx->mbx_hdr); in fm10k_mbx_connect()
1459 mbx->mbx_lock = FM10K_MBX_REQ_INTERRUPT | FM10K_MBX_ACK_INTERRUPT | in fm10k_mbx_connect()
1463 fm10k_mbx_create_connect_hdr(mbx); in fm10k_mbx_connect()
1464 fm10k_mbx_write(hw, mbx); in fm10k_mbx_connect()
1531 static s32 fm10k_mbx_register_handlers(struct fm10k_mbx_info *mbx, in fm10k_mbx_register_handlers() argument
1539 mbx->msg_data = msg_data; in fm10k_mbx_register_handlers()
1558 s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx, in fm10k_pfvf_mbx_init() argument
1564 mbx->mbx_reg = FM10K_VFMBX; in fm10k_pfvf_mbx_init()
1565 mbx->mbmem_reg = FM10K_VFMBMEM(FM10K_VFMBMEM_VF_XOR); in fm10k_pfvf_mbx_init()
1570 mbx->mbx_reg = FM10K_MBX(id); in fm10k_pfvf_mbx_init()
1571 mbx->mbmem_reg = FM10K_MBMEM_VF(id, 0); in fm10k_pfvf_mbx_init()
1580 mbx->state = FM10K_STATE_CLOSED; in fm10k_pfvf_mbx_init()
1587 mbx->msg_data = msg_data; in fm10k_pfvf_mbx_init()
1592 mbx->timeout = 0; in fm10k_pfvf_mbx_init()
1593 mbx->udelay = FM10K_MBX_INIT_DELAY; in fm10k_pfvf_mbx_init()
1596 mbx->tail = 1; in fm10k_pfvf_mbx_init()
1597 mbx->head = 1; in fm10k_pfvf_mbx_init()
1600 mbx->local = FM10K_MBX_CRC_SEED; in fm10k_pfvf_mbx_init()
1601 mbx->remote = FM10K_MBX_CRC_SEED; in fm10k_pfvf_mbx_init()
1604 mbx->max_size = FM10K_MBX_MSG_MAX_SIZE; in fm10k_pfvf_mbx_init()
1605 mbx->mbmem_len = FM10K_VFMBMEM_VF_XOR; in fm10k_pfvf_mbx_init()
1608 fm10k_fifo_init(&mbx->tx, mbx->buffer, FM10K_MBX_TX_BUFFER_SIZE); in fm10k_pfvf_mbx_init()
1609 fm10k_fifo_init(&mbx->rx, &mbx->buffer[FM10K_MBX_TX_BUFFER_SIZE], in fm10k_pfvf_mbx_init()
1613 mbx->ops.connect = fm10k_mbx_connect; in fm10k_pfvf_mbx_init()
1614 mbx->ops.disconnect = fm10k_mbx_disconnect; in fm10k_pfvf_mbx_init()
1615 mbx->ops.rx_ready = fm10k_mbx_rx_ready; in fm10k_pfvf_mbx_init()
1616 mbx->ops.tx_ready = fm10k_mbx_tx_ready; in fm10k_pfvf_mbx_init()
1617 mbx->ops.tx_complete = fm10k_mbx_tx_complete; in fm10k_pfvf_mbx_init()
1618 mbx->ops.enqueue_tx = fm10k_mbx_enqueue_tx; in fm10k_pfvf_mbx_init()
1619 mbx->ops.process = fm10k_mbx_process; in fm10k_pfvf_mbx_init()
1620 mbx->ops.register_handlers = fm10k_mbx_register_handlers; in fm10k_pfvf_mbx_init()
1631 static void fm10k_sm_mbx_create_data_hdr(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_create_data_hdr() argument
1633 if (mbx->tail_len) in fm10k_sm_mbx_create_data_hdr()
1634 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_sm_mbx_create_data_hdr()
1636 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(mbx->tail, SM_TAIL) | in fm10k_sm_mbx_create_data_hdr()
1637 FM10K_MSG_HDR_FIELD_SET(mbx->remote, SM_VER) | in fm10k_sm_mbx_create_data_hdr()
1638 FM10K_MSG_HDR_FIELD_SET(mbx->head, SM_HEAD); in fm10k_sm_mbx_create_data_hdr()
1648 static void fm10k_sm_mbx_create_connect_hdr(struct fm10k_mbx_info *mbx, u8 err) in fm10k_sm_mbx_create_connect_hdr() argument
1650 if (mbx->local) in fm10k_sm_mbx_create_connect_hdr()
1651 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_sm_mbx_create_connect_hdr()
1653 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(mbx->tail, SM_TAIL) | in fm10k_sm_mbx_create_connect_hdr()
1654 FM10K_MSG_HDR_FIELD_SET(mbx->remote, SM_VER) | in fm10k_sm_mbx_create_connect_hdr()
1655 FM10K_MSG_HDR_FIELD_SET(mbx->head, SM_HEAD) | in fm10k_sm_mbx_create_connect_hdr()
1665 static void fm10k_sm_mbx_connect_reset(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_connect_reset() argument
1668 fm10k_mbx_reset_work(mbx); in fm10k_sm_mbx_connect_reset()
1671 mbx->local = FM10K_SM_MBX_VERSION; in fm10k_sm_mbx_connect_reset()
1672 mbx->remote = 0; in fm10k_sm_mbx_connect_reset()
1675 mbx->tail = 1; in fm10k_sm_mbx_connect_reset()
1676 mbx->head = 1; in fm10k_sm_mbx_connect_reset()
1679 mbx->state = FM10K_STATE_CONNECT; in fm10k_sm_mbx_connect_reset()
1694 static s32 fm10k_sm_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_connect() argument
1697 if (!mbx->rx.buffer) in fm10k_sm_mbx_connect()
1701 if (mbx->state != FM10K_STATE_CLOSED) in fm10k_sm_mbx_connect()
1705 mbx->timeout = FM10K_MBX_INIT_TIMEOUT; in fm10k_sm_mbx_connect()
1708 mbx->state = FM10K_STATE_CONNECT; in fm10k_sm_mbx_connect()
1709 mbx->max_size = FM10K_MBX_MSG_MAX_SIZE; in fm10k_sm_mbx_connect()
1712 fm10k_sm_mbx_connect_reset(mbx); in fm10k_sm_mbx_connect()
1715 mbx->mbx_lock = FM10K_MBX_REQ_INTERRUPT | FM10K_MBX_ACK_INTERRUPT | in fm10k_sm_mbx_connect()
1719 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_connect()
1720 fm10k_mbx_write(hw, mbx); in fm10k_sm_mbx_connect()
1739 struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_disconnect() argument
1741 int timeout = mbx->timeout ? FM10K_MBX_DISCONNECT_TIMEOUT : 0; in fm10k_sm_mbx_disconnect()
1744 mbx->state = FM10K_STATE_DISCONNECT; in fm10k_sm_mbx_disconnect()
1747 fm10k_write_reg(hw, mbx->mbx_reg, FM10K_MBX_REQ | in fm10k_sm_mbx_disconnect()
1751 mbx->ops.process(hw, mbx); in fm10k_sm_mbx_disconnect()
1753 } while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED)); in fm10k_sm_mbx_disconnect()
1756 mbx->state = FM10K_STATE_CLOSED; in fm10k_sm_mbx_disconnect()
1757 mbx->remote = 0; in fm10k_sm_mbx_disconnect()
1758 fm10k_mbx_reset_work(mbx); in fm10k_sm_mbx_disconnect()
1759 fm10k_fifo_drop_all(&mbx->tx); in fm10k_sm_mbx_disconnect()
1761 fm10k_write_reg(hw, mbx->mbmem_reg, 0); in fm10k_sm_mbx_disconnect()
1772 static s32 fm10k_sm_mbx_validate_fifo_hdr(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_validate_fifo_hdr() argument
1774 const u32 *hdr = &mbx->mbx_hdr; in fm10k_sm_mbx_validate_fifo_hdr()
1789 if (mbx->tail < head) in fm10k_sm_mbx_validate_fifo_hdr()
1790 head += mbx->mbmem_len - 1; in fm10k_sm_mbx_validate_fifo_hdr()
1791 if (tail < mbx->head) in fm10k_sm_mbx_validate_fifo_hdr()
1792 tail += mbx->mbmem_len - 1; in fm10k_sm_mbx_validate_fifo_hdr()
1793 if (fm10k_mbx_index_len(mbx, head, mbx->tail) > mbx->tail_len) in fm10k_sm_mbx_validate_fifo_hdr()
1795 if (fm10k_mbx_index_len(mbx, mbx->head, tail) < mbx->mbmem_len) in fm10k_sm_mbx_validate_fifo_hdr()
1814 static void fm10k_sm_mbx_process_error(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_process_error() argument
1816 const enum fm10k_mbx_state state = mbx->state; in fm10k_sm_mbx_process_error()
1821 mbx->remote = 0; in fm10k_sm_mbx_process_error()
1825 fm10k_sm_mbx_connect_reset(mbx); in fm10k_sm_mbx_process_error()
1829 if (mbx->remote) { in fm10k_sm_mbx_process_error()
1830 while (mbx->local > 1) in fm10k_sm_mbx_process_error()
1831 mbx->local--; in fm10k_sm_mbx_process_error()
1832 mbx->remote = 0; in fm10k_sm_mbx_process_error()
1839 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_process_error()
1850 static void fm10k_sm_mbx_create_error_msg(struct fm10k_mbx_info *mbx, s32 err) in fm10k_sm_mbx_create_error_msg() argument
1865 fm10k_sm_mbx_process_error(mbx); in fm10k_sm_mbx_create_error_msg()
1866 fm10k_sm_mbx_create_connect_hdr(mbx, 1); in fm10k_sm_mbx_create_error_msg()
1879 struct fm10k_mbx_info *mbx, in fm10k_sm_mbx_receive() argument
1883 u16 mbmem_len = mbx->mbmem_len - 1; in fm10k_sm_mbx_receive()
1887 if (tail < mbx->head) in fm10k_sm_mbx_receive()
1891 err = fm10k_mbx_push_tail(hw, mbx, tail); in fm10k_sm_mbx_receive()
1896 fm10k_mbx_dequeue_rx(hw, mbx); in fm10k_sm_mbx_receive()
1899 mbx->head = fm10k_mbx_head_sub(mbx, mbx->pushed); in fm10k_sm_mbx_receive()
1900 mbx->pushed = 0; in fm10k_sm_mbx_receive()
1903 if (mbx->head > mbmem_len) in fm10k_sm_mbx_receive()
1904 mbx->head -= mbmem_len; in fm10k_sm_mbx_receive()
1919 struct fm10k_mbx_info *mbx, u16 head) in fm10k_sm_mbx_transmit() argument
1921 struct fm10k_mbx_fifo *fifo = &mbx->tx; in fm10k_sm_mbx_transmit()
1923 u16 mbmem_len = mbx->mbmem_len - 1; in fm10k_sm_mbx_transmit()
1927 if (mbx->tail < head) in fm10k_sm_mbx_transmit()
1930 fm10k_mbx_pull_head(hw, mbx, head); in fm10k_sm_mbx_transmit()
1939 } while ((len <= mbx->tail_len) && (len < mbmem_len)); in fm10k_sm_mbx_transmit()
1942 if (mbx->tail_len > tail_len) { in fm10k_sm_mbx_transmit()
1943 mbx->tail = fm10k_mbx_tail_sub(mbx, mbx->tail_len - tail_len); in fm10k_sm_mbx_transmit()
1944 mbx->tail_len = tail_len; in fm10k_sm_mbx_transmit()
1948 if (mbx->tail > mbmem_len) in fm10k_sm_mbx_transmit()
1949 mbx->tail -= mbmem_len; in fm10k_sm_mbx_transmit()
1964 struct fm10k_mbx_info *mbx, u16 head) in fm10k_sm_mbx_create_reply() argument
1966 switch (mbx->state) { in fm10k_sm_mbx_create_reply()
1970 fm10k_sm_mbx_transmit(hw, mbx, head); in fm10k_sm_mbx_create_reply()
1973 if (mbx->tail_len || (mbx->state == FM10K_STATE_OPEN)) { in fm10k_sm_mbx_create_reply()
1974 fm10k_sm_mbx_create_data_hdr(mbx); in fm10k_sm_mbx_create_reply()
1976 mbx->remote = 0; in fm10k_sm_mbx_create_reply()
1977 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_create_reply()
1982 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_create_reply()
2001 struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_process_reset() argument
2004 const enum fm10k_mbx_state state = mbx->state; in fm10k_sm_mbx_process_reset()
2009 mbx->state = FM10K_STATE_CLOSED; in fm10k_sm_mbx_process_reset()
2010 mbx->remote = 0; in fm10k_sm_mbx_process_reset()
2011 mbx->local = 0; in fm10k_sm_mbx_process_reset()
2015 fm10k_sm_mbx_connect_reset(mbx); in fm10k_sm_mbx_process_reset()
2020 mbx->remote = mbx->local; in fm10k_sm_mbx_process_reset()
2026 fm10k_sm_mbx_create_reply(hw, mbx, mbx->tail); in fm10k_sm_mbx_process_reset()
2040 struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_process_version_1() argument
2042 const u32 *hdr = &mbx->mbx_hdr; in fm10k_sm_mbx_process_version_1()
2051 if (mbx->state == FM10K_STATE_CONNECT) { in fm10k_sm_mbx_process_version_1()
2052 if (!mbx->remote) in fm10k_sm_mbx_process_version_1()
2054 if (mbx->remote != 1) in fm10k_sm_mbx_process_version_1()
2057 mbx->state = FM10K_STATE_OPEN; in fm10k_sm_mbx_process_version_1()
2062 len = fm10k_sm_mbx_receive(hw, mbx, tail); in fm10k_sm_mbx_process_version_1()
2070 fm10k_sm_mbx_create_reply(hw, mbx, head); in fm10k_sm_mbx_process_version_1()
2085 struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_process() argument
2090 if (mbx->state == FM10K_STATE_CLOSED) in fm10k_sm_mbx_process()
2094 err = fm10k_mbx_read(hw, mbx); in fm10k_sm_mbx_process()
2098 err = fm10k_sm_mbx_validate_fifo_hdr(mbx); in fm10k_sm_mbx_process()
2102 if (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, SM_ERR)) { in fm10k_sm_mbx_process()
2103 fm10k_sm_mbx_process_error(mbx); in fm10k_sm_mbx_process()
2107 switch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, SM_VER)) { in fm10k_sm_mbx_process()
2109 err = fm10k_sm_mbx_process_reset(hw, mbx); in fm10k_sm_mbx_process()
2112 err = fm10k_sm_mbx_process_version_1(hw, mbx); in fm10k_sm_mbx_process()
2118 fm10k_sm_mbx_create_error_msg(mbx, err); in fm10k_sm_mbx_process()
2121 fm10k_mbx_write(hw, mbx); in fm10k_sm_mbx_process()
2140 struct fm10k_mbx_info *mbx, in fm10k_sm_mbx_init() argument
2143 mbx->mbx_reg = FM10K_GMBX; in fm10k_sm_mbx_init()
2144 mbx->mbmem_reg = FM10K_MBMEM_PF(0); in fm10k_sm_mbx_init()
2147 mbx->state = FM10K_STATE_CLOSED; in fm10k_sm_mbx_init()
2154 mbx->msg_data = msg_data; in fm10k_sm_mbx_init()
2159 mbx->timeout = 0; in fm10k_sm_mbx_init()
2160 mbx->udelay = FM10K_MBX_INIT_DELAY; in fm10k_sm_mbx_init()
2163 mbx->max_size = FM10K_MBX_MSG_MAX_SIZE; in fm10k_sm_mbx_init()
2164 mbx->mbmem_len = FM10K_MBMEM_PF_XOR; in fm10k_sm_mbx_init()
2167 fm10k_fifo_init(&mbx->tx, mbx->buffer, FM10K_MBX_TX_BUFFER_SIZE); in fm10k_sm_mbx_init()
2168 fm10k_fifo_init(&mbx->rx, &mbx->buffer[FM10K_MBX_TX_BUFFER_SIZE], in fm10k_sm_mbx_init()
2172 mbx->ops.connect = fm10k_sm_mbx_connect; in fm10k_sm_mbx_init()
2173 mbx->ops.disconnect = fm10k_sm_mbx_disconnect; in fm10k_sm_mbx_init()
2174 mbx->ops.rx_ready = fm10k_mbx_rx_ready; in fm10k_sm_mbx_init()
2175 mbx->ops.tx_ready = fm10k_mbx_tx_ready; in fm10k_sm_mbx_init()
2176 mbx->ops.tx_complete = fm10k_mbx_tx_complete; in fm10k_sm_mbx_init()
2177 mbx->ops.enqueue_tx = fm10k_mbx_enqueue_tx; in fm10k_sm_mbx_init()
2178 mbx->ops.process = fm10k_sm_mbx_process; in fm10k_sm_mbx_init()
2179 mbx->ops.register_handlers = fm10k_mbx_register_handlers; in fm10k_sm_mbx_init()