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