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