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