]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2019 Intel Corporation
6 #include "ifpga_compat.h"
8 /*transaction opcodes*/
9 #define SPI_TRAN_SEQ_WRITE 0x04 /* SPI transaction sequential write */
10 #define SPI_TRAN_SEQ_READ 0x14 /* SPI transaction sequential read */
11 #define SPI_TRAN_NON_SEQ_WRITE 0x00 /* SPI transaction non-sequential write */
12 #define SPI_TRAN_NON_SEQ_READ 0x10 /* SPI transaction non-sequential read*/
14 /*specail packet characters*/
15 #define SPI_PACKET_SOP 0x7a
16 #define SPI_PACKET_EOP 0x7b
17 #define SPI_PACKET_CHANNEL 0x7c
18 #define SPI_PACKET_ESC 0x7d
20 /*special byte characters*/
21 #define SPI_BYTE_IDLE 0x4a
22 #define SPI_BYTE_ESC 0x4d
24 #define SPI_REG_BYTES 4
26 #define INIT_SPI_TRAN_HEADER(trans_type, size, address) \
28 header.trans_type = trans_type; \
30 header.size = cpu_to_be16(size); \
31 header.addr = cpu_to_be32(addr); \
35 static void print_buffer(const char *string
, void *buffer
, int len
)
38 unsigned char *p
= buffer
;
40 printf("%s print buffer, len=%d\n", string
, len
);
42 for (i
= 0; i
< len
; i
++)
43 printf("%x ", *(p
+i
));
47 static void print_buffer(const char *string
, void *buffer
, int len
)
55 static unsigned char xor_20(unsigned char val
)
60 static void reorder_phy_data(u8 bits_per_word
,
61 void *buf
, unsigned int len
)
63 unsigned int count
= len
/ (bits_per_word
/8);
66 if (bits_per_word
== 32) {
81 static int resp_find_sop_eop(unsigned char *resp
, unsigned int len
,
84 int ret
= SPI_NOT_FOUND
;
86 unsigned char *b
= resp
;
89 if (flags
!= SPI_FOUND_SOP
) {
90 while (b
< resp
+ len
&& *b
!= SPI_PACKET_SOP
)
93 if (*b
!= SPI_PACKET_SOP
)
100 while (b
< resp
+ len
&& *b
!= SPI_PACKET_EOP
)
103 if (*b
!= SPI_PACKET_EOP
)
112 static int byte_to_core_convert(struct spi_transaction_dev
*dev
,
113 unsigned int send_len
, unsigned char *send_data
,
114 unsigned int resp_len
, unsigned char *resp_data
,
115 unsigned int *valid_resp_len
)
119 unsigned char *send_packet
= dev
->buffer
->bytes_send
;
120 unsigned char *resp_packet
= dev
->buffer
->bytes_resp
;
122 unsigned char current_byte
;
123 unsigned char *tx_buffer
;
124 unsigned int tx_len
= 0;
125 unsigned char *rx_buffer
;
126 unsigned int rx_len
= 0;
129 unsigned int resp_max_len
= 2 * resp_len
;
131 print_buffer("before bytes:", send_data
, send_len
);
135 for (i
= 0; i
< send_len
; i
++) {
136 current_byte
= send_data
[i
];
137 switch (current_byte
) {
139 *p
++ = SPI_BYTE_IDLE
;
140 *p
++ = xor_20(current_byte
);
144 *p
++ = xor_20(current_byte
);
152 print_buffer("before spi:", send_packet
, p
-send_packet
);
154 reorder_phy_data(32, send_packet
, p
- send_packet
);
156 print_buffer("after order to spi:", send_packet
, p
-send_packet
);
159 tx_buffer
= send_packet
;
160 tx_len
= p
- send_packet
;
161 rx_buffer
= resp_packet
;
162 rx_len
= resp_max_len
;
163 spi_flags
= SPI_NOT_FOUND
;
166 ret
= spi_command(dev
->dev
, dev
->chipselect
, tx_len
, tx_buffer
,
171 print_buffer("read from spi:", rx_buffer
, rx_len
);
173 /* look for SOP firstly*/
174 ret
= resp_find_sop_eop(rx_buffer
, rx_len
- 1, spi_flags
);
175 if (ret
!= SPI_FOUND_EOP
) {
179 dev_err(NULL
, "cannot found valid data from SPI\n");
183 if (ret
== SPI_FOUND_SOP
) {
185 resp_max_len
+= rx_len
;
192 print_buffer("found valid data:", resp_packet
, resp_max_len
);
194 /* analyze response packet */
197 while (i
< resp_max_len
) {
198 current_byte
= resp_packet
[i
];
199 switch (current_byte
) {
205 current_byte
= resp_packet
[i
];
206 *p
++ = xor_20(current_byte
);
216 /* receive "4a" means the SPI is idle, not valid data */
217 *valid_resp_len
= p
- resp_data
;
218 if (*valid_resp_len
== 0) {
219 dev_err(NULL
, "error: repond package without valid data\n");
226 static int packet_to_byte_conver(struct spi_transaction_dev
*dev
,
227 unsigned int send_len
, unsigned char *send_buf
,
228 unsigned int resp_len
, unsigned char *resp_buf
,
233 unsigned char current_byte
;
234 unsigned int resp_max_len
;
235 unsigned char *send_packet
= dev
->buffer
->packet_send
;
236 unsigned char *resp_packet
= dev
->buffer
->packet_resp
;
238 unsigned int valid_resp_len
= 0;
240 print_buffer("before packet:", send_buf
, send_len
);
242 resp_max_len
= 2 * resp_len
+ 4;
247 *p
++ = SPI_PACKET_SOP
;
249 *p
++ = SPI_PACKET_CHANNEL
;
252 /* append the data into a packet */
253 for (i
= 0; i
< send_len
; i
++) {
254 current_byte
= send_buf
[i
];
256 /* EOP for last byte */
257 if (i
== send_len
- 1)
258 *p
++ = SPI_PACKET_EOP
;
260 switch (current_byte
) {
263 case SPI_PACKET_CHANNEL
:
265 *p
++ = SPI_PACKET_ESC
;
266 *p
++ = xor_20(current_byte
);
273 ret
= byte_to_core_convert(dev
, p
- send_packet
,
274 send_packet
, resp_max_len
, resp_packet
,
279 print_buffer("after byte conver:", resp_packet
, valid_resp_len
);
281 /* analyze the response packet */
285 for (i
= 0; i
< valid_resp_len
; i
++) {
286 if (resp_packet
[i
] == SPI_PACKET_SOP
)
290 if (i
== valid_resp_len
) {
291 dev_err(NULL
, "error on analyze response packet 0x%x\n",
298 /* continue parsing data after SOP */
299 while (i
< valid_resp_len
) {
300 current_byte
= resp_packet
[i
];
302 switch (current_byte
) {
304 case SPI_PACKET_CHANNEL
:
307 current_byte
= resp_packet
[i
];
308 *p
++ = xor_20(current_byte
);
313 current_byte
= resp_packet
[i
];
314 if (current_byte
== SPI_PACKET_ESC
||
315 current_byte
== SPI_PACKET_CHANNEL
||
316 current_byte
== SPI_PACKET_SOP
) {
318 current_byte
= resp_packet
[i
];
319 *p
++ = xor_20(current_byte
);
331 *valid
= p
- resp_buf
;
333 print_buffer("after packet:", resp_buf
, *valid
);
338 static int do_transaction(struct spi_transaction_dev
*dev
, unsigned int addr
,
339 unsigned int size
, unsigned char *data
,
340 unsigned int trans_type
)
343 struct spi_tran_header header
;
344 unsigned char *transaction
= dev
->buffer
->tran_send
;
345 unsigned char *response
= dev
->buffer
->tran_resp
;
349 unsigned int valid_len
= 0;
351 /* make transacation header */
352 INIT_SPI_TRAN_HEADER(trans_type
, size
, addr
);
354 /* fill the header */
356 opae_memcpy(p
, &header
, sizeof(struct spi_tran_header
));
357 p
= p
+ sizeof(struct spi_tran_header
);
359 switch (trans_type
) {
360 case SPI_TRAN_SEQ_WRITE
:
361 case SPI_TRAN_NON_SEQ_WRITE
:
362 for (i
= 0; i
< size
; i
++)
365 ret
= packet_to_byte_conver(dev
, size
+ HEADER_LEN
,
366 transaction
, RESPONSE_LEN
, response
,
371 /* check the result */
372 if (size
!= ((unsigned int)(response
[2] & 0xff) << 8 |
373 (unsigned int)(response
[3] & 0xff)))
377 case SPI_TRAN_SEQ_READ
:
378 case SPI_TRAN_NON_SEQ_READ
:
379 ret
= packet_to_byte_conver(dev
, HEADER_LEN
,
380 transaction
, size
, response
,
382 if (ret
|| valid_len
!= size
)
385 for (i
= 0; i
< size
; i
++)
386 *data
++ = *response
++;
395 int spi_transaction_read(struct spi_transaction_dev
*dev
, unsigned int addr
,
396 unsigned int size
, unsigned char *data
)
398 return do_transaction(dev
, addr
, size
, data
,
399 (size
> SPI_REG_BYTES
) ?
400 SPI_TRAN_SEQ_READ
: SPI_TRAN_NON_SEQ_READ
);
403 int spi_transaction_write(struct spi_transaction_dev
*dev
, unsigned int addr
,
404 unsigned int size
, unsigned char *data
)
406 return do_transaction(dev
, addr
, size
, data
,
407 (size
> SPI_REG_BYTES
) ?
408 SPI_TRAN_SEQ_WRITE
: SPI_TRAN_NON_SEQ_WRITE
);
411 struct spi_transaction_dev
*spi_transaction_init(struct altera_spi_device
*dev
,
414 struct spi_transaction_dev
*spi_tran_dev
;
416 spi_tran_dev
= opae_malloc(sizeof(struct spi_transaction_dev
));
420 spi_tran_dev
->dev
= dev
;
421 spi_tran_dev
->chipselect
= chipselect
;
423 spi_tran_dev
->buffer
= opae_malloc(sizeof(struct spi_tran_buffer
));
424 if (!spi_tran_dev
->buffer
) {
425 opae_free(spi_tran_dev
);
432 void spi_transaction_remove(struct spi_transaction_dev
*dev
)
434 if (dev
&& dev
->buffer
)
435 opae_free(dev
->buffer
);