igc_api.c revision 1.2 1 1.2 rin /* $NetBSD: igc_api.c,v 1.2 2023/10/04 07:35:27 rin Exp $ */
2 1.1 rin /* $OpenBSD: igc_api.c,v 1.1 2021/10/31 14:52:57 patrick Exp $ */
3 1.1 rin /*-
4 1.1 rin * Copyright 2021 Intel Corp
5 1.1 rin * Copyright 2021 Rubicon Communications, LLC (Netgate)
6 1.1 rin * SPDX-License-Identifier: BSD-3-Clause
7 1.1 rin */
8 1.1 rin
9 1.2 rin #include <sys/cdefs.h>
10 1.2 rin __KERNEL_RCSID(0, "$NetBSD: igc_api.c,v 1.2 2023/10/04 07:35:27 rin Exp $");
11 1.2 rin
12 1.2 rin #include <dev/pci/igc/igc_api.h>
13 1.2 rin #include <dev/pci/igc/igc_hw.h>
14 1.1 rin
15 1.1 rin /**
16 1.1 rin * igc_init_mac_params - Initialize MAC function pointers
17 1.1 rin * @hw: pointer to the HW structure
18 1.1 rin *
19 1.1 rin * This function initializes the function pointers for the MAC
20 1.1 rin * set of functions. Called by drivers or by igc_setup_init_funcs.
21 1.1 rin **/
22 1.1 rin int
23 1.1 rin igc_init_mac_params(struct igc_hw *hw)
24 1.1 rin {
25 1.1 rin int ret_val = IGC_SUCCESS;
26 1.1 rin
27 1.1 rin if (hw->mac.ops.init_params) {
28 1.1 rin ret_val = hw->mac.ops.init_params(hw);
29 1.1 rin if (ret_val) {
30 1.1 rin DEBUGOUT("MAC Initialization Error\n");
31 1.1 rin goto out;
32 1.1 rin }
33 1.1 rin } else {
34 1.1 rin DEBUGOUT("mac.init_mac_params was NULL\n");
35 1.1 rin ret_val = -IGC_ERR_CONFIG;
36 1.1 rin }
37 1.1 rin out:
38 1.1 rin return ret_val;
39 1.1 rin }
40 1.1 rin
41 1.1 rin /**
42 1.1 rin * igc_init_nvm_params - Initialize NVM function pointers
43 1.1 rin * @hw: pointer to the HW structure
44 1.1 rin *
45 1.1 rin * This function initializes the function pointers for the NVM
46 1.1 rin * set of functions. Called by drivers or by igc_setup_init_funcs.
47 1.1 rin **/
48 1.1 rin int
49 1.1 rin igc_init_nvm_params(struct igc_hw *hw)
50 1.1 rin {
51 1.1 rin int ret_val = IGC_SUCCESS;
52 1.1 rin
53 1.1 rin if (hw->nvm.ops.init_params) {
54 1.1 rin ret_val = hw->nvm.ops.init_params(hw);
55 1.1 rin if (ret_val) {
56 1.1 rin DEBUGOUT("NVM Initialization Error\n");
57 1.1 rin goto out;
58 1.1 rin }
59 1.1 rin } else {
60 1.1 rin DEBUGOUT("nvm.init_nvm_params was NULL\n");
61 1.1 rin ret_val = -IGC_ERR_CONFIG;
62 1.1 rin }
63 1.1 rin out:
64 1.1 rin return ret_val;
65 1.1 rin }
66 1.1 rin
67 1.1 rin /**
68 1.1 rin * igc_init_phy_params - Initialize PHY function pointers
69 1.1 rin * @hw: pointer to the HW structure
70 1.1 rin *
71 1.1 rin * This function initializes the function pointers for the PHY
72 1.1 rin * set of functions. Called by drivers or by igc_setup_init_funcs.
73 1.1 rin **/
74 1.1 rin int
75 1.1 rin igc_init_phy_params(struct igc_hw *hw)
76 1.1 rin {
77 1.1 rin int ret_val = IGC_SUCCESS;
78 1.1 rin
79 1.1 rin if (hw->phy.ops.init_params) {
80 1.1 rin ret_val = hw->phy.ops.init_params(hw);
81 1.1 rin if (ret_val) {
82 1.1 rin DEBUGOUT("PHY Initialization Error\n");
83 1.1 rin goto out;
84 1.1 rin }
85 1.1 rin } else {
86 1.1 rin DEBUGOUT("phy.init_phy_params was NULL\n");
87 1.1 rin ret_val = -IGC_ERR_CONFIG;
88 1.1 rin }
89 1.1 rin out:
90 1.1 rin return ret_val;
91 1.1 rin }
92 1.1 rin
93 1.1 rin /**
94 1.1 rin * igc_set_mac_type - Sets MAC type
95 1.1 rin * @hw: pointer to the HW structure
96 1.1 rin *
97 1.1 rin * This function sets the mac type of the adapter based on the
98 1.1 rin * device ID stored in the hw structure.
99 1.1 rin * MUST BE FIRST FUNCTION CALLED (explicitly or through
100 1.1 rin * igc_setup_init_funcs()).
101 1.1 rin **/
102 1.1 rin int
103 1.1 rin igc_set_mac_type(struct igc_hw *hw)
104 1.1 rin {
105 1.1 rin struct igc_mac_info *mac = &hw->mac;
106 1.1 rin int ret_val = IGC_SUCCESS;
107 1.1 rin
108 1.1 rin DEBUGFUNC("igc_set_mac_type");
109 1.1 rin
110 1.1 rin switch (hw->device_id) {
111 1.1 rin case PCI_PRODUCT_INTEL_I220_V:
112 1.1 rin case PCI_PRODUCT_INTEL_I221_V:
113 1.1 rin case PCI_PRODUCT_INTEL_I225_BLANK_NVM:
114 1.1 rin case PCI_PRODUCT_INTEL_I225_I:
115 1.1 rin case PCI_PRODUCT_INTEL_I225_IT:
116 1.1 rin case PCI_PRODUCT_INTEL_I225_K:
117 1.1 rin case PCI_PRODUCT_INTEL_I225_K2:
118 1.1 rin case PCI_PRODUCT_INTEL_I225_LM:
119 1.1 rin case PCI_PRODUCT_INTEL_I225_LMVP:
120 1.1 rin case PCI_PRODUCT_INTEL_I225_V:
121 1.1 rin case PCI_PRODUCT_INTEL_I226_BLANK_NVM:
122 1.1 rin case PCI_PRODUCT_INTEL_I226_IT:
123 1.1 rin case PCI_PRODUCT_INTEL_I226_LM:
124 1.2 rin case PCI_PRODUCT_INTEL_I226_LMVP:
125 1.1 rin case PCI_PRODUCT_INTEL_I226_K:
126 1.1 rin case PCI_PRODUCT_INTEL_I226_V:
127 1.1 rin mac->type = igc_i225;
128 1.1 rin break;
129 1.1 rin default:
130 1.1 rin /* Should never have loaded on this device */
131 1.1 rin ret_val = -IGC_ERR_MAC_INIT;
132 1.1 rin break;
133 1.1 rin }
134 1.1 rin
135 1.1 rin return ret_val;
136 1.1 rin }
137 1.1 rin
138 1.1 rin /**
139 1.1 rin * igc_setup_init_funcs - Initializes function pointers
140 1.1 rin * @hw: pointer to the HW structure
141 1.1 rin * @init_device: true will initialize the rest of the function pointers
142 1.1 rin * getting the device ready for use. FALSE will only set
143 1.1 rin * MAC type and the function pointers for the other init
144 1.1 rin * functions. Passing FALSE will not generate any hardware
145 1.1 rin * reads or writes.
146 1.1 rin *
147 1.1 rin * This function must be called by a driver in order to use the rest
148 1.1 rin * of the 'shared' code files. Called by drivers only.
149 1.1 rin **/
150 1.1 rin int
151 1.1 rin igc_setup_init_funcs(struct igc_hw *hw, bool init_device)
152 1.1 rin {
153 1.1 rin int ret_val;
154 1.1 rin
155 1.1 rin /* Can't do much good without knowing the MAC type. */
156 1.1 rin ret_val = igc_set_mac_type(hw);
157 1.1 rin if (ret_val) {
158 1.1 rin DEBUGOUT("ERROR: MAC type could not be set properly.\n");
159 1.1 rin goto out;
160 1.1 rin }
161 1.1 rin
162 1.1 rin if (!hw->hw_addr) {
163 1.1 rin DEBUGOUT("ERROR: Registers not mapped\n");
164 1.1 rin ret_val = -IGC_ERR_CONFIG;
165 1.1 rin goto out;
166 1.1 rin }
167 1.1 rin
168 1.1 rin /*
169 1.1 rin * Init function pointers to generic implementations. We do this first
170 1.1 rin * allowing a driver module to override it afterward.
171 1.1 rin */
172 1.1 rin igc_init_mac_ops_generic(hw);
173 1.1 rin igc_init_phy_ops_generic(hw);
174 1.1 rin igc_init_nvm_ops_generic(hw);
175 1.1 rin
176 1.1 rin /*
177 1.1 rin * Set up the init function pointers. These are functions within the
178 1.1 rin * adapter family file that sets up function pointers for the rest of
179 1.1 rin * the functions in that family.
180 1.1 rin */
181 1.1 rin switch (hw->mac.type) {
182 1.1 rin case igc_i225:
183 1.1 rin igc_init_function_pointers_i225(hw);
184 1.1 rin break;
185 1.1 rin default:
186 1.1 rin DEBUGOUT("Hardware not supported\n");
187 1.1 rin ret_val = -IGC_ERR_CONFIG;
188 1.1 rin break;
189 1.1 rin }
190 1.1 rin
191 1.1 rin /*
192 1.1 rin * Initialize the rest of the function pointers. These require some
193 1.1 rin * register reads/writes in some cases.
194 1.1 rin */
195 1.1 rin if (!(ret_val) && init_device) {
196 1.1 rin ret_val = igc_init_mac_params(hw);
197 1.1 rin if (ret_val)
198 1.1 rin goto out;
199 1.1 rin
200 1.1 rin ret_val = igc_init_nvm_params(hw);
201 1.1 rin if (ret_val)
202 1.1 rin goto out;
203 1.1 rin
204 1.1 rin ret_val = igc_init_phy_params(hw);
205 1.1 rin if (ret_val)
206 1.1 rin goto out;
207 1.1 rin }
208 1.1 rin out:
209 1.1 rin return ret_val;
210 1.1 rin }
211 1.1 rin
212 1.1 rin /**
213 1.1 rin * igc_update_mc_addr_list - Update Multicast addresses
214 1.1 rin * @hw: pointer to the HW structure
215 1.1 rin * @mc_addr_list: array of multicast addresses to program
216 1.1 rin * @mc_addr_count: number of multicast addresses to program
217 1.1 rin *
218 1.1 rin * Updates the Multicast Table Array.
219 1.1 rin * The caller must have a packed mc_addr_list of multicast addresses.
220 1.1 rin **/
221 1.1 rin void
222 1.1 rin igc_update_mc_addr_list(struct igc_hw *hw, uint8_t *mc_addr_list,
223 1.1 rin uint32_t mc_addr_count)
224 1.1 rin {
225 1.1 rin if (hw->mac.ops.update_mc_addr_list)
226 1.1 rin hw->mac.ops.update_mc_addr_list(hw, mc_addr_list,
227 1.1 rin mc_addr_count);
228 1.1 rin }
229 1.1 rin
230 1.1 rin /**
231 1.1 rin * igc_check_for_link - Check/Store link connection
232 1.1 rin * @hw: pointer to the HW structure
233 1.1 rin *
234 1.1 rin * This checks the link condition of the adapter and stores the
235 1.1 rin * results in the hw->mac structure. This is a function pointer entry
236 1.1 rin * point called by drivers.
237 1.1 rin **/
238 1.1 rin int
239 1.1 rin igc_check_for_link(struct igc_hw *hw)
240 1.1 rin {
241 1.1 rin if (hw->mac.ops.check_for_link)
242 1.1 rin return hw->mac.ops.check_for_link(hw);
243 1.1 rin
244 1.1 rin return -IGC_ERR_CONFIG;
245 1.1 rin }
246 1.1 rin
247 1.1 rin /**
248 1.1 rin * igc_reset_hw - Reset hardware
249 1.1 rin * @hw: pointer to the HW structure
250 1.1 rin *
251 1.1 rin * This resets the hardware into a known state. This is a function pointer
252 1.1 rin * entry point called by drivers.
253 1.1 rin **/
254 1.1 rin int
255 1.1 rin igc_reset_hw(struct igc_hw *hw)
256 1.1 rin {
257 1.1 rin if (hw->mac.ops.reset_hw)
258 1.1 rin return hw->mac.ops.reset_hw(hw);
259 1.1 rin
260 1.1 rin return -IGC_ERR_CONFIG;
261 1.1 rin }
262 1.1 rin
263 1.1 rin /**
264 1.1 rin * igc_init_hw - Initialize hardware
265 1.1 rin * @hw: pointer to the HW structure
266 1.1 rin *
267 1.1 rin * This inits the hardware readying it for operation. This is a function
268 1.1 rin * pointer entry point called by drivers.
269 1.1 rin **/
270 1.1 rin int
271 1.1 rin igc_init_hw(struct igc_hw *hw)
272 1.1 rin {
273 1.1 rin if (hw->mac.ops.init_hw)
274 1.1 rin return hw->mac.ops.init_hw(hw);
275 1.1 rin
276 1.1 rin return -IGC_ERR_CONFIG;
277 1.1 rin }
278 1.1 rin
279 1.1 rin /**
280 1.1 rin * igc_get_speed_and_duplex - Returns current speed and duplex
281 1.1 rin * @hw: pointer to the HW structure
282 1.1 rin * @speed: pointer to a 16-bit value to store the speed
283 1.1 rin * @duplex: pointer to a 16-bit value to store the duplex.
284 1.1 rin *
285 1.1 rin * This returns the speed and duplex of the adapter in the two 'out'
286 1.1 rin * variables passed in. This is a function pointer entry point called
287 1.1 rin * by drivers.
288 1.1 rin **/
289 1.1 rin int
290 1.1 rin igc_get_speed_and_duplex(struct igc_hw *hw, uint16_t *speed, uint16_t *duplex)
291 1.1 rin {
292 1.1 rin if (hw->mac.ops.get_link_up_info)
293 1.1 rin return hw->mac.ops.get_link_up_info(hw, speed, duplex);
294 1.1 rin
295 1.1 rin return -IGC_ERR_CONFIG;
296 1.1 rin }
297 1.1 rin
298 1.1 rin /**
299 1.1 rin * igc_rar_set - Sets a receive address register
300 1.1 rin * @hw: pointer to the HW structure
301 1.1 rin * @addr: address to set the RAR to
302 1.1 rin * @index: the RAR to set
303 1.1 rin *
304 1.1 rin * Sets a Receive Address Register (RAR) to the specified address.
305 1.1 rin **/
306 1.1 rin int
307 1.1 rin igc_rar_set(struct igc_hw *hw, uint8_t *addr, uint32_t index)
308 1.1 rin {
309 1.1 rin if (hw->mac.ops.rar_set)
310 1.1 rin return hw->mac.ops.rar_set(hw, addr, index);
311 1.1 rin
312 1.1 rin return IGC_SUCCESS;
313 1.1 rin }
314 1.1 rin
315 1.1 rin /**
316 1.1 rin * igc_check_reset_block - Verifies PHY can be reset
317 1.1 rin * @hw: pointer to the HW structure
318 1.1 rin *
319 1.1 rin * Checks if the PHY is in a state that can be reset or if manageability
320 1.1 rin * has it tied up. This is a function pointer entry point called by drivers.
321 1.1 rin **/
322 1.1 rin int
323 1.1 rin igc_check_reset_block(struct igc_hw *hw)
324 1.1 rin {
325 1.1 rin if (hw->phy.ops.check_reset_block)
326 1.1 rin return hw->phy.ops.check_reset_block(hw);
327 1.1 rin
328 1.1 rin return IGC_SUCCESS;
329 1.1 rin }
330 1.1 rin
331 1.1 rin /**
332 1.1 rin * igc_get_phy_info - Retrieves PHY information from registers
333 1.1 rin * @hw: pointer to the HW structure
334 1.1 rin *
335 1.1 rin * This function gets some information from various PHY registers and
336 1.1 rin * populates hw->phy values with it. This is a function pointer entry
337 1.1 rin * point called by drivers.
338 1.1 rin **/
339 1.1 rin int
340 1.1 rin igc_get_phy_info(struct igc_hw *hw)
341 1.1 rin {
342 1.1 rin if (hw->phy.ops.get_info)
343 1.1 rin return hw->phy.ops.get_info(hw);
344 1.1 rin
345 1.1 rin return IGC_SUCCESS;
346 1.1 rin }
347 1.1 rin
348 1.1 rin /**
349 1.1 rin * igc_phy_hw_reset - Hard PHY reset
350 1.1 rin * @hw: pointer to the HW structure
351 1.1 rin *
352 1.1 rin * Performs a hard PHY reset. This is a function pointer entry point called
353 1.1 rin * by drivers.
354 1.1 rin **/
355 1.1 rin int
356 1.1 rin igc_phy_hw_reset(struct igc_hw *hw)
357 1.1 rin {
358 1.1 rin if (hw->phy.ops.reset)
359 1.1 rin return hw->phy.ops.reset(hw);
360 1.1 rin
361 1.1 rin return IGC_SUCCESS;
362 1.1 rin }
363 1.1 rin
364 1.1 rin /**
365 1.1 rin * igc_read_mac_addr - Reads MAC address
366 1.1 rin * @hw: pointer to the HW structure
367 1.1 rin *
368 1.1 rin * Reads the MAC address out of the adapter and stores it in the HW structure.
369 1.1 rin * Currently no func pointer exists and all implementations are handled in the
370 1.1 rin * generic version of this function.
371 1.1 rin **/
372 1.1 rin int
373 1.1 rin igc_read_mac_addr(struct igc_hw *hw)
374 1.1 rin {
375 1.1 rin if (hw->mac.ops.read_mac_addr)
376 1.1 rin return hw->mac.ops.read_mac_addr(hw);
377 1.1 rin
378 1.1 rin return igc_read_mac_addr_generic(hw);
379 1.1 rin }
380 1.1 rin
381 1.1 rin /**
382 1.1 rin * igc_validate_nvm_checksum - Verifies NVM (EEPROM) checksum
383 1.1 rin * @hw: pointer to the HW structure
384 1.1 rin *
385 1.1 rin * Validates the NVM checksum is correct. This is a function pointer entry
386 1.1 rin * point called by drivers.
387 1.1 rin **/
388 1.1 rin int
389 1.1 rin igc_validate_nvm_checksum(struct igc_hw *hw)
390 1.1 rin {
391 1.1 rin if (hw->nvm.ops.validate)
392 1.1 rin return hw->nvm.ops.validate(hw);
393 1.1 rin
394 1.1 rin return -IGC_ERR_CONFIG;
395 1.1 rin }
396