diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2014-09-20 19:51:27 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-09-23 06:59:20 -0400 |
commit | b651957c202cabc8d5abfc5ad1ddc2607daf6a4f (patch) | |
tree | a7c1fcf82835fcb4a69961dbce82de31470ffb3f /drivers/net | |
parent | 5cd5e2e98205df377d93fb8dd15c6f3ed4bfa1d6 (diff) |
fm10k: Add support for PF <-> VF mailbox
This patch adds support for the PF <-> VF mailbox. It functions similar to
the PF <-> SM mailbox however there are several modifications made to
improve the reliability of the mailbox itself. In addition the PF/VF
mailbox is much smaller an only supports a total size of 16 DWORDs vs the
1024 DWORDS provided for the PF/SM mailbox.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_mbx.c | 770 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_mbx.h | 64 |
2 files changed, 834 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c index 2609847bbdea..a6a66fd9e2c2 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c | |||
@@ -511,6 +511,148 @@ static s32 fm10k_mbx_push_tail(struct fm10k_hw *hw, | |||
511 | return 0; | 511 | return 0; |
512 | } | 512 | } |
513 | 513 | ||
514 | /* pre-generated data for generating the CRC based on the poly 0xAC9A. */ | ||
515 | static const u16 fm10k_crc_16b_table[256] = { | ||
516 | 0x0000, 0x7956, 0xF2AC, 0x8BFA, 0xBC6D, 0xC53B, 0x4EC1, 0x3797, | ||
517 | 0x21EF, 0x58B9, 0xD343, 0xAA15, 0x9D82, 0xE4D4, 0x6F2E, 0x1678, | ||
518 | 0x43DE, 0x3A88, 0xB172, 0xC824, 0xFFB3, 0x86E5, 0x0D1F, 0x7449, | ||
519 | 0x6231, 0x1B67, 0x909D, 0xE9CB, 0xDE5C, 0xA70A, 0x2CF0, 0x55A6, | ||
520 | 0x87BC, 0xFEEA, 0x7510, 0x0C46, 0x3BD1, 0x4287, 0xC97D, 0xB02B, | ||
521 | 0xA653, 0xDF05, 0x54FF, 0x2DA9, 0x1A3E, 0x6368, 0xE892, 0x91C4, | ||
522 | 0xC462, 0xBD34, 0x36CE, 0x4F98, 0x780F, 0x0159, 0x8AA3, 0xF3F5, | ||
523 | 0xE58D, 0x9CDB, 0x1721, 0x6E77, 0x59E0, 0x20B6, 0xAB4C, 0xD21A, | ||
524 | 0x564D, 0x2F1B, 0xA4E1, 0xDDB7, 0xEA20, 0x9376, 0x188C, 0x61DA, | ||
525 | 0x77A2, 0x0EF4, 0x850E, 0xFC58, 0xCBCF, 0xB299, 0x3963, 0x4035, | ||
526 | 0x1593, 0x6CC5, 0xE73F, 0x9E69, 0xA9FE, 0xD0A8, 0x5B52, 0x2204, | ||
527 | 0x347C, 0x4D2A, 0xC6D0, 0xBF86, 0x8811, 0xF147, 0x7ABD, 0x03EB, | ||
528 | 0xD1F1, 0xA8A7, 0x235D, 0x5A0B, 0x6D9C, 0x14CA, 0x9F30, 0xE666, | ||
529 | 0xF01E, 0x8948, 0x02B2, 0x7BE4, 0x4C73, 0x3525, 0xBEDF, 0xC789, | ||
530 | 0x922F, 0xEB79, 0x6083, 0x19D5, 0x2E42, 0x5714, 0xDCEE, 0xA5B8, | ||
531 | 0xB3C0, 0xCA96, 0x416C, 0x383A, 0x0FAD, 0x76FB, 0xFD01, 0x8457, | ||
532 | 0xAC9A, 0xD5CC, 0x5E36, 0x2760, 0x10F7, 0x69A1, 0xE25B, 0x9B0D, | ||
533 | 0x8D75, 0xF423, 0x7FD9, 0x068F, 0x3118, 0x484E, 0xC3B4, 0xBAE2, | ||
534 | 0xEF44, 0x9612, 0x1DE8, 0x64BE, 0x5329, 0x2A7F, 0xA185, 0xD8D3, | ||
535 | 0xCEAB, 0xB7FD, 0x3C07, 0x4551, 0x72C6, 0x0B90, 0x806A, 0xF93C, | ||
536 | 0x2B26, 0x5270, 0xD98A, 0xA0DC, 0x974B, 0xEE1D, 0x65E7, 0x1CB1, | ||
537 | 0x0AC9, 0x739F, 0xF865, 0x8133, 0xB6A4, 0xCFF2, 0x4408, 0x3D5E, | ||
538 | 0x68F8, 0x11AE, 0x9A54, 0xE302, 0xD495, 0xADC3, 0x2639, 0x5F6F, | ||
539 | 0x4917, 0x3041, 0xBBBB, 0xC2ED, 0xF57A, 0x8C2C, 0x07D6, 0x7E80, | ||
540 | 0xFAD7, 0x8381, 0x087B, 0x712D, 0x46BA, 0x3FEC, 0xB416, 0xCD40, | ||
541 | 0xDB38, 0xA26E, 0x2994, 0x50C2, 0x6755, 0x1E03, 0x95F9, 0xECAF, | ||
542 | 0xB909, 0xC05F, 0x4BA5, 0x32F3, 0x0564, 0x7C32, 0xF7C8, 0x8E9E, | ||
543 | 0x98E6, 0xE1B0, 0x6A4A, 0x131C, 0x248B, 0x5DDD, 0xD627, 0xAF71, | ||
544 | 0x7D6B, 0x043D, 0x8FC7, 0xF691, 0xC106, 0xB850, 0x33AA, 0x4AFC, | ||
545 | 0x5C84, 0x25D2, 0xAE28, 0xD77E, 0xE0E9, 0x99BF, 0x1245, 0x6B13, | ||
546 | 0x3EB5, 0x47E3, 0xCC19, 0xB54F, 0x82D8, 0xFB8E, 0x7074, 0x0922, | ||
547 | 0x1F5A, 0x660C, 0xEDF6, 0x94A0, 0xA337, 0xDA61, 0x519B, 0x28CD }; | ||
548 | |||
549 | /** | ||
550 | * fm10k_crc_16b - Generate a 16 bit CRC for a region of 16 bit data | ||
551 | * @data: pointer to data to process | ||
552 | * @seed: seed value for CRC | ||
553 | * @len: length measured in 16 bits words | ||
554 | * | ||
555 | * This function will generate a CRC based on the polynomial 0xAC9A and | ||
556 | * whatever value is stored in the seed variable. Note that this | ||
557 | * value inverts the local seed and the result in order to capture all | ||
558 | * leading and trailing zeros. | ||
559 | */ | ||
560 | static u16 fm10k_crc_16b(const u32 *data, u16 seed, u16 len) | ||
561 | { | ||
562 | u32 result = seed; | ||
563 | |||
564 | while (len--) { | ||
565 | result ^= *(data++); | ||
566 | result = (result >> 8) ^ fm10k_crc_16b_table[result & 0xFF]; | ||
567 | result = (result >> 8) ^ fm10k_crc_16b_table[result & 0xFF]; | ||
568 | |||
569 | if (!(len--)) | ||
570 | break; | ||
571 | |||
572 | result = (result >> 8) ^ fm10k_crc_16b_table[result & 0xFF]; | ||
573 | result = (result >> 8) ^ fm10k_crc_16b_table[result & 0xFF]; | ||
574 | } | ||
575 | |||
576 | return (u16)result; | ||
577 | } | ||
578 | |||
579 | /** | ||
580 | * fm10k_fifo_crc - generate a CRC based off of FIFO data | ||
581 | * @fifo: pointer to FIFO | ||
582 | * @offset: offset point for start of FIFO | ||
583 | * @len: number of DWORDS words to process | ||
584 | * @seed: seed value for CRC | ||
585 | * | ||
586 | * This function generates a CRC for some region of the FIFO | ||
587 | **/ | ||
588 | static u16 fm10k_fifo_crc(struct fm10k_mbx_fifo *fifo, u16 offset, | ||
589 | u16 len, u16 seed) | ||
590 | { | ||
591 | u32 *data = fifo->buffer + offset; | ||
592 | |||
593 | /* track when we should cross the end of the FIFO */ | ||
594 | offset = fifo->size - offset; | ||
595 | |||
596 | /* if we are in 2 blocks process the end of the FIFO first */ | ||
597 | if (offset < len) { | ||
598 | seed = fm10k_crc_16b(data, seed, offset * 2); | ||
599 | data = fifo->buffer; | ||
600 | len -= offset; | ||
601 | } | ||
602 | |||
603 | /* process any remaining bits */ | ||
604 | return fm10k_crc_16b(data, seed, len * 2); | ||
605 | } | ||
606 | |||
607 | /** | ||
608 | * fm10k_mbx_update_local_crc - Update the local CRC for outgoing data | ||
609 | * @mbx: pointer to mailbox | ||
610 | * @head: head index provided by remote mailbox | ||
611 | * | ||
612 | * This function will generate the CRC for all data from the end of the | ||
613 | * last head update to the current one. It uses the result of the | ||
614 | * previous CRC as the seed for this update. The result is stored in | ||
615 | * mbx->local. | ||
616 | **/ | ||
617 | static void fm10k_mbx_update_local_crc(struct fm10k_mbx_info *mbx, u16 head) | ||
618 | { | ||
619 | u16 len = mbx->tail_len - fm10k_mbx_index_len(mbx, head, mbx->tail); | ||
620 | |||
621 | /* determine the offset for the start of the region to be pulled */ | ||
622 | head = fm10k_fifo_head_offset(&mbx->tx, mbx->pulled); | ||
623 | |||
624 | /* update local CRC to include all of the pulled data */ | ||
625 | mbx->local = fm10k_fifo_crc(&mbx->tx, head, len, mbx->local); | ||
626 | } | ||
627 | |||
628 | /** | ||
629 | * fm10k_mbx_verify_remote_crc - Verify the CRC is correct for current data | ||
630 | * @mbx: pointer to mailbox | ||
631 | * | ||
632 | * This function will take all data that has been provided from the remote | ||
633 | * end and generate a CRC for it. This is stored in mbx->remote. The | ||
634 | * CRC for the header is then computed and if the result is non-zero this | ||
635 | * is an error and we signal an error dropping all data and resetting the | ||
636 | * connection. | ||
637 | */ | ||
638 | static s32 fm10k_mbx_verify_remote_crc(struct fm10k_mbx_info *mbx) | ||
639 | { | ||
640 | struct fm10k_mbx_fifo *fifo = &mbx->rx; | ||
641 | u16 len = mbx->head_len; | ||
642 | u16 offset = fm10k_fifo_tail_offset(fifo, mbx->pushed) - len; | ||
643 | u16 crc; | ||
644 | |||
645 | /* update the remote CRC if new data has been received */ | ||
646 | if (len) | ||
647 | mbx->remote = fm10k_fifo_crc(fifo, offset, len, mbx->remote); | ||
648 | |||
649 | /* process the full header as we have to validate the CRC */ | ||
650 | crc = fm10k_crc_16b(&mbx->mbx_hdr, mbx->remote, 1); | ||
651 | |||
652 | /* notify other end if we have a problem */ | ||
653 | return crc ? FM10K_MBX_ERR_CRC : 0; | ||
654 | } | ||
655 | |||
514 | /** | 656 | /** |
515 | * fm10k_mbx_rx_ready - Indicates that a message is ready in the Rx FIFO | 657 | * fm10k_mbx_rx_ready - Indicates that a message is ready in the Rx FIFO |
516 | * @mbx: pointer to mailbox | 658 | * @mbx: pointer to mailbox |
@@ -686,6 +828,204 @@ static void fm10k_mbx_write(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) | |||
686 | } | 828 | } |
687 | 829 | ||
688 | /** | 830 | /** |
831 | * fm10k_mbx_create_connect_hdr - Generate a connect mailbox header | ||
832 | * @mbx: pointer to mailbox | ||
833 | * | ||
834 | * This function returns a connection mailbox header | ||
835 | **/ | ||
836 | static void fm10k_mbx_create_connect_hdr(struct fm10k_mbx_info *mbx) | ||
837 | { | ||
838 | mbx->mbx_lock |= FM10K_MBX_REQ; | ||
839 | |||
840 | mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_CONNECT, TYPE) | | ||
841 | FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD) | | ||
842 | FM10K_MSG_HDR_FIELD_SET(mbx->rx.size - 1, CONNECT_SIZE); | ||
843 | } | ||
844 | |||
845 | /** | ||
846 | * fm10k_mbx_create_data_hdr - Generate a data mailbox header | ||
847 | * @mbx: pointer to mailbox | ||
848 | * | ||
849 | * This function returns a data mailbox header | ||
850 | **/ | ||
851 | static void fm10k_mbx_create_data_hdr(struct fm10k_mbx_info *mbx) | ||
852 | { | ||
853 | u32 hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_DATA, TYPE) | | ||
854 | FM10K_MSG_HDR_FIELD_SET(mbx->tail, TAIL) | | ||
855 | FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD); | ||
856 | struct fm10k_mbx_fifo *fifo = &mbx->tx; | ||
857 | u16 crc; | ||
858 | |||
859 | if (mbx->tail_len) | ||
860 | mbx->mbx_lock |= FM10K_MBX_REQ; | ||
861 | |||
862 | /* generate CRC for data in flight and header */ | ||
863 | crc = fm10k_fifo_crc(fifo, fm10k_fifo_head_offset(fifo, mbx->pulled), | ||
864 | mbx->tail_len, mbx->local); | ||
865 | crc = fm10k_crc_16b(&hdr, crc, 1); | ||
866 | |||
867 | /* load header to memory to be written */ | ||
868 | mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC); | ||
869 | } | ||
870 | |||
871 | /** | ||
872 | * fm10k_mbx_create_disconnect_hdr - Generate a disconnect mailbox header | ||
873 | * @mbx: pointer to mailbox | ||
874 | * | ||
875 | * This function returns a disconnect mailbox header | ||
876 | **/ | ||
877 | static void fm10k_mbx_create_disconnect_hdr(struct fm10k_mbx_info *mbx) | ||
878 | { | ||
879 | u32 hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_DISCONNECT, TYPE) | | ||
880 | FM10K_MSG_HDR_FIELD_SET(mbx->tail, TAIL) | | ||
881 | FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD); | ||
882 | u16 crc = fm10k_crc_16b(&hdr, mbx->local, 1); | ||
883 | |||
884 | mbx->mbx_lock |= FM10K_MBX_ACK; | ||
885 | |||
886 | /* load header to memory to be written */ | ||
887 | mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC); | ||
888 | } | ||
889 | |||
890 | /** | ||
891 | * fm10k_mbx_create_error_msg - Generate a error message | ||
892 | * @mbx: pointer to mailbox | ||
893 | * @err: local error encountered | ||
894 | * | ||
895 | * This function will interpret the error provided by err, and based on | ||
896 | * that it may shift the message by 1 DWORD and then place an error header | ||
897 | * at the start of the message. | ||
898 | **/ | ||
899 | static void fm10k_mbx_create_error_msg(struct fm10k_mbx_info *mbx, s32 err) | ||
900 | { | ||
901 | /* only generate an error message for these types */ | ||
902 | switch (err) { | ||
903 | case FM10K_MBX_ERR_TAIL: | ||
904 | case FM10K_MBX_ERR_HEAD: | ||
905 | case FM10K_MBX_ERR_TYPE: | ||
906 | case FM10K_MBX_ERR_SIZE: | ||
907 | case FM10K_MBX_ERR_RSVD0: | ||
908 | case FM10K_MBX_ERR_CRC: | ||
909 | break; | ||
910 | default: | ||
911 | return; | ||
912 | } | ||
913 | |||
914 | mbx->mbx_lock |= FM10K_MBX_REQ; | ||
915 | |||
916 | mbx->mbx_hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_ERROR, TYPE) | | ||
917 | FM10K_MSG_HDR_FIELD_SET(err, ERR_NO) | | ||
918 | FM10K_MSG_HDR_FIELD_SET(mbx->head, HEAD); | ||
919 | } | ||
920 | |||
921 | /** | ||
922 | * fm10k_mbx_validate_msg_hdr - Validate common fields in the message header | ||
923 | * @mbx: pointer to mailbox | ||
924 | * @msg: message array to read | ||
925 | * | ||
926 | * This function will parse up the fields in the mailbox header and return | ||
927 | * an error if the header contains any of a number of invalid configurations | ||
928 | * including unrecognized type, invalid route, or a malformed message. | ||
929 | **/ | ||
930 | static s32 fm10k_mbx_validate_msg_hdr(struct fm10k_mbx_info *mbx) | ||
931 | { | ||
932 | u16 type, rsvd0, head, tail, size; | ||
933 | const u32 *hdr = &mbx->mbx_hdr; | ||
934 | |||
935 | type = FM10K_MSG_HDR_FIELD_GET(*hdr, TYPE); | ||
936 | rsvd0 = FM10K_MSG_HDR_FIELD_GET(*hdr, RSVD0); | ||
937 | tail = FM10K_MSG_HDR_FIELD_GET(*hdr, TAIL); | ||
938 | head = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD); | ||
939 | size = FM10K_MSG_HDR_FIELD_GET(*hdr, CONNECT_SIZE); | ||
940 | |||
941 | if (rsvd0) | ||
942 | return FM10K_MBX_ERR_RSVD0; | ||
943 | |||
944 | switch (type) { | ||
945 | case FM10K_MSG_DISCONNECT: | ||
946 | /* validate that all data has been received */ | ||
947 | if (tail != mbx->head) | ||
948 | return FM10K_MBX_ERR_TAIL; | ||
949 | |||
950 | /* fall through */ | ||
951 | case FM10K_MSG_DATA: | ||
952 | /* validate that head is moving correctly */ | ||
953 | if (!head || (head == FM10K_MSG_HDR_MASK(HEAD))) | ||
954 | return FM10K_MBX_ERR_HEAD; | ||
955 | if (fm10k_mbx_index_len(mbx, head, mbx->tail) > mbx->tail_len) | ||
956 | return FM10K_MBX_ERR_HEAD; | ||
957 | |||
958 | /* validate that tail is moving correctly */ | ||
959 | if (!tail || (tail == FM10K_MSG_HDR_MASK(TAIL))) | ||
960 | return FM10K_MBX_ERR_TAIL; | ||
961 | if (fm10k_mbx_index_len(mbx, mbx->head, tail) < mbx->mbmem_len) | ||
962 | break; | ||
963 | |||
964 | return FM10K_MBX_ERR_TAIL; | ||
965 | case FM10K_MSG_CONNECT: | ||
966 | /* validate size is in range and is power of 2 mask */ | ||
967 | if ((size < FM10K_VFMBX_MSG_MTU) || (size & (size + 1))) | ||
968 | return FM10K_MBX_ERR_SIZE; | ||
969 | |||
970 | /* fall through */ | ||
971 | case FM10K_MSG_ERROR: | ||
972 | if (!head || (head == FM10K_MSG_HDR_MASK(HEAD))) | ||
973 | return FM10K_MBX_ERR_HEAD; | ||
974 | /* neither create nor error include a tail offset */ | ||
975 | if (tail) | ||
976 | return FM10K_MBX_ERR_TAIL; | ||
977 | |||
978 | break; | ||
979 | default: | ||
980 | return FM10K_MBX_ERR_TYPE; | ||
981 | } | ||
982 | |||
983 | return 0; | ||
984 | } | ||
985 | |||
986 | /** | ||
987 | * fm10k_mbx_create_reply - Generate reply based on state and remote head | ||
988 | * @mbx: pointer to mailbox | ||
989 | * @head: acknowledgement number | ||
990 | * | ||
991 | * This function will generate an outgoing message based on the current | ||
992 | * mailbox state and the remote fifo head. It will return the length | ||
993 | * of the outgoing message excluding header on success, and a negative value | ||
994 | * on error. | ||
995 | **/ | ||
996 | static s32 fm10k_mbx_create_reply(struct fm10k_hw *hw, | ||
997 | struct fm10k_mbx_info *mbx, u16 head) | ||
998 | { | ||
999 | switch (mbx->state) { | ||
1000 | case FM10K_STATE_OPEN: | ||
1001 | case FM10K_STATE_DISCONNECT: | ||
1002 | /* update our checksum for the outgoing data */ | ||
1003 | fm10k_mbx_update_local_crc(mbx, head); | ||
1004 | |||
1005 | /* as long as other end recognizes us keep sending data */ | ||
1006 | fm10k_mbx_pull_head(hw, mbx, head); | ||
1007 | |||
1008 | /* generate new header based on data */ | ||
1009 | if (mbx->tail_len || (mbx->state == FM10K_STATE_OPEN)) | ||
1010 | fm10k_mbx_create_data_hdr(mbx); | ||
1011 | else | ||
1012 | fm10k_mbx_create_disconnect_hdr(mbx); | ||
1013 | break; | ||
1014 | case FM10K_STATE_CONNECT: | ||
1015 | /* send disconnect even if we aren't connected */ | ||
1016 | fm10k_mbx_create_connect_hdr(mbx); | ||
1017 | break; | ||
1018 | case FM10K_STATE_CLOSED: | ||
1019 | /* generate new header based on data */ | ||
1020 | fm10k_mbx_create_disconnect_hdr(mbx); | ||
1021 | default: | ||
1022 | break; | ||
1023 | } | ||
1024 | |||
1025 | return 0; | ||
1026 | } | ||
1027 | |||
1028 | /** | ||
689 | * fm10k_mbx_reset_work- Reset internal pointers for any pending work | 1029 | * fm10k_mbx_reset_work- Reset internal pointers for any pending work |
690 | * @mbx: pointer to mailbox | 1030 | * @mbx: pointer to mailbox |
691 | * | 1031 | * |
@@ -731,6 +1071,359 @@ static void fm10k_mbx_update_max_size(struct fm10k_mbx_info *mbx, u16 size) | |||
731 | } | 1071 | } |
732 | 1072 | ||
733 | /** | 1073 | /** |
1074 | * fm10k_mbx_connect_reset - Reset following request for reset | ||
1075 | * @mbx: pointer to mailbox | ||
1076 | * | ||
1077 | * This function resets the mailbox to either a disconnected state | ||
1078 | * or a connect state depending on the current mailbox state | ||
1079 | **/ | ||
1080 | static void fm10k_mbx_connect_reset(struct fm10k_mbx_info *mbx) | ||
1081 | { | ||
1082 | /* just do a quick resysnc to start of frame */ | ||
1083 | fm10k_mbx_reset_work(mbx); | ||
1084 | |||
1085 | /* reset CRC seeds */ | ||
1086 | mbx->local = FM10K_MBX_CRC_SEED; | ||
1087 | mbx->remote = FM10K_MBX_CRC_SEED; | ||
1088 | |||
1089 | /* we cannot exit connect until the size is good */ | ||
1090 | if (mbx->state == FM10K_STATE_OPEN) | ||
1091 | mbx->state = FM10K_STATE_CONNECT; | ||
1092 | else | ||
1093 | mbx->state = FM10K_STATE_CLOSED; | ||
1094 | } | ||
1095 | |||
1096 | /** | ||
1097 | * fm10k_mbx_process_connect - Process connect header | ||
1098 | * @mbx: pointer to mailbox | ||
1099 | * @msg: message array to process | ||
1100 | * | ||
1101 | * This function will read an incoming connect header and reply with the | ||
1102 | * appropriate message. It will return a value indicating the number of | ||
1103 | * data DWORDs on success, or will return a negative value on failure. | ||
1104 | **/ | ||
1105 | static s32 fm10k_mbx_process_connect(struct fm10k_hw *hw, | ||
1106 | struct fm10k_mbx_info *mbx) | ||
1107 | { | ||
1108 | const enum fm10k_mbx_state state = mbx->state; | ||
1109 | const u32 *hdr = &mbx->mbx_hdr; | ||
1110 | u16 size, head; | ||
1111 | |||
1112 | /* we will need to pull all of the fields for verification */ | ||
1113 | size = FM10K_MSG_HDR_FIELD_GET(*hdr, CONNECT_SIZE); | ||
1114 | head = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD); | ||
1115 | |||
1116 | switch (state) { | ||
1117 | case FM10K_STATE_DISCONNECT: | ||
1118 | case FM10K_STATE_OPEN: | ||
1119 | /* reset any in-progress work */ | ||
1120 | fm10k_mbx_connect_reset(mbx); | ||
1121 | break; | ||
1122 | case FM10K_STATE_CONNECT: | ||
1123 | /* we cannot exit connect until the size is good */ | ||
1124 | if (size > mbx->rx.size) { | ||
1125 | mbx->max_size = mbx->rx.size - 1; | ||
1126 | } else { | ||
1127 | /* record the remote system requesting connection */ | ||
1128 | mbx->state = FM10K_STATE_OPEN; | ||
1129 | |||
1130 | fm10k_mbx_update_max_size(mbx, size); | ||
1131 | } | ||
1132 | break; | ||
1133 | default: | ||
1134 | break; | ||
1135 | } | ||
1136 | |||
1137 | /* align our tail index to remote head index */ | ||
1138 | mbx->tail = head; | ||
1139 | |||
1140 | return fm10k_mbx_create_reply(hw, mbx, head); | ||
1141 | } | ||
1142 | |||
1143 | /** | ||
1144 | * fm10k_mbx_process_data - Process data header | ||
1145 | * @mbx: pointer to mailbox | ||
1146 | * | ||
1147 | * This function will read an incoming data header and reply with the | ||
1148 | * appropriate message. It will return a value indicating the number of | ||
1149 | * data DWORDs on success, or will return a negative value on failure. | ||
1150 | **/ | ||
1151 | static s32 fm10k_mbx_process_data(struct fm10k_hw *hw, | ||
1152 | struct fm10k_mbx_info *mbx) | ||
1153 | { | ||
1154 | const u32 *hdr = &mbx->mbx_hdr; | ||
1155 | u16 head, tail; | ||
1156 | s32 err; | ||
1157 | |||
1158 | /* we will need to pull all of the fields for verification */ | ||
1159 | head = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD); | ||
1160 | tail = FM10K_MSG_HDR_FIELD_GET(*hdr, TAIL); | ||
1161 | |||
1162 | /* if we are in connect just update our data and go */ | ||
1163 | if (mbx->state == FM10K_STATE_CONNECT) { | ||
1164 | mbx->tail = head; | ||
1165 | mbx->state = FM10K_STATE_OPEN; | ||
1166 | } | ||
1167 | |||
1168 | /* abort on message size errors */ | ||
1169 | err = fm10k_mbx_push_tail(hw, mbx, tail); | ||
1170 | if (err < 0) | ||
1171 | return err; | ||
1172 | |||
1173 | /* verify the checksum on the incoming data */ | ||
1174 | err = fm10k_mbx_verify_remote_crc(mbx); | ||
1175 | if (err) | ||
1176 | return err; | ||
1177 | |||
1178 | /* process messages if we have received any */ | ||
1179 | fm10k_mbx_dequeue_rx(hw, mbx); | ||
1180 | |||
1181 | return fm10k_mbx_create_reply(hw, mbx, head); | ||
1182 | } | ||
1183 | |||
1184 | /** | ||
1185 | * fm10k_mbx_process_disconnect - Process disconnect header | ||
1186 | * @mbx: pointer to mailbox | ||
1187 | * | ||
1188 | * This function will read an incoming disconnect header and reply with the | ||
1189 | * appropriate message. It will return a value indicating the number of | ||
1190 | * data DWORDs on success, or will return a negative value on failure. | ||
1191 | **/ | ||
1192 | static s32 fm10k_mbx_process_disconnect(struct fm10k_hw *hw, | ||
1193 | struct fm10k_mbx_info *mbx) | ||
1194 | { | ||
1195 | const enum fm10k_mbx_state state = mbx->state; | ||
1196 | const u32 *hdr = &mbx->mbx_hdr; | ||
1197 | u16 head, tail; | ||
1198 | s32 err; | ||
1199 | |||
1200 | /* we will need to pull all of the fields for verification */ | ||
1201 | head = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD); | ||
1202 | tail = FM10K_MSG_HDR_FIELD_GET(*hdr, TAIL); | ||
1203 | |||
1204 | /* We should not be receiving disconnect if Rx is incomplete */ | ||
1205 | if (mbx->pushed) | ||
1206 | return FM10K_MBX_ERR_TAIL; | ||
1207 | |||
1208 | /* we have already verified mbx->head == tail so we know this is 0 */ | ||
1209 | mbx->head_len = 0; | ||
1210 | |||
1211 | /* verify the checksum on the incoming header is correct */ | ||
1212 | err = fm10k_mbx_verify_remote_crc(mbx); | ||
1213 | if (err) | ||
1214 | return err; | ||
1215 | |||
1216 | switch (state) { | ||
1217 | case FM10K_STATE_DISCONNECT: | ||
1218 | case FM10K_STATE_OPEN: | ||
1219 | /* state doesn't change if we still have work to do */ | ||
1220 | if (!fm10k_mbx_tx_complete(mbx)) | ||
1221 | break; | ||
1222 | |||
1223 | /* verify the head indicates we completed all transmits */ | ||
1224 | if (head != mbx->tail) | ||
1225 | return FM10K_MBX_ERR_HEAD; | ||
1226 | |||
1227 | /* reset any in-progress work */ | ||
1228 | fm10k_mbx_connect_reset(mbx); | ||
1229 | break; | ||
1230 | default: | ||
1231 | break; | ||
1232 | } | ||
1233 | |||
1234 | return fm10k_mbx_create_reply(hw, mbx, head); | ||
1235 | } | ||
1236 | |||
1237 | /** | ||
1238 | * fm10k_mbx_process_error - Process error header | ||
1239 | * @mbx: pointer to mailbox | ||
1240 | * | ||
1241 | * This function will read an incoming error header and reply with the | ||
1242 | * appropriate message. It will return a value indicating the number of | ||
1243 | * data DWORDs on success, or will return a negative value on failure. | ||
1244 | **/ | ||
1245 | static s32 fm10k_mbx_process_error(struct fm10k_hw *hw, | ||
1246 | struct fm10k_mbx_info *mbx) | ||
1247 | { | ||
1248 | const u32 *hdr = &mbx->mbx_hdr; | ||
1249 | s32 err_no; | ||
1250 | u16 head; | ||
1251 | |||
1252 | /* we will need to pull all of the fields for verification */ | ||
1253 | head = FM10K_MSG_HDR_FIELD_GET(*hdr, HEAD); | ||
1254 | |||
1255 | /* we only have lower 10 bits of error number os add upper bits */ | ||
1256 | err_no = FM10K_MSG_HDR_FIELD_GET(*hdr, ERR_NO); | ||
1257 | err_no |= ~FM10K_MSG_HDR_MASK(ERR_NO); | ||
1258 | |||
1259 | switch (mbx->state) { | ||
1260 | case FM10K_STATE_OPEN: | ||
1261 | case FM10K_STATE_DISCONNECT: | ||
1262 | /* flush any uncompleted work */ | ||
1263 | fm10k_mbx_reset_work(mbx); | ||
1264 | |||
1265 | /* reset CRC seeds */ | ||
1266 | mbx->local = FM10K_MBX_CRC_SEED; | ||
1267 | mbx->remote = FM10K_MBX_CRC_SEED; | ||
1268 | |||
1269 | /* reset tail index and size to prepare for reconnect */ | ||
1270 | mbx->tail = head; | ||
1271 | |||
1272 | /* if open then reset max_size and go back to connect */ | ||
1273 | if (mbx->state == FM10K_STATE_OPEN) { | ||
1274 | mbx->state = FM10K_STATE_CONNECT; | ||
1275 | break; | ||
1276 | } | ||
1277 | |||
1278 | /* send a connect message to get data flowing again */ | ||
1279 | fm10k_mbx_create_connect_hdr(mbx); | ||
1280 | return 0; | ||
1281 | default: | ||
1282 | break; | ||
1283 | } | ||
1284 | |||
1285 | return fm10k_mbx_create_reply(hw, mbx, mbx->tail); | ||
1286 | } | ||
1287 | |||
1288 | /** | ||
1289 | * fm10k_mbx_process - Process mailbox interrupt | ||
1290 | * @hw: pointer to hardware structure | ||
1291 | * @mbx: pointer to mailbox | ||
1292 | * | ||
1293 | * This function will process incoming mailbox events and generate mailbox | ||
1294 | * replies. It will return a value indicating the number of DWORDs | ||
1295 | * transmitted excluding header on success or a negative value on error. | ||
1296 | **/ | ||
1297 | static s32 fm10k_mbx_process(struct fm10k_hw *hw, | ||
1298 | struct fm10k_mbx_info *mbx) | ||
1299 | { | ||
1300 | s32 err; | ||
1301 | |||
1302 | /* we do not read mailbox if closed */ | ||
1303 | if (mbx->state == FM10K_STATE_CLOSED) | ||
1304 | return 0; | ||
1305 | |||
1306 | /* copy data from mailbox */ | ||
1307 | err = fm10k_mbx_read(hw, mbx); | ||
1308 | if (err) | ||
1309 | return err; | ||
1310 | |||
1311 | /* validate type, source, and destination */ | ||
1312 | err = fm10k_mbx_validate_msg_hdr(mbx); | ||
1313 | if (err < 0) | ||
1314 | goto msg_err; | ||
1315 | |||
1316 | switch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, TYPE)) { | ||
1317 | case FM10K_MSG_CONNECT: | ||
1318 | err = fm10k_mbx_process_connect(hw, mbx); | ||
1319 | break; | ||
1320 | case FM10K_MSG_DATA: | ||
1321 | err = fm10k_mbx_process_data(hw, mbx); | ||
1322 | break; | ||
1323 | case FM10K_MSG_DISCONNECT: | ||
1324 | err = fm10k_mbx_process_disconnect(hw, mbx); | ||
1325 | break; | ||
1326 | case FM10K_MSG_ERROR: | ||
1327 | err = fm10k_mbx_process_error(hw, mbx); | ||
1328 | break; | ||
1329 | default: | ||
1330 | err = FM10K_MBX_ERR_TYPE; | ||
1331 | break; | ||
1332 | } | ||
1333 | |||
1334 | msg_err: | ||
1335 | /* notify partner of errors on our end */ | ||
1336 | if (err < 0) | ||
1337 | fm10k_mbx_create_error_msg(mbx, err); | ||
1338 | |||
1339 | /* copy data from mailbox */ | ||
1340 | fm10k_mbx_write(hw, mbx); | ||
1341 | |||
1342 | return err; | ||
1343 | } | ||
1344 | |||
1345 | /** | ||
1346 | * fm10k_mbx_disconnect - Shutdown mailbox connection | ||
1347 | * @hw: pointer to hardware structure | ||
1348 | * @mbx: pointer to mailbox | ||
1349 | * | ||
1350 | * This function will shut down the mailbox. It places the mailbox first | ||
1351 | * in the disconnect state, it then allows up to a predefined timeout for | ||
1352 | * the mailbox to transition to close on its own. If this does not occur | ||
1353 | * then the mailbox will be forced into the closed state. | ||
1354 | * | ||
1355 | * Any mailbox transactions not completed before calling this function | ||
1356 | * are not guaranteed to complete and may be dropped. | ||
1357 | **/ | ||
1358 | static void fm10k_mbx_disconnect(struct fm10k_hw *hw, | ||
1359 | struct fm10k_mbx_info *mbx) | ||
1360 | { | ||
1361 | int timeout = mbx->timeout ? FM10K_MBX_DISCONNECT_TIMEOUT : 0; | ||
1362 | |||
1363 | /* Place mbx in ready to disconnect state */ | ||
1364 | mbx->state = FM10K_STATE_DISCONNECT; | ||
1365 | |||
1366 | /* trigger interrupt to start shutdown process */ | ||
1367 | fm10k_write_reg(hw, mbx->mbx_reg, FM10K_MBX_REQ | | ||
1368 | FM10K_MBX_INTERRUPT_DISABLE); | ||
1369 | do { | ||
1370 | udelay(FM10K_MBX_POLL_DELAY); | ||
1371 | mbx->ops.process(hw, mbx); | ||
1372 | timeout -= FM10K_MBX_POLL_DELAY; | ||
1373 | } while ((timeout > 0) && (mbx->state != FM10K_STATE_CLOSED)); | ||
1374 | |||
1375 | /* in case we didn't close just force the mailbox into shutdown */ | ||
1376 | fm10k_mbx_connect_reset(mbx); | ||
1377 | fm10k_mbx_update_max_size(mbx, 0); | ||
1378 | |||
1379 | fm10k_write_reg(hw, mbx->mbmem_reg, 0); | ||
1380 | } | ||
1381 | |||
1382 | /** | ||
1383 | * fm10k_mbx_connect - Start mailbox connection | ||
1384 | * @hw: pointer to hardware structure | ||
1385 | * @mbx: pointer to mailbox | ||
1386 | * | ||
1387 | * This function will initiate a mailbox connection. It will populate the | ||
1388 | * mailbox with a broadcast connect message and then initialize the lock. | ||
1389 | * This is safe since the connect message is a single DWORD so the mailbox | ||
1390 | * transaction is guaranteed to be atomic. | ||
1391 | * | ||
1392 | * This function will return an error if the mailbox has not been initiated | ||
1393 | * or is currently in use. | ||
1394 | **/ | ||
1395 | static s32 fm10k_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx) | ||
1396 | { | ||
1397 | /* we cannot connect an uninitialized mailbox */ | ||
1398 | if (!mbx->rx.buffer) | ||
1399 | return FM10K_MBX_ERR_NO_SPACE; | ||
1400 | |||
1401 | /* we cannot connect an already connected mailbox */ | ||
1402 | if (mbx->state != FM10K_STATE_CLOSED) | ||
1403 | return FM10K_MBX_ERR_BUSY; | ||
1404 | |||
1405 | /* mailbox timeout can now become active */ | ||
1406 | mbx->timeout = FM10K_MBX_INIT_TIMEOUT; | ||
1407 | |||
1408 | /* Place mbx in ready to connect state */ | ||
1409 | mbx->state = FM10K_STATE_CONNECT; | ||
1410 | |||
1411 | /* initialize header of remote mailbox */ | ||
1412 | fm10k_mbx_create_disconnect_hdr(mbx); | ||
1413 | fm10k_write_reg(hw, mbx->mbmem_reg ^ mbx->mbmem_len, mbx->mbx_hdr); | ||
1414 | |||
1415 | /* enable interrupt and notify other party of new message */ | ||
1416 | mbx->mbx_lock = FM10K_MBX_REQ_INTERRUPT | FM10K_MBX_ACK_INTERRUPT | | ||
1417 | FM10K_MBX_INTERRUPT_ENABLE; | ||
1418 | |||
1419 | /* generate and load connect header into mailbox */ | ||
1420 | fm10k_mbx_create_connect_hdr(mbx); | ||
1421 | fm10k_mbx_write(hw, mbx); | ||
1422 | |||
1423 | return 0; | ||
1424 | } | ||
1425 | |||
1426 | /** | ||
734 | * fm10k_mbx_validate_handlers - Validate layout of message parsing data | 1427 | * fm10k_mbx_validate_handlers - Validate layout of message parsing data |
735 | * @msg_data: handlers for mailbox events | 1428 | * @msg_data: handlers for mailbox events |
736 | * | 1429 | * |
@@ -806,6 +1499,83 @@ static s32 fm10k_mbx_register_handlers(struct fm10k_mbx_info *mbx, | |||
806 | } | 1499 | } |
807 | 1500 | ||
808 | /** | 1501 | /** |
1502 | * fm10k_pfvf_mbx_init - Initialize mailbox memory for PF/VF mailbox | ||
1503 | * @hw: pointer to hardware structure | ||
1504 | * @mbx: pointer to mailbox | ||
1505 | * @msg_data: handlers for mailbox events | ||
1506 | * @id: ID reference for PF as it supports up to 64 PF/VF mailboxes | ||
1507 | * | ||
1508 | * This function initializes the mailbox for use. It will split the | ||
1509 | * buffer provided an use that th populate both the Tx and Rx FIFO by | ||
1510 | * evenly splitting it. In order to allow for easy masking of head/tail | ||
1511 | * the value reported in size must be a power of 2 and is reported in | ||
1512 | * DWORDs, not bytes. Any invalid values will cause the mailbox to return | ||
1513 | * error. | ||
1514 | **/ | ||
1515 | s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx, | ||
1516 | const struct fm10k_msg_data *msg_data, u8 id) | ||
1517 | { | ||
1518 | /* initialize registers */ | ||
1519 | switch (hw->mac.type) { | ||
1520 | case fm10k_mac_pf: | ||
1521 | /* there are only 64 VF <-> PF mailboxes */ | ||
1522 | if (id < 64) { | ||
1523 | mbx->mbx_reg = FM10K_MBX(id); | ||
1524 | mbx->mbmem_reg = FM10K_MBMEM_VF(id, 0); | ||
1525 | break; | ||
1526 | } | ||
1527 | /* fallthough */ | ||
1528 | default: | ||
1529 | return FM10K_MBX_ERR_NO_MBX; | ||
1530 | } | ||
1531 | |||
1532 | /* start out in closed state */ | ||
1533 | mbx->state = FM10K_STATE_CLOSED; | ||
1534 | |||
1535 | /* validate layout of handlers before assigning them */ | ||
1536 | if (fm10k_mbx_validate_handlers(msg_data)) | ||
1537 | return FM10K_ERR_PARAM; | ||
1538 | |||
1539 | /* initialize the message handlers */ | ||
1540 | mbx->msg_data = msg_data; | ||
1541 | |||
1542 | /* start mailbox as timed out and let the reset_hw call | ||
1543 | * set the timeout value to begin communications | ||
1544 | */ | ||
1545 | mbx->timeout = 0; | ||
1546 | mbx->udelay = FM10K_MBX_INIT_DELAY; | ||
1547 | |||
1548 | /* initalize tail and head */ | ||
1549 | mbx->tail = 1; | ||
1550 | mbx->head = 1; | ||
1551 | |||
1552 | /* initialize CRC seeds */ | ||
1553 | mbx->local = FM10K_MBX_CRC_SEED; | ||
1554 | mbx->remote = FM10K_MBX_CRC_SEED; | ||
1555 | |||
1556 | /* Split buffer for use by Tx/Rx FIFOs */ | ||
1557 | mbx->max_size = FM10K_MBX_MSG_MAX_SIZE; | ||
1558 | mbx->mbmem_len = FM10K_VFMBMEM_VF_XOR; | ||
1559 | |||
1560 | /* initialize the FIFOs, sizes are in 4 byte increments */ | ||
1561 | fm10k_fifo_init(&mbx->tx, mbx->buffer, FM10K_MBX_TX_BUFFER_SIZE); | ||
1562 | fm10k_fifo_init(&mbx->rx, &mbx->buffer[FM10K_MBX_TX_BUFFER_SIZE], | ||
1563 | FM10K_MBX_RX_BUFFER_SIZE); | ||
1564 | |||
1565 | /* initialize function pointers */ | ||
1566 | mbx->ops.connect = fm10k_mbx_connect; | ||
1567 | mbx->ops.disconnect = fm10k_mbx_disconnect; | ||
1568 | mbx->ops.rx_ready = fm10k_mbx_rx_ready; | ||
1569 | mbx->ops.tx_ready = fm10k_mbx_tx_ready; | ||
1570 | mbx->ops.tx_complete = fm10k_mbx_tx_complete; | ||
1571 | mbx->ops.enqueue_tx = fm10k_mbx_enqueue_tx; | ||
1572 | mbx->ops.process = fm10k_mbx_process; | ||
1573 | mbx->ops.register_handlers = fm10k_mbx_register_handlers; | ||
1574 | |||
1575 | return 0; | ||
1576 | } | ||
1577 | |||
1578 | /** | ||
809 | * fm10k_sm_mbx_create_data_hdr - Generate a mailbox header for local FIFO | 1579 | * fm10k_sm_mbx_create_data_hdr - Generate a mailbox header for local FIFO |
810 | * @mbx: pointer to mailbox | 1580 | * @mbx: pointer to mailbox |
811 | * | 1581 | * |
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.h b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.h index f5ba86f0f725..0419a7f0035e 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.h +++ b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.h | |||
@@ -99,6 +99,39 @@ enum fm10k_mbx_state { | |||
99 | FM10K_STATE_DISCONNECT, | 99 | FM10K_STATE_DISCONNECT, |
100 | }; | 100 | }; |
101 | 101 | ||
102 | /* PF/VF Mailbox header format | ||
103 | * 3 2 1 0 | ||
104 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ||
105 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
106 | * | Size/Err_no/CRC | Rsvd0 | Head | Tail | Type | | ||
107 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
108 | * | ||
109 | * The layout above describes the format for the header used in the PF/VF | ||
110 | * mailbox. The header is broken out into the following fields: | ||
111 | * Type: There are 4 supported message types | ||
112 | * 0x8: Data header - used to transport message data | ||
113 | * 0xC: Connect header - used to establish connection | ||
114 | * 0xD: Disconnect header - used to tear down a connection | ||
115 | * 0xE: Error header - used to address message exceptions | ||
116 | * Tail: Tail index for local FIFO | ||
117 | * Tail index actually consists of two parts. The MSB of | ||
118 | * the head is a loop tracker, it is 0 on an even numbered | ||
119 | * loop through the FIFO, and 1 on the odd numbered loops. | ||
120 | * To get the actual mailbox offset based on the tail it | ||
121 | * is necessary to add bit 3 to bit 0 and clear bit 3. This | ||
122 | * gives us a valid range of 0x1 - 0xE. | ||
123 | * Head: Head index for remote FIFO | ||
124 | * Head index follows the same format as the tail index. | ||
125 | * Rsvd0: Reserved 0 portion of the mailbox header | ||
126 | * CRC: Running CRC for all data since connect plus current message header | ||
127 | * Size: Maximum message size - Applies only to connect headers | ||
128 | * The maximum message size is provided during connect to avoid | ||
129 | * jamming the mailbox with messages that do not fit. | ||
130 | * Err_no: Error number - Applies only to error headers | ||
131 | * The error number provides a indication of the type of error | ||
132 | * experienced. | ||
133 | */ | ||
134 | |||
102 | /* macros for retriving and setting header values */ | 135 | /* macros for retriving and setting header values */ |
103 | #define FM10K_MSG_HDR_MASK(name) \ | 136 | #define FM10K_MSG_HDR_MASK(name) \ |
104 | ((0x1u << FM10K_MSG_##name##_SIZE) - 1) | 137 | ((0x1u << FM10K_MSG_##name##_SIZE) - 1) |
@@ -107,6 +140,35 @@ enum fm10k_mbx_state { | |||
107 | #define FM10K_MSG_HDR_FIELD_GET(value, name) \ | 140 | #define FM10K_MSG_HDR_FIELD_GET(value, name) \ |
108 | ((u16)((value) >> FM10K_MSG_##name##_SHIFT) & FM10K_MSG_HDR_MASK(name)) | 141 | ((u16)((value) >> FM10K_MSG_##name##_SHIFT) & FM10K_MSG_HDR_MASK(name)) |
109 | 142 | ||
143 | /* offsets shared between all headers */ | ||
144 | #define FM10K_MSG_TYPE_SHIFT 0 | ||
145 | #define FM10K_MSG_TYPE_SIZE 4 | ||
146 | #define FM10K_MSG_TAIL_SHIFT 4 | ||
147 | #define FM10K_MSG_TAIL_SIZE 4 | ||
148 | #define FM10K_MSG_HEAD_SHIFT 8 | ||
149 | #define FM10K_MSG_HEAD_SIZE 4 | ||
150 | #define FM10K_MSG_RSVD0_SHIFT 12 | ||
151 | #define FM10K_MSG_RSVD0_SIZE 4 | ||
152 | |||
153 | /* offsets for data/disconnect headers */ | ||
154 | #define FM10K_MSG_CRC_SHIFT 16 | ||
155 | #define FM10K_MSG_CRC_SIZE 16 | ||
156 | |||
157 | /* offsets for connect headers */ | ||
158 | #define FM10K_MSG_CONNECT_SIZE_SHIFT 16 | ||
159 | #define FM10K_MSG_CONNECT_SIZE_SIZE 16 | ||
160 | |||
161 | /* offsets for error headers */ | ||
162 | #define FM10K_MSG_ERR_NO_SHIFT 16 | ||
163 | #define FM10K_MSG_ERR_NO_SIZE 16 | ||
164 | |||
165 | enum fm10k_msg_type { | ||
166 | FM10K_MSG_DATA = 0x8, | ||
167 | FM10K_MSG_CONNECT = 0xC, | ||
168 | FM10K_MSG_DISCONNECT = 0xD, | ||
169 | FM10K_MSG_ERROR = 0xE, | ||
170 | }; | ||
171 | |||
110 | /* HNI/SM Mailbox FIFO format | 172 | /* HNI/SM Mailbox FIFO format |
111 | * 3 2 1 0 | 173 | * 3 2 1 0 |
112 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | 174 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 |
@@ -237,6 +299,8 @@ struct fm10k_mbx_info { | |||
237 | u32 buffer[FM10K_MBX_BUFFER_SIZE]; | 299 | u32 buffer[FM10K_MBX_BUFFER_SIZE]; |
238 | }; | 300 | }; |
239 | 301 | ||
302 | s32 fm10k_pfvf_mbx_init(struct fm10k_hw *, struct fm10k_mbx_info *, | ||
303 | const struct fm10k_msg_data *, u8); | ||
240 | s32 fm10k_sm_mbx_init(struct fm10k_hw *, struct fm10k_mbx_info *, | 304 | s32 fm10k_sm_mbx_init(struct fm10k_hw *, struct fm10k_mbx_info *, |
241 | const struct fm10k_msg_data *); | 305 | const struct fm10k_msg_data *); |
242 | 306 | ||