1 /* ////////////////////////////////////////////////////////////////////////// */
2 /*  */
3 /* Copyright (c) Atmel Corporation.  All rights reserved. */
4 /*  */
5 /* Module Name:  wilc_spi.c */
6 /*  */
7 /*  */
8 /* //////////////////////////////////////////////////////////////////////////// */
9 
10 #include <linux/string.h>
11 #include "wilc_wlan_if.h"
12 #include "wilc_wlan.h"
13 
14 typedef struct {
15 	void *os_context;
16 	int (*spi_tx)(u8 *, u32);
17 	int (*spi_rx)(u8 *, u32);
18 	int (*spi_trx)(u8 *, u8 *, u32);
19 	int (*spi_max_speed)(void);
20 	wilc_debug_func dPrint;
21 	int crc_off;
22 	int nint;
23 	int has_thrpt_enh;
24 } wilc_spi_t;
25 
26 static wilc_spi_t g_spi;
27 
28 static int spi_read(u32, u8 *, u32);
29 static int spi_write(u32, u8 *, u32);
30 
31 /********************************************
32  *
33  *      Crc7
34  *
35  ********************************************/
36 
37 static const u8 crc7_syndrome_table[256] = {
38 	0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
39 	0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
40 	0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
41 	0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
42 	0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
43 	0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
44 	0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
45 	0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
46 	0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
47 	0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
48 	0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
49 	0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
50 	0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
51 	0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
52 	0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
53 	0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
54 	0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
55 	0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
56 	0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
57 	0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
58 	0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
59 	0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
60 	0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
61 	0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
62 	0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
63 	0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
64 	0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
65 	0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
66 	0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
67 	0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
68 	0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
69 	0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
70 };
71 
crc7_byte(u8 crc,u8 data)72 static u8 crc7_byte(u8 crc, u8 data)
73 {
74 	return crc7_syndrome_table[(crc << 1) ^ data];
75 }
76 
crc7(u8 crc,const u8 * buffer,u32 len)77 static u8 crc7(u8 crc, const u8 *buffer, u32 len)
78 {
79 	while (len--)
80 		crc = crc7_byte(crc, *buffer++);
81 	return crc;
82 }
83 
84 /********************************************
85  *
86  *      Spi protocol Function
87  *
88  ********************************************/
89 
90 #define CMD_DMA_WRITE				0xc1
91 #define CMD_DMA_READ				0xc2
92 #define CMD_INTERNAL_WRITE		0xc3
93 #define CMD_INTERNAL_READ		0xc4
94 #define CMD_TERMINATE				0xc5
95 #define CMD_REPEAT					0xc6
96 #define CMD_DMA_EXT_WRITE		0xc7
97 #define CMD_DMA_EXT_READ		0xc8
98 #define CMD_SINGLE_WRITE			0xc9
99 #define CMD_SINGLE_READ			0xca
100 #define CMD_RESET						0xcf
101 
102 #define N_OK								1
103 #define N_FAIL								0
104 #define N_RESET							-1
105 #define N_RETRY							-2
106 
107 #define DATA_PKT_SZ_256				256
108 #define DATA_PKT_SZ_512			512
109 #define DATA_PKT_SZ_1K				1024
110 #define DATA_PKT_SZ_4K				(4 * 1024)
111 #define DATA_PKT_SZ_8K				(8 * 1024)
112 #define DATA_PKT_SZ					DATA_PKT_SZ_8K
113 
spi_cmd(u8 cmd,u32 adr,u32 data,u32 sz,u8 clockless)114 static int spi_cmd(u8 cmd, u32 adr, u32 data, u32 sz, u8 clockless)
115 {
116 	u8 bc[9];
117 	int len = 5;
118 	int result = N_OK;
119 
120 	bc[0] = cmd;
121 	switch (cmd) {
122 	case CMD_SINGLE_READ:                           /* single word (4 bytes) read */
123 		bc[1] = (u8)(adr >> 16);
124 		bc[2] = (u8)(adr >> 8);
125 		bc[3] = (u8)adr;
126 		len = 5;
127 		break;
128 
129 	case CMD_INTERNAL_READ:                 /* internal register read */
130 		bc[1] = (u8)(adr >> 8);
131 		if (clockless)
132 			bc[1] |= BIT(7);
133 		bc[2] = (u8)adr;
134 		bc[3] = 0x00;
135 		len = 5;
136 		break;
137 
138 	case CMD_TERMINATE:                                     /* termination */
139 		bc[1] = 0x00;
140 		bc[2] = 0x00;
141 		bc[3] = 0x00;
142 		len = 5;
143 		break;
144 
145 	case CMD_REPEAT:                                                /* repeat */
146 		bc[1] = 0x00;
147 		bc[2] = 0x00;
148 		bc[3] = 0x00;
149 		len = 5;
150 		break;
151 
152 	case CMD_RESET:                                                 /* reset */
153 		bc[1] = 0xff;
154 		bc[2] = 0xff;
155 		bc[3] = 0xff;
156 		len = 5;
157 		break;
158 
159 	case CMD_DMA_WRITE:                                     /* dma write */
160 	case CMD_DMA_READ:                                      /* dma read */
161 		bc[1] = (u8)(adr >> 16);
162 		bc[2] = (u8)(adr >> 8);
163 		bc[3] = (u8)adr;
164 		bc[4] = (u8)(sz >> 8);
165 		bc[5] = (u8)(sz);
166 		len = 7;
167 		break;
168 
169 	case CMD_DMA_EXT_WRITE:         /* dma extended write */
170 	case CMD_DMA_EXT_READ:                  /* dma extended read */
171 		bc[1] = (u8)(adr >> 16);
172 		bc[2] = (u8)(adr >> 8);
173 		bc[3] = (u8)adr;
174 		bc[4] = (u8)(sz >> 16);
175 		bc[5] = (u8)(sz >> 8);
176 		bc[6] = (u8)(sz);
177 		len = 8;
178 		break;
179 
180 	case CMD_INTERNAL_WRITE:                /* internal register write */
181 		bc[1] = (u8)(adr >> 8);
182 		if (clockless)
183 			bc[1] |= BIT(7);
184 		bc[2] = (u8)(adr);
185 		bc[3] = (u8)(data >> 24);
186 		bc[4] = (u8)(data >> 16);
187 		bc[5] = (u8)(data >> 8);
188 		bc[6] = (u8)(data);
189 		len = 8;
190 		break;
191 
192 	case CMD_SINGLE_WRITE:                  /* single word write */
193 		bc[1] = (u8)(adr >> 16);
194 		bc[2] = (u8)(adr >> 8);
195 		bc[3] = (u8)(adr);
196 		bc[4] = (u8)(data >> 24);
197 		bc[5] = (u8)(data >> 16);
198 		bc[6] = (u8)(data >> 8);
199 		bc[7] = (u8)(data);
200 		len = 9;
201 		break;
202 
203 	default:
204 		result = N_FAIL;
205 		break;
206 	}
207 
208 	if (result) {
209 		if (!g_spi.crc_off)
210 			bc[len - 1] = (crc7(0x7f, (const u8 *)&bc[0], len - 1)) << 1;
211 		else
212 			len -= 1;
213 
214 		if (!g_spi.spi_tx(bc, len)) {
215 			PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n");
216 			result = N_FAIL;
217 		}
218 	}
219 
220 	return result;
221 }
222 
spi_cmd_rsp(u8 cmd)223 static int spi_cmd_rsp(u8 cmd)
224 {
225 	u8 rsp;
226 	int result = N_OK;
227 
228 	/**
229 	 *      Command/Control response
230 	 **/
231 	if ((cmd == CMD_RESET) ||
232 	    (cmd == CMD_TERMINATE) ||
233 	    (cmd == CMD_REPEAT)) {
234 		if (!g_spi.spi_rx(&rsp, 1)) {
235 			result = N_FAIL;
236 			goto _fail_;
237 		}
238 	}
239 
240 	if (!g_spi.spi_rx(&rsp, 1)) {
241 		PRINT_ER("[wilc spi]: Failed cmd response read, bus error...\n");
242 		result = N_FAIL;
243 		goto _fail_;
244 	}
245 
246 	if (rsp != cmd) {
247 		PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x), resp (%02x)\n", cmd, rsp);
248 		result = N_FAIL;
249 		goto _fail_;
250 	}
251 
252 	/**
253 	 *      State response
254 	 **/
255 	if (!g_spi.spi_rx(&rsp, 1)) {
256 		PRINT_ER("[wilc spi]: Failed cmd state read, bus error...\n");
257 		result = N_FAIL;
258 		goto _fail_;
259 	}
260 
261 	if (rsp != 0x00) {
262 		PRINT_ER("[wilc spi]: Failed cmd state response state (%02x)\n", rsp);
263 		result = N_FAIL;
264 	}
265 
266 _fail_:
267 
268 	return result;
269 }
270 
spi_cmd_complete(u8 cmd,u32 adr,u8 * b,u32 sz,u8 clockless)271 static int spi_cmd_complete(u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless)
272 {
273 	u8 wb[32], rb[32];
274 	u8 wix, rix;
275 	u32 len2;
276 	u8 rsp;
277 	int len = 0;
278 	int result = N_OK;
279 
280 	wb[0] = cmd;
281 	switch (cmd) {
282 	case CMD_SINGLE_READ:                           /* single word (4 bytes) read */
283 		wb[1] = (u8)(adr >> 16);
284 		wb[2] = (u8)(adr >> 8);
285 		wb[3] = (u8)adr;
286 		len = 5;
287 		break;
288 
289 	case CMD_INTERNAL_READ:                 /* internal register read */
290 		wb[1] = (u8)(adr >> 8);
291 		if (clockless == 1)
292 			wb[1] |= BIT(7);
293 		wb[2] = (u8)adr;
294 		wb[3] = 0x00;
295 		len = 5;
296 		break;
297 
298 	case CMD_TERMINATE:                                     /* termination */
299 		wb[1] = 0x00;
300 		wb[2] = 0x00;
301 		wb[3] = 0x00;
302 		len = 5;
303 		break;
304 
305 	case CMD_REPEAT:                                                /* repeat */
306 		wb[1] = 0x00;
307 		wb[2] = 0x00;
308 		wb[3] = 0x00;
309 		len = 5;
310 		break;
311 
312 	case CMD_RESET:                                                 /* reset */
313 		wb[1] = 0xff;
314 		wb[2] = 0xff;
315 		wb[3] = 0xff;
316 		len = 5;
317 		break;
318 
319 	case CMD_DMA_WRITE:                                     /* dma write */
320 	case CMD_DMA_READ:                                      /* dma read */
321 		wb[1] = (u8)(adr >> 16);
322 		wb[2] = (u8)(adr >> 8);
323 		wb[3] = (u8)adr;
324 		wb[4] = (u8)(sz >> 8);
325 		wb[5] = (u8)(sz);
326 		len = 7;
327 		break;
328 
329 	case CMD_DMA_EXT_WRITE:         /* dma extended write */
330 	case CMD_DMA_EXT_READ:                  /* dma extended read */
331 		wb[1] = (u8)(adr >> 16);
332 		wb[2] = (u8)(adr >> 8);
333 		wb[3] = (u8)adr;
334 		wb[4] = (u8)(sz >> 16);
335 		wb[5] = (u8)(sz >> 8);
336 		wb[6] = (u8)(sz);
337 		len = 8;
338 		break;
339 
340 	case CMD_INTERNAL_WRITE:                /* internal register write */
341 		wb[1] = (u8)(adr >> 8);
342 		if (clockless == 1)
343 			wb[1] |= BIT(7);
344 		wb[2] = (u8)(adr);
345 		wb[3] = b[3];
346 		wb[4] = b[2];
347 		wb[5] = b[1];
348 		wb[6] = b[0];
349 		len = 8;
350 		break;
351 
352 	case CMD_SINGLE_WRITE:                  /* single word write */
353 		wb[1] = (u8)(adr >> 16);
354 		wb[2] = (u8)(adr >> 8);
355 		wb[3] = (u8)(adr);
356 		wb[4] = b[3];
357 		wb[5] = b[2];
358 		wb[6] = b[1];
359 		wb[7] = b[0];
360 		len = 9;
361 		break;
362 
363 	default:
364 		result = N_FAIL;
365 		break;
366 	}
367 
368 	if (result != N_OK) {
369 		return result;
370 	}
371 
372 	if (!g_spi.crc_off)
373 		wb[len - 1] = (crc7(0x7f, (const u8 *)&wb[0], len - 1)) << 1;
374 	else
375 		len -= 1;
376 
377 #define NUM_SKIP_BYTES (1)
378 #define NUM_RSP_BYTES (2)
379 #define NUM_DATA_HDR_BYTES (1)
380 #define NUM_DATA_BYTES (4)
381 #define NUM_CRC_BYTES (2)
382 #define NUM_DUMMY_BYTES (3)
383 	if ((cmd == CMD_RESET) ||
384 	    (cmd == CMD_TERMINATE) ||
385 	    (cmd == CMD_REPEAT)) {
386 		len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES);
387 	} else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
388 		if (!g_spi.crc_off) {
389 			len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
390 				      + NUM_CRC_BYTES + NUM_DUMMY_BYTES);
391 		} else {
392 			len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
393 				      + NUM_DUMMY_BYTES);
394 		}
395 	} else {
396 		len2 = len + (NUM_RSP_BYTES + NUM_DUMMY_BYTES);
397 	}
398 #undef NUM_DUMMY_BYTES
399 
400 	if (len2 > ARRAY_SIZE(wb)) {
401 		PRINT_ER("[wilc spi]: spi buffer size too small (%d) (%zu)\n",
402 			 len2, ARRAY_SIZE(wb));
403 		result = N_FAIL;
404 		return result;
405 	}
406 	/* zero spi write buffers. */
407 	for (wix = len; wix < len2; wix++) {
408 		wb[wix] = 0;
409 	}
410 	rix = len;
411 
412 	if (!g_spi.spi_trx(wb, rb, len2)) {
413 		PRINT_ER("[wilc spi]: Failed cmd write, bus error...\n");
414 		result = N_FAIL;
415 		return result;
416 	}
417 
418 	/**
419 	 * Command/Control response
420 	 **/
421 	if ((cmd == CMD_RESET) ||
422 	    (cmd == CMD_TERMINATE) ||
423 	    (cmd == CMD_REPEAT)) {
424 		rix++;         /* skip 1 byte */
425 	}
426 
427 	/* do { */
428 	rsp = rb[rix++];
429 	/*	if(rsp == cmd) break; */
430 	/* } while(&rptr[1] <= &rb[len2]); */
431 
432 	if (rsp != cmd) {
433 		PRINT_ER("[wilc spi]: Failed cmd response, cmd (%02x)"
434 			 ", resp (%02x)\n", cmd, rsp);
435 		result = N_FAIL;
436 		return result;
437 	}
438 
439 	/**
440 	 * State response
441 	 **/
442 	rsp = rb[rix++];
443 	if (rsp != 0x00) {
444 		PRINT_ER("[wilc spi]: Failed cmd state response "
445 			 "state (%02x)\n", rsp);
446 		result = N_FAIL;
447 		return result;
448 	}
449 
450 	if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)
451 	    || (cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
452 		int retry;
453 		/* u16 crc1, crc2; */
454 		u8 crc[2];
455 		/**
456 		 * Data Respnose header
457 		 **/
458 		retry = 100;
459 		do {
460 			/* ensure there is room in buffer later to read data and crc */
461 			if (rix < len2) {
462 				rsp = rb[rix++];
463 			} else {
464 				retry = 0;
465 				break;
466 			}
467 			if (((rsp >> 4) & 0xf) == 0xf)
468 				break;
469 		} while (retry--);
470 
471 		if (retry <= 0) {
472 			PRINT_ER("[wilc spi]: Error, data read "
473 				 "response (%02x)\n", rsp);
474 			result = N_RESET;
475 			return result;
476 		}
477 
478 		if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
479 			/**
480 			 * Read bytes
481 			 **/
482 			if ((rix + 3) < len2) {
483 				b[0] = rb[rix++];
484 				b[1] = rb[rix++];
485 				b[2] = rb[rix++];
486 				b[3] = rb[rix++];
487 			} else {
488 				PRINT_ER("[wilc spi]: buffer overrun when reading data.\n");
489 				result = N_FAIL;
490 				return result;
491 			}
492 
493 			if (!g_spi.crc_off) {
494 				/**
495 				 * Read Crc
496 				 **/
497 				if ((rix + 1) < len2) {
498 					crc[0] = rb[rix++];
499 					crc[1] = rb[rix++];
500 				} else {
501 					PRINT_ER("[wilc spi]: buffer overrun when reading crc.\n");
502 					result = N_FAIL;
503 					return result;
504 				}
505 			}
506 		} else if ((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
507 			int ix;
508 
509 			/* some data may be read in response to dummy bytes. */
510 			for (ix = 0; (rix < len2) && (ix < sz); ) {
511 				b[ix++] = rb[rix++];
512 			}
513 
514 			sz -= ix;
515 
516 			if (sz > 0) {
517 				int nbytes;
518 
519 				if (sz <= (DATA_PKT_SZ - ix))
520 					nbytes = sz;
521 				else
522 					nbytes = DATA_PKT_SZ - ix;
523 
524 				/**
525 				 * Read bytes
526 				 **/
527 				if (!g_spi.spi_rx(&b[ix], nbytes)) {
528 					PRINT_ER("[wilc spi]: Failed data block read, bus error...\n");
529 					result = N_FAIL;
530 					goto _error_;
531 				}
532 
533 				/**
534 				 * Read Crc
535 				 **/
536 				if (!g_spi.crc_off) {
537 					if (!g_spi.spi_rx(crc, 2)) {
538 						PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n");
539 						result = N_FAIL;
540 						goto _error_;
541 					}
542 				}
543 
544 
545 				ix += nbytes;
546 				sz -= nbytes;
547 			}
548 
549 			/*  if any data in left unread, then read the rest using normal DMA code.*/
550 			while (sz > 0) {
551 				int nbytes;
552 
553 				if (sz <= DATA_PKT_SZ)
554 					nbytes = sz;
555 				else
556 					nbytes = DATA_PKT_SZ;
557 
558 				/**
559 				 * read data response only on the next DMA cycles not
560 				 * the first DMA since data response header is already
561 				 * handled above for the first DMA.
562 				 **/
563 				/**
564 				 * Data Respnose header
565 				 **/
566 				retry = 10;
567 				do {
568 					if (!g_spi.spi_rx(&rsp, 1)) {
569 						PRINT_ER("[wilc spi]: Failed data response read, bus error...\n");
570 						result = N_FAIL;
571 						break;
572 					}
573 					if (((rsp >> 4) & 0xf) == 0xf)
574 						break;
575 				} while (retry--);
576 
577 				if (result == N_FAIL)
578 					break;
579 
580 
581 				/**
582 				 * Read bytes
583 				 **/
584 				if (!g_spi.spi_rx(&b[ix], nbytes)) {
585 					PRINT_ER("[wilc spi]: Failed data block read, bus error...\n");
586 					result = N_FAIL;
587 					break;
588 				}
589 
590 				/**
591 				 * Read Crc
592 				 **/
593 				if (!g_spi.crc_off) {
594 					if (!g_spi.spi_rx(crc, 2)) {
595 						PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n");
596 						result = N_FAIL;
597 						break;
598 					}
599 				}
600 
601 				ix += nbytes;
602 				sz -= nbytes;
603 			}
604 		}
605 	}
606 _error_:
607 	return result;
608 }
609 
spi_data_read(u8 * b,u32 sz)610 static int spi_data_read(u8 *b, u32 sz)
611 {
612 	int retry, ix, nbytes;
613 	int result = N_OK;
614 	u8 crc[2];
615 	u8 rsp;
616 
617 	/**
618 	 *      Data
619 	 **/
620 	ix = 0;
621 	do {
622 		if (sz <= DATA_PKT_SZ)
623 			nbytes = sz;
624 		else
625 			nbytes = DATA_PKT_SZ;
626 
627 		/**
628 		 *      Data Respnose header
629 		 **/
630 		retry = 10;
631 		do {
632 			if (!g_spi.spi_rx(&rsp, 1)) {
633 				PRINT_ER("[wilc spi]: Failed data response read, bus error...\n");
634 				result = N_FAIL;
635 				break;
636 			}
637 			if (((rsp >> 4) & 0xf) == 0xf)
638 				break;
639 		} while (retry--);
640 
641 		if (result == N_FAIL)
642 			break;
643 
644 		if (retry <= 0) {
645 			PRINT_ER("[wilc spi]: Failed data response read...(%02x)\n", rsp);
646 			result = N_FAIL;
647 			break;
648 		}
649 
650 		/**
651 		 *      Read bytes
652 		 **/
653 		if (!g_spi.spi_rx(&b[ix], nbytes)) {
654 			PRINT_ER("[wilc spi]: Failed data block read, bus error...\n");
655 			result = N_FAIL;
656 			break;
657 		}
658 
659 		/**
660 		 *      Read Crc
661 		 **/
662 		if (!g_spi.crc_off) {
663 			if (!g_spi.spi_rx(crc, 2)) {
664 				PRINT_ER("[wilc spi]: Failed data block crc read, bus error...\n");
665 				result = N_FAIL;
666 				break;
667 			}
668 		}
669 
670 		ix += nbytes;
671 		sz -= nbytes;
672 
673 	} while (sz);
674 
675 	return result;
676 }
677 
spi_data_write(u8 * b,u32 sz)678 static int spi_data_write(u8 *b, u32 sz)
679 {
680 	int ix, nbytes;
681 	int result = 1;
682 	u8 cmd, order, crc[2] = {0};
683 	/* u8 rsp; */
684 
685 	/**
686 	 *      Data
687 	 **/
688 	ix = 0;
689 	do {
690 		if (sz <= DATA_PKT_SZ)
691 			nbytes = sz;
692 		else
693 			nbytes = DATA_PKT_SZ;
694 
695 		/**
696 		 *      Write command
697 		 **/
698 		cmd = 0xf0;
699 		if (ix == 0) {
700 			if (sz <= DATA_PKT_SZ)
701 
702 				order = 0x3;
703 			else
704 				order = 0x1;
705 		} else {
706 			if (sz <= DATA_PKT_SZ)
707 				order = 0x3;
708 			else
709 				order = 0x2;
710 		}
711 		cmd |= order;
712 		if (!g_spi.spi_tx(&cmd, 1)) {
713 			PRINT_ER("[wilc spi]: Failed data block cmd write, bus error...\n");
714 			result = N_FAIL;
715 			break;
716 		}
717 
718 		/**
719 		 *      Write data
720 		 **/
721 		if (!g_spi.spi_tx(&b[ix], nbytes)) {
722 			PRINT_ER("[wilc spi]: Failed data block write, bus error...\n");
723 			result = N_FAIL;
724 			break;
725 		}
726 
727 		/**
728 		 *      Write Crc
729 		 **/
730 		if (!g_spi.crc_off) {
731 			if (!g_spi.spi_tx(crc, 2)) {
732 				PRINT_ER("[wilc spi]: Failed data block crc write, bus error...\n");
733 				result = N_FAIL;
734 				break;
735 			}
736 		}
737 
738 		/**
739 		 *      No need to wait for response
740 		 **/
741 		ix += nbytes;
742 		sz -= nbytes;
743 	} while (sz);
744 
745 
746 	return result;
747 }
748 
749 /********************************************
750  *
751  *      Spi Internal Read/Write Function
752  *
753  ********************************************/
754 
spi_internal_write(u32 adr,u32 dat)755 static int spi_internal_write(u32 adr, u32 dat)
756 {
757 	int result;
758 
759 #ifdef BIG_ENDIAN
760 	dat = BYTE_SWAP(dat);
761 #endif
762 	result = spi_cmd_complete(CMD_INTERNAL_WRITE, adr, (u8 *)&dat, 4, 0);
763 	if (result != N_OK) {
764 		PRINT_ER("[wilc spi]: Failed internal write cmd...\n");
765 	}
766 
767 	return result;
768 }
769 
spi_internal_read(u32 adr,u32 * data)770 static int spi_internal_read(u32 adr, u32 *data)
771 {
772 	int result;
773 
774 	result = spi_cmd_complete(CMD_INTERNAL_READ, adr, (u8 *)data, 4, 0);
775 	if (result != N_OK) {
776 		PRINT_ER("[wilc spi]: Failed internal read cmd...\n");
777 		return 0;
778 	}
779 
780 #ifdef BIG_ENDIAN
781 	*data = BYTE_SWAP(*data);
782 #endif
783 
784 	return 1;
785 }
786 
787 /********************************************
788  *
789  *      Spi interfaces
790  *
791  ********************************************/
792 
spi_write_reg(u32 addr,u32 data)793 static int spi_write_reg(u32 addr, u32 data)
794 {
795 	int result = N_OK;
796 	u8 cmd = CMD_SINGLE_WRITE;
797 	u8 clockless = 0;
798 
799 #ifdef BIG_ENDIAN
800 	data = BYTE_SWAP(data);
801 #endif
802 	if (addr < 0x30) {
803 		/* Clockless register*/
804 		cmd = CMD_INTERNAL_WRITE;
805 		clockless = 1;
806 	}
807 
808 	result = spi_cmd_complete(cmd, addr, (u8 *)&data, 4, clockless);
809 	if (result != N_OK) {
810 		PRINT_ER("[wilc spi]: Failed cmd, write reg (%08x)...\n", addr);
811 	}
812 
813 	return result;
814 }
815 
spi_write(u32 addr,u8 * buf,u32 size)816 static int spi_write(u32 addr, u8 *buf, u32 size)
817 {
818 	int result;
819 	u8 cmd = CMD_DMA_EXT_WRITE;
820 
821 	/**
822 	 *      has to be greated than 4
823 	 **/
824 	if (size <= 4)
825 		return 0;
826 
827 	result = spi_cmd_complete(cmd, addr, NULL, size, 0);
828 	if (result != N_OK) {
829 		PRINT_ER("[wilc spi]: Failed cmd, write block (%08x)...\n", addr);
830 		return 0;
831 	}
832 
833 	/**
834 	 *      Data
835 	 **/
836 	result = spi_data_write(buf, size);
837 	if (result != N_OK) {
838 		PRINT_ER("[wilc spi]: Failed block data write...\n");
839 	}
840 
841 	return 1;
842 }
843 
spi_read_reg(u32 addr,u32 * data)844 static int spi_read_reg(u32 addr, u32 *data)
845 {
846 	int result = N_OK;
847 	u8 cmd = CMD_SINGLE_READ;
848 	u8 clockless = 0;
849 
850 	if (addr < 0x30) {
851 		/* PRINT_ER("***** read addr %d\n\n", addr); */
852 		/* Clockless register*/
853 		cmd = CMD_INTERNAL_READ;
854 		clockless = 1;
855 	}
856 
857 	result = spi_cmd_complete(cmd, addr, (u8 *)data, 4, clockless);
858 	if (result != N_OK) {
859 		PRINT_ER("[wilc spi]: Failed cmd, read reg (%08x)...\n", addr);
860 		return 0;
861 	}
862 
863 #ifdef BIG_ENDIAN
864 	*data = BYTE_SWAP(*data);
865 #endif
866 
867 	return 1;
868 }
869 
spi_read(u32 addr,u8 * buf,u32 size)870 static int spi_read(u32 addr, u8 *buf, u32 size)
871 {
872 	u8 cmd = CMD_DMA_EXT_READ;
873 	int result;
874 
875 	if (size <= 4)
876 		return 0;
877 
878 	result = spi_cmd_complete(cmd, addr, buf, size, 0);
879 	if (result != N_OK) {
880 		PRINT_ER("[wilc spi]: Failed cmd, read block (%08x)...\n", addr);
881 		return 0;
882 	}
883 
884 	return 1;
885 }
886 
887 /********************************************
888  *
889  *      Bus interfaces
890  *
891  ********************************************/
892 
spi_clear_int(void)893 static int spi_clear_int(void)
894 {
895 	u32 reg;
896 
897 	if (!spi_read_reg(WILC_HOST_RX_CTRL_0, ®)) {
898 		PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_HOST_RX_CTRL_0);
899 		return 0;
900 	}
901 	reg &= ~0x1;
902 	spi_write_reg(WILC_HOST_RX_CTRL_0, reg);
903 	return 1;
904 }
905 
spi_deinit(void * pv)906 static int spi_deinit(void *pv)
907 {
908 	/**
909 	 *      TODO:
910 	 **/
911 	return 1;
912 }
913 
spi_sync(void)914 static int spi_sync(void)
915 {
916 	u32 reg;
917 	int ret;
918 
919 	/**
920 	 *      interrupt pin mux select
921 	 **/
922 	ret = spi_read_reg(WILC_PIN_MUX_0, ®);
923 	if (!ret) {
924 		PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
925 		return 0;
926 	}
927 	reg |= BIT(8);
928 	ret = spi_write_reg(WILC_PIN_MUX_0, reg);
929 	if (!ret) {
930 		PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
931 		return 0;
932 	}
933 
934 	/**
935 	 *      interrupt enable
936 	 **/
937 	ret = spi_read_reg(WILC_INTR_ENABLE, ®);
938 	if (!ret) {
939 		PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
940 		return 0;
941 	}
942 	reg |= BIT(16);
943 	ret = spi_write_reg(WILC_INTR_ENABLE, reg);
944 	if (!ret) {
945 		PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
946 		return 0;
947 	}
948 
949 	return 1;
950 }
951 
spi_init(wilc_wlan_inp_t * inp,wilc_debug_func func)952 static int spi_init(wilc_wlan_inp_t *inp, wilc_debug_func func)
953 {
954 	u32 reg;
955 	u32 chipid;
956 
957 	static int isinit;
958 
959 	if (isinit) {
960 
961 		if (!spi_read_reg(0x1000, &chipid)) {
962 			PRINT_ER("[wilc spi]: Fail cmd read chip id...\n");
963 			return 0;
964 		}
965 		return 1;
966 	}
967 
968 	memset(&g_spi, 0, sizeof(wilc_spi_t));
969 
970 	g_spi.dPrint = func;
971 	g_spi.os_context = inp->os_context.os_private;
972 	if (inp->io_func.io_init) {
973 		if (!inp->io_func.io_init(g_spi.os_context)) {
974 			PRINT_ER("[wilc spi]: Failed io init bus...\n");
975 			return 0;
976 		}
977 	} else {
978 		return 0;
979 	}
980 	g_spi.spi_tx = inp->io_func.u.spi.spi_tx;
981 	g_spi.spi_rx = inp->io_func.u.spi.spi_rx;
982 	g_spi.spi_trx = inp->io_func.u.spi.spi_trx;
983 	g_spi.spi_max_speed = inp->io_func.u.spi.spi_max_speed;
984 
985 	/**
986 	 *      configure protocol
987 	 **/
988 	g_spi.crc_off = 0;
989 
990 	/* TODO: We can remove the CRC trials if there is a definite way to reset */
991 	/* the SPI to it's initial value. */
992 	if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, ®)) {
993 		/* Read failed. Try with CRC off. This might happen when module
994 		 * is removed but chip isn't reset*/
995 		g_spi.crc_off = 1;
996 		PRINT_ER("[wilc spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n");
997 		if (!spi_internal_read(WILC_SPI_PROTOCOL_OFFSET, ®)) {
998 			/* Reaad failed with both CRC on and off, something went bad */
999 			PRINT_ER("[wilc spi]: Failed internal read protocol...\n");
1000 			return 0;
1001 		}
1002 	}
1003 	if (g_spi.crc_off == 0)	{
1004 		reg &= ~0xc;    /* disable crc checking */
1005 		reg &= ~0x70;
1006 		reg |= (0x5 << 4);
1007 		if (!spi_internal_write(WILC_SPI_PROTOCOL_OFFSET, reg)) {
1008 			PRINT_ER("[wilc spi %d]: Failed internal write protocol reg...\n", __LINE__);
1009 			return 0;
1010 		}
1011 		g_spi.crc_off = 1;
1012 	}
1013 
1014 
1015 	/**
1016 	 *      make sure can read back chip id correctly
1017 	 **/
1018 	if (!spi_read_reg(0x1000, &chipid)) {
1019 		PRINT_ER("[wilc spi]: Fail cmd read chip id...\n");
1020 		return 0;
1021 	}
1022 	/* PRINT_ER("[wilc spi]: chipid (%08x)\n", chipid); */
1023 
1024 	g_spi.has_thrpt_enh = 1;
1025 
1026 	isinit = 1;
1027 
1028 	return 1;
1029 }
1030 
spi_max_bus_speed(void)1031 static void spi_max_bus_speed(void)
1032 {
1033 	g_spi.spi_max_speed();
1034 }
1035 
spi_default_bus_speed(void)1036 static void spi_default_bus_speed(void)
1037 {
1038 }
1039 
spi_read_size(u32 * size)1040 static int spi_read_size(u32 *size)
1041 {
1042 	int ret;
1043 
1044 	if (g_spi.has_thrpt_enh) {
1045 		ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, size);
1046 		*size = *size  & IRQ_DMA_WD_CNT_MASK;
1047 	} else {
1048 		u32 tmp;
1049 		u32 byte_cnt;
1050 
1051 		ret = spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt);
1052 		if (!ret) {
1053 			PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n");
1054 			goto _fail_;
1055 		}
1056 		tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
1057 		*size = tmp;
1058 	}
1059 
1060 
1061 
1062 _fail_:
1063 	return ret;
1064 }
1065 
1066 
1067 
spi_read_int(u32 * int_status)1068 static int spi_read_int(u32 *int_status)
1069 {
1070 	int ret;
1071 
1072 	if (g_spi.has_thrpt_enh) {
1073 		ret = spi_internal_read(0xe840 - WILC_SPI_REG_BASE, int_status);
1074 	} else {
1075 		u32 tmp;
1076 		u32 byte_cnt;
1077 
1078 		ret = spi_read_reg(WILC_VMM_TO_HOST_SIZE, &byte_cnt);
1079 		if (!ret) {
1080 			PRINT_ER("[wilc spi]: Failed read WILC_VMM_TO_HOST_SIZE ...\n");
1081 			goto _fail_;
1082 		}
1083 		tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
1084 
1085 		{
1086 			int happended, j;
1087 
1088 			j = 0;
1089 			do {
1090 				u32 irq_flags;
1091 
1092 				happended = 0;
1093 
1094 				spi_read_reg(0x1a90, &irq_flags);
1095 				tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET);
1096 
1097 				if (g_spi.nint > 5) {
1098 					spi_read_reg(0x1a94, &irq_flags);
1099 					tmp |= (((irq_flags >> 0) & 0x7) << (IRG_FLAGS_OFFSET + 5));
1100 				}
1101 
1102 				{
1103 					u32 unkmown_mask;
1104 
1105 					unkmown_mask = ~((1ul << g_spi.nint) - 1);
1106 
1107 					if ((tmp >> IRG_FLAGS_OFFSET) & unkmown_mask) {
1108 						PRINT_ER("[wilc spi]: Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask);
1109 						happended = 1;
1110 					}
1111 				}
1112 				j++;
1113 			} while (happended);
1114 		}
1115 
1116 		*int_status = tmp;
1117 
1118 	}
1119 
1120 _fail_:
1121 	return ret;
1122 }
1123 
spi_clear_int_ext(u32 val)1124 static int spi_clear_int_ext(u32 val)
1125 {
1126 	int ret;
1127 
1128 	if (g_spi.has_thrpt_enh) {
1129 		ret = spi_internal_write(0xe844 - WILC_SPI_REG_BASE, val);
1130 	} else {
1131 		u32 flags;
1132 
1133 		flags = val & (BIT(MAX_NUM_INT) - 1);
1134 		if (flags) {
1135 			int i;
1136 
1137 			ret = 1;
1138 			for (i = 0; i < g_spi.nint; i++) {
1139 				/* No matter what you write 1 or 0, it will clear interrupt. */
1140 				if (flags & 1)
1141 					ret = spi_write_reg(0x10c8 + i * 4, 1);
1142 				if (!ret)
1143 					break;
1144 				flags >>= 1;
1145 			}
1146 			if (!ret) {
1147 				PRINT_ER("[wilc spi]: Failed spi_write_reg, set reg %x ...\n", 0x10c8 + i * 4);
1148 				goto _fail_;
1149 			}
1150 			for (i = g_spi.nint; i < MAX_NUM_INT; i++) {
1151 				if (flags & 1)
1152 					PRINT_ER("[wilc spi]: Unexpected interrupt cleared %d...\n", i);
1153 				flags >>= 1;
1154 			}
1155 		}
1156 
1157 		{
1158 			u32 tbl_ctl;
1159 
1160 			tbl_ctl = 0;
1161 			/* select VMM table 0 */
1162 			if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
1163 				tbl_ctl |= BIT(0);
1164 			/* select VMM table 1 */
1165 			if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
1166 				tbl_ctl |= BIT(1);
1167 
1168 			ret = spi_write_reg(WILC_VMM_TBL_CTL, tbl_ctl);
1169 			if (!ret) {
1170 				PRINT_ER("[wilc spi]: fail write reg vmm_tbl_ctl...\n");
1171 				goto _fail_;
1172 			}
1173 
1174 			if ((val & EN_VMM) == EN_VMM) {
1175 				/**
1176 				 *      enable vmm transfer.
1177 				 **/
1178 				ret = spi_write_reg(WILC_VMM_CORE_CTL, 1);
1179 				if (!ret) {
1180 					PRINT_ER("[wilc spi]: fail write reg vmm_core_ctl...\n");
1181 					goto _fail_;
1182 				}
1183 			}
1184 		}
1185 	}
1186 _fail_:
1187 	return ret;
1188 }
1189 
spi_sync_ext(int nint)1190 static int spi_sync_ext(int nint /*  how mant interrupts to enable. */)
1191 {
1192 	u32 reg;
1193 	int ret, i;
1194 
1195 	if (nint > MAX_NUM_INT) {
1196 		PRINT_ER("[wilc spi]: Too many interupts (%d)...\n", nint);
1197 		return 0;
1198 	}
1199 
1200 	g_spi.nint = nint;
1201 
1202 	/**
1203 	 *      interrupt pin mux select
1204 	 **/
1205 	ret = spi_read_reg(WILC_PIN_MUX_0, ®);
1206 	if (!ret) {
1207 		PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_PIN_MUX_0);
1208 		return 0;
1209 	}
1210 	reg |= BIT(8);
1211 	ret = spi_write_reg(WILC_PIN_MUX_0, reg);
1212 	if (!ret) {
1213 		PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_PIN_MUX_0);
1214 		return 0;
1215 	}
1216 
1217 	/**
1218 	 *      interrupt enable
1219 	 **/
1220 	ret = spi_read_reg(WILC_INTR_ENABLE, ®);
1221 	if (!ret) {
1222 		PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR_ENABLE);
1223 		return 0;
1224 	}
1225 
1226 	for (i = 0; (i < 5) && (nint > 0); i++, nint--) {
1227 		reg |= (BIT((27 + i)));
1228 	}
1229 	ret = spi_write_reg(WILC_INTR_ENABLE, reg);
1230 	if (!ret) {
1231 		PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR_ENABLE);
1232 		return 0;
1233 	}
1234 	if (nint) {
1235 		ret = spi_read_reg(WILC_INTR2_ENABLE, ®);
1236 		if (!ret) {
1237 			PRINT_ER("[wilc spi]: Failed read reg (%08x)...\n", WILC_INTR2_ENABLE);
1238 			return 0;
1239 		}
1240 
1241 		for (i = 0; (i < 3) && (nint > 0); i++, nint--) {
1242 			reg |= BIT(i);
1243 		}
1244 
1245 		ret = spi_read_reg(WILC_INTR2_ENABLE, ®);
1246 		if (!ret) {
1247 			PRINT_ER("[wilc spi]: Failed write reg (%08x)...\n", WILC_INTR2_ENABLE);
1248 			return 0;
1249 		}
1250 	}
1251 
1252 	return 1;
1253 }
1254 /********************************************
1255  *
1256  *      Global spi HIF function table
1257  *
1258  ********************************************/
1259 wilc_hif_func_t hif_spi = {
1260 	spi_init,
1261 	spi_deinit,
1262 	spi_read_reg,
1263 	spi_write_reg,
1264 	spi_read,
1265 	spi_write,
1266 	spi_sync,
1267 	spi_clear_int,
1268 	spi_read_int,
1269 	spi_clear_int_ext,
1270 	spi_read_size,
1271 	spi_write,
1272 	spi_read,
1273 	spi_sync_ext,
1274 	spi_max_bus_speed,
1275 	spi_default_bus_speed,
1276 };
1277