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