162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* Copyright(c) 2013 - 2018 Intel Corporation. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#ifndef _FM10K_MBX_H_ 562306a36Sopenharmony_ci#define _FM10K_MBX_H_ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci/* forward declaration */ 862306a36Sopenharmony_cistruct fm10k_mbx_info; 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "fm10k_type.h" 1162306a36Sopenharmony_ci#include "fm10k_tlv.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* PF Mailbox Registers */ 1462306a36Sopenharmony_ci#define FM10K_MBMEM(_n) ((_n) + 0x18000) 1562306a36Sopenharmony_ci#define FM10K_MBMEM_VF(_n, _m) (((_n) * 0x10) + (_m) + 0x18000) 1662306a36Sopenharmony_ci#define FM10K_MBMEM_SM(_n) ((_n) + 0x18400) 1762306a36Sopenharmony_ci#define FM10K_MBMEM_PF(_n) ((_n) + 0x18600) 1862306a36Sopenharmony_ci/* XOR provides means of switching from Tx to Rx FIFO */ 1962306a36Sopenharmony_ci#define FM10K_MBMEM_PF_XOR (FM10K_MBMEM_SM(0) ^ FM10K_MBMEM_PF(0)) 2062306a36Sopenharmony_ci#define FM10K_MBX(_n) ((_n) + 0x18800) 2162306a36Sopenharmony_ci#define FM10K_MBX_REQ 0x00000002 2262306a36Sopenharmony_ci#define FM10K_MBX_ACK 0x00000004 2362306a36Sopenharmony_ci#define FM10K_MBX_REQ_INTERRUPT 0x00000008 2462306a36Sopenharmony_ci#define FM10K_MBX_ACK_INTERRUPT 0x00000010 2562306a36Sopenharmony_ci#define FM10K_MBX_INTERRUPT_ENABLE 0x00000020 2662306a36Sopenharmony_ci#define FM10K_MBX_INTERRUPT_DISABLE 0x00000040 2762306a36Sopenharmony_ci#define FM10K_MBX_GLOBAL_REQ_INTERRUPT 0x00000200 2862306a36Sopenharmony_ci#define FM10K_MBX_GLOBAL_ACK_INTERRUPT 0x00000400 2962306a36Sopenharmony_ci#define FM10K_MBICR(_n) ((_n) + 0x18840) 3062306a36Sopenharmony_ci#define FM10K_GMBX 0x18842 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* VF Mailbox Registers */ 3362306a36Sopenharmony_ci#define FM10K_VFMBX 0x00010 3462306a36Sopenharmony_ci#define FM10K_VFMBMEM(_n) ((_n) + 0x00020) 3562306a36Sopenharmony_ci#define FM10K_VFMBMEM_LEN 16 3662306a36Sopenharmony_ci#define FM10K_VFMBMEM_VF_XOR (FM10K_VFMBMEM_LEN / 2) 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* Delays/timeouts */ 3962306a36Sopenharmony_ci#define FM10K_MBX_DISCONNECT_TIMEOUT 500 4062306a36Sopenharmony_ci#define FM10K_MBX_POLL_DELAY 19 4162306a36Sopenharmony_ci#define FM10K_MBX_INT_DELAY 20 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* PF/VF Mailbox state machine 4462306a36Sopenharmony_ci * 4562306a36Sopenharmony_ci * +----------+ connect() +----------+ 4662306a36Sopenharmony_ci * | CLOSED | --------------> | CONNECT | 4762306a36Sopenharmony_ci * +----------+ +----------+ 4862306a36Sopenharmony_ci * ^ ^ | 4962306a36Sopenharmony_ci * | rcv: rcv: | | rcv: 5062306a36Sopenharmony_ci * | Connect Disconnect | | Connect 5162306a36Sopenharmony_ci * | Disconnect Error | | Data 5262306a36Sopenharmony_ci * | | | 5362306a36Sopenharmony_ci * | | V 5462306a36Sopenharmony_ci * +----------+ disconnect() +----------+ 5562306a36Sopenharmony_ci * |DISCONNECT| <-------------- | OPEN | 5662306a36Sopenharmony_ci * +----------+ +----------+ 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * The diagram above describes the PF/VF mailbox state machine. There 5962306a36Sopenharmony_ci * are four main states to this machine. 6062306a36Sopenharmony_ci * Closed: This state represents a mailbox that is in a standby state 6162306a36Sopenharmony_ci * with interrupts disabled. In this state the mailbox should not 6262306a36Sopenharmony_ci * read the mailbox or write any data. The only means of exiting 6362306a36Sopenharmony_ci * this state is for the system to make the connect() call for the 6462306a36Sopenharmony_ci * mailbox, it will then transition to the connect state. 6562306a36Sopenharmony_ci * Connect: In this state the mailbox is seeking a connection. It will 6662306a36Sopenharmony_ci * post a connect message with no specified destination and will 6762306a36Sopenharmony_ci * wait for a reply from the other side of the mailbox. This state 6862306a36Sopenharmony_ci * is exited when either a connect with the local mailbox as the 6962306a36Sopenharmony_ci * destination is received or when a data message is received with 7062306a36Sopenharmony_ci * a valid sequence number. 7162306a36Sopenharmony_ci * Open: In this state the mailbox is able to transfer data between the local 7262306a36Sopenharmony_ci * entity and the remote. It will fall back to connect in the event of 7362306a36Sopenharmony_ci * receiving either an error message, or a disconnect message. It will 7462306a36Sopenharmony_ci * transition to disconnect on a call to disconnect(); 7562306a36Sopenharmony_ci * Disconnect: In this state the mailbox is attempting to gracefully terminate 7662306a36Sopenharmony_ci * the connection. It will do so at the first point where it knows 7762306a36Sopenharmony_ci * that the remote endpoint is either done sending, or when the 7862306a36Sopenharmony_ci * remote endpoint has fallen back into connect. 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_cienum fm10k_mbx_state { 8162306a36Sopenharmony_ci FM10K_STATE_CLOSED, 8262306a36Sopenharmony_ci FM10K_STATE_CONNECT, 8362306a36Sopenharmony_ci FM10K_STATE_OPEN, 8462306a36Sopenharmony_ci FM10K_STATE_DISCONNECT, 8562306a36Sopenharmony_ci}; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* PF/VF Mailbox header format 8862306a36Sopenharmony_ci * 3 2 1 0 8962306a36Sopenharmony_ci * 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 9062306a36Sopenharmony_ci * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 9162306a36Sopenharmony_ci * | Size/Err_no/CRC | Rsvd0 | Head | Tail | Type | 9262306a36Sopenharmony_ci * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 9362306a36Sopenharmony_ci * 9462306a36Sopenharmony_ci * The layout above describes the format for the header used in the PF/VF 9562306a36Sopenharmony_ci * mailbox. The header is broken out into the following fields: 9662306a36Sopenharmony_ci * Type: There are 4 supported message types 9762306a36Sopenharmony_ci * 0x8: Data header - used to transport message data 9862306a36Sopenharmony_ci * 0xC: Connect header - used to establish connection 9962306a36Sopenharmony_ci * 0xD: Disconnect header - used to tear down a connection 10062306a36Sopenharmony_ci * 0xE: Error header - used to address message exceptions 10162306a36Sopenharmony_ci * Tail: Tail index for local FIFO 10262306a36Sopenharmony_ci * Tail index actually consists of two parts. The MSB of 10362306a36Sopenharmony_ci * the head is a loop tracker, it is 0 on an even numbered 10462306a36Sopenharmony_ci * loop through the FIFO, and 1 on the odd numbered loops. 10562306a36Sopenharmony_ci * To get the actual mailbox offset based on the tail it 10662306a36Sopenharmony_ci * is necessary to add bit 3 to bit 0 and clear bit 3. This 10762306a36Sopenharmony_ci * gives us a valid range of 0x1 - 0xE. 10862306a36Sopenharmony_ci * Head: Head index for remote FIFO 10962306a36Sopenharmony_ci * Head index follows the same format as the tail index. 11062306a36Sopenharmony_ci * Rsvd0: Reserved 0 portion of the mailbox header 11162306a36Sopenharmony_ci * CRC: Running CRC for all data since connect plus current message header 11262306a36Sopenharmony_ci * Size: Maximum message size - Applies only to connect headers 11362306a36Sopenharmony_ci * The maximum message size is provided during connect to avoid 11462306a36Sopenharmony_ci * jamming the mailbox with messages that do not fit. 11562306a36Sopenharmony_ci * Err_no: Error number - Applies only to error headers 11662306a36Sopenharmony_ci * The error number provides an indication of the type of error 11762306a36Sopenharmony_ci * experienced. 11862306a36Sopenharmony_ci */ 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/* macros for retrieving and setting header values */ 12162306a36Sopenharmony_ci#define FM10K_MSG_HDR_MASK(name) \ 12262306a36Sopenharmony_ci ((0x1u << FM10K_MSG_##name##_SIZE) - 1) 12362306a36Sopenharmony_ci#define FM10K_MSG_HDR_FIELD_SET(value, name) \ 12462306a36Sopenharmony_ci (((u32)(value) & FM10K_MSG_HDR_MASK(name)) << FM10K_MSG_##name##_SHIFT) 12562306a36Sopenharmony_ci#define FM10K_MSG_HDR_FIELD_GET(value, name) \ 12662306a36Sopenharmony_ci ((u16)((value) >> FM10K_MSG_##name##_SHIFT) & FM10K_MSG_HDR_MASK(name)) 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci/* offsets shared between all headers */ 12962306a36Sopenharmony_ci#define FM10K_MSG_TYPE_SHIFT 0 13062306a36Sopenharmony_ci#define FM10K_MSG_TYPE_SIZE 4 13162306a36Sopenharmony_ci#define FM10K_MSG_TAIL_SHIFT 4 13262306a36Sopenharmony_ci#define FM10K_MSG_TAIL_SIZE 4 13362306a36Sopenharmony_ci#define FM10K_MSG_HEAD_SHIFT 8 13462306a36Sopenharmony_ci#define FM10K_MSG_HEAD_SIZE 4 13562306a36Sopenharmony_ci#define FM10K_MSG_RSVD0_SHIFT 12 13662306a36Sopenharmony_ci#define FM10K_MSG_RSVD0_SIZE 4 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci/* offsets for data/disconnect headers */ 13962306a36Sopenharmony_ci#define FM10K_MSG_CRC_SHIFT 16 14062306a36Sopenharmony_ci#define FM10K_MSG_CRC_SIZE 16 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci/* offsets for connect headers */ 14362306a36Sopenharmony_ci#define FM10K_MSG_CONNECT_SIZE_SHIFT 16 14462306a36Sopenharmony_ci#define FM10K_MSG_CONNECT_SIZE_SIZE 16 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci/* offsets for error headers */ 14762306a36Sopenharmony_ci#define FM10K_MSG_ERR_NO_SHIFT 16 14862306a36Sopenharmony_ci#define FM10K_MSG_ERR_NO_SIZE 16 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cienum fm10k_msg_type { 15162306a36Sopenharmony_ci FM10K_MSG_DATA = 0x8, 15262306a36Sopenharmony_ci FM10K_MSG_CONNECT = 0xC, 15362306a36Sopenharmony_ci FM10K_MSG_DISCONNECT = 0xD, 15462306a36Sopenharmony_ci FM10K_MSG_ERROR = 0xE, 15562306a36Sopenharmony_ci}; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci/* HNI/SM Mailbox FIFO format 15862306a36Sopenharmony_ci * 3 2 1 0 15962306a36Sopenharmony_ci * 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 16062306a36Sopenharmony_ci * +-------+-----------------------+-------+-----------------------+ 16162306a36Sopenharmony_ci * | Error | Remote Head |Version| Local Tail | 16262306a36Sopenharmony_ci * +-------+-----------------------+-------+-----------------------+ 16362306a36Sopenharmony_ci * | | 16462306a36Sopenharmony_ci * . Local FIFO Data . 16562306a36Sopenharmony_ci * . . 16662306a36Sopenharmony_ci * +-------+-----------------------+-------+-----------------------+ 16762306a36Sopenharmony_ci * 16862306a36Sopenharmony_ci * The layout above describes the format for the FIFOs used by the host 16962306a36Sopenharmony_ci * network interface and the switch manager to communicate messages back 17062306a36Sopenharmony_ci * and forth. Both the HNI and the switch maintain one such FIFO. The 17162306a36Sopenharmony_ci * layout in memory has the switch manager FIFO followed immediately by 17262306a36Sopenharmony_ci * the HNI FIFO. For this reason I am using just the pointer to the 17362306a36Sopenharmony_ci * HNI FIFO in the mailbox ops as the offset between the two is fixed. 17462306a36Sopenharmony_ci * 17562306a36Sopenharmony_ci * The header for the FIFO is broken out into the following fields: 17662306a36Sopenharmony_ci * Local Tail: Offset into FIFO region for next DWORD to write. 17762306a36Sopenharmony_ci * Version: Version info for mailbox, only values of 0/1 are supported. 17862306a36Sopenharmony_ci * Remote Head: Offset into remote FIFO to indicate how much we have read. 17962306a36Sopenharmony_ci * Error: Error indication, values TBD. 18062306a36Sopenharmony_ci */ 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci/* version number for switch manager mailboxes */ 18362306a36Sopenharmony_ci#define FM10K_SM_MBX_VERSION 1 18462306a36Sopenharmony_ci#define FM10K_SM_MBX_FIFO_LEN (FM10K_MBMEM_PF_XOR - 1) 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci/* offsets shared between all SM FIFO headers */ 18762306a36Sopenharmony_ci#define FM10K_MSG_SM_TAIL_SHIFT 0 18862306a36Sopenharmony_ci#define FM10K_MSG_SM_TAIL_SIZE 12 18962306a36Sopenharmony_ci#define FM10K_MSG_SM_VER_SHIFT 12 19062306a36Sopenharmony_ci#define FM10K_MSG_SM_VER_SIZE 4 19162306a36Sopenharmony_ci#define FM10K_MSG_SM_HEAD_SHIFT 16 19262306a36Sopenharmony_ci#define FM10K_MSG_SM_HEAD_SIZE 12 19362306a36Sopenharmony_ci#define FM10K_MSG_SM_ERR_SHIFT 28 19462306a36Sopenharmony_ci#define FM10K_MSG_SM_ERR_SIZE 4 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci/* All error messages returned by mailbox functions 19762306a36Sopenharmony_ci * The value -511 is 0xFE01 in hex. The idea is to order the errors 19862306a36Sopenharmony_ci * from 0xFE01 - 0xFEFF so error codes are easily visible in the mailbox 19962306a36Sopenharmony_ci * messages. This also helps to avoid error number collisions as Linux 20062306a36Sopenharmony_ci * doesn't appear to use error numbers 256 - 511. 20162306a36Sopenharmony_ci */ 20262306a36Sopenharmony_ci#define FM10K_MBX_ERR(_n) ((_n) - 512) 20362306a36Sopenharmony_ci#define FM10K_MBX_ERR_NO_MBX FM10K_MBX_ERR(0x01) 20462306a36Sopenharmony_ci#define FM10K_MBX_ERR_NO_SPACE FM10K_MBX_ERR(0x03) 20562306a36Sopenharmony_ci#define FM10K_MBX_ERR_TAIL FM10K_MBX_ERR(0x05) 20662306a36Sopenharmony_ci#define FM10K_MBX_ERR_HEAD FM10K_MBX_ERR(0x06) 20762306a36Sopenharmony_ci#define FM10K_MBX_ERR_SRC FM10K_MBX_ERR(0x08) 20862306a36Sopenharmony_ci#define FM10K_MBX_ERR_TYPE FM10K_MBX_ERR(0x09) 20962306a36Sopenharmony_ci#define FM10K_MBX_ERR_SIZE FM10K_MBX_ERR(0x0B) 21062306a36Sopenharmony_ci#define FM10K_MBX_ERR_BUSY FM10K_MBX_ERR(0x0C) 21162306a36Sopenharmony_ci#define FM10K_MBX_ERR_RSVD0 FM10K_MBX_ERR(0x0E) 21262306a36Sopenharmony_ci#define FM10K_MBX_ERR_CRC FM10K_MBX_ERR(0x0F) 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci#define FM10K_MBX_CRC_SEED 0xFFFF 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_cistruct fm10k_mbx_ops { 21762306a36Sopenharmony_ci s32 (*connect)(struct fm10k_hw *, struct fm10k_mbx_info *); 21862306a36Sopenharmony_ci void (*disconnect)(struct fm10k_hw *, struct fm10k_mbx_info *); 21962306a36Sopenharmony_ci bool (*rx_ready)(struct fm10k_mbx_info *); 22062306a36Sopenharmony_ci bool (*tx_ready)(struct fm10k_mbx_info *, u16); 22162306a36Sopenharmony_ci bool (*tx_complete)(struct fm10k_mbx_info *); 22262306a36Sopenharmony_ci s32 (*enqueue_tx)(struct fm10k_hw *, struct fm10k_mbx_info *, 22362306a36Sopenharmony_ci const u32 *); 22462306a36Sopenharmony_ci s32 (*process)(struct fm10k_hw *, struct fm10k_mbx_info *); 22562306a36Sopenharmony_ci s32 (*register_handlers)(struct fm10k_mbx_info *, 22662306a36Sopenharmony_ci const struct fm10k_msg_data *); 22762306a36Sopenharmony_ci}; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_cistruct fm10k_mbx_fifo { 23062306a36Sopenharmony_ci u32 *buffer; 23162306a36Sopenharmony_ci u16 head; 23262306a36Sopenharmony_ci u16 tail; 23362306a36Sopenharmony_ci u16 size; 23462306a36Sopenharmony_ci}; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci/* size of buffer to be stored in mailbox for FIFOs */ 23762306a36Sopenharmony_ci#define FM10K_MBX_TX_BUFFER_SIZE 512 23862306a36Sopenharmony_ci#define FM10K_MBX_RX_BUFFER_SIZE 128 23962306a36Sopenharmony_ci#define FM10K_MBX_BUFFER_SIZE \ 24062306a36Sopenharmony_ci (FM10K_MBX_TX_BUFFER_SIZE + FM10K_MBX_RX_BUFFER_SIZE) 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci/* minimum and maximum message size in dwords */ 24362306a36Sopenharmony_ci#define FM10K_MBX_MSG_MAX_SIZE \ 24462306a36Sopenharmony_ci ((FM10K_MBX_TX_BUFFER_SIZE - 1) & (FM10K_MBX_RX_BUFFER_SIZE - 1)) 24562306a36Sopenharmony_ci#define FM10K_VFMBX_MSG_MTU ((FM10K_VFMBMEM_LEN / 2) - 1) 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci#define FM10K_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */ 24862306a36Sopenharmony_ci#define FM10K_MBX_INIT_DELAY 500 /* microseconds between retries */ 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistruct fm10k_mbx_info { 25162306a36Sopenharmony_ci /* function pointers for mailbox operations */ 25262306a36Sopenharmony_ci struct fm10k_mbx_ops ops; 25362306a36Sopenharmony_ci const struct fm10k_msg_data *msg_data; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci /* message FIFOs */ 25662306a36Sopenharmony_ci struct fm10k_mbx_fifo rx; 25762306a36Sopenharmony_ci struct fm10k_mbx_fifo tx; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci /* delay for handling timeouts */ 26062306a36Sopenharmony_ci u32 timeout; 26162306a36Sopenharmony_ci u32 udelay; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci /* mailbox state info */ 26462306a36Sopenharmony_ci u32 mbx_reg, mbmem_reg, mbx_lock, mbx_hdr; 26562306a36Sopenharmony_ci u16 max_size, mbmem_len; 26662306a36Sopenharmony_ci u16 tail, tail_len, pulled; 26762306a36Sopenharmony_ci u16 head, head_len, pushed; 26862306a36Sopenharmony_ci u16 local, remote; 26962306a36Sopenharmony_ci enum fm10k_mbx_state state; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci /* result of last mailbox test */ 27262306a36Sopenharmony_ci s32 test_result; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci /* statistics */ 27562306a36Sopenharmony_ci u64 tx_busy; 27662306a36Sopenharmony_ci u64 tx_dropped; 27762306a36Sopenharmony_ci u64 tx_messages; 27862306a36Sopenharmony_ci u64 tx_dwords; 27962306a36Sopenharmony_ci u64 tx_mbmem_pulled; 28062306a36Sopenharmony_ci u64 rx_messages; 28162306a36Sopenharmony_ci u64 rx_dwords; 28262306a36Sopenharmony_ci u64 rx_mbmem_pushed; 28362306a36Sopenharmony_ci u64 rx_parse_err; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci /* Buffer to store messages */ 28662306a36Sopenharmony_ci u32 buffer[FM10K_MBX_BUFFER_SIZE]; 28762306a36Sopenharmony_ci}; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cis32 fm10k_pfvf_mbx_init(struct fm10k_hw *, struct fm10k_mbx_info *, 29062306a36Sopenharmony_ci const struct fm10k_msg_data *, u8); 29162306a36Sopenharmony_cis32 fm10k_sm_mbx_init(struct fm10k_hw *, struct fm10k_mbx_info *, 29262306a36Sopenharmony_ci const struct fm10k_msg_data *); 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci#endif /* _FM10K_MBX_H_ */ 295