Lines Matching refs:mbx

149 static u16 fm10k_mbx_index_len(struct fm10k_mbx_info *mbx, u16 head, u16 tail)  in fm10k_mbx_index_len()  argument
157 return len & ((mbx->mbmem_len << 1) - 1); in fm10k_mbx_index_len()
168 static u16 fm10k_mbx_tail_add(struct fm10k_mbx_info *mbx, u16 offset) in fm10k_mbx_tail_add() argument
170 u16 tail = (mbx->tail + offset + 1) & ((mbx->mbmem_len << 1) - 1); in fm10k_mbx_tail_add()
173 return (tail > mbx->tail) ? --tail : ++tail; in fm10k_mbx_tail_add()
184 static u16 fm10k_mbx_tail_sub(struct fm10k_mbx_info *mbx, u16 offset) in fm10k_mbx_tail_sub() argument
186 u16 tail = (mbx->tail - offset - 1) & ((mbx->mbmem_len << 1) - 1); in fm10k_mbx_tail_sub()
189 return (tail < mbx->tail) ? ++tail : --tail; in fm10k_mbx_tail_sub()
200 static u16 fm10k_mbx_head_add(struct fm10k_mbx_info *mbx, u16 offset) in fm10k_mbx_head_add() argument
202 u16 head = (mbx->head + offset + 1) & ((mbx->mbmem_len << 1) - 1); in fm10k_mbx_head_add()
205 return (head > mbx->head) ? --head : ++head; in fm10k_mbx_head_add()
216 static u16 fm10k_mbx_head_sub(struct fm10k_mbx_info *mbx, u16 offset) in fm10k_mbx_head_sub() argument
218 u16 head = (mbx->head - offset - 1) & ((mbx->mbmem_len << 1) - 1); in fm10k_mbx_head_sub()
221 return (head < mbx->head) ? ++head : --head; in fm10k_mbx_head_sub()
231 static u16 fm10k_mbx_pushed_tail_len(struct fm10k_mbx_info *mbx) in fm10k_mbx_pushed_tail_len() argument
233 u32 *tail = mbx->rx.buffer + fm10k_fifo_tail_offset(&mbx->rx, 0); in fm10k_mbx_pushed_tail_len()
236 if (!mbx->pushed) in fm10k_mbx_pushed_tail_len()
313 static u16 fm10k_mbx_validate_msg_size(struct fm10k_mbx_info *mbx, u16 len) in fm10k_mbx_validate_msg_size() argument
315 struct fm10k_mbx_fifo *fifo = &mbx->rx; in fm10k_mbx_validate_msg_size()
320 len += mbx->pushed; in fm10k_mbx_validate_msg_size()
330 if ((len < total_len) && (msg_len <= mbx->max_size)) in fm10k_mbx_validate_msg_size()
346 struct fm10k_mbx_info *mbx) in fm10k_mbx_write_copy() argument
348 struct fm10k_mbx_fifo *fifo = &mbx->tx; in fm10k_mbx_write_copy()
349 u32 mbmem = mbx->mbmem_reg; in fm10k_mbx_write_copy()
353 if (!mbx->tail_len) in fm10k_mbx_write_copy()
357 mask = mbx->mbmem_len - 1; in fm10k_mbx_write_copy()
358 len = mbx->tail_len; in fm10k_mbx_write_copy()
359 tail = fm10k_mbx_tail_sub(mbx, len); in fm10k_mbx_write_copy()
364 end = fm10k_fifo_head_offset(fifo, mbx->pulled); in fm10k_mbx_write_copy()
396 struct fm10k_mbx_info *mbx, u16 head) in fm10k_mbx_pull_head() argument
398 u16 mbmem_len, len, ack = fm10k_mbx_index_len(mbx, head, mbx->tail); in fm10k_mbx_pull_head()
399 struct fm10k_mbx_fifo *fifo = &mbx->tx; in fm10k_mbx_pull_head()
402 mbx->pulled += mbx->tail_len - ack; in fm10k_mbx_pull_head()
405 mbmem_len = mbx->mbmem_len - 1; in fm10k_mbx_pull_head()
406 len = fm10k_fifo_used(fifo) - mbx->pulled; in fm10k_mbx_pull_head()
411 mbx->tail = fm10k_mbx_tail_add(mbx, len - ack); in fm10k_mbx_pull_head()
412 mbx->tail_len = len; in fm10k_mbx_pull_head()
416 len && (mbx->pulled >= len); in fm10k_mbx_pull_head()
418 mbx->pulled -= fm10k_fifo_head_drop(fifo); in fm10k_mbx_pull_head()
419 mbx->tx_messages++; in fm10k_mbx_pull_head()
420 mbx->tx_dwords += len; in fm10k_mbx_pull_head()
424 fm10k_mbx_write_copy(hw, mbx); in fm10k_mbx_pull_head()
437 struct fm10k_mbx_info *mbx) in fm10k_mbx_read_copy() argument
439 struct fm10k_mbx_fifo *fifo = &mbx->rx; in fm10k_mbx_read_copy()
440 u32 mbmem = mbx->mbmem_reg ^ mbx->mbmem_len; in fm10k_mbx_read_copy()
445 len = mbx->head_len; in fm10k_mbx_read_copy()
446 head = fm10k_mbx_head_sub(mbx, len); in fm10k_mbx_read_copy()
447 if (head >= mbx->mbmem_len) in fm10k_mbx_read_copy()
451 end = fm10k_fifo_tail_offset(fifo, mbx->pushed); in fm10k_mbx_read_copy()
458 head &= mbx->mbmem_len - 1; in fm10k_mbx_read_copy()
483 struct fm10k_mbx_info *mbx, in fm10k_mbx_push_tail() argument
486 struct fm10k_mbx_fifo *fifo = &mbx->rx; in fm10k_mbx_push_tail()
487 u16 len, seq = fm10k_mbx_index_len(mbx, mbx->head, tail); in fm10k_mbx_push_tail()
490 len = fm10k_fifo_unused(fifo) - mbx->pushed; in fm10k_mbx_push_tail()
495 mbx->head = fm10k_mbx_head_add(mbx, len); in fm10k_mbx_push_tail()
496 mbx->head_len = len; in fm10k_mbx_push_tail()
503 fm10k_mbx_read_copy(hw, mbx); in fm10k_mbx_push_tail()
506 if (fm10k_mbx_validate_msg_size(mbx, len)) in fm10k_mbx_push_tail()
510 mbx->pushed += len; in fm10k_mbx_push_tail()
513 for (len = fm10k_mbx_pushed_tail_len(mbx); in fm10k_mbx_push_tail()
514 len && (mbx->pushed >= len); in fm10k_mbx_push_tail()
515 len = fm10k_mbx_pushed_tail_len(mbx)) { in fm10k_mbx_push_tail()
517 mbx->pushed -= len; in fm10k_mbx_push_tail()
518 mbx->rx_messages++; in fm10k_mbx_push_tail()
519 mbx->rx_dwords += len; in fm10k_mbx_push_tail()
628 static void fm10k_mbx_update_local_crc(struct fm10k_mbx_info *mbx, u16 head) in fm10k_mbx_update_local_crc() argument
630 u16 len = mbx->tail_len - fm10k_mbx_index_len(mbx, head, mbx->tail); in fm10k_mbx_update_local_crc()
633 head = fm10k_fifo_head_offset(&mbx->tx, mbx->pulled); in fm10k_mbx_update_local_crc()
636 mbx->local = fm10k_fifo_crc(&mbx->tx, head, len, mbx->local); in fm10k_mbx_update_local_crc()
649 static s32 fm10k_mbx_verify_remote_crc(struct fm10k_mbx_info *mbx) in fm10k_mbx_verify_remote_crc() argument
651 struct fm10k_mbx_fifo *fifo = &mbx->rx; in fm10k_mbx_verify_remote_crc()
652 u16 len = mbx->head_len; in fm10k_mbx_verify_remote_crc()
653 u16 offset = fm10k_fifo_tail_offset(fifo, mbx->pushed) - len; in fm10k_mbx_verify_remote_crc()
658 mbx->remote = fm10k_fifo_crc(fifo, offset, len, mbx->remote); in fm10k_mbx_verify_remote_crc()
661 crc = fm10k_crc_16b(&mbx->mbx_hdr, mbx->remote, 1); in fm10k_mbx_verify_remote_crc()
673 static bool fm10k_mbx_rx_ready(struct fm10k_mbx_info *mbx) in fm10k_mbx_rx_ready() argument
675 u16 msg_size = fm10k_fifo_head_len(&mbx->rx); in fm10k_mbx_rx_ready()
677 return msg_size && (fm10k_fifo_used(&mbx->rx) >= msg_size); in fm10k_mbx_rx_ready()
687 static bool fm10k_mbx_tx_ready(struct fm10k_mbx_info *mbx, u16 len) in fm10k_mbx_tx_ready() argument
689 u16 fifo_unused = fm10k_fifo_unused(&mbx->tx); in fm10k_mbx_tx_ready()
691 return (mbx->state == FM10K_STATE_OPEN) && (fifo_unused >= len); in fm10k_mbx_tx_ready()
700 static bool fm10k_mbx_tx_complete(struct fm10k_mbx_info *mbx) in fm10k_mbx_tx_complete() argument
702 return fm10k_fifo_empty(&mbx->tx); in fm10k_mbx_tx_complete()
714 struct fm10k_mbx_info *mbx) in fm10k_mbx_dequeue_rx() argument
716 struct fm10k_mbx_fifo *fifo = &mbx->rx; in fm10k_mbx_dequeue_rx()
723 mbx, mbx->msg_data); in fm10k_mbx_dequeue_rx()
725 mbx->rx_parse_err++; in fm10k_mbx_dequeue_rx()
731 memmove(fifo->buffer, fifo->buffer + fifo->tail, mbx->pushed << 2); in fm10k_mbx_dequeue_rx()
751 struct fm10k_mbx_info *mbx, const u32 *msg) in fm10k_mbx_enqueue_tx() argument
753 u32 countdown = mbx->timeout; in fm10k_mbx_enqueue_tx()
756 switch (mbx->state) { in fm10k_mbx_enqueue_tx()
765 err = fm10k_fifo_enqueue(&mbx->tx, msg); in fm10k_mbx_enqueue_tx()
770 udelay(mbx->udelay); in fm10k_mbx_enqueue_tx()
771 mbx->ops.process(hw, mbx); in fm10k_mbx_enqueue_tx()
772 err = fm10k_fifo_enqueue(&mbx->tx, msg); in fm10k_mbx_enqueue_tx()
777 mbx->timeout = 0; in fm10k_mbx_enqueue_tx()
778 mbx->tx_busy++; in fm10k_mbx_enqueue_tx()
785 if (!mbx->tail_len) in fm10k_mbx_enqueue_tx()
786 mbx->ops.process(hw, mbx); in fm10k_mbx_enqueue_tx()
798 static s32 fm10k_mbx_read(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) in fm10k_mbx_read() argument
801 if (mbx->mbx_hdr) in fm10k_mbx_read()
805 if (fm10k_read_reg(hw, mbx->mbx_reg) & FM10K_MBX_REQ_INTERRUPT) in fm10k_mbx_read()
806 mbx->mbx_lock = FM10K_MBX_ACK; in fm10k_mbx_read()
809 fm10k_write_reg(hw, mbx->mbx_reg, in fm10k_mbx_read()
813 mbx->mbx_hdr = fm10k_read_reg(hw, mbx->mbmem_reg ^ mbx->mbmem_len); in fm10k_mbx_read()
825 static void fm10k_mbx_write(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) in fm10k_mbx_write() argument
827 u32 mbmem = mbx->mbmem_reg; in fm10k_mbx_write()
830 fm10k_write_reg(hw, mbmem, mbx->mbx_hdr); in fm10k_mbx_write()
833 if (mbx->mbx_lock) in fm10k_mbx_write()
834 fm10k_write_reg(hw, mbx->mbx_reg, mbx->mbx_lock); in fm10k_mbx_write()
837 mbx->mbx_hdr = 0; in fm10k_mbx_write()
838 mbx->mbx_lock = 0; in fm10k_mbx_write()
847 static void fm10k_mbx_create_connect_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_create_connect_hdr() argument
849 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_mbx_create_connect_hdr()
851 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_CONNECT, TYPE) | in fm10k_mbx_create_connect_hdr()
852 FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD) | in fm10k_mbx_create_connect_hdr()
853 FM10K_MSG_HDR_FIELD_SET(mbx->rx.size - 1, CONNECT_SIZE); in fm10k_mbx_create_connect_hdr()
862 static void fm10k_mbx_create_data_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_create_data_hdr() argument
865 FM10K_MSG_HDR_FIELD_SET(mbx->tail, TAIL) | in fm10k_mbx_create_data_hdr()
866 FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD); in fm10k_mbx_create_data_hdr()
867 struct fm10k_mbx_fifo *fifo = &mbx->tx; in fm10k_mbx_create_data_hdr()
870 if (mbx->tail_len) in fm10k_mbx_create_data_hdr()
871 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_mbx_create_data_hdr()
874 crc = fm10k_fifo_crc(fifo, fm10k_fifo_head_offset(fifo, mbx->pulled), in fm10k_mbx_create_data_hdr()
875 mbx->tail_len, mbx->local); in fm10k_mbx_create_data_hdr()
879 mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC); in fm10k_mbx_create_data_hdr()
888 static void fm10k_mbx_create_disconnect_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_create_disconnect_hdr() argument
891 FM10K_MSG_HDR_FIELD_SET(mbx->tail, TAIL) | in fm10k_mbx_create_disconnect_hdr()
892 FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD); in fm10k_mbx_create_disconnect_hdr()
893 u16 crc = fm10k_crc_16b(&hdr, mbx->local, 1); in fm10k_mbx_create_disconnect_hdr()
895 mbx->mbx_lock |= FM10K_MBX_ACK; in fm10k_mbx_create_disconnect_hdr()
898 mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC); in fm10k_mbx_create_disconnect_hdr()
909 static void fm10k_mbx_create_fake_disconnect_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_create_fake_disconnect_hdr() argument
912 FM10K_MSG_HDR_FIELD_SET(mbx->head, TAIL) | in fm10k_mbx_create_fake_disconnect_hdr()
913 FM10K_MSG_HDR_FIELD_SET(mbx->tail, HEAD); in fm10k_mbx_create_fake_disconnect_hdr()
914 u16 crc = fm10k_crc_16b(&hdr, mbx->local, 1); in fm10k_mbx_create_fake_disconnect_hdr()
916 mbx->mbx_lock |= FM10K_MBX_ACK; in fm10k_mbx_create_fake_disconnect_hdr()
919 mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC); in fm10k_mbx_create_fake_disconnect_hdr()
931 static void fm10k_mbx_create_error_msg(struct fm10k_mbx_info *mbx, s32 err) in fm10k_mbx_create_error_msg() argument
946 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_mbx_create_error_msg()
948 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_ERROR, TYPE) | in fm10k_mbx_create_error_msg()
950 FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD); in fm10k_mbx_create_error_msg()
962 static s32 fm10k_mbx_validate_msg_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_validate_msg_hdr() argument
965 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_validate_msg_hdr()
979 if (tail != mbx->head) in fm10k_mbx_validate_msg_hdr()
987 if (fm10k_mbx_index_len(mbx, head, mbx->tail) > mbx->tail_len) in fm10k_mbx_validate_msg_hdr()
993 if (fm10k_mbx_index_len(mbx, mbx->head, tail) < mbx->mbmem_len) in fm10k_mbx_validate_msg_hdr()
1029 struct fm10k_mbx_info *mbx, u16 head) in fm10k_mbx_create_reply() argument
1031 switch (mbx->state) { in fm10k_mbx_create_reply()
1035 fm10k_mbx_update_local_crc(mbx, head); in fm10k_mbx_create_reply()
1038 fm10k_mbx_pull_head(hw, mbx, head); in fm10k_mbx_create_reply()
1041 if (mbx->tail_len || (mbx->state == FM10K_STATE_OPEN)) in fm10k_mbx_create_reply()
1042 fm10k_mbx_create_data_hdr(mbx); in fm10k_mbx_create_reply()
1044 fm10k_mbx_create_disconnect_hdr(mbx); in fm10k_mbx_create_reply()
1048 fm10k_mbx_create_connect_hdr(mbx); in fm10k_mbx_create_reply()
1052 fm10k_mbx_create_disconnect_hdr(mbx); in fm10k_mbx_create_reply()
1068 static void fm10k_mbx_reset_work(struct fm10k_mbx_info *mbx) in fm10k_mbx_reset_work() argument
1073 mbx->max_size = mbx->rx.size - 1; in fm10k_mbx_reset_work()
1076 head = FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, HEAD); in fm10k_mbx_reset_work()
1077 ack = fm10k_mbx_index_len(mbx, head, mbx->tail); in fm10k_mbx_reset_work()
1078 mbx->pulled += mbx->tail_len - ack; in fm10k_mbx_reset_work()
1081 while (fm10k_fifo_head_len(&mbx->tx) && mbx->pulled) { in fm10k_mbx_reset_work()
1082 len = fm10k_fifo_head_drop(&mbx->tx); in fm10k_mbx_reset_work()
1083 mbx->tx_dropped++; in fm10k_mbx_reset_work()
1084 if (mbx->pulled >= len) in fm10k_mbx_reset_work()
1085 mbx->pulled -= len; in fm10k_mbx_reset_work()
1087 mbx->pulled = 0; in fm10k_mbx_reset_work()
1091 mbx->pushed = 0; in fm10k_mbx_reset_work()
1092 mbx->pulled = 0; in fm10k_mbx_reset_work()
1093 mbx->tail_len = 0; in fm10k_mbx_reset_work()
1094 mbx->head_len = 0; in fm10k_mbx_reset_work()
1095 mbx->rx.tail = 0; in fm10k_mbx_reset_work()
1096 mbx->rx.head = 0; in fm10k_mbx_reset_work()
1110 static void fm10k_mbx_update_max_size(struct fm10k_mbx_info *mbx, u16 size) in fm10k_mbx_update_max_size() argument
1114 mbx->max_size = size; in fm10k_mbx_update_max_size()
1117 for (len = fm10k_fifo_head_len(&mbx->tx); in fm10k_mbx_update_max_size()
1119 len = fm10k_fifo_head_len(&mbx->tx)) { in fm10k_mbx_update_max_size()
1120 fm10k_fifo_head_drop(&mbx->tx); in fm10k_mbx_update_max_size()
1121 mbx->tx_dropped++; in fm10k_mbx_update_max_size()
1132 static void fm10k_mbx_connect_reset(struct fm10k_mbx_info *mbx) in fm10k_mbx_connect_reset() argument
1135 fm10k_mbx_reset_work(mbx); in fm10k_mbx_connect_reset()
1138 mbx->local = FM10K_MBX_CRC_SEED; in fm10k_mbx_connect_reset()
1139 mbx->remote = FM10K_MBX_CRC_SEED; in fm10k_mbx_connect_reset()
1142 if (mbx->state == FM10K_STATE_OPEN) in fm10k_mbx_connect_reset()
1143 mbx->state = FM10K_STATE_CONNECT; in fm10k_mbx_connect_reset()
1145 mbx->state = FM10K_STATE_CLOSED; in fm10k_mbx_connect_reset()
1158 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_connect() argument
1160 const enum fm10k_mbx_state state = mbx->state; in fm10k_mbx_process_connect()
1161 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_connect()
1172 fm10k_mbx_connect_reset(mbx); in fm10k_mbx_process_connect()
1176 if (size > mbx->rx.size) { in fm10k_mbx_process_connect()
1177 mbx->max_size = mbx->rx.size - 1; in fm10k_mbx_process_connect()
1180 mbx->state = FM10K_STATE_OPEN; in fm10k_mbx_process_connect()
1182 fm10k_mbx_update_max_size(mbx, size); in fm10k_mbx_process_connect()
1190 mbx->tail = head; in fm10k_mbx_process_connect()
1192 return fm10k_mbx_create_reply(hw, mbx, head); in fm10k_mbx_process_connect()
1204 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_data() argument
1206 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_data()
1215 if (mbx->state == FM10K_STATE_CONNECT) { in fm10k_mbx_process_data()
1216 mbx->tail = head; in fm10k_mbx_process_data()
1217 mbx->state = FM10K_STATE_OPEN; in fm10k_mbx_process_data()
1221 err = fm10k_mbx_push_tail(hw, mbx, tail); in fm10k_mbx_process_data()
1226 err = fm10k_mbx_verify_remote_crc(mbx); in fm10k_mbx_process_data()
1231 fm10k_mbx_dequeue_rx(hw, mbx); in fm10k_mbx_process_data()
1233 return fm10k_mbx_create_reply(hw, mbx, head); in fm10k_mbx_process_data()
1245 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_disconnect() argument
1247 const enum fm10k_mbx_state state = mbx->state; in fm10k_mbx_process_disconnect()
1248 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_disconnect()
1256 if (mbx->pushed) in fm10k_mbx_process_disconnect()
1260 mbx->head_len = 0; in fm10k_mbx_process_disconnect()
1263 err = fm10k_mbx_verify_remote_crc(mbx); in fm10k_mbx_process_disconnect()
1271 if (!fm10k_mbx_tx_complete(mbx)) in fm10k_mbx_process_disconnect()
1275 if (head != mbx->tail) in fm10k_mbx_process_disconnect()
1279 fm10k_mbx_connect_reset(mbx); in fm10k_mbx_process_disconnect()
1285 return fm10k_mbx_create_reply(hw, mbx, head); in fm10k_mbx_process_disconnect()
1297 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_error() argument
1299 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_error()
1305 switch (mbx->state) { in fm10k_mbx_process_error()
1309 fm10k_mbx_reset_work(mbx); in fm10k_mbx_process_error()
1312 mbx->local = FM10K_MBX_CRC_SEED; in fm10k_mbx_process_error()
1313 mbx->remote = FM10K_MBX_CRC_SEED; in fm10k_mbx_process_error()
1316 mbx->tail = head; in fm10k_mbx_process_error()
1319 if (mbx->state == FM10K_STATE_OPEN) { in fm10k_mbx_process_error()
1320 mbx->state = FM10K_STATE_CONNECT; in fm10k_mbx_process_error()
1325 fm10k_mbx_create_connect_hdr(mbx); in fm10k_mbx_process_error()
1331 return fm10k_mbx_create_reply(hw, mbx, mbx->tail); in fm10k_mbx_process_error()
1344 struct fm10k_mbx_info *mbx) in fm10k_mbx_process() argument
1349 if (mbx->state == FM10K_STATE_CLOSED) in fm10k_mbx_process()
1353 err = fm10k_mbx_read(hw, mbx); in fm10k_mbx_process()
1358 err = fm10k_mbx_validate_msg_hdr(mbx); in fm10k_mbx_process()
1362 switch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, TYPE)) { in fm10k_mbx_process()
1364 err = fm10k_mbx_process_connect(hw, mbx); in fm10k_mbx_process()
1367 err = fm10k_mbx_process_data(hw, mbx); in fm10k_mbx_process()
1370 err = fm10k_mbx_process_disconnect(hw, mbx); in fm10k_mbx_process()
1373 err = fm10k_mbx_process_error(hw, mbx); in fm10k_mbx_process()
1383 fm10k_mbx_create_error_msg(mbx, err); in fm10k_mbx_process()
1386 fm10k_mbx_write(hw, mbx); in fm10k_mbx_process()
1405 struct fm10k_mbx_info *mbx) in fm10k_mbx_disconnect() argument
1407 int timeout = mbx->timeout ? FM10K_MBX_DISCONNECT_TIMEOUT : 0; in fm10k_mbx_disconnect()
1410 mbx->state = FM10K_STATE_DISCONNECT; in fm10k_mbx_disconnect()
1413 fm10k_write_reg(hw, mbx->mbx_reg, FM10K_MBX_REQ | in fm10k_mbx_disconnect()
1417 mbx->ops.process(hw, mbx); in fm10k_mbx_disconnect()
1419 } while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED)); in fm10k_mbx_disconnect()
1424 fm10k_mbx_connect_reset(mbx); in fm10k_mbx_disconnect()
1425 fm10k_fifo_drop_all(&mbx->tx); in fm10k_mbx_disconnect()
1427 fm10k_write_reg(hw, mbx->mbmem_reg, 0); in fm10k_mbx_disconnect()
1443 static s32 fm10k_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) in fm10k_mbx_connect() argument
1446 if (!mbx->rx.buffer) in fm10k_mbx_connect()
1450 if (mbx->state != FM10K_STATE_CLOSED) in fm10k_mbx_connect()
1454 mbx->timeout = FM10K_MBX_INIT_TIMEOUT; in fm10k_mbx_connect()
1457 mbx->state = FM10K_STATE_CONNECT; in fm10k_mbx_connect()
1459 fm10k_mbx_reset_work(mbx); in fm10k_mbx_connect()
1462 fm10k_mbx_create_fake_disconnect_hdr(mbx); in fm10k_mbx_connect()
1463 fm10k_write_reg(hw, mbx->mbmem_reg ^ mbx->mbmem_len, mbx->mbx_hdr); in fm10k_mbx_connect()
1466 mbx->mbx_lock = FM10K_MBX_REQ_INTERRUPT | FM10K_MBX_ACK_INTERRUPT | in fm10k_mbx_connect()
1470 fm10k_mbx_create_connect_hdr(mbx); in fm10k_mbx_connect()
1471 fm10k_mbx_write(hw, mbx); in fm10k_mbx_connect()
1538 static s32 fm10k_mbx_register_handlers(struct fm10k_mbx_info *mbx, in fm10k_mbx_register_handlers() argument
1546 mbx->msg_data = msg_data; in fm10k_mbx_register_handlers()
1565 s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx, in fm10k_pfvf_mbx_init() argument
1571 mbx->mbx_reg = FM10K_VFMBX; in fm10k_pfvf_mbx_init()
1572 mbx->mbmem_reg = FM10K_VFMBMEM(FM10K_VFMBMEM_VF_XOR); in fm10k_pfvf_mbx_init()
1577 mbx->mbx_reg = FM10K_MBX(id); in fm10k_pfvf_mbx_init()
1578 mbx->mbmem_reg = FM10K_MBMEM_VF(id, 0); in fm10k_pfvf_mbx_init()
1587 mbx->state = FM10K_STATE_CLOSED; in fm10k_pfvf_mbx_init()
1594 mbx->msg_data = msg_data; in fm10k_pfvf_mbx_init()
1599 mbx->timeout = 0; in fm10k_pfvf_mbx_init()
1600 mbx->udelay = FM10K_MBX_INIT_DELAY; in fm10k_pfvf_mbx_init()
1603 mbx->tail = 1; in fm10k_pfvf_mbx_init()
1604 mbx->head = 1; in fm10k_pfvf_mbx_init()
1607 mbx->local = FM10K_MBX_CRC_SEED; in fm10k_pfvf_mbx_init()
1608 mbx->remote = FM10K_MBX_CRC_SEED; in fm10k_pfvf_mbx_init()
1611 mbx->max_size = FM10K_MBX_MSG_MAX_SIZE; in fm10k_pfvf_mbx_init()
1612 mbx->mbmem_len = FM10K_VFMBMEM_VF_XOR; in fm10k_pfvf_mbx_init()
1615 fm10k_fifo_init(&mbx->tx, mbx->buffer, FM10K_MBX_TX_BUFFER_SIZE); in fm10k_pfvf_mbx_init()
1616 fm10k_fifo_init(&mbx->rx, &mbx->buffer[FM10K_MBX_TX_BUFFER_SIZE], in fm10k_pfvf_mbx_init()
1620 mbx->ops.connect = fm10k_mbx_connect; in fm10k_pfvf_mbx_init()
1621 mbx->ops.disconnect = fm10k_mbx_disconnect; in fm10k_pfvf_mbx_init()
1622 mbx->ops.rx_ready = fm10k_mbx_rx_ready; in fm10k_pfvf_mbx_init()
1623 mbx->ops.tx_ready = fm10k_mbx_tx_ready; in fm10k_pfvf_mbx_init()
1624 mbx->ops.tx_complete = fm10k_mbx_tx_complete; in fm10k_pfvf_mbx_init()
1625 mbx->ops.enqueue_tx = fm10k_mbx_enqueue_tx; in fm10k_pfvf_mbx_init()
1626 mbx->ops.process = fm10k_mbx_process; in fm10k_pfvf_mbx_init()
1627 mbx->ops.register_handlers = fm10k_mbx_register_handlers; in fm10k_pfvf_mbx_init()
1638 static void fm10k_sm_mbx_create_data_hdr(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_create_data_hdr() argument
1640 if (mbx->tail_len) in fm10k_sm_mbx_create_data_hdr()
1641 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_sm_mbx_create_data_hdr()
1643 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(mbx->tail, SM_TAIL) | in fm10k_sm_mbx_create_data_hdr()
1644 FM10K_MSG_HDR_FIELD_SET(mbx->remote, SM_VER) | in fm10k_sm_mbx_create_data_hdr()
1645 FM10K_MSG_HDR_FIELD_SET(mbx->head, SM_HEAD); in fm10k_sm_mbx_create_data_hdr()
1655 static void fm10k_sm_mbx_create_connect_hdr(struct fm10k_mbx_info *mbx, u8 err) in fm10k_sm_mbx_create_connect_hdr() argument
1657 if (mbx->local) in fm10k_sm_mbx_create_connect_hdr()
1658 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_sm_mbx_create_connect_hdr()
1660 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(mbx->tail, SM_TAIL) | in fm10k_sm_mbx_create_connect_hdr()
1661 FM10K_MSG_HDR_FIELD_SET(mbx->remote, SM_VER) | in fm10k_sm_mbx_create_connect_hdr()
1662 FM10K_MSG_HDR_FIELD_SET(mbx->head, SM_HEAD) | in fm10k_sm_mbx_create_connect_hdr()
1672 static void fm10k_sm_mbx_connect_reset(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_connect_reset() argument
1675 fm10k_mbx_reset_work(mbx); in fm10k_sm_mbx_connect_reset()
1678 mbx->local = FM10K_SM_MBX_VERSION; in fm10k_sm_mbx_connect_reset()
1679 mbx->remote = 0; in fm10k_sm_mbx_connect_reset()
1682 mbx->tail = 1; in fm10k_sm_mbx_connect_reset()
1683 mbx->head = 1; in fm10k_sm_mbx_connect_reset()
1686 mbx->state = FM10K_STATE_CONNECT; in fm10k_sm_mbx_connect_reset()
1701 static s32 fm10k_sm_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_connect() argument
1704 if (!mbx->rx.buffer) in fm10k_sm_mbx_connect()
1708 if (mbx->state != FM10K_STATE_CLOSED) in fm10k_sm_mbx_connect()
1712 mbx->timeout = FM10K_MBX_INIT_TIMEOUT; in fm10k_sm_mbx_connect()
1715 mbx->state = FM10K_STATE_CONNECT; in fm10k_sm_mbx_connect()
1716 mbx->max_size = FM10K_MBX_MSG_MAX_SIZE; in fm10k_sm_mbx_connect()
1719 fm10k_sm_mbx_connect_reset(mbx); in fm10k_sm_mbx_connect()
1722 mbx->mbx_lock = FM10K_MBX_REQ_INTERRUPT | FM10K_MBX_ACK_INTERRUPT | in fm10k_sm_mbx_connect()
1726 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_connect()
1727 fm10k_mbx_write(hw, mbx); in fm10k_sm_mbx_connect()
1748 struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_disconnect() argument
1750 int timeout = mbx->timeout ? FM10K_MBX_DISCONNECT_TIMEOUT : 0; in fm10k_sm_mbx_disconnect()
1753 mbx->state = FM10K_STATE_DISCONNECT; in fm10k_sm_mbx_disconnect()
1756 fm10k_write_reg(hw, mbx->mbx_reg, FM10K_MBX_REQ | in fm10k_sm_mbx_disconnect()
1760 mbx->ops.process(hw, mbx); in fm10k_sm_mbx_disconnect()
1762 } while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED)); in fm10k_sm_mbx_disconnect()
1765 mbx->state = FM10K_STATE_CLOSED; in fm10k_sm_mbx_disconnect()
1766 mbx->remote = 0; in fm10k_sm_mbx_disconnect()
1767 fm10k_mbx_reset_work(mbx); in fm10k_sm_mbx_disconnect()
1768 fm10k_fifo_drop_all(&mbx->tx); in fm10k_sm_mbx_disconnect()
1770 fm10k_write_reg(hw, mbx->mbmem_reg, 0); in fm10k_sm_mbx_disconnect()
1781 static s32 fm10k_sm_mbx_validate_fifo_hdr(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_validate_fifo_hdr() argument
1783 const u32 *hdr = &mbx->mbx_hdr; in fm10k_sm_mbx_validate_fifo_hdr()
1798 if (mbx->tail < head) in fm10k_sm_mbx_validate_fifo_hdr()
1799 head += mbx->mbmem_len - 1; in fm10k_sm_mbx_validate_fifo_hdr()
1800 if (tail < mbx->head) in fm10k_sm_mbx_validate_fifo_hdr()
1801 tail += mbx->mbmem_len - 1; in fm10k_sm_mbx_validate_fifo_hdr()
1802 if (fm10k_mbx_index_len(mbx, head, mbx->tail) > mbx->tail_len) in fm10k_sm_mbx_validate_fifo_hdr()
1804 if (fm10k_mbx_index_len(mbx, mbx->head, tail) < mbx->mbmem_len) in fm10k_sm_mbx_validate_fifo_hdr()
1823 static void fm10k_sm_mbx_process_error(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_process_error() argument
1825 const enum fm10k_mbx_state state = mbx->state; in fm10k_sm_mbx_process_error()
1830 mbx->remote = 0; in fm10k_sm_mbx_process_error()
1834 fm10k_sm_mbx_connect_reset(mbx); in fm10k_sm_mbx_process_error()
1838 if (mbx->remote) { in fm10k_sm_mbx_process_error()
1839 while (mbx->local > 1) in fm10k_sm_mbx_process_error()
1840 mbx->local--; in fm10k_sm_mbx_process_error()
1841 mbx->remote = 0; in fm10k_sm_mbx_process_error()
1848 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_process_error()
1859 static void fm10k_sm_mbx_create_error_msg(struct fm10k_mbx_info *mbx, s32 err) in fm10k_sm_mbx_create_error_msg() argument
1874 fm10k_sm_mbx_process_error(mbx); in fm10k_sm_mbx_create_error_msg()
1875 fm10k_sm_mbx_create_connect_hdr(mbx, 1); in fm10k_sm_mbx_create_error_msg()
1887 struct fm10k_mbx_info *mbx, in fm10k_sm_mbx_receive() argument
1891 u16 mbmem_len = mbx->mbmem_len - 1; in fm10k_sm_mbx_receive()
1895 if (tail < mbx->head) in fm10k_sm_mbx_receive()
1899 err = fm10k_mbx_push_tail(hw, mbx, tail); in fm10k_sm_mbx_receive()
1904 fm10k_mbx_dequeue_rx(hw, mbx); in fm10k_sm_mbx_receive()
1907 mbx->head = fm10k_mbx_head_sub(mbx, mbx->pushed); in fm10k_sm_mbx_receive()
1908 mbx->pushed = 0; in fm10k_sm_mbx_receive()
1911 if (mbx->head > mbmem_len) in fm10k_sm_mbx_receive()
1912 mbx->head -= mbmem_len; in fm10k_sm_mbx_receive()
1926 struct fm10k_mbx_info *mbx, u16 head) in fm10k_sm_mbx_transmit() argument
1928 struct fm10k_mbx_fifo *fifo = &mbx->tx; in fm10k_sm_mbx_transmit()
1930 u16 mbmem_len = mbx->mbmem_len - 1; in fm10k_sm_mbx_transmit()
1935 if (mbx->tail < head) in fm10k_sm_mbx_transmit()
1938 fm10k_mbx_pull_head(hw, mbx, head); in fm10k_sm_mbx_transmit()
1945 } while ((len <= mbx->tail_len) && (len < mbmem_len)); in fm10k_sm_mbx_transmit()
1948 if (mbx->tail_len > tail_len) { in fm10k_sm_mbx_transmit()
1949 mbx->tail = fm10k_mbx_tail_sub(mbx, mbx->tail_len - tail_len); in fm10k_sm_mbx_transmit()
1950 mbx->tail_len = tail_len; in fm10k_sm_mbx_transmit()
1954 if (mbx->tail > mbmem_len) in fm10k_sm_mbx_transmit()
1955 mbx->tail -= mbmem_len; in fm10k_sm_mbx_transmit()
1969 struct fm10k_mbx_info *mbx, u16 head) in fm10k_sm_mbx_create_reply() argument
1971 switch (mbx->state) { in fm10k_sm_mbx_create_reply()
1975 fm10k_sm_mbx_transmit(hw, mbx, head); in fm10k_sm_mbx_create_reply()
1978 if (mbx->tail_len || (mbx->state == FM10K_STATE_OPEN)) { in fm10k_sm_mbx_create_reply()
1979 fm10k_sm_mbx_create_data_hdr(mbx); in fm10k_sm_mbx_create_reply()
1981 mbx->remote = 0; in fm10k_sm_mbx_create_reply()
1982 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_create_reply()
1987 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_create_reply()
2006 struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_process_reset() argument
2008 const enum fm10k_mbx_state state = mbx->state; in fm10k_sm_mbx_process_reset()
2013 mbx->state = FM10K_STATE_CLOSED; in fm10k_sm_mbx_process_reset()
2014 mbx->remote = 0; in fm10k_sm_mbx_process_reset()
2015 mbx->local = 0; in fm10k_sm_mbx_process_reset()
2019 fm10k_sm_mbx_connect_reset(mbx); in fm10k_sm_mbx_process_reset()
2023 mbx->remote = mbx->local; in fm10k_sm_mbx_process_reset()
2028 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 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()
2134 s32 fm10k_sm_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx, in fm10k_sm_mbx_init() argument
2137 mbx->mbx_reg = FM10K_GMBX; in fm10k_sm_mbx_init()
2138 mbx->mbmem_reg = FM10K_MBMEM_PF(0); in fm10k_sm_mbx_init()
2140 mbx->state = FM10K_STATE_CLOSED; in fm10k_sm_mbx_init()
2147 mbx->msg_data = msg_data; in fm10k_sm_mbx_init()
2152 mbx->timeout = 0; in fm10k_sm_mbx_init()
2153 mbx->udelay = FM10K_MBX_INIT_DELAY; in fm10k_sm_mbx_init()
2156 mbx->max_size = FM10K_MBX_MSG_MAX_SIZE; in fm10k_sm_mbx_init()
2157 mbx->mbmem_len = FM10K_MBMEM_PF_XOR; in fm10k_sm_mbx_init()
2160 fm10k_fifo_init(&mbx->tx, mbx->buffer, FM10K_MBX_TX_BUFFER_SIZE); in fm10k_sm_mbx_init()
2161 fm10k_fifo_init(&mbx->rx, &mbx->buffer[FM10K_MBX_TX_BUFFER_SIZE], in fm10k_sm_mbx_init()
2165 mbx->ops.connect = fm10k_sm_mbx_connect; in fm10k_sm_mbx_init()
2166 mbx->ops.disconnect = fm10k_sm_mbx_disconnect; in fm10k_sm_mbx_init()
2167 mbx->ops.rx_ready = fm10k_mbx_rx_ready; in fm10k_sm_mbx_init()
2168 mbx->ops.tx_ready = fm10k_mbx_tx_ready; in fm10k_sm_mbx_init()
2169 mbx->ops.tx_complete = fm10k_mbx_tx_complete; in fm10k_sm_mbx_init()
2170 mbx->ops.enqueue_tx = fm10k_mbx_enqueue_tx; in fm10k_sm_mbx_init()
2171 mbx->ops.process = fm10k_sm_mbx_process; in fm10k_sm_mbx_init()
2172 mbx->ops.register_handlers = fm10k_mbx_register_handlers; in fm10k_sm_mbx_init()