net/txgbe: add Rx and Tx data path start and stop
[dpdk.git] / drivers / net / txgbe / base / txgbe_eeprom.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015-2020
3  */
4
5 #include "txgbe_hw.h"
6 #include "txgbe_mng.h"
7 #include "txgbe_eeprom.h"
8
9 /**
10  *  txgbe_init_eeprom_params - Initialize EEPROM params
11  *  @hw: pointer to hardware structure
12  *
13  *  Initializes the EEPROM parameters txgbe_rom_info within the
14  *  txgbe_hw struct in order to set up EEPROM access.
15  **/
16 s32 txgbe_init_eeprom_params(struct txgbe_hw *hw)
17 {
18         struct txgbe_rom_info *eeprom = &hw->rom;
19         u32 eec;
20         u16 eeprom_size;
21         int err = 0;
22
23         DEBUGFUNC("txgbe_init_eeprom_params");
24
25         if (eeprom->type != txgbe_eeprom_unknown)
26                 return 0;
27
28         eeprom->type = txgbe_eeprom_none;
29         /* Set default semaphore delay to 10ms which is a well
30          * tested value
31          */
32         eeprom->semaphore_delay = 10; /*ms*/
33         /* Clear EEPROM page size, it will be initialized as needed */
34         eeprom->word_page_size = 0;
35
36         /*
37          * Check for EEPROM present first.
38          * If not present leave as none
39          */
40         eec = rd32(hw, TXGBE_SPISTAT);
41         if (!(eec & TXGBE_SPISTAT_BPFLASH)) {
42                 eeprom->type = txgbe_eeprom_flash;
43
44                 /*
45                  * SPI EEPROM is assumed here.  This code would need to
46                  * change if a future EEPROM is not SPI.
47                  */
48                 eeprom_size = 4096;
49                 eeprom->word_size = eeprom_size >> 1;
50         }
51
52         eeprom->address_bits = 16;
53
54         err = eeprom->read32(hw, TXGBE_SW_REGION_PTR << 1, &eeprom->sw_addr);
55         if (err) {
56                 DEBUGOUT("EEPROM read failed.\n");
57                 return err;
58         }
59
60         DEBUGOUT("eeprom params: type = %d, size = %d, address bits: "
61                   "%d %d\n", eeprom->type, eeprom->word_size,
62                   eeprom->address_bits, eeprom->sw_addr);
63
64         return 0;
65 }
66
67 /**
68  *  txgbe_get_eeprom_semaphore - Get hardware semaphore
69  *  @hw: pointer to hardware structure
70  *
71  *  Sets the hardware semaphores so EEPROM access can occur for bit-bang method
72  **/
73 s32 txgbe_get_eeprom_semaphore(struct txgbe_hw *hw)
74 {
75         s32 status = TXGBE_ERR_EEPROM;
76         u32 timeout = 2000;
77         u32 i;
78         u32 swsm;
79
80         DEBUGFUNC("txgbe_get_eeprom_semaphore");
81
82
83         /* Get SMBI software semaphore between device drivers first */
84         for (i = 0; i < timeout; i++) {
85                 /*
86                  * If the SMBI bit is 0 when we read it, then the bit will be
87                  * set and we have the semaphore
88                  */
89                 swsm = rd32(hw, TXGBE_SWSEM);
90                 if (!(swsm & TXGBE_SWSEM_PF)) {
91                         status = 0;
92                         break;
93                 }
94                 usec_delay(50);
95         }
96
97         if (i == timeout) {
98                 DEBUGOUT("Driver can't access the eeprom - SMBI Semaphore "
99                          "not granted.\n");
100                 /*
101                  * this release is particularly important because our attempts
102                  * above to get the semaphore may have succeeded, and if there
103                  * was a timeout, we should unconditionally clear the semaphore
104                  * bits to free the driver to make progress
105                  */
106                 txgbe_release_eeprom_semaphore(hw);
107
108                 usec_delay(50);
109                 /*
110                  * one last try
111                  * If the SMBI bit is 0 when we read it, then the bit will be
112                  * set and we have the semaphore
113                  */
114                 swsm = rd32(hw, TXGBE_SWSEM);
115                 if (!(swsm & TXGBE_SWSEM_PF))
116                         status = 0;
117         }
118
119         /* Now get the semaphore between SW/FW through the SWESMBI bit */
120         if (status == 0) {
121                 for (i = 0; i < timeout; i++) {
122                         /* Set the SW EEPROM semaphore bit to request access */
123                         wr32m(hw, TXGBE_MNGSWSYNC,
124                                 TXGBE_MNGSWSYNC_REQ, TXGBE_MNGSWSYNC_REQ);
125
126                         /*
127                          * If we set the bit successfully then we got the
128                          * semaphore.
129                          */
130                         swsm = rd32(hw, TXGBE_MNGSWSYNC);
131                         if (swsm & TXGBE_MNGSWSYNC_REQ)
132                                 break;
133
134                         usec_delay(50);
135                 }
136
137                 /*
138                  * Release semaphores and return error if SW EEPROM semaphore
139                  * was not granted because we don't have access to the EEPROM
140                  */
141                 if (i >= timeout) {
142                         DEBUGOUT("SWESMBI Software EEPROM semaphore not granted.\n");
143                         txgbe_release_eeprom_semaphore(hw);
144                         status = TXGBE_ERR_EEPROM;
145                 }
146         } else {
147                 DEBUGOUT("Software semaphore SMBI between device drivers "
148                          "not granted.\n");
149         }
150
151         return status;
152 }
153
154 /**
155  *  txgbe_release_eeprom_semaphore - Release hardware semaphore
156  *  @hw: pointer to hardware structure
157  *
158  *  This function clears hardware semaphore bits.
159  **/
160 void txgbe_release_eeprom_semaphore(struct txgbe_hw *hw)
161 {
162         DEBUGFUNC("txgbe_release_eeprom_semaphore");
163
164         wr32m(hw, TXGBE_MNGSWSYNC, TXGBE_MNGSWSYNC_REQ, 0);
165         wr32m(hw, TXGBE_SWSEM, TXGBE_SWSEM_PF, 0);
166         txgbe_flush(hw);
167 }
168
169 /**
170  *  txgbe_ee_read - Read EEPROM word using a host interface cmd
171  *  @hw: pointer to hardware structure
172  *  @offset: offset of  word in the EEPROM to read
173  *  @data: word read from the EEPROM
174  *
175  *  Reads a 16 bit word from the EEPROM using the hostif.
176  **/
177 s32 txgbe_ee_read16(struct txgbe_hw *hw, u32 offset,
178                               u16 *data)
179 {
180         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
181         u32 addr = (offset << 1);
182         int err;
183
184         err = hw->mac.acquire_swfw_sync(hw, mask);
185         if (err)
186                 return err;
187
188         err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 2);
189
190         hw->mac.release_swfw_sync(hw, mask);
191
192         return err;
193 }
194
195 /**
196  *  txgbe_ee_read_buffer- Read EEPROM word(s) using hostif
197  *  @hw: pointer to hardware structure
198  *  @offset: offset of  word in the EEPROM to read
199  *  @words: number of words
200  *  @data: word(s) read from the EEPROM
201  *
202  *  Reads a 16 bit word(s) from the EEPROM using the hostif.
203  **/
204 s32 txgbe_ee_readw_buffer(struct txgbe_hw *hw,
205                                      u32 offset, u32 words, void *data)
206 {
207         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
208         u32 addr = (offset << 1);
209         u32 len = (words << 1);
210         u8 *buf = (u8 *)data;
211         int err;
212
213         err = hw->mac.acquire_swfw_sync(hw, mask);
214         if (err)
215                 return err;
216
217         while (len) {
218                 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
219                                 ? len : TXGBE_PMMBX_DATA_SIZE);
220
221                 err = txgbe_hic_sr_read(hw, addr, buf, seg);
222                 if (err)
223                         break;
224
225                 len -= seg;
226                 addr += seg;
227                 buf += seg;
228         }
229
230         hw->mac.release_swfw_sync(hw, mask);
231         return err;
232 }
233
234
235 s32 txgbe_ee_readw_sw(struct txgbe_hw *hw, u32 offset,
236                               u16 *data)
237 {
238         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
239         u32 addr = hw->rom.sw_addr + (offset << 1);
240         int err;
241
242         err = hw->mac.acquire_swfw_sync(hw, mask);
243         if (err)
244                 return err;
245
246         err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 2);
247
248         hw->mac.release_swfw_sync(hw, mask);
249
250         return err;
251 }
252
253 /**
254  *  txgbe_ee_read32 - Read EEPROM word using a host interface cmd
255  *  @hw: pointer to hardware structure
256  *  @offset: offset of  word in the EEPROM to read
257  *  @data: word read from the EEPROM
258  *
259  *  Reads a 32 bit word from the EEPROM using the hostif.
260  **/
261 s32 txgbe_ee_read32(struct txgbe_hw *hw, u32 addr, u32 *data)
262 {
263         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
264         int err;
265
266         err = hw->mac.acquire_swfw_sync(hw, mask);
267         if (err)
268                 return err;
269
270         err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 4);
271
272         hw->mac.release_swfw_sync(hw, mask);
273
274         return err;
275 }
276
277 /**
278  *  txgbe_ee_read_buffer - Read EEPROM byte(s) using hostif
279  *  @hw: pointer to hardware structure
280  *  @addr: offset of bytes in the EEPROM to read
281  *  @len: number of bytes
282  *  @data: byte(s) read from the EEPROM
283  *
284  *  Reads a 8 bit byte(s) from the EEPROM using the hostif.
285  **/
286 s32 txgbe_ee_read_buffer(struct txgbe_hw *hw,
287                                      u32 addr, u32 len, void *data)
288 {
289         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
290         u8 *buf = (u8 *)data;
291         int err;
292
293         err = hw->mac.acquire_swfw_sync(hw, mask);
294         if (err)
295                 return err;
296
297         while (len) {
298                 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
299                                 ? len : TXGBE_PMMBX_DATA_SIZE);
300
301                 err = txgbe_hic_sr_read(hw, addr, buf, seg);
302                 if (err)
303                         break;
304
305                 len -= seg;
306                 buf += seg;
307         }
308
309         hw->mac.release_swfw_sync(hw, mask);
310         return err;
311 }
312
313 /**
314  *  txgbe_ee_write - Write EEPROM word using hostif
315  *  @hw: pointer to hardware structure
316  *  @offset: offset of  word in the EEPROM to write
317  *  @data: word write to the EEPROM
318  *
319  *  Write a 16 bit word to the EEPROM using the hostif.
320  **/
321 s32 txgbe_ee_write16(struct txgbe_hw *hw, u32 offset,
322                                u16 data)
323 {
324         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
325         u32 addr = (offset << 1);
326         int err;
327
328         DEBUGFUNC("\n");
329
330         err = hw->mac.acquire_swfw_sync(hw, mask);
331         if (err)
332                 return err;
333
334         err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2);
335
336         hw->mac.release_swfw_sync(hw, mask);
337
338         return err;
339 }
340
341 /**
342  *  txgbe_ee_write_buffer - Write EEPROM word(s) using hostif
343  *  @hw: pointer to hardware structure
344  *  @offset: offset of  word in the EEPROM to write
345  *  @words: number of words
346  *  @data: word(s) write to the EEPROM
347  *
348  *  Write a 16 bit word(s) to the EEPROM using the hostif.
349  **/
350 s32 txgbe_ee_writew_buffer(struct txgbe_hw *hw,
351                                       u32 offset, u32 words, void *data)
352 {
353         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
354         u32 addr = (offset << 1);
355         u32 len = (words << 1);
356         u8 *buf = (u8 *)data;
357         int err;
358
359         err = hw->mac.acquire_swfw_sync(hw, mask);
360         if (err)
361                 return err;
362
363         while (len) {
364                 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
365                                 ? len : TXGBE_PMMBX_DATA_SIZE);
366
367                 err = txgbe_hic_sr_write(hw, addr, buf, seg);
368                 if (err)
369                         break;
370
371                 len -= seg;
372                 buf += seg;
373         }
374
375         hw->mac.release_swfw_sync(hw, mask);
376         return err;
377 }
378
379 s32 txgbe_ee_writew_sw(struct txgbe_hw *hw, u32 offset,
380                                u16 data)
381 {
382         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
383         u32 addr = hw->rom.sw_addr + (offset << 1);
384         int err;
385
386         DEBUGFUNC("\n");
387
388         err = hw->mac.acquire_swfw_sync(hw, mask);
389         if (err)
390                 return err;
391
392         err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2);
393
394         hw->mac.release_swfw_sync(hw, mask);
395
396         return err;
397 }
398
399 /**
400  *  txgbe_ee_write32 - Read EEPROM word using a host interface cmd
401  *  @hw: pointer to hardware structure
402  *  @offset: offset of  word in the EEPROM to read
403  *  @data: word read from the EEPROM
404  *
405  *  Reads a 32 bit word from the EEPROM using the hostif.
406  **/
407 s32 txgbe_ee_write32(struct txgbe_hw *hw, u32 addr, u32 data)
408 {
409         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
410         int err;
411
412         err = hw->mac.acquire_swfw_sync(hw, mask);
413         if (err)
414                 return err;
415
416         err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 4);
417
418         hw->mac.release_swfw_sync(hw, mask);
419
420         return err;
421 }
422
423 /**
424  *  txgbe_ee_write_buffer - Write EEPROM byte(s) using hostif
425  *  @hw: pointer to hardware structure
426  *  @addr: offset of bytes in the EEPROM to write
427  *  @len: number of bytes
428  *  @data: word(s) write to the EEPROM
429  *
430  *  Write a 8 bit byte(s) to the EEPROM using the hostif.
431  **/
432 s32 txgbe_ee_write_buffer(struct txgbe_hw *hw,
433                                       u32 addr, u32 len, void *data)
434 {
435         const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
436         u8 *buf = (u8 *)data;
437         int err;
438
439         err = hw->mac.acquire_swfw_sync(hw, mask);
440         if (err)
441                 return err;
442
443         while (len) {
444                 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
445                                 ? len : TXGBE_PMMBX_DATA_SIZE);
446
447                 err = txgbe_hic_sr_write(hw, addr, buf, seg);
448                 if (err)
449                         break;
450
451                 len -= seg;
452                 buf += seg;
453         }
454
455         hw->mac.release_swfw_sync(hw, mask);
456         return err;
457 }
458
459 /**
460  *  txgbe_calc_eeprom_checksum - Calculates and returns the checksum
461  *  @hw: pointer to hardware structure
462  *
463  *  Returns a negative error code on error, or the 16-bit checksum
464  **/
465 #define BUFF_SIZE  64
466 s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw)
467 {
468         u16 checksum = 0, read_checksum = 0;
469         int i, j, seg;
470         int err;
471         u16 buffer[BUFF_SIZE];
472
473         DEBUGFUNC("txgbe_calc_eeprom_checksum");
474
475         err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum);
476         if (err) {
477                 DEBUGOUT("EEPROM read failed\n");
478                 return err;
479         }
480
481         for (i = 0; i < TXGBE_EE_CSUM_MAX; i += seg) {
482                 seg = (i + BUFF_SIZE < TXGBE_EE_CSUM_MAX
483                        ? BUFF_SIZE : TXGBE_EE_CSUM_MAX - i);
484                 err = hw->rom.readw_buffer(hw, i, seg, buffer);
485                 if (err)
486                         return err;
487                 for (j = 0; j < seg; j++)
488                         checksum += buffer[j];
489         }
490
491         checksum = (u16)TXGBE_EEPROM_SUM - checksum + read_checksum;
492
493         return (s32)checksum;
494 }
495
496 /**
497  *  txgbe_validate_eeprom_checksum - Validate EEPROM checksum
498  *  @hw: pointer to hardware structure
499  *  @checksum_val: calculated checksum
500  *
501  *  Performs checksum calculation and validates the EEPROM checksum.  If the
502  *  caller does not need checksum_val, the value can be NULL.
503  **/
504 s32 txgbe_validate_eeprom_checksum(struct txgbe_hw *hw,
505                                            u16 *checksum_val)
506 {
507         u16 checksum;
508         u16 read_checksum = 0;
509         int err;
510
511         DEBUGFUNC("txgbe_validate_eeprom_checksum");
512
513         /* Read the first word from the EEPROM. If this times out or fails, do
514          * not continue or we could be in for a very long wait while every
515          * EEPROM read fails
516          */
517         err = hw->rom.read16(hw, 0, &checksum);
518         if (err) {
519                 DEBUGOUT("EEPROM read failed\n");
520                 return err;
521         }
522
523         err = hw->rom.calc_checksum(hw);
524         if (err < 0)
525                 return err;
526
527         checksum = (u16)(err & 0xffff);
528
529         err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum);
530         if (err) {
531                 DEBUGOUT("EEPROM read failed\n");
532                 return err;
533         }
534
535         /* Verify read checksum from EEPROM is the same as
536          * calculated checksum
537          */
538         if (read_checksum != checksum) {
539                 err = TXGBE_ERR_EEPROM_CHECKSUM;
540                 DEBUGOUT("EEPROM checksum error\n");
541         }
542
543         /* If the user cares, return the calculated checksum */
544         if (checksum_val)
545                 *checksum_val = checksum;
546
547         return err;
548 }
549
550 /**
551  *  txgbe_update_eeprom_checksum - Updates the EEPROM checksum
552  *  @hw: pointer to hardware structure
553  **/
554 s32 txgbe_update_eeprom_checksum(struct txgbe_hw *hw)
555 {
556         s32 status;
557         u16 checksum;
558
559         DEBUGFUNC("txgbe_update_eeprom_checksum");
560
561         /* Read the first word from the EEPROM. If this times out or fails, do
562          * not continue or we could be in for a very long wait while every
563          * EEPROM read fails
564          */
565         status = hw->rom.read16(hw, 0, &checksum);
566         if (status) {
567                 DEBUGOUT("EEPROM read failed\n");
568                 return status;
569         }
570
571         status = hw->rom.calc_checksum(hw);
572         if (status < 0)
573                 return status;
574
575         checksum = (u16)(status & 0xffff);
576
577         status = hw->rom.writew_sw(hw, TXGBE_EEPROM_CHECKSUM, checksum);
578
579         return status;
580 }
581