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