xref: /openbsd/sys/dev/pci/igc_api.c (revision 83306792)
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