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()
910 static void fm10k_mbx_create_error_msg(struct fm10k_mbx_info *mbx, s32 err) in fm10k_mbx_create_error_msg() argument
925 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_mbx_create_error_msg()
927 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_ERROR, TYPE) | in fm10k_mbx_create_error_msg()
929 FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD); in fm10k_mbx_create_error_msg()
941 static s32 fm10k_mbx_validate_msg_hdr(struct fm10k_mbx_info *mbx) in fm10k_mbx_validate_msg_hdr() argument
944 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_validate_msg_hdr()
958 if (tail != mbx->head) in fm10k_mbx_validate_msg_hdr()
966 if (fm10k_mbx_index_len(mbx, head, mbx->tail) > mbx->tail_len) in fm10k_mbx_validate_msg_hdr()
972 if (fm10k_mbx_index_len(mbx, mbx->head, tail) < mbx->mbmem_len) in fm10k_mbx_validate_msg_hdr()
1008 struct fm10k_mbx_info *mbx, u16 head) in fm10k_mbx_create_reply() argument
1010 switch (mbx->state) { in fm10k_mbx_create_reply()
1014 fm10k_mbx_update_local_crc(mbx, head); in fm10k_mbx_create_reply()
1017 fm10k_mbx_pull_head(hw, mbx, head); in fm10k_mbx_create_reply()
1020 if (mbx->tail_len || (mbx->state == FM10K_STATE_OPEN)) in fm10k_mbx_create_reply()
1021 fm10k_mbx_create_data_hdr(mbx); in fm10k_mbx_create_reply()
1023 fm10k_mbx_create_disconnect_hdr(mbx); in fm10k_mbx_create_reply()
1027 fm10k_mbx_create_connect_hdr(mbx); in fm10k_mbx_create_reply()
1031 fm10k_mbx_create_disconnect_hdr(mbx); in fm10k_mbx_create_reply()
1047 static void fm10k_mbx_reset_work(struct fm10k_mbx_info *mbx) in fm10k_mbx_reset_work() argument
1050 mbx->max_size = mbx->rx.size - 1; in fm10k_mbx_reset_work()
1053 mbx->pushed = 0; in fm10k_mbx_reset_work()
1054 mbx->pulled = 0; in fm10k_mbx_reset_work()
1055 mbx->tail_len = 0; in fm10k_mbx_reset_work()
1056 mbx->head_len = 0; in fm10k_mbx_reset_work()
1057 mbx->rx.tail = 0; in fm10k_mbx_reset_work()
1058 mbx->rx.head = 0; in fm10k_mbx_reset_work()
1072 static void fm10k_mbx_update_max_size(struct fm10k_mbx_info *mbx, u16 size) in fm10k_mbx_update_max_size() argument
1076 mbx->max_size = size; in fm10k_mbx_update_max_size()
1079 for (len = fm10k_fifo_head_len(&mbx->tx); in fm10k_mbx_update_max_size()
1081 len = fm10k_fifo_head_len(&mbx->tx)) { in fm10k_mbx_update_max_size()
1082 fm10k_fifo_head_drop(&mbx->tx); in fm10k_mbx_update_max_size()
1083 mbx->tx_dropped++; in fm10k_mbx_update_max_size()
1094 static void fm10k_mbx_connect_reset(struct fm10k_mbx_info *mbx) in fm10k_mbx_connect_reset() argument
1097 fm10k_mbx_reset_work(mbx); in fm10k_mbx_connect_reset()
1100 mbx->local = FM10K_MBX_CRC_SEED; in fm10k_mbx_connect_reset()
1101 mbx->remote = FM10K_MBX_CRC_SEED; in fm10k_mbx_connect_reset()
1104 if (mbx->state == FM10K_STATE_OPEN) in fm10k_mbx_connect_reset()
1105 mbx->state = FM10K_STATE_CONNECT; in fm10k_mbx_connect_reset()
1107 mbx->state = FM10K_STATE_CLOSED; in fm10k_mbx_connect_reset()
1120 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_connect() argument
1122 const enum fm10k_mbx_state state = mbx->state; in fm10k_mbx_process_connect()
1123 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_connect()
1134 fm10k_mbx_connect_reset(mbx); in fm10k_mbx_process_connect()
1138 if (size > mbx->rx.size) { in fm10k_mbx_process_connect()
1139 mbx->max_size = mbx->rx.size - 1; in fm10k_mbx_process_connect()
1142 mbx->state = FM10K_STATE_OPEN; in fm10k_mbx_process_connect()
1144 fm10k_mbx_update_max_size(mbx, size); in fm10k_mbx_process_connect()
1152 mbx->tail = head; in fm10k_mbx_process_connect()
1154 return fm10k_mbx_create_reply(hw, mbx, head); in fm10k_mbx_process_connect()
1166 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_data() argument
1168 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_data()
1177 if (mbx->state == FM10K_STATE_CONNECT) { in fm10k_mbx_process_data()
1178 mbx->tail = head; in fm10k_mbx_process_data()
1179 mbx->state = FM10K_STATE_OPEN; in fm10k_mbx_process_data()
1183 err = fm10k_mbx_push_tail(hw, mbx, tail); in fm10k_mbx_process_data()
1188 err = fm10k_mbx_verify_remote_crc(mbx); in fm10k_mbx_process_data()
1193 fm10k_mbx_dequeue_rx(hw, mbx); in fm10k_mbx_process_data()
1195 return fm10k_mbx_create_reply(hw, mbx, head); in fm10k_mbx_process_data()
1207 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_disconnect() argument
1209 const enum fm10k_mbx_state state = mbx->state; in fm10k_mbx_process_disconnect()
1210 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_disconnect()
1218 if (mbx->pushed) in fm10k_mbx_process_disconnect()
1222 mbx->head_len = 0; in fm10k_mbx_process_disconnect()
1225 err = fm10k_mbx_verify_remote_crc(mbx); in fm10k_mbx_process_disconnect()
1233 if (!fm10k_mbx_tx_complete(mbx)) in fm10k_mbx_process_disconnect()
1237 if (head != mbx->tail) in fm10k_mbx_process_disconnect()
1241 fm10k_mbx_connect_reset(mbx); in fm10k_mbx_process_disconnect()
1247 return fm10k_mbx_create_reply(hw, mbx, head); in fm10k_mbx_process_disconnect()
1259 struct fm10k_mbx_info *mbx) in fm10k_mbx_process_error() argument
1261 const u32 *hdr = &mbx->mbx_hdr; in fm10k_mbx_process_error()
1272 switch (mbx->state) { in fm10k_mbx_process_error()
1276 fm10k_mbx_reset_work(mbx); in fm10k_mbx_process_error()
1279 mbx->local = FM10K_MBX_CRC_SEED; in fm10k_mbx_process_error()
1280 mbx->remote = FM10K_MBX_CRC_SEED; in fm10k_mbx_process_error()
1283 mbx->tail = head; in fm10k_mbx_process_error()
1286 if (mbx->state == FM10K_STATE_OPEN) { in fm10k_mbx_process_error()
1287 mbx->state = FM10K_STATE_CONNECT; in fm10k_mbx_process_error()
1292 fm10k_mbx_create_connect_hdr(mbx); in fm10k_mbx_process_error()
1298 return fm10k_mbx_create_reply(hw, mbx, mbx->tail); in fm10k_mbx_process_error()
1311 struct fm10k_mbx_info *mbx) in fm10k_mbx_process() argument
1316 if (mbx->state == FM10K_STATE_CLOSED) in fm10k_mbx_process()
1320 err = fm10k_mbx_read(hw, mbx); in fm10k_mbx_process()
1325 err = fm10k_mbx_validate_msg_hdr(mbx); in fm10k_mbx_process()
1329 switch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, TYPE)) { in fm10k_mbx_process()
1331 err = fm10k_mbx_process_connect(hw, mbx); in fm10k_mbx_process()
1334 err = fm10k_mbx_process_data(hw, mbx); in fm10k_mbx_process()
1337 err = fm10k_mbx_process_disconnect(hw, mbx); in fm10k_mbx_process()
1340 err = fm10k_mbx_process_error(hw, mbx); in fm10k_mbx_process()
1350 fm10k_mbx_create_error_msg(mbx, err); in fm10k_mbx_process()
1353 fm10k_mbx_write(hw, mbx); in fm10k_mbx_process()
1372 struct fm10k_mbx_info *mbx) in fm10k_mbx_disconnect() argument
1374 int timeout = mbx->timeout ? FM10K_MBX_DISCONNECT_TIMEOUT : 0; in fm10k_mbx_disconnect()
1377 mbx->state = FM10K_STATE_DISCONNECT; in fm10k_mbx_disconnect()
1380 fm10k_write_reg(hw, mbx->mbx_reg, FM10K_MBX_REQ | in fm10k_mbx_disconnect()
1384 mbx->ops.process(hw, mbx); in fm10k_mbx_disconnect()
1386 } while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED)); in fm10k_mbx_disconnect()
1391 fm10k_mbx_connect_reset(mbx); in fm10k_mbx_disconnect()
1392 fm10k_fifo_drop_all(&mbx->tx); in fm10k_mbx_disconnect()
1394 fm10k_write_reg(hw, mbx->mbmem_reg, 0); in fm10k_mbx_disconnect()
1410 static s32 fm10k_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) in fm10k_mbx_connect() argument
1413 if (!mbx->rx.buffer) in fm10k_mbx_connect()
1417 if (mbx->state != FM10K_STATE_CLOSED) in fm10k_mbx_connect()
1421 mbx->timeout = FM10K_MBX_INIT_TIMEOUT; in fm10k_mbx_connect()
1424 mbx->state = FM10K_STATE_CONNECT; in fm10k_mbx_connect()
1427 fm10k_mbx_create_disconnect_hdr(mbx); in fm10k_mbx_connect()
1428 fm10k_write_reg(hw, mbx->mbmem_reg ^ mbx->mbmem_len, mbx->mbx_hdr); in fm10k_mbx_connect()
1431 mbx->mbx_lock = FM10K_MBX_REQ_INTERRUPT | FM10K_MBX_ACK_INTERRUPT | in fm10k_mbx_connect()
1435 fm10k_mbx_create_connect_hdr(mbx); in fm10k_mbx_connect()
1436 fm10k_mbx_write(hw, mbx); in fm10k_mbx_connect()
1503 static s32 fm10k_mbx_register_handlers(struct fm10k_mbx_info *mbx, in fm10k_mbx_register_handlers() argument
1511 mbx->msg_data = msg_data; in fm10k_mbx_register_handlers()
1530 s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx, in fm10k_pfvf_mbx_init() argument
1536 mbx->mbx_reg = FM10K_VFMBX; in fm10k_pfvf_mbx_init()
1537 mbx->mbmem_reg = FM10K_VFMBMEM(FM10K_VFMBMEM_VF_XOR); in fm10k_pfvf_mbx_init()
1542 mbx->mbx_reg = FM10K_MBX(id); in fm10k_pfvf_mbx_init()
1543 mbx->mbmem_reg = FM10K_MBMEM_VF(id, 0); in fm10k_pfvf_mbx_init()
1552 mbx->state = FM10K_STATE_CLOSED; in fm10k_pfvf_mbx_init()
1559 mbx->msg_data = msg_data; in fm10k_pfvf_mbx_init()
1564 mbx->timeout = 0; in fm10k_pfvf_mbx_init()
1565 mbx->udelay = FM10K_MBX_INIT_DELAY; in fm10k_pfvf_mbx_init()
1568 mbx->tail = 1; in fm10k_pfvf_mbx_init()
1569 mbx->head = 1; in fm10k_pfvf_mbx_init()
1572 mbx->local = FM10K_MBX_CRC_SEED; in fm10k_pfvf_mbx_init()
1573 mbx->remote = FM10K_MBX_CRC_SEED; in fm10k_pfvf_mbx_init()
1576 mbx->max_size = FM10K_MBX_MSG_MAX_SIZE; in fm10k_pfvf_mbx_init()
1577 mbx->mbmem_len = FM10K_VFMBMEM_VF_XOR; in fm10k_pfvf_mbx_init()
1580 fm10k_fifo_init(&mbx->tx, mbx->buffer, FM10K_MBX_TX_BUFFER_SIZE); in fm10k_pfvf_mbx_init()
1581 fm10k_fifo_init(&mbx->rx, &mbx->buffer[FM10K_MBX_TX_BUFFER_SIZE], in fm10k_pfvf_mbx_init()
1585 mbx->ops.connect = fm10k_mbx_connect; in fm10k_pfvf_mbx_init()
1586 mbx->ops.disconnect = fm10k_mbx_disconnect; in fm10k_pfvf_mbx_init()
1587 mbx->ops.rx_ready = fm10k_mbx_rx_ready; in fm10k_pfvf_mbx_init()
1588 mbx->ops.tx_ready = fm10k_mbx_tx_ready; in fm10k_pfvf_mbx_init()
1589 mbx->ops.tx_complete = fm10k_mbx_tx_complete; in fm10k_pfvf_mbx_init()
1590 mbx->ops.enqueue_tx = fm10k_mbx_enqueue_tx; in fm10k_pfvf_mbx_init()
1591 mbx->ops.process = fm10k_mbx_process; in fm10k_pfvf_mbx_init()
1592 mbx->ops.register_handlers = fm10k_mbx_register_handlers; in fm10k_pfvf_mbx_init()
1603 static void fm10k_sm_mbx_create_data_hdr(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_create_data_hdr() argument
1605 if (mbx->tail_len) in fm10k_sm_mbx_create_data_hdr()
1606 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_sm_mbx_create_data_hdr()
1608 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(mbx->tail, SM_TAIL) | in fm10k_sm_mbx_create_data_hdr()
1609 FM10K_MSG_HDR_FIELD_SET(mbx->remote, SM_VER) | in fm10k_sm_mbx_create_data_hdr()
1610 FM10K_MSG_HDR_FIELD_SET(mbx->head, SM_HEAD); in fm10k_sm_mbx_create_data_hdr()
1620 static void fm10k_sm_mbx_create_connect_hdr(struct fm10k_mbx_info *mbx, u8 err) in fm10k_sm_mbx_create_connect_hdr() argument
1622 if (mbx->local) in fm10k_sm_mbx_create_connect_hdr()
1623 mbx->mbx_lock |= FM10K_MBX_REQ; in fm10k_sm_mbx_create_connect_hdr()
1625 mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(mbx->tail, SM_TAIL) | in fm10k_sm_mbx_create_connect_hdr()
1626 FM10K_MSG_HDR_FIELD_SET(mbx->remote, SM_VER) | in fm10k_sm_mbx_create_connect_hdr()
1627 FM10K_MSG_HDR_FIELD_SET(mbx->head, SM_HEAD) | in fm10k_sm_mbx_create_connect_hdr()
1637 static void fm10k_sm_mbx_connect_reset(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_connect_reset() argument
1640 fm10k_mbx_reset_work(mbx); in fm10k_sm_mbx_connect_reset()
1643 mbx->local = FM10K_SM_MBX_VERSION; in fm10k_sm_mbx_connect_reset()
1644 mbx->remote = 0; in fm10k_sm_mbx_connect_reset()
1647 mbx->tail = 1; in fm10k_sm_mbx_connect_reset()
1648 mbx->head = 1; in fm10k_sm_mbx_connect_reset()
1651 mbx->state = FM10K_STATE_CONNECT; in fm10k_sm_mbx_connect_reset()
1666 static s32 fm10k_sm_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_connect() argument
1669 if (!mbx->rx.buffer) in fm10k_sm_mbx_connect()
1673 if (mbx->state != FM10K_STATE_CLOSED) in fm10k_sm_mbx_connect()
1677 mbx->timeout = FM10K_MBX_INIT_TIMEOUT; in fm10k_sm_mbx_connect()
1680 mbx->state = FM10K_STATE_CONNECT; in fm10k_sm_mbx_connect()
1681 mbx->max_size = FM10K_MBX_MSG_MAX_SIZE; in fm10k_sm_mbx_connect()
1684 fm10k_sm_mbx_connect_reset(mbx); in fm10k_sm_mbx_connect()
1687 mbx->mbx_lock = FM10K_MBX_REQ_INTERRUPT | FM10K_MBX_ACK_INTERRUPT | in fm10k_sm_mbx_connect()
1691 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_connect()
1692 fm10k_mbx_write(hw, mbx); in fm10k_sm_mbx_connect()
1713 struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_disconnect() argument
1715 int timeout = mbx->timeout ? FM10K_MBX_DISCONNECT_TIMEOUT : 0; in fm10k_sm_mbx_disconnect()
1718 mbx->state = FM10K_STATE_DISCONNECT; in fm10k_sm_mbx_disconnect()
1721 fm10k_write_reg(hw, mbx->mbx_reg, FM10K_MBX_REQ | in fm10k_sm_mbx_disconnect()
1725 mbx->ops.process(hw, mbx); in fm10k_sm_mbx_disconnect()
1727 } while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED)); in fm10k_sm_mbx_disconnect()
1730 mbx->state = FM10K_STATE_CLOSED; in fm10k_sm_mbx_disconnect()
1731 mbx->remote = 0; in fm10k_sm_mbx_disconnect()
1732 fm10k_mbx_reset_work(mbx); in fm10k_sm_mbx_disconnect()
1733 fm10k_mbx_update_max_size(mbx, 0); in fm10k_sm_mbx_disconnect()
1735 fm10k_write_reg(hw, mbx->mbmem_reg, 0); in fm10k_sm_mbx_disconnect()
1746 static s32 fm10k_sm_mbx_validate_fifo_hdr(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_validate_fifo_hdr() argument
1748 const u32 *hdr = &mbx->mbx_hdr; in fm10k_sm_mbx_validate_fifo_hdr()
1763 if (mbx->tail < head) in fm10k_sm_mbx_validate_fifo_hdr()
1764 head += mbx->mbmem_len - 1; in fm10k_sm_mbx_validate_fifo_hdr()
1765 if (tail < mbx->head) in fm10k_sm_mbx_validate_fifo_hdr()
1766 tail += mbx->mbmem_len - 1; in fm10k_sm_mbx_validate_fifo_hdr()
1767 if (fm10k_mbx_index_len(mbx, head, mbx->tail) > mbx->tail_len) in fm10k_sm_mbx_validate_fifo_hdr()
1769 if (fm10k_mbx_index_len(mbx, mbx->head, tail) < mbx->mbmem_len) in fm10k_sm_mbx_validate_fifo_hdr()
1788 static void fm10k_sm_mbx_process_error(struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_process_error() argument
1790 const enum fm10k_mbx_state state = mbx->state; in fm10k_sm_mbx_process_error()
1795 mbx->remote = 0; in fm10k_sm_mbx_process_error()
1799 fm10k_sm_mbx_connect_reset(mbx); in fm10k_sm_mbx_process_error()
1803 if (mbx->remote) { in fm10k_sm_mbx_process_error()
1804 while (mbx->local > 1) in fm10k_sm_mbx_process_error()
1805 mbx->local--; in fm10k_sm_mbx_process_error()
1806 mbx->remote = 0; in fm10k_sm_mbx_process_error()
1813 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_process_error()
1824 static void fm10k_sm_mbx_create_error_msg(struct fm10k_mbx_info *mbx, s32 err) in fm10k_sm_mbx_create_error_msg() argument
1839 fm10k_sm_mbx_process_error(mbx); in fm10k_sm_mbx_create_error_msg()
1840 fm10k_sm_mbx_create_connect_hdr(mbx, 1); in fm10k_sm_mbx_create_error_msg()
1852 struct fm10k_mbx_info *mbx, in fm10k_sm_mbx_receive() argument
1856 u16 mbmem_len = mbx->mbmem_len - 1; in fm10k_sm_mbx_receive()
1860 if (tail < mbx->head) in fm10k_sm_mbx_receive()
1864 err = fm10k_mbx_push_tail(hw, mbx, tail); in fm10k_sm_mbx_receive()
1869 fm10k_mbx_dequeue_rx(hw, mbx); in fm10k_sm_mbx_receive()
1872 mbx->head = fm10k_mbx_head_sub(mbx, mbx->pushed); in fm10k_sm_mbx_receive()
1873 mbx->pushed = 0; in fm10k_sm_mbx_receive()
1876 if (mbx->head > mbmem_len) in fm10k_sm_mbx_receive()
1877 mbx->head -= mbmem_len; in fm10k_sm_mbx_receive()
1891 struct fm10k_mbx_info *mbx, u16 head) in fm10k_sm_mbx_transmit() argument
1893 struct fm10k_mbx_fifo *fifo = &mbx->tx; in fm10k_sm_mbx_transmit()
1895 u16 mbmem_len = mbx->mbmem_len - 1; in fm10k_sm_mbx_transmit()
1900 if (mbx->tail < head) in fm10k_sm_mbx_transmit()
1903 fm10k_mbx_pull_head(hw, mbx, head); in fm10k_sm_mbx_transmit()
1910 } while ((len <= mbx->tail_len) && (len < mbmem_len)); in fm10k_sm_mbx_transmit()
1913 if (mbx->tail_len > tail_len) { in fm10k_sm_mbx_transmit()
1914 mbx->tail = fm10k_mbx_tail_sub(mbx, mbx->tail_len - tail_len); in fm10k_sm_mbx_transmit()
1915 mbx->tail_len = tail_len; in fm10k_sm_mbx_transmit()
1919 if (mbx->tail > mbmem_len) in fm10k_sm_mbx_transmit()
1920 mbx->tail -= mbmem_len; in fm10k_sm_mbx_transmit()
1934 struct fm10k_mbx_info *mbx, u16 head) in fm10k_sm_mbx_create_reply() argument
1936 switch (mbx->state) { in fm10k_sm_mbx_create_reply()
1940 fm10k_sm_mbx_transmit(hw, mbx, head); in fm10k_sm_mbx_create_reply()
1943 if (mbx->tail_len || (mbx->state == FM10K_STATE_OPEN)) { in fm10k_sm_mbx_create_reply()
1944 fm10k_sm_mbx_create_data_hdr(mbx); in fm10k_sm_mbx_create_reply()
1946 mbx->remote = 0; in fm10k_sm_mbx_create_reply()
1947 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_create_reply()
1952 fm10k_sm_mbx_create_connect_hdr(mbx, 0); in fm10k_sm_mbx_create_reply()
1971 struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_process_reset() argument
1973 const enum fm10k_mbx_state state = mbx->state; in fm10k_sm_mbx_process_reset()
1978 mbx->state = FM10K_STATE_CLOSED; in fm10k_sm_mbx_process_reset()
1979 mbx->remote = 0; in fm10k_sm_mbx_process_reset()
1980 mbx->local = 0; in fm10k_sm_mbx_process_reset()
1984 fm10k_sm_mbx_connect_reset(mbx); in fm10k_sm_mbx_process_reset()
1988 mbx->remote = mbx->local; in fm10k_sm_mbx_process_reset()
1993 fm10k_sm_mbx_create_reply(hw, mbx, mbx->tail); in fm10k_sm_mbx_process_reset()
2005 struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_process_version_1() argument
2007 const u32 *hdr = &mbx->mbx_hdr; in fm10k_sm_mbx_process_version_1()
2016 if (mbx->state == FM10K_STATE_CONNECT) { in fm10k_sm_mbx_process_version_1()
2017 if (!mbx->remote) in fm10k_sm_mbx_process_version_1()
2019 if (mbx->remote != 1) in fm10k_sm_mbx_process_version_1()
2022 mbx->state = FM10K_STATE_OPEN; in fm10k_sm_mbx_process_version_1()
2027 len = fm10k_sm_mbx_receive(hw, mbx, tail); in fm10k_sm_mbx_process_version_1()
2035 fm10k_sm_mbx_create_reply(hw, mbx, head); in fm10k_sm_mbx_process_version_1()
2050 struct fm10k_mbx_info *mbx) in fm10k_sm_mbx_process() argument
2055 if (mbx->state == FM10K_STATE_CLOSED) in fm10k_sm_mbx_process()
2059 err = fm10k_mbx_read(hw, mbx); in fm10k_sm_mbx_process()
2063 err = fm10k_sm_mbx_validate_fifo_hdr(mbx); in fm10k_sm_mbx_process()
2067 if (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, SM_ERR)) { in fm10k_sm_mbx_process()
2068 fm10k_sm_mbx_process_error(mbx); in fm10k_sm_mbx_process()
2072 switch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, SM_VER)) { in fm10k_sm_mbx_process()
2074 fm10k_sm_mbx_process_reset(hw, mbx); in fm10k_sm_mbx_process()
2077 err = fm10k_sm_mbx_process_version_1(hw, mbx); in fm10k_sm_mbx_process()
2083 fm10k_sm_mbx_create_error_msg(mbx, err); in fm10k_sm_mbx_process()
2086 fm10k_mbx_write(hw, mbx); in fm10k_sm_mbx_process()
2099 s32 fm10k_sm_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx, in fm10k_sm_mbx_init() argument
2102 mbx->mbx_reg = FM10K_GMBX; in fm10k_sm_mbx_init()
2103 mbx->mbmem_reg = FM10K_MBMEM_PF(0); in fm10k_sm_mbx_init()
2105 mbx->state = FM10K_STATE_CLOSED; in fm10k_sm_mbx_init()
2112 mbx->msg_data = msg_data; in fm10k_sm_mbx_init()
2117 mbx->timeout = 0; in fm10k_sm_mbx_init()
2118 mbx->udelay = FM10K_MBX_INIT_DELAY; in fm10k_sm_mbx_init()
2121 mbx->max_size = FM10K_MBX_MSG_MAX_SIZE; in fm10k_sm_mbx_init()
2122 mbx->mbmem_len = FM10K_MBMEM_PF_XOR; in fm10k_sm_mbx_init()
2125 fm10k_fifo_init(&mbx->tx, mbx->buffer, FM10K_MBX_TX_BUFFER_SIZE); in fm10k_sm_mbx_init()
2126 fm10k_fifo_init(&mbx->rx, &mbx->buffer[FM10K_MBX_TX_BUFFER_SIZE], in fm10k_sm_mbx_init()
2130 mbx->ops.connect = fm10k_sm_mbx_connect; in fm10k_sm_mbx_init()
2131 mbx->ops.disconnect = fm10k_sm_mbx_disconnect; in fm10k_sm_mbx_init()
2132 mbx->ops.rx_ready = fm10k_mbx_rx_ready; in fm10k_sm_mbx_init()
2133 mbx->ops.tx_ready = fm10k_mbx_tx_ready; in fm10k_sm_mbx_init()
2134 mbx->ops.tx_complete = fm10k_mbx_tx_complete; in fm10k_sm_mbx_init()
2135 mbx->ops.enqueue_tx = fm10k_mbx_enqueue_tx; in fm10k_sm_mbx_init()
2136 mbx->ops.process = fm10k_sm_mbx_process; in fm10k_sm_mbx_init()
2137 mbx->ops.register_handlers = fm10k_mbx_register_handlers; in fm10k_sm_mbx_init()