1 /* $NetBSD: igc_base.c,v 1.2 2023/10/04 07:35:27 rin Exp $ */
2 /* $OpenBSD: igc_base.c,v 1.1 2021/10/31 14:52:57 patrick Exp $ */
3 /*-
4 * Copyright 2021 Intel Corp
5 * Copyright 2021 Rubicon Communications, LLC (Netgate)
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include <sys/cdefs.h>
10 __KERNEL_RCSID(0, "$NetBSD: igc_base.c,v 1.2 2023/10/04 07:35:27 rin Exp $");
11
12 #include <dev/pci/igc/igc_hw.h>
13 #include <dev/pci/igc/igc_i225.h>
14 #include <dev/pci/igc/if_igc.h>
15 #include <dev/pci/igc/igc_mac.h>
16 #include <dev/pci/igc/igc_base.h>
17
18 /**
19 * igc_acquire_phy_base - Acquire rights to access PHY
20 * @hw: pointer to the HW structure
21 *
22 * Acquire access rights to the correct PHY.
23 **/
24 int
igc_acquire_phy_base(struct igc_hw * hw)25 igc_acquire_phy_base(struct igc_hw *hw)
26 {
27 uint16_t mask = IGC_SWFW_PHY0_SM;
28
29 DEBUGFUNC("igc_acquire_phy_base");
30
31 if (hw->bus.func == IGC_FUNC_1)
32 mask = IGC_SWFW_PHY1_SM;
33
34 return hw->mac.ops.acquire_swfw_sync(hw, mask);
35 }
36
37 /**
38 * igc_release_phy_base - Release rights to access PHY
39 * @hw: pointer to the HW structure
40 *
41 * A wrapper to release access rights to the correct PHY.
42 **/
43 void
igc_release_phy_base(struct igc_hw * hw)44 igc_release_phy_base(struct igc_hw *hw)
45 {
46 uint16_t mask = IGC_SWFW_PHY0_SM;
47
48 DEBUGFUNC("igc_release_phy_base");
49
50 if (hw->bus.func == IGC_FUNC_1)
51 mask = IGC_SWFW_PHY1_SM;
52
53 hw->mac.ops.release_swfw_sync(hw, mask);
54 }
55
56 /**
57 * igc_init_hw_base - Initialize hardware
58 * @hw: pointer to the HW structure
59 *
60 * This inits the hardware readying it for operation.
61 **/
62 int
igc_init_hw_base(struct igc_hw * hw)63 igc_init_hw_base(struct igc_hw *hw)
64 {
65 struct igc_mac_info *mac = &hw->mac;
66 uint16_t i, rar_count = mac->rar_entry_count;
67 int ret_val;
68
69 DEBUGFUNC("igc_init_hw_base");
70
71 /* Setup the receive address */
72 igc_init_rx_addrs_generic(hw, rar_count);
73
74 /* Zero out the Multicast HASH table */
75 DEBUGOUT("Zeroing the MTA\n");
76 for (i = 0; i < mac->mta_reg_count; i++)
77 IGC_WRITE_REG_ARRAY(hw, IGC_MTA, i, 0);
78
79 /* Zero out the Unicast HASH table */
80 DEBUGOUT("Zeroing the UTA\n");
81 for (i = 0; i < mac->uta_reg_count; i++)
82 IGC_WRITE_REG_ARRAY(hw, IGC_UTA, i, 0);
83
84 /* Setup link and flow control */
85 ret_val = mac->ops.setup_link(hw);
86 /*
87 * Clear all of the statistics registers (clear on read). It is
88 * important that we do this after we have tried to establish link
89 * because the symbol error count will increment wildly if there
90 * is no link.
91 */
92 igc_clear_hw_cntrs_base_generic(hw);
93
94 return ret_val;
95 }
96
97 /**
98 * igc_power_down_phy_copper_base - Remove link during PHY power down
99 * @hw: pointer to the HW structure
100 *
101 * In the case of a PHY power down to save power, or to turn off link during a
102 * driver unload, or wake on lan is not enabled, remove the link.
103 **/
104 void
igc_power_down_phy_copper_base(struct igc_hw * hw)105 igc_power_down_phy_copper_base(struct igc_hw *hw)
106 {
107 struct igc_phy_info *phy = &hw->phy;
108
109 if (!(phy->ops.check_reset_block))
110 return;
111
112 /* If the management interface is not enabled, then power down */
113 if (phy->ops.check_reset_block(hw))
114 igc_power_down_phy_copper(hw);
115
116 return;
117 }
118