1 /*******************************************************************************
3 Copyright (c) 2013 - 2015, Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
32 ***************************************************************************/
37 /* forward declaration */
38 struct fm10k_mbx_info;
40 #include "fm10k_type.h"
41 #include "fm10k_tlv.h"
43 /* PF Mailbox Registers */
44 #define FM10K_MBMEM(_n) ((_n) + 0x18000)
45 #define FM10K_MBMEM_VF(_n, _m) (((_n) * 0x10) + (_m) + 0x18000)
46 #define FM10K_MBMEM_SM(_n) ((_n) + 0x18400)
47 #define FM10K_MBMEM_PF(_n) ((_n) + 0x18600)
48 /* XOR provides means of switching from Tx to Rx FIFO */
49 #define FM10K_MBMEM_PF_XOR (FM10K_MBMEM_SM(0) ^ FM10K_MBMEM_PF(0))
50 #define FM10K_MBX(_n) ((_n) + 0x18800)
51 #define FM10K_MBX_REQ 0x00000002
52 #define FM10K_MBX_ACK 0x00000004
53 #define FM10K_MBX_REQ_INTERRUPT 0x00000008
54 #define FM10K_MBX_ACK_INTERRUPT 0x00000010
55 #define FM10K_MBX_INTERRUPT_ENABLE 0x00000020
56 #define FM10K_MBX_INTERRUPT_DISABLE 0x00000040
57 #define FM10K_MBX_GLOBAL_REQ_INTERRUPT 0x00000200
58 #define FM10K_MBX_GLOBAL_ACK_INTERRUPT 0x00000400
59 #define FM10K_MBICR(_n) ((_n) + 0x18840)
60 #define FM10K_GMBX 0x18842
62 /* VF Mailbox Registers */
63 #define FM10K_VFMBX 0x00010
64 #define FM10K_VFMBMEM(_n) ((_n) + 0x00020)
65 #define FM10K_VFMBMEM_LEN 16
66 #define FM10K_VFMBMEM_VF_XOR (FM10K_VFMBMEM_LEN / 2)
69 #define FM10K_MBX_DISCONNECT_TIMEOUT 500
70 #define FM10K_MBX_POLL_DELAY 19
71 #define FM10K_MBX_INT_DELAY 20
73 #define FM10K_WRITE_MBX(hw, reg, value) FM10K_WRITE_REG(hw, reg, value)
75 /* PF/VF Mailbox state machine
77 * +----------+ connect() +----------+
78 * | CLOSED | --------------> | CONNECT |
79 * +----------+ +----------+
81 * | rcv: rcv: | | rcv:
82 * | Connect Disconnect | | Connect
83 * | Disconnect Error | | Data
86 * +----------+ disconnect() +----------+
87 * |DISCONNECT| <-------------- | OPEN |
88 * +----------+ +----------+
90 * The diagram above describes the PF/VF mailbox state machine. There
91 * are four main states to this machine.
92 * Closed: This state represents a mailbox that is in a standby state
93 * with interrupts disabled. In this state the mailbox should not
94 * read the mailbox or write any data. The only means of exiting
95 * this state is for the system to make the connect() call for the
96 * mailbox, it will then transition to the connect state.
97 * Connect: In this state the mailbox is seeking a connection. It will
98 * post a connect message with no specified destination and will
99 * wait for a reply from the other side of the mailbox. This state
100 * is exited when either a connect with the local mailbox as the
101 * destination is received or when a data message is received with
102 * a valid sequence number.
103 * Open: In this state the mailbox is able to transfer data between the local
104 * entity and the remote. It will fall back to connect in the event of
105 * receiving either an error message, or a disconnect message. It will
106 * transition to disconnect on a call to disconnect();
107 * Disconnect: In this state the mailbox is attempting to gracefully terminate
108 * the connection. It will do so at the first point where it knows
109 * that the remote endpoint is either done sending, or when the
110 * remote endpoint has fallen back into connect.
112 enum fm10k_mbx_state {
116 FM10K_STATE_DISCONNECT,
119 /* PF/VF Mailbox header format
121 * 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
122 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
123 * | Size/Err_no/CRC | Rsvd0 | Head | Tail | Type |
124 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126 * The layout above describes the format for the header used in the PF/VF
127 * mailbox. The header is broken out into the following fields:
128 * Type: There are 4 supported message types
129 * 0x8: Data header - used to transport message data
130 * 0xC: Connect header - used to establish connection
131 * 0xD: Disconnect header - used to tear down a connection
132 * 0xE: Error header - used to address message exceptions
133 * Tail: Tail index for local FIFO
134 * Tail index actually consists of two parts. The MSB of
135 * the head is a loop tracker, it is 0 on an even numbered
136 * loop through the FIFO, and 1 on the odd numbered loops.
137 * To get the actual mailbox offset based on the tail it
138 * is necessary to add bit 3 to bit 0 and clear bit 3. This
139 * gives us a valid range of 0x1 - 0xE.
140 * Head: Head index for remote FIFO
141 * Head index follows the same format as the tail index.
142 * Rsvd0: Reserved 0 portion of the mailbox header
143 * CRC: Running CRC for all data since connect plus current message header
144 * Size: Maximum message size - Applies only to connect headers
145 * The maximum message size is provided during connect to avoid
146 * jamming the mailbox with messages that do not fit.
147 * Err_no: Error number - Applies only to error headers
148 * The error number provides an indication of the type of error
152 /* macros for retrieving and setting header values */
153 #define FM10K_MSG_HDR_MASK(name) \
154 ((0x1u << FM10K_MSG_##name##_SIZE) - 1)
155 #define FM10K_MSG_HDR_FIELD_SET(value, name) \
156 (((u32)(value) & FM10K_MSG_HDR_MASK(name)) << FM10K_MSG_##name##_SHIFT)
157 #define FM10K_MSG_HDR_FIELD_GET(value, name) \
158 ((u16)((value) >> FM10K_MSG_##name##_SHIFT) & FM10K_MSG_HDR_MASK(name))
160 /* offsets shared between all headers */
161 #define FM10K_MSG_TYPE_SHIFT 0
162 #define FM10K_MSG_TYPE_SIZE 4
163 #define FM10K_MSG_TAIL_SHIFT 4
164 #define FM10K_MSG_TAIL_SIZE 4
165 #define FM10K_MSG_HEAD_SHIFT 8
166 #define FM10K_MSG_HEAD_SIZE 4
167 #define FM10K_MSG_RSVD0_SHIFT 12
168 #define FM10K_MSG_RSVD0_SIZE 4
170 /* offsets for data/disconnect headers */
171 #define FM10K_MSG_CRC_SHIFT 16
172 #define FM10K_MSG_CRC_SIZE 16
174 /* offsets for connect headers */
175 #define FM10K_MSG_CONNECT_SIZE_SHIFT 16
176 #define FM10K_MSG_CONNECT_SIZE_SIZE 16
178 /* offsets for error headers */
179 #define FM10K_MSG_ERR_NO_SHIFT 16
180 #define FM10K_MSG_ERR_NO_SIZE 16
182 enum fm10k_msg_type {
183 FM10K_MSG_DATA = 0x8,
184 FM10K_MSG_CONNECT = 0xC,
185 FM10K_MSG_DISCONNECT = 0xD,
186 FM10K_MSG_ERROR = 0xE,
189 /* HNI/SM Mailbox FIFO format
191 * 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
192 * +-------+-----------------------+-------+-----------------------+
193 * | Error | Remote Head |Version| Local Tail |
194 * +-------+-----------------------+-------+-----------------------+
196 * . Local FIFO Data .
198 * +-------+-----------------------+-------+-----------------------+
200 * The layout above describes the format for the FIFOs used by the host
201 * network interface and the switch manager to communicate messages back
202 * and forth. Both the HNI and the switch maintain one such FIFO. The
203 * layout in memory has the switch manager FIFO followed immediately by
204 * the HNI FIFO. For this reason I am using just the pointer to the
205 * HNI FIFO in the mailbox ops as the offset between the two is fixed.
207 * The header for the FIFO is broken out into the following fields:
208 * Local Tail: Offset into FIFO region for next DWORD to write.
209 * Version: Version info for mailbox, only values of 0/1 are supported.
210 * Remote Head: Offset into remote FIFO to indicate how much we have read.
211 * Error: Error indication, values TBD.
214 /* version number for switch manager mailboxes */
215 #define FM10K_SM_MBX_VERSION 1
216 #define FM10K_SM_MBX_FIFO_LEN (FM10K_MBMEM_PF_XOR - 1)
218 /* offsets shared between all SM FIFO headers */
219 #define FM10K_MSG_SM_TAIL_SHIFT 0
220 #define FM10K_MSG_SM_TAIL_SIZE 12
221 #define FM10K_MSG_SM_VER_SHIFT 12
222 #define FM10K_MSG_SM_VER_SIZE 4
223 #define FM10K_MSG_SM_HEAD_SHIFT 16
224 #define FM10K_MSG_SM_HEAD_SIZE 12
225 #define FM10K_MSG_SM_ERR_SHIFT 28
226 #define FM10K_MSG_SM_ERR_SIZE 4
228 /* All error messages returned by mailbox functions
229 * The value -511 is 0xFE01 in hex. The idea is to order the errors
230 * from 0xFE01 - 0xFEFF so error codes are easily visible in the mailbox
231 * messages. This also helps to avoid error number collisions as Linux
232 * doesn't appear to use error numbers 256 - 511.
234 #define FM10K_MBX_ERR(_n) ((_n) - 512)
235 #define FM10K_MBX_ERR_NO_MBX FM10K_MBX_ERR(0x01)
236 #define FM10K_MBX_ERR_NO_SPACE FM10K_MBX_ERR(0x03)
237 #define FM10K_MBX_ERR_TAIL FM10K_MBX_ERR(0x05)
238 #define FM10K_MBX_ERR_HEAD FM10K_MBX_ERR(0x06)
239 #define FM10K_MBX_ERR_SRC FM10K_MBX_ERR(0x08)
240 #define FM10K_MBX_ERR_TYPE FM10K_MBX_ERR(0x09)
241 #define FM10K_MBX_ERR_SIZE FM10K_MBX_ERR(0x0B)
242 #define FM10K_MBX_ERR_BUSY FM10K_MBX_ERR(0x0C)
243 #define FM10K_MBX_ERR_RSVD0 FM10K_MBX_ERR(0x0E)
244 #define FM10K_MBX_ERR_CRC FM10K_MBX_ERR(0x0F)
246 #define FM10K_MBX_CRC_SEED 0xFFFF
248 struct fm10k_mbx_ops {
249 s32 (*connect)(struct fm10k_hw *, struct fm10k_mbx_info *);
250 void (*disconnect)(struct fm10k_hw *, struct fm10k_mbx_info *);
251 bool (*rx_ready)(struct fm10k_mbx_info *);
252 bool (*tx_ready)(struct fm10k_mbx_info *, u16);
253 bool (*tx_complete)(struct fm10k_mbx_info *);
254 s32 (*enqueue_tx)(struct fm10k_hw *, struct fm10k_mbx_info *,
256 s32 (*process)(struct fm10k_hw *, struct fm10k_mbx_info *);
257 s32 (*register_handlers)(struct fm10k_mbx_info *,
258 const struct fm10k_msg_data *);
261 struct fm10k_mbx_fifo {
268 /* size of buffer to be stored in mailbox for FIFOs */
269 #define FM10K_MBX_TX_BUFFER_SIZE 512
270 #define FM10K_MBX_RX_BUFFER_SIZE 128
271 #define FM10K_MBX_BUFFER_SIZE \
272 (FM10K_MBX_TX_BUFFER_SIZE + FM10K_MBX_RX_BUFFER_SIZE)
274 /* minimum and maximum message size in dwords */
275 #define FM10K_MBX_MSG_MAX_SIZE \
276 ((FM10K_MBX_TX_BUFFER_SIZE - 1) & (FM10K_MBX_RX_BUFFER_SIZE - 1))
277 #define FM10K_VFMBX_MSG_MTU ((FM10K_VFMBMEM_LEN / 2) - 1)
279 #define FM10K_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
280 #define FM10K_MBX_INIT_DELAY 500 /* microseconds between retries */
282 struct fm10k_mbx_info {
283 /* function pointers for mailbox operations */
284 struct fm10k_mbx_ops ops;
285 const struct fm10k_msg_data *msg_data;
288 struct fm10k_mbx_fifo rx;
289 struct fm10k_mbx_fifo tx;
291 /* delay for handling timeouts */
295 /* mailbox state info */
296 u32 mbx_reg, mbmem_reg, mbx_lock, mbx_hdr;
297 u16 max_size, mbmem_len;
298 u16 tail, tail_len, pulled;
299 u16 head, head_len, pushed;
301 enum fm10k_mbx_state state;
303 /* result of last mailbox test */
317 /* Buffer to store messages */
318 u32 buffer[FM10K_MBX_BUFFER_SIZE];
321 s32 fm10k_pfvf_mbx_init(struct fm10k_hw *, struct fm10k_mbx_info *,
322 const struct fm10k_msg_data *, u8);
323 s32 fm10k_sm_mbx_init(struct fm10k_hw *, struct fm10k_mbx_info *,
324 const struct fm10k_msg_data *);
326 #endif /* _FM10K_MBX_H_ */