1/*-
2 * Copyright 2021 Intel Corp
3 * Copyright 2021 Rubicon Communications, LLC (Netgate)
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <sys/cdefs.h>
8#include "igc_api.h"
9
10/**
11 *  igc_init_mac_params - Initialize MAC function pointers
12 *  @hw: pointer to the HW structure
13 *
14 *  This function initializes the function pointers for the MAC
15 *  set of functions.  Called by drivers or by igc_setup_init_funcs.
16 **/
17s32 igc_init_mac_params(struct igc_hw *hw)
18{
19	s32 ret_val = IGC_SUCCESS;
20
21	if (hw->mac.ops.init_params) {
22		ret_val = hw->mac.ops.init_params(hw);
23		if (ret_val) {
24			DEBUGOUT("MAC Initialization Error\n");
25			goto out;
26		}
27	} else {
28		DEBUGOUT("mac.init_mac_params was NULL\n");
29		ret_val = -IGC_ERR_CONFIG;
30	}
31
32out:
33	return ret_val;
34}
35
36/**
37 *  igc_init_nvm_params - Initialize NVM function pointers
38 *  @hw: pointer to the HW structure
39 *
40 *  This function initializes the function pointers for the NVM
41 *  set of functions.  Called by drivers or by igc_setup_init_funcs.
42 **/
43s32 igc_init_nvm_params(struct igc_hw *hw)
44{
45	s32 ret_val = IGC_SUCCESS;
46
47	if (hw->nvm.ops.init_params) {
48		ret_val = hw->nvm.ops.init_params(hw);
49		if (ret_val) {
50			DEBUGOUT("NVM Initialization Error\n");
51			goto out;
52		}
53	} else {
54		DEBUGOUT("nvm.init_nvm_params was NULL\n");
55		ret_val = -IGC_ERR_CONFIG;
56	}
57
58out:
59	return ret_val;
60}
61
62/**
63 *  igc_init_phy_params - Initialize PHY function pointers
64 *  @hw: pointer to the HW structure
65 *
66 *  This function initializes the function pointers for the PHY
67 *  set of functions.  Called by drivers or by igc_setup_init_funcs.
68 **/
69s32 igc_init_phy_params(struct igc_hw *hw)
70{
71	s32 ret_val = IGC_SUCCESS;
72
73	if (hw->phy.ops.init_params) {
74		ret_val = hw->phy.ops.init_params(hw);
75		if (ret_val) {
76			DEBUGOUT("PHY Initialization Error\n");
77			goto out;
78		}
79	} else {
80		DEBUGOUT("phy.init_phy_params was NULL\n");
81		ret_val =  -IGC_ERR_CONFIG;
82	}
83
84out:
85	return ret_val;
86}
87
88/**
89 *  igc_set_mac_type - Sets MAC type
90 *  @hw: pointer to the HW structure
91 *
92 *  This function sets the mac type of the adapter based on the
93 *  device ID stored in the hw structure.
94 *  MUST BE FIRST FUNCTION CALLED (explicitly or through
95 *  igc_setup_init_funcs()).
96 **/
97s32 igc_set_mac_type(struct igc_hw *hw)
98{
99	struct igc_mac_info *mac = &hw->mac;
100	s32 ret_val = IGC_SUCCESS;
101
102	DEBUGFUNC("igc_set_mac_type");
103
104	switch (hw->device_id) {
105	case IGC_DEV_ID_I225_LM:
106	case IGC_DEV_ID_I225_V:
107	case IGC_DEV_ID_I225_K:
108	case IGC_DEV_ID_I225_I:
109	case IGC_DEV_ID_I220_V:
110	case IGC_DEV_ID_I225_K2:
111	case IGC_DEV_ID_I225_LMVP:
112	case IGC_DEV_ID_I225_IT:
113	case IGC_DEV_ID_I226_LM:
114	case IGC_DEV_ID_I226_V:
115	case IGC_DEV_ID_I226_IT:
116	case IGC_DEV_ID_I221_V:
117	case IGC_DEV_ID_I226_BLANK_NVM:
118	case IGC_DEV_ID_I225_BLANK_NVM:
119		mac->type = igc_i225;
120		break;
121	default:
122		/* Should never have loaded on this device */
123		ret_val = -IGC_ERR_MAC_INIT;
124		break;
125	}
126
127	return ret_val;
128}
129
130/**
131 *  igc_setup_init_funcs - Initializes function pointers
132 *  @hw: pointer to the HW structure
133 *  @init_device: true will initialize the rest of the function pointers
134 *		  getting the device ready for use.  FALSE will only set
135 *		  MAC type and the function pointers for the other init
136 *		  functions.  Passing FALSE will not generate any hardware
137 *		  reads or writes.
138 *
139 *  This function must be called by a driver in order to use the rest
140 *  of the 'shared' code files. Called by drivers only.
141 **/
142s32 igc_setup_init_funcs(struct igc_hw *hw, bool init_device)
143{
144	s32 ret_val;
145
146	/* Can't do much good without knowing the MAC type. */
147	ret_val = igc_set_mac_type(hw);
148	if (ret_val) {
149		DEBUGOUT("ERROR: MAC type could not be set properly.\n");
150		goto out;
151	}
152
153	if (!hw->hw_addr) {
154		DEBUGOUT("ERROR: Registers not mapped\n");
155		ret_val = -IGC_ERR_CONFIG;
156		goto out;
157	}
158
159	/*
160	 * Init function pointers to generic implementations. We do this first
161	 * allowing a driver module to override it afterward.
162	 */
163	igc_init_mac_ops_generic(hw);
164	igc_init_phy_ops_generic(hw);
165	igc_init_nvm_ops_generic(hw);
166
167	/*
168	 * Set up the init function pointers. These are functions within the
169	 * adapter family file that sets up function pointers for the rest of
170	 * the functions in that family.
171	 */
172	switch (hw->mac.type) {
173	case igc_i225:
174		igc_init_function_pointers_i225(hw);
175		break;
176	default:
177		DEBUGOUT("Hardware not supported\n");
178		ret_val = -IGC_ERR_CONFIG;
179		break;
180	}
181
182	/*
183	 * Initialize the rest of the function pointers. These require some
184	 * register reads/writes in some cases.
185	 */
186	if (!(ret_val) && init_device) {
187		ret_val = igc_init_mac_params(hw);
188		if (ret_val)
189			goto out;
190
191		ret_val = igc_init_nvm_params(hw);
192		if (ret_val)
193			goto out;
194
195		ret_val = igc_init_phy_params(hw);
196		if (ret_val)
197			goto out;
198	}
199
200out:
201	return ret_val;
202}
203
204/**
205 *  igc_get_bus_info - Obtain bus information for adapter
206 *  @hw: pointer to the HW structure
207 *
208 *  This will obtain information about the HW bus for which the
209 *  adapter is attached and stores it in the hw structure. This is a
210 *  function pointer entry point called by drivers.
211 **/
212s32 igc_get_bus_info(struct igc_hw *hw)
213{
214	if (hw->mac.ops.get_bus_info)
215		return hw->mac.ops.get_bus_info(hw);
216
217	return IGC_SUCCESS;
218}
219
220/**
221 *  igc_clear_vfta - Clear VLAN filter table
222 *  @hw: pointer to the HW structure
223 *
224 *  This clears the VLAN filter table on the adapter. This is a function
225 *  pointer entry point called by drivers.
226 **/
227void igc_clear_vfta(struct igc_hw *hw)
228{
229	if (hw->mac.ops.clear_vfta)
230		hw->mac.ops.clear_vfta(hw);
231}
232
233/**
234 *  igc_write_vfta - Write value to VLAN filter table
235 *  @hw: pointer to the HW structure
236 *  @offset: the 32-bit offset in which to write the value to.
237 *  @value: the 32-bit value to write at location offset.
238 *
239 *  This writes a 32-bit value to a 32-bit offset in the VLAN filter
240 *  table. This is a function pointer entry point called by drivers.
241 **/
242void igc_write_vfta(struct igc_hw *hw, u32 offset, u32 value)
243{
244	if (hw->mac.ops.write_vfta)
245		hw->mac.ops.write_vfta(hw, offset, value);
246}
247
248/**
249 *  igc_update_mc_addr_list - Update Multicast addresses
250 *  @hw: pointer to the HW structure
251 *  @mc_addr_list: array of multicast addresses to program
252 *  @mc_addr_count: number of multicast addresses to program
253 *
254 *  Updates the Multicast Table Array.
255 *  The caller must have a packed mc_addr_list of multicast addresses.
256 **/
257void igc_update_mc_addr_list(struct igc_hw *hw, u8 *mc_addr_list,
258			       u32 mc_addr_count)
259{
260	if (hw->mac.ops.update_mc_addr_list)
261		hw->mac.ops.update_mc_addr_list(hw, mc_addr_list,
262						mc_addr_count);
263}
264
265/**
266 *  igc_force_mac_fc - Force MAC flow control
267 *  @hw: pointer to the HW structure
268 *
269 *  Force the MAC's flow control settings. Currently no func pointer exists
270 *  and all implementations are handled in the generic version of this
271 *  function.
272 **/
273s32 igc_force_mac_fc(struct igc_hw *hw)
274{
275	return igc_force_mac_fc_generic(hw);
276}
277
278/**
279 *  igc_check_for_link - Check/Store link connection
280 *  @hw: pointer to the HW structure
281 *
282 *  This checks the link condition of the adapter and stores the
283 *  results in the hw->mac structure. This is a function pointer entry
284 *  point called by drivers.
285 **/
286s32 igc_check_for_link(struct igc_hw *hw)
287{
288	if (hw->mac.ops.check_for_link)
289		return hw->mac.ops.check_for_link(hw);
290
291	return -IGC_ERR_CONFIG;
292}
293
294/**
295 *  igc_reset_hw - Reset hardware
296 *  @hw: pointer to the HW structure
297 *
298 *  This resets the hardware into a known state. This is a function pointer
299 *  entry point called by drivers.
300 **/
301s32 igc_reset_hw(struct igc_hw *hw)
302{
303	if (hw->mac.ops.reset_hw)
304		return hw->mac.ops.reset_hw(hw);
305
306	return -IGC_ERR_CONFIG;
307}
308
309/**
310 *  igc_init_hw - Initialize hardware
311 *  @hw: pointer to the HW structure
312 *
313 *  This inits the hardware readying it for operation. This is a function
314 *  pointer entry point called by drivers.
315 **/
316s32 igc_init_hw(struct igc_hw *hw)
317{
318	if (hw->mac.ops.init_hw)
319		return hw->mac.ops.init_hw(hw);
320
321	return -IGC_ERR_CONFIG;
322}
323
324/**
325 *  igc_setup_link - Configures link and flow control
326 *  @hw: pointer to the HW structure
327 *
328 *  This configures link and flow control settings for the adapter. This
329 *  is a function pointer entry point called by drivers. While modules can
330 *  also call this, they probably call their own version of this function.
331 **/
332s32 igc_setup_link(struct igc_hw *hw)
333{
334	if (hw->mac.ops.setup_link)
335		return hw->mac.ops.setup_link(hw);
336
337	return -IGC_ERR_CONFIG;
338}
339
340/**
341 *  igc_get_speed_and_duplex - Returns current speed and duplex
342 *  @hw: pointer to the HW structure
343 *  @speed: pointer to a 16-bit value to store the speed
344 *  @duplex: pointer to a 16-bit value to store the duplex.
345 *
346 *  This returns the speed and duplex of the adapter in the two 'out'
347 *  variables passed in. This is a function pointer entry point called
348 *  by drivers.
349 **/
350s32 igc_get_speed_and_duplex(struct igc_hw *hw, u16 *speed, u16 *duplex)
351{
352	if (hw->mac.ops.get_link_up_info)
353		return hw->mac.ops.get_link_up_info(hw, speed, duplex);
354
355	return -IGC_ERR_CONFIG;
356}
357
358/**
359 *  igc_disable_pcie_master - Disable PCI-Express master access
360 *  @hw: pointer to the HW structure
361 *
362 *  Disables PCI-Express master access and verifies there are no pending
363 *  requests. Currently no func pointer exists and all implementations are
364 *  handled in the generic version of this function.
365 **/
366s32 igc_disable_pcie_master(struct igc_hw *hw)
367{
368	return igc_disable_pcie_master_generic(hw);
369}
370
371/**
372 *  igc_config_collision_dist - Configure collision distance
373 *  @hw: pointer to the HW structure
374 *
375 *  Configures the collision distance to the default value and is used
376 *  during link setup.
377 **/
378void igc_config_collision_dist(struct igc_hw *hw)
379{
380	if (hw->mac.ops.config_collision_dist)
381		hw->mac.ops.config_collision_dist(hw);
382}
383
384/**
385 *  igc_rar_set - Sets a receive address register
386 *  @hw: pointer to the HW structure
387 *  @addr: address to set the RAR to
388 *  @index: the RAR to set
389 *
390 *  Sets a Receive Address Register (RAR) to the specified address.
391 **/
392int igc_rar_set(struct igc_hw *hw, u8 *addr, u32 index)
393{
394	if (hw->mac.ops.rar_set)
395		return hw->mac.ops.rar_set(hw, addr, index);
396
397	return IGC_SUCCESS;
398}
399
400/**
401 *  igc_validate_mdi_setting - Ensures valid MDI/MDIX SW state
402 *  @hw: pointer to the HW structure
403 *
404 *  Ensures that the MDI/MDIX SW state is valid.
405 **/
406s32 igc_validate_mdi_setting(struct igc_hw *hw)
407{
408	if (hw->mac.ops.validate_mdi_setting)
409		return hw->mac.ops.validate_mdi_setting(hw);
410
411	return IGC_SUCCESS;
412}
413
414/**
415 *  igc_hash_mc_addr - Determines address location in multicast table
416 *  @hw: pointer to the HW structure
417 *  @mc_addr: Multicast address to hash.
418 *
419 *  This hashes an address to determine its location in the multicast
420 *  table. Currently no func pointer exists and all implementations
421 *  are handled in the generic version of this function.
422 **/
423u32 igc_hash_mc_addr(struct igc_hw *hw, u8 *mc_addr)
424{
425	return igc_hash_mc_addr_generic(hw, mc_addr);
426}
427
428/**
429 *  igc_check_reset_block - Verifies PHY can be reset
430 *  @hw: pointer to the HW structure
431 *
432 *  Checks if the PHY is in a state that can be reset or if manageability
433 *  has it tied up. This is a function pointer entry point called by drivers.
434 **/
435s32 igc_check_reset_block(struct igc_hw *hw)
436{
437	if (hw->phy.ops.check_reset_block)
438		return hw->phy.ops.check_reset_block(hw);
439
440	return IGC_SUCCESS;
441}
442
443/**
444 *  igc_read_phy_reg - Reads PHY register
445 *  @hw: pointer to the HW structure
446 *  @offset: the register to read
447 *  @data: the buffer to store the 16-bit read.
448 *
449 *  Reads the PHY register and returns the value in data.
450 *  This is a function pointer entry point called by drivers.
451 **/
452s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data)
453{
454	if (hw->phy.ops.read_reg)
455		return hw->phy.ops.read_reg(hw, offset, data);
456
457	return IGC_SUCCESS;
458}
459
460/**
461 *  igc_write_phy_reg - Writes PHY register
462 *  @hw: pointer to the HW structure
463 *  @offset: the register to write
464 *  @data: the value to write.
465 *
466 *  Writes the PHY register at offset with the value in data.
467 *  This is a function pointer entry point called by drivers.
468 **/
469s32 igc_write_phy_reg(struct igc_hw *hw, u32 offset, u16 data)
470{
471	if (hw->phy.ops.write_reg)
472		return hw->phy.ops.write_reg(hw, offset, data);
473
474	return IGC_SUCCESS;
475}
476
477/**
478 *  igc_release_phy - Generic release PHY
479 *  @hw: pointer to the HW structure
480 *
481 *  Return if silicon family does not require a semaphore when accessing the
482 *  PHY.
483 **/
484void igc_release_phy(struct igc_hw *hw)
485{
486	if (hw->phy.ops.release)
487		hw->phy.ops.release(hw);
488}
489
490/**
491 *  igc_acquire_phy - Generic acquire PHY
492 *  @hw: pointer to the HW structure
493 *
494 *  Return success if silicon family does not require a semaphore when
495 *  accessing the PHY.
496 **/
497s32 igc_acquire_phy(struct igc_hw *hw)
498{
499	if (hw->phy.ops.acquire)
500		return hw->phy.ops.acquire(hw);
501
502	return IGC_SUCCESS;
503}
504
505/**
506 *  igc_get_phy_info - Retrieves PHY information from registers
507 *  @hw: pointer to the HW structure
508 *
509 *  This function gets some information from various PHY registers and
510 *  populates hw->phy values with it. This is a function pointer entry
511 *  point called by drivers.
512 **/
513s32 igc_get_phy_info(struct igc_hw *hw)
514{
515	if (hw->phy.ops.get_info)
516		return hw->phy.ops.get_info(hw);
517
518	return IGC_SUCCESS;
519}
520
521/**
522 *  igc_phy_hw_reset - Hard PHY reset
523 *  @hw: pointer to the HW structure
524 *
525 *  Performs a hard PHY reset. This is a function pointer entry point called
526 *  by drivers.
527 **/
528s32 igc_phy_hw_reset(struct igc_hw *hw)
529{
530	if (hw->phy.ops.reset)
531		return hw->phy.ops.reset(hw);
532
533	return IGC_SUCCESS;
534}
535
536/**
537 *  igc_set_d0_lplu_state - Sets low power link up state for D0
538 *  @hw: pointer to the HW structure
539 *  @active: boolean used to enable/disable lplu
540 *
541 *  Success returns 0, Failure returns 1
542 *
543 *  The low power link up (lplu) state is set to the power management level D0
544 *  and SmartSpeed is disabled when active is true, else clear lplu for D0
545 *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
546 *  is used during Dx states where the power conservation is most important.
547 *  During driver activity, SmartSpeed should be enabled so performance is
548 *  maintained.  This is a function pointer entry point called by drivers.
549 **/
550s32 igc_set_d0_lplu_state(struct igc_hw *hw, bool active)
551{
552	if (hw->phy.ops.set_d0_lplu_state)
553		return hw->phy.ops.set_d0_lplu_state(hw, active);
554
555	return IGC_SUCCESS;
556}
557
558/**
559 *  igc_set_d3_lplu_state - Sets low power link up state for D3
560 *  @hw: pointer to the HW structure
561 *  @active: boolean used to enable/disable lplu
562 *
563 *  Success returns 0, Failure returns 1
564 *
565 *  The low power link up (lplu) state is set to the power management level D3
566 *  and SmartSpeed is disabled when active is true, else clear lplu for D3
567 *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
568 *  is used during Dx states where the power conservation is most important.
569 *  During driver activity, SmartSpeed should be enabled so performance is
570 *  maintained.  This is a function pointer entry point called by drivers.
571 **/
572s32 igc_set_d3_lplu_state(struct igc_hw *hw, bool active)
573{
574	if (hw->phy.ops.set_d3_lplu_state)
575		return hw->phy.ops.set_d3_lplu_state(hw, active);
576
577	return IGC_SUCCESS;
578}
579
580/**
581 *  igc_read_mac_addr - Reads MAC address
582 *  @hw: pointer to the HW structure
583 *
584 *  Reads the MAC address out of the adapter and stores it in the HW structure.
585 *  Currently no func pointer exists and all implementations are handled in the
586 *  generic version of this function.
587 **/
588s32 igc_read_mac_addr(struct igc_hw *hw)
589{
590	if (hw->mac.ops.read_mac_addr)
591		return hw->mac.ops.read_mac_addr(hw);
592
593	return igc_read_mac_addr_generic(hw);
594}
595
596/**
597 *  igc_read_pba_string - Read device part number string
598 *  @hw: pointer to the HW structure
599 *  @pba_num: pointer to device part number
600 *  @pba_num_size: size of part number buffer
601 *
602 *  Reads the product board assembly (PBA) number from the EEPROM and stores
603 *  the value in pba_num.
604 *  Currently no func pointer exists and all implementations are handled in the
605 *  generic version of this function.
606 **/
607s32 igc_read_pba_string(struct igc_hw *hw, u8 *pba_num, u32 pba_num_size)
608{
609	return igc_read_pba_string_generic(hw, pba_num, pba_num_size);
610}
611
612/**
613 *  igc_validate_nvm_checksum - Verifies NVM (EEPROM) checksum
614 *  @hw: pointer to the HW structure
615 *
616 *  Validates the NVM checksum is correct. This is a function pointer entry
617 *  point called by drivers.
618 **/
619s32 igc_validate_nvm_checksum(struct igc_hw *hw)
620{
621	if (hw->nvm.ops.validate)
622		return hw->nvm.ops.validate(hw);
623
624	return -IGC_ERR_CONFIG;
625}
626
627/**
628 *  igc_update_nvm_checksum - Updates NVM (EEPROM) checksum
629 *  @hw: pointer to the HW structure
630 *
631 *  Updates the NVM checksum. Currently no func pointer exists and all
632 *  implementations are handled in the generic version of this function.
633 **/
634s32 igc_update_nvm_checksum(struct igc_hw *hw)
635{
636	if (hw->nvm.ops.update)
637		return hw->nvm.ops.update(hw);
638
639	return -IGC_ERR_CONFIG;
640}
641
642/**
643 *  igc_reload_nvm - Reloads EEPROM
644 *  @hw: pointer to the HW structure
645 *
646 *  Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
647 *  extended control register.
648 **/
649void igc_reload_nvm(struct igc_hw *hw)
650{
651	if (hw->nvm.ops.reload)
652		hw->nvm.ops.reload(hw);
653}
654
655/**
656 *  igc_read_nvm - Reads NVM (EEPROM)
657 *  @hw: pointer to the HW structure
658 *  @offset: the word offset to read
659 *  @words: number of 16-bit words to read
660 *  @data: pointer to the properly sized buffer for the data.
661 *
662 *  Reads 16-bit chunks of data from the NVM (EEPROM). This is a function
663 *  pointer entry point called by drivers.
664 **/
665s32 igc_read_nvm(struct igc_hw *hw, u16 offset, u16 words, u16 *data)
666{
667	if (hw->nvm.ops.read)
668		return hw->nvm.ops.read(hw, offset, words, data);
669
670	return -IGC_ERR_CONFIG;
671}
672
673/**
674 *  igc_write_nvm - Writes to NVM (EEPROM)
675 *  @hw: pointer to the HW structure
676 *  @offset: the word offset to read
677 *  @words: number of 16-bit words to write
678 *  @data: pointer to the properly sized buffer for the data.
679 *
680 *  Writes 16-bit chunks of data to the NVM (EEPROM). This is a function
681 *  pointer entry point called by drivers.
682 **/
683s32 igc_write_nvm(struct igc_hw *hw, u16 offset, u16 words, u16 *data)
684{
685	if (hw->nvm.ops.write)
686		return hw->nvm.ops.write(hw, offset, words, data);
687
688	return IGC_SUCCESS;
689}
690
691/**
692 * igc_power_up_phy - Restores link in case of PHY power down
693 * @hw: pointer to the HW structure
694 *
695 * The phy may be powered down to save power, to turn off link when the
696 * driver is unloaded, or wake on lan is not enabled (among others).
697 **/
698void igc_power_up_phy(struct igc_hw *hw)
699{
700	if (hw->phy.ops.power_up)
701		hw->phy.ops.power_up(hw);
702
703	igc_setup_link(hw);
704}
705
706/**
707 * igc_power_down_phy - Power down PHY
708 * @hw: pointer to the HW structure
709 *
710 * The phy may be powered down to save power, to turn off link when the
711 * driver is unloaded, or wake on lan is not enabled (among others).
712 **/
713void igc_power_down_phy(struct igc_hw *hw)
714{
715	if (hw->phy.ops.power_down)
716		hw->phy.ops.power_down(hw);
717}
718
719