net/ngbe: support Rx queue start/stop
[dpdk.git] / drivers / net / ngbe / base / ngbe_eeprom.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3  * Copyright(c) 2010-2017 Intel Corporation
4  */
5
6 #include "ngbe_hw.h"
7 #include "ngbe_mng.h"
8 #include "ngbe_eeprom.h"
9
10 /**
11  *  ngbe_init_eeprom_params - Initialize EEPROM params
12  *  @hw: pointer to hardware structure
13  *
14  *  Initializes the EEPROM parameters ngbe_rom_info within the
15  *  ngbe_hw struct in order to set up EEPROM access.
16  **/
17 s32 ngbe_init_eeprom_params(struct ngbe_hw *hw)
18 {
19         struct ngbe_rom_info *eeprom = &hw->rom;
20         u32 eec;
21         u16 eeprom_size;
22
23         DEBUGFUNC("ngbe_init_eeprom_params");
24
25         if (eeprom->type != ngbe_eeprom_unknown)
26                 return 0;
27
28         eeprom->type = ngbe_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, NGBE_SPISTAT);
41         if (!(eec & NGBE_SPISTAT_BPFLASH)) {
42                 eeprom->type = ngbe_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         eeprom->sw_addr = 0x80;
54
55         DEBUGOUT("eeprom params: type = %d, size = %d, address bits: "
56                   "%d %d\n", eeprom->type, eeprom->word_size,
57                   eeprom->address_bits, eeprom->sw_addr);
58
59         return 0;
60 }
61
62 /**
63  *  ngbe_get_eeprom_semaphore - Get hardware semaphore
64  *  @hw: pointer to hardware structure
65  *
66  *  Sets the hardware semaphores so EEPROM access can occur for bit-bang method
67  **/
68 s32 ngbe_get_eeprom_semaphore(struct ngbe_hw *hw)
69 {
70         s32 status = NGBE_ERR_EEPROM;
71         u32 timeout = 2000;
72         u32 i;
73         u32 swsm;
74
75         DEBUGFUNC("ngbe_get_eeprom_semaphore");
76
77
78         /* Get SMBI software semaphore between device drivers first */
79         for (i = 0; i < timeout; i++) {
80                 /*
81                  * If the SMBI bit is 0 when we read it, then the bit will be
82                  * set and we have the semaphore
83                  */
84                 swsm = rd32(hw, NGBE_SWSEM);
85                 if (!(swsm & NGBE_SWSEM_PF)) {
86                         status = 0;
87                         break;
88                 }
89                 usec_delay(50);
90         }
91
92         if (i == timeout) {
93                 DEBUGOUT("Driver can't access the eeprom - SMBI Semaphore "
94                          "not granted.\n");
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                 ngbe_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, NGBE_SWSEM);
110                 if (!(swsm & NGBE_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, NGBE_MNGSWSYNC,
119                                 NGBE_MNGSWSYNC_REQ, NGBE_MNGSWSYNC_REQ);
120
121                         /*
122                          * If we set the bit successfully then we got the
123                          * semaphore.
124                          */
125                         swsm = rd32(hw, NGBE_MNGSWSYNC);
126                         if (swsm & NGBE_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.\n");
138                         ngbe_release_eeprom_semaphore(hw);
139                         status = NGBE_ERR_EEPROM;
140                 }
141         } else {
142                 DEBUGOUT("Software semaphore SMBI between device drivers "
143                          "not granted.\n");
144         }
145
146         return status;
147 }
148
149 /**
150  *  ngbe_release_eeprom_semaphore - Release hardware semaphore
151  *  @hw: pointer to hardware structure
152  *
153  *  This function clears hardware semaphore bits.
154  **/
155 void ngbe_release_eeprom_semaphore(struct ngbe_hw *hw)
156 {
157         DEBUGFUNC("ngbe_release_eeprom_semaphore");
158
159         wr32m(hw, NGBE_MNGSWSYNC, NGBE_MNGSWSYNC_REQ, 0);
160         wr32m(hw, NGBE_SWSEM, NGBE_SWSEM_PF, 0);
161         ngbe_flush(hw);
162 }
163
164 /**
165  *  ngbe_validate_eeprom_checksum_em - Validate EEPROM checksum
166  *  @hw: pointer to hardware structure
167  *  @checksum_val: calculated checksum
168  *
169  *  Performs checksum calculation and validates the EEPROM checksum.  If the
170  *  caller does not need checksum_val, the value can be NULL.
171  **/
172 s32 ngbe_validate_eeprom_checksum_em(struct ngbe_hw *hw,
173                                            u16 *checksum_val)
174 {
175         u32 eeprom_cksum_devcap = 0;
176         int err = 0;
177
178         DEBUGFUNC("ngbe_validate_eeprom_checksum_em");
179         UNREFERENCED_PARAMETER(checksum_val);
180
181         /* Check EEPROM only once */
182         if (hw->bus.lan_id == 0) {
183                 wr32(hw, NGBE_CALSUM_CAP_STATUS, 0x0);
184                 wr32(hw, NGBE_EEPROM_VERSION_STORE_REG, 0x0);
185         } else {
186                 eeprom_cksum_devcap = rd32(hw, NGBE_CALSUM_CAP_STATUS);
187                 hw->rom.saved_version = rd32(hw, NGBE_EEPROM_VERSION_STORE_REG);
188         }
189
190         if (hw->bus.lan_id == 0 || eeprom_cksum_devcap == 0) {
191                 err = ngbe_hic_check_cap(hw);
192                 if (err != 0) {
193                         PMD_INIT_LOG(ERR,
194                                 "The EEPROM checksum is not valid: %d", err);
195                         return -EIO;
196                 }
197         }
198
199         hw->rom.cksum_devcap = eeprom_cksum_devcap & 0xffff;
200
201         return err;
202 }
203