igc_phy.c revision 1.1 1 1.1 rin /* $OpenBSD: igc_phy.c,v 1.3 2023/02/03 11:31:52 mbuhl Exp $ */
2 1.1 rin /*-
3 1.1 rin * Copyright 2021 Intel Corp
4 1.1 rin * Copyright 2021 Rubicon Communications, LLC (Netgate)
5 1.1 rin * SPDX-License-Identifier: BSD-3-Clause
6 1.1 rin */
7 1.1 rin
8 1.1 rin #include <dev/pci/igc_api.h>
9 1.1 rin
10 1.1 rin /**
11 1.1 rin * igc_init_phy_ops_generic - Initialize PHY function pointers
12 1.1 rin * @hw: pointer to the HW structure
13 1.1 rin *
14 1.1 rin * Setups up the function pointers to no-op functions
15 1.1 rin **/
16 1.1 rin void
17 1.1 rin igc_init_phy_ops_generic(struct igc_hw *hw)
18 1.1 rin {
19 1.1 rin struct igc_phy_info *phy = &hw->phy;
20 1.1 rin DEBUGFUNC("igc_init_phy_ops_generic");
21 1.1 rin
22 1.1 rin /* Initialize function pointers */
23 1.1 rin phy->ops.init_params = igc_null_ops_generic;
24 1.1 rin phy->ops.acquire = igc_null_ops_generic;
25 1.1 rin phy->ops.check_reset_block = igc_null_ops_generic;
26 1.1 rin phy->ops.force_speed_duplex = igc_null_ops_generic;
27 1.1 rin phy->ops.get_info = igc_null_ops_generic;
28 1.1 rin phy->ops.set_page = igc_null_set_page;
29 1.1 rin phy->ops.read_reg = igc_null_read_reg;
30 1.1 rin phy->ops.read_reg_locked = igc_null_read_reg;
31 1.1 rin phy->ops.read_reg_page = igc_null_read_reg;
32 1.1 rin phy->ops.release = igc_null_phy_generic;
33 1.1 rin phy->ops.reset = igc_null_ops_generic;
34 1.1 rin phy->ops.set_d0_lplu_state = igc_null_lplu_state;
35 1.1 rin phy->ops.set_d3_lplu_state = igc_null_lplu_state;
36 1.1 rin phy->ops.write_reg = igc_null_write_reg;
37 1.1 rin phy->ops.write_reg_locked = igc_null_write_reg;
38 1.1 rin phy->ops.write_reg_page = igc_null_write_reg;
39 1.1 rin phy->ops.power_up = igc_null_phy_generic;
40 1.1 rin phy->ops.power_down = igc_null_phy_generic;
41 1.1 rin }
42 1.1 rin
43 1.1 rin /**
44 1.1 rin * igc_null_set_page - No-op function, return 0
45 1.1 rin * @hw: pointer to the HW structure
46 1.1 rin * @data: dummy variable
47 1.1 rin **/
48 1.1 rin int
49 1.1 rin igc_null_set_page(struct igc_hw IGC_UNUSEDARG *hw, uint16_t IGC_UNUSEDARG data)
50 1.1 rin {
51 1.1 rin DEBUGFUNC("igc_null_set_page");
52 1.1 rin return IGC_SUCCESS;
53 1.1 rin }
54 1.1 rin
55 1.1 rin /**
56 1.1 rin * igc_null_read_reg - No-op function, return 0
57 1.1 rin * @hw: pointer to the HW structure
58 1.1 rin * @offset: dummy variable
59 1.1 rin * @data: dummy variable
60 1.1 rin **/
61 1.1 rin int
62 1.1 rin igc_null_read_reg(struct igc_hw IGC_UNUSEDARG *hw,
63 1.1 rin uint32_t IGC_UNUSEDARG offset, uint16_t IGC_UNUSEDARG *data)
64 1.1 rin {
65 1.1 rin DEBUGFUNC("igc_null_read_reg");
66 1.1 rin return IGC_SUCCESS;
67 1.1 rin }
68 1.1 rin
69 1.1 rin /**
70 1.1 rin * igc_null_phy_generic - No-op function, return void
71 1.1 rin * @hw: pointer to the HW structure
72 1.1 rin **/
73 1.1 rin void
74 1.1 rin igc_null_phy_generic(struct igc_hw IGC_UNUSEDARG *hw)
75 1.1 rin {
76 1.1 rin DEBUGFUNC("igc_null_phy_generic");
77 1.1 rin return;
78 1.1 rin }
79 1.1 rin
80 1.1 rin /**
81 1.1 rin * igc_null_lplu_state - No-op function, return 0
82 1.1 rin * @hw: pointer to the HW structure
83 1.1 rin * @active: dummy variable
84 1.1 rin **/
85 1.1 rin int
86 1.1 rin igc_null_lplu_state(struct igc_hw IGC_UNUSEDARG *hw, bool IGC_UNUSEDARG active)
87 1.1 rin {
88 1.1 rin DEBUGFUNC("igc_null_lplu_state");
89 1.1 rin return IGC_SUCCESS;
90 1.1 rin }
91 1.1 rin
92 1.1 rin /**
93 1.1 rin * igc_null_write_reg - No-op function, return 0
94 1.1 rin * @hw: pointer to the HW structure
95 1.1 rin * @offset: dummy variable
96 1.1 rin * @data: dummy variable
97 1.1 rin **/
98 1.1 rin int
99 1.1 rin igc_null_write_reg(struct igc_hw IGC_UNUSEDARG *hw,
100 1.1 rin uint32_t IGC_UNUSEDARG offset, uint16_t IGC_UNUSEDARG data)
101 1.1 rin {
102 1.1 rin DEBUGFUNC("igc_null_write_reg");
103 1.1 rin return IGC_SUCCESS;
104 1.1 rin }
105 1.1 rin
106 1.1 rin /**
107 1.1 rin * igc_check_reset_block_generic - Check if PHY reset is blocked
108 1.1 rin * @hw: pointer to the HW structure
109 1.1 rin *
110 1.1 rin * Read the PHY management control register and check whether a PHY reset
111 1.1 rin * is blocked. If a reset is not blocked return IGC_SUCCESS, otherwise
112 1.1 rin * return IGC_BLK_PHY_RESET (12).
113 1.1 rin **/
114 1.1 rin int
115 1.1 rin igc_check_reset_block_generic(struct igc_hw *hw)
116 1.1 rin {
117 1.1 rin uint32_t manc;
118 1.1 rin
119 1.1 rin DEBUGFUNC("igc_check_reset_block");
120 1.1 rin
121 1.1 rin manc = IGC_READ_REG(hw, IGC_MANC);
122 1.1 rin
123 1.1 rin return (manc & IGC_MANC_BLK_PHY_RST_ON_IDE) ?
124 1.1 rin IGC_BLK_PHY_RESET : IGC_SUCCESS;
125 1.1 rin }
126 1.1 rin
127 1.1 rin /**
128 1.1 rin * igc_get_phy_id - Retrieve the PHY ID and revision
129 1.1 rin * @hw: pointer to the HW structure
130 1.1 rin *
131 1.1 rin * Reads the PHY registers and stores the PHY ID and possibly the PHY
132 1.1 rin * revision in the hardware structure.
133 1.1 rin **/
134 1.1 rin int
135 1.1 rin igc_get_phy_id(struct igc_hw *hw)
136 1.1 rin {
137 1.1 rin struct igc_phy_info *phy = &hw->phy;
138 1.1 rin uint16_t phy_id;
139 1.1 rin int ret_val = IGC_SUCCESS;
140 1.1 rin
141 1.1 rin DEBUGFUNC("igc_get_phy_id");
142 1.1 rin
143 1.1 rin if (!phy->ops.read_reg)
144 1.1 rin return IGC_SUCCESS;
145 1.1 rin
146 1.1 rin ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
147 1.1 rin if (ret_val)
148 1.1 rin return ret_val;
149 1.1 rin
150 1.1 rin phy->id = (uint32_t)(phy_id << 16);
151 1.1 rin DELAY(200);
152 1.1 rin ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
153 1.1 rin if (ret_val)
154 1.1 rin return ret_val;
155 1.1 rin
156 1.1 rin phy->id |= (uint32_t)(phy_id & PHY_REVISION_MASK);
157 1.1 rin phy->revision = (uint32_t)(phy_id & ~PHY_REVISION_MASK);
158 1.1 rin
159 1.1 rin return IGC_SUCCESS;
160 1.1 rin }
161 1.1 rin
162 1.1 rin /**
163 1.1 rin * igc_read_phy_reg_mdic - Read MDI control register
164 1.1 rin * @hw: pointer to the HW structure
165 1.1 rin * @offset: register offset to be read
166 1.1 rin * @data: pointer to the read data
167 1.1 rin *
168 1.1 rin * Reads the MDI control register in the PHY at offset and stores the
169 1.1 rin * information read to data.
170 1.1 rin **/
171 1.1 rin int
172 1.1 rin igc_read_phy_reg_mdic(struct igc_hw *hw, uint32_t offset, uint16_t *data)
173 1.1 rin {
174 1.1 rin struct igc_phy_info *phy = &hw->phy;
175 1.1 rin uint32_t i, mdic = 0;
176 1.1 rin
177 1.1 rin DEBUGFUNC("igc_read_phy_reg_mdic");
178 1.1 rin
179 1.1 rin if (offset > MAX_PHY_REG_ADDRESS) {
180 1.1 rin DEBUGOUT1("PHY Address %d is out of range\n", offset);
181 1.1 rin return -IGC_ERR_PARAM;
182 1.1 rin }
183 1.1 rin
184 1.1 rin /* Set up Op-code, Phy Address, and register offset in the MDI
185 1.1 rin * Control register. The MAC will take care of interfacing with the
186 1.1 rin * PHY to retrieve the desired data.
187 1.1 rin */
188 1.1 rin mdic = ((offset << IGC_MDIC_REG_SHIFT) |
189 1.1 rin (phy->addr << IGC_MDIC_PHY_SHIFT) | (IGC_MDIC_OP_READ));
190 1.1 rin
191 1.1 rin IGC_WRITE_REG(hw, IGC_MDIC, mdic);
192 1.1 rin
193 1.1 rin /* Poll the ready bit to see if the MDI read completed
194 1.1 rin * Increasing the time out as testing showed failures with
195 1.1 rin * the lower time out
196 1.1 rin */
197 1.1 rin for (i = 0; i < (IGC_GEN_POLL_TIMEOUT * 3); i++) {
198 1.1 rin DELAY(50);
199 1.1 rin mdic = IGC_READ_REG(hw, IGC_MDIC);
200 1.1 rin if (mdic & IGC_MDIC_READY)
201 1.1 rin break;
202 1.1 rin }
203 1.1 rin if (!(mdic & IGC_MDIC_READY)) {
204 1.1 rin DEBUGOUT("MDI Read did not complete\n");
205 1.1 rin return -IGC_ERR_PHY;
206 1.1 rin }
207 1.1 rin if (mdic & IGC_MDIC_ERROR) {
208 1.1 rin DEBUGOUT("MDI Error\n");
209 1.1 rin return -IGC_ERR_PHY;
210 1.1 rin }
211 1.1 rin if (((mdic & IGC_MDIC_REG_MASK) >> IGC_MDIC_REG_SHIFT) != offset) {
212 1.1 rin DEBUGOUT2("MDI Read offset error - requested %d, returned %d\n",
213 1.1 rin offset, (mdic & IGC_MDIC_REG_MASK) >> IGC_MDIC_REG_SHIFT);
214 1.1 rin return -IGC_ERR_PHY;
215 1.1 rin }
216 1.1 rin *data = (uint16_t)mdic;
217 1.1 rin
218 1.1 rin return IGC_SUCCESS;
219 1.1 rin }
220 1.1 rin
221 1.1 rin /**
222 1.1 rin * igc_write_phy_reg_mdic - Write MDI control register
223 1.1 rin * @hw: pointer to the HW structure
224 1.1 rin * @offset: register offset to write to
225 1.1 rin * @data: data to write to register at offset
226 1.1 rin *
227 1.1 rin * Writes data to MDI control register in the PHY at offset.
228 1.1 rin **/
229 1.1 rin int
230 1.1 rin igc_write_phy_reg_mdic(struct igc_hw *hw, uint32_t offset, uint16_t data)
231 1.1 rin {
232 1.1 rin struct igc_phy_info *phy = &hw->phy;
233 1.1 rin uint32_t i, mdic = 0;
234 1.1 rin
235 1.1 rin DEBUGFUNC("igc_write_phy_reg_mdic");
236 1.1 rin
237 1.1 rin if (offset > MAX_PHY_REG_ADDRESS) {
238 1.1 rin DEBUGOUT1("PHY Address %d is out of range\n", offset);
239 1.1 rin return -IGC_ERR_PARAM;
240 1.1 rin }
241 1.1 rin
242 1.1 rin /* Set up Op-code, Phy Address, and register offset in the MDI
243 1.1 rin * Control register. The MAC will take care of interfacing with the
244 1.1 rin * PHY to retrieve the desired data.
245 1.1 rin */
246 1.1 rin mdic = (((uint32_t)data) | (offset << IGC_MDIC_REG_SHIFT) |
247 1.1 rin (phy->addr << IGC_MDIC_PHY_SHIFT) | (IGC_MDIC_OP_WRITE));
248 1.1 rin
249 1.1 rin IGC_WRITE_REG(hw, IGC_MDIC, mdic);
250 1.1 rin
251 1.1 rin /* Poll the ready bit to see if the MDI read completed
252 1.1 rin * Increasing the time out as testing showed failures with
253 1.1 rin * the lower time out
254 1.1 rin */
255 1.1 rin for (i = 0; i < (IGC_GEN_POLL_TIMEOUT * 3); i++) {
256 1.1 rin DELAY(50);
257 1.1 rin mdic = IGC_READ_REG(hw, IGC_MDIC);
258 1.1 rin if (mdic & IGC_MDIC_READY)
259 1.1 rin break;
260 1.1 rin }
261 1.1 rin if (!(mdic & IGC_MDIC_READY)) {
262 1.1 rin DEBUGOUT("MDI Write did not complete\n");
263 1.1 rin return -IGC_ERR_PHY;
264 1.1 rin }
265 1.1 rin if (mdic & IGC_MDIC_ERROR) {
266 1.1 rin DEBUGOUT("MDI Error\n");
267 1.1 rin return -IGC_ERR_PHY;
268 1.1 rin }
269 1.1 rin if (((mdic & IGC_MDIC_REG_MASK) >> IGC_MDIC_REG_SHIFT) != offset)
270 1.1 rin return -IGC_ERR_PHY;
271 1.1 rin
272 1.1 rin return IGC_SUCCESS;
273 1.1 rin }
274 1.1 rin
275 1.1 rin /**
276 1.1 rin * igc_phy_setup_autoneg - Configure PHY for auto-negotiation
277 1.1 rin * @hw: pointer to the HW structure
278 1.1 rin *
279 1.1 rin * Reads the MII auto-neg advertisement register and/or the 1000T control
280 1.1 rin * register and if the PHY is already setup for auto-negotiation, then
281 1.1 rin * return successful. Otherwise, setup advertisement and flow control to
282 1.1 rin * the appropriate values for the wanted auto-negotiation.
283 1.1 rin **/
284 1.1 rin int
285 1.1 rin igc_phy_setup_autoneg(struct igc_hw *hw)
286 1.1 rin {
287 1.1 rin struct igc_phy_info *phy = &hw->phy;
288 1.1 rin uint16_t mii_autoneg_adv_reg;
289 1.1 rin uint16_t mii_1000t_ctrl_reg = 0;
290 1.1 rin uint16_t aneg_multigbt_an_ctrl = 0;
291 1.1 rin int ret_val;
292 1.1 rin
293 1.1 rin DEBUGFUNC("igc_phy_setup_autoneg");
294 1.1 rin
295 1.1 rin phy->autoneg_advertised &= phy->autoneg_mask;
296 1.1 rin
297 1.1 rin /* Read the MII Auto-Neg Advertisement Register (Address 4). */
298 1.1 rin ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
299 1.1 rin if (ret_val)
300 1.1 rin return ret_val;
301 1.1 rin
302 1.1 rin if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
303 1.1 rin /* Read the MII 1000Base-T Control Register (Address 9). */
304 1.1 rin ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
305 1.1 rin &mii_1000t_ctrl_reg);
306 1.1 rin if (ret_val)
307 1.1 rin return ret_val;
308 1.1 rin }
309 1.1 rin
310 1.1 rin if (phy->autoneg_mask & ADVERTISE_2500_FULL) {
311 1.1 rin /* Read the MULTI GBT AN Control Register - reg 7.32 */
312 1.1 rin ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
313 1.1 rin MMD_DEVADDR_SHIFT) | ANEG_MULTIGBT_AN_CTRL,
314 1.1 rin &aneg_multigbt_an_ctrl);
315 1.1 rin if (ret_val)
316 1.1 rin return ret_val;
317 1.1 rin }
318 1.1 rin
319 1.1 rin /* Need to parse both autoneg_advertised and fc and set up
320 1.1 rin * the appropriate PHY registers. First we will parse for
321 1.1 rin * autoneg_advertised software override. Since we can advertise
322 1.1 rin * a plethora of combinations, we need to check each bit
323 1.1 rin * individually.
324 1.1 rin */
325 1.1 rin
326 1.1 rin /* First we clear all the 10/100 mb speed bits in the Auto-Neg
327 1.1 rin * Advertisement Register (Address 4) and the 1000 mb speed bits in
328 1.1 rin * the 1000Base-T Control Register (Address 9).
329 1.1 rin */
330 1.1 rin mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS | NWAY_AR_100TX_HD_CAPS |
331 1.1 rin NWAY_AR_10T_FD_CAPS | NWAY_AR_10T_HD_CAPS);
332 1.1 rin mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
333 1.1 rin
334 1.1 rin DEBUGOUT1("autoneg_advertised %x\n", phy->autoneg_advertised);
335 1.1 rin
336 1.1 rin /* Do we want to advertise 10 Mb Half Duplex? */
337 1.1 rin if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
338 1.1 rin DEBUGOUT("Advertise 10mb Half duplex\n");
339 1.1 rin mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
340 1.1 rin }
341 1.1 rin
342 1.1 rin /* Do we want to advertise 10 Mb Full Duplex? */
343 1.1 rin if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
344 1.1 rin DEBUGOUT("Advertise 10mb Full duplex\n");
345 1.1 rin mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
346 1.1 rin }
347 1.1 rin
348 1.1 rin /* Do we want to advertise 100 Mb Half Duplex? */
349 1.1 rin if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
350 1.1 rin DEBUGOUT("Advertise 100mb Half duplex\n");
351 1.1 rin mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
352 1.1 rin }
353 1.1 rin
354 1.1 rin /* Do we want to advertise 100 Mb Full Duplex? */
355 1.1 rin if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
356 1.1 rin DEBUGOUT("Advertise 100mb Full duplex\n");
357 1.1 rin mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
358 1.1 rin }
359 1.1 rin
360 1.1 rin /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
361 1.1 rin if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
362 1.1 rin DEBUGOUT("Advertise 1000mb Half duplex request denied!\n");
363 1.1 rin
364 1.1 rin /* Do we want to advertise 1000 Mb Full Duplex? */
365 1.1 rin if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
366 1.1 rin DEBUGOUT("Advertise 1000mb Full duplex\n");
367 1.1 rin mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
368 1.1 rin }
369 1.1 rin
370 1.1 rin /* We do not allow the Phy to advertise 2500 Mb Half Duplex */
371 1.1 rin if (phy->autoneg_advertised & ADVERTISE_2500_HALF)
372 1.1 rin DEBUGOUT("Advertise 2500mb Half duplex request denied!\n");
373 1.1 rin
374 1.1 rin /* Do we want to advertise 2500 Mb Full Duplex? */
375 1.1 rin if (phy->autoneg_advertised & ADVERTISE_2500_FULL) {
376 1.1 rin DEBUGOUT("Advertise 2500mb Full duplex\n");
377 1.1 rin aneg_multigbt_an_ctrl |= CR_2500T_FD_CAPS;
378 1.1 rin } else
379 1.1 rin aneg_multigbt_an_ctrl &= ~CR_2500T_FD_CAPS;
380 1.1 rin
381 1.1 rin /* Check for a software override of the flow control settings, and
382 1.1 rin * setup the PHY advertisement registers accordingly. If
383 1.1 rin * auto-negotiation is enabled, then software will have to set the
384 1.1 rin * "PAUSE" bits to the correct value in the Auto-Negotiation
385 1.1 rin * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
386 1.1 rin * negotiation.
387 1.1 rin *
388 1.1 rin * The possible values of the "fc" parameter are:
389 1.1 rin * 0: Flow control is completely disabled
390 1.1 rin * 1: Rx flow control is enabled (we can receive pause frames
391 1.1 rin * but not send pause frames).
392 1.1 rin * 2: Tx flow control is enabled (we can send pause frames
393 1.1 rin * but we do not support receiving pause frames).
394 1.1 rin * 3: Both Rx and Tx flow control (symmetric) are enabled.
395 1.1 rin * other: No software override. The flow control configuration
396 1.1 rin * in the EEPROM is used.
397 1.1 rin */
398 1.1 rin switch (hw->fc.current_mode) {
399 1.1 rin case igc_fc_none:
400 1.1 rin /* Flow control (Rx & Tx) is completely disabled by a
401 1.1 rin * software over-ride.
402 1.1 rin */
403 1.1 rin mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
404 1.1 rin break;
405 1.1 rin case igc_fc_rx_pause:
406 1.1 rin /* Rx Flow control is enabled, and Tx Flow control is
407 1.1 rin * disabled, by a software over-ride.
408 1.1 rin *
409 1.1 rin * Since there really isn't a way to advertise that we are
410 1.1 rin * capable of Rx Pause ONLY, we will advertise that we
411 1.1 rin * support both symmetric and asymmetric Rx PAUSE. Later
412 1.1 rin * (in igc_config_fc_after_link_up) we will disable the
413 1.1 rin * hw's ability to send PAUSE frames.
414 1.1 rin */
415 1.1 rin mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
416 1.1 rin break;
417 1.1 rin case igc_fc_tx_pause:
418 1.1 rin /* Tx Flow control is enabled, and Rx Flow control is
419 1.1 rin * disabled, by a software over-ride.
420 1.1 rin */
421 1.1 rin mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
422 1.1 rin mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
423 1.1 rin break;
424 1.1 rin case igc_fc_full:
425 1.1 rin /* Flow control (both Rx and Tx) is enabled by a software
426 1.1 rin * over-ride.
427 1.1 rin */
428 1.1 rin mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
429 1.1 rin break;
430 1.1 rin default:
431 1.1 rin DEBUGOUT("Flow control param set incorrectly\n");
432 1.1 rin return -IGC_ERR_CONFIG;
433 1.1 rin }
434 1.1 rin
435 1.1 rin ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
436 1.1 rin if (ret_val)
437 1.1 rin return ret_val;
438 1.1 rin
439 1.1 rin DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
440 1.1 rin
441 1.1 rin if (phy->autoneg_mask & ADVERTISE_1000_FULL)
442 1.1 rin ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL,
443 1.1 rin mii_1000t_ctrl_reg);
444 1.1 rin
445 1.1 rin if (phy->autoneg_mask & ADVERTISE_2500_FULL)
446 1.1 rin ret_val = phy->ops.write_reg(hw,
447 1.1 rin (STANDARD_AN_REG_MASK << MMD_DEVADDR_SHIFT) |
448 1.1 rin ANEG_MULTIGBT_AN_CTRL, aneg_multigbt_an_ctrl);
449 1.1 rin
450 1.1 rin return ret_val;
451 1.1 rin }
452 1.1 rin
453 1.1 rin /**
454 1.1 rin * igc_copper_link_autoneg - Setup/Enable autoneg for copper link
455 1.1 rin * @hw: pointer to the HW structure
456 1.1 rin *
457 1.1 rin * Performs initial bounds checking on autoneg advertisement parameter, then
458 1.1 rin * configure to advertise the full capability. Setup the PHY to autoneg
459 1.1 rin * and restart the negotiation process between the link partner. If
460 1.1 rin * autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
461 1.1 rin **/
462 1.1 rin int
463 1.1 rin igc_copper_link_autoneg(struct igc_hw *hw)
464 1.1 rin {
465 1.1 rin struct igc_phy_info *phy = &hw->phy;
466 1.1 rin uint16_t phy_ctrl;
467 1.1 rin int ret_val;
468 1.1 rin
469 1.1 rin DEBUGFUNC("igc_copper_link_autoneg");
470 1.1 rin
471 1.1 rin /* Perform some bounds checking on the autoneg advertisement
472 1.1 rin * parameter.
473 1.1 rin */
474 1.1 rin phy->autoneg_advertised &= phy->autoneg_mask;
475 1.1 rin
476 1.1 rin /* If autoneg_advertised is zero, we assume it was not defaulted
477 1.1 rin * by the calling code so we set to advertise full capability.
478 1.1 rin */
479 1.1 rin if (!phy->autoneg_advertised)
480 1.1 rin phy->autoneg_advertised = phy->autoneg_mask;
481 1.1 rin
482 1.1 rin DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
483 1.1 rin ret_val = igc_phy_setup_autoneg(hw);
484 1.1 rin if (ret_val) {
485 1.1 rin DEBUGOUT("Error Setting up Auto-Negotiation\n");
486 1.1 rin return ret_val;
487 1.1 rin }
488 1.1 rin DEBUGOUT("Restarting Auto-Neg\n");
489 1.1 rin
490 1.1 rin /* Restart auto-negotiation by setting the Auto Neg Enable bit and
491 1.1 rin * the Auto Neg Restart bit in the PHY control register.
492 1.1 rin */
493 1.1 rin ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
494 1.1 rin if (ret_val)
495 1.1 rin return ret_val;
496 1.1 rin
497 1.1 rin phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
498 1.1 rin ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
499 1.1 rin if (ret_val)
500 1.1 rin return ret_val;
501 1.1 rin
502 1.1 rin /* Does the user want to wait for Auto-Neg to complete here, or
503 1.1 rin * check at a later time (for example, callback routine).
504 1.1 rin */
505 1.1 rin if (phy->autoneg_wait_to_complete) {
506 1.1 rin ret_val = igc_wait_autoneg(hw);
507 1.1 rin if (ret_val)
508 1.1 rin return ret_val;
509 1.1 rin }
510 1.1 rin
511 1.1 rin hw->mac.get_link_status = true;
512 1.1 rin
513 1.1 rin return ret_val;
514 1.1 rin }
515 1.1 rin
516 1.1 rin /**
517 1.1 rin * igc_setup_copper_link_generic - Configure copper link settings
518 1.1 rin * @hw: pointer to the HW structure
519 1.1 rin *
520 1.1 rin * Calls the appropriate function to configure the link for auto-neg or forced
521 1.1 rin * speed and duplex. Then we check for link, once link is established calls
522 1.1 rin * to configure collision distance and flow control are called. If link is
523 1.1 rin * not established, we return -IGC_ERR_PHY (-2).
524 1.1 rin **/
525 1.1 rin int
526 1.1 rin igc_setup_copper_link_generic(struct igc_hw *hw)
527 1.1 rin {
528 1.1 rin int ret_val;
529 1.1 rin bool link;
530 1.1 rin
531 1.1 rin DEBUGFUNC("igc_setup_copper_link_generic");
532 1.1 rin
533 1.1 rin if (hw->mac.autoneg) {
534 1.1 rin /* Setup autoneg and flow control advertisement and perform
535 1.1 rin * autonegotiation.
536 1.1 rin */
537 1.1 rin ret_val = igc_copper_link_autoneg(hw);
538 1.1 rin if (ret_val)
539 1.1 rin return ret_val;
540 1.1 rin } else {
541 1.1 rin /* PHY will be set to 10H, 10F, 100H or 100F
542 1.1 rin * depending on user settings.
543 1.1 rin */
544 1.1 rin DEBUGOUT("Forcing Speed and Duplex\n");
545 1.1 rin ret_val = hw->phy.ops.force_speed_duplex(hw);
546 1.1 rin if (ret_val) {
547 1.1 rin DEBUGOUT("Error Forcing Speed and Duplex\n");
548 1.1 rin return ret_val;
549 1.1 rin }
550 1.1 rin }
551 1.1 rin
552 1.1 rin /* Check link status. Wait up to 100 microseconds for link to become
553 1.1 rin * valid.
554 1.1 rin */
555 1.1 rin ret_val = igc_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
556 1.1 rin &link);
557 1.1 rin if (ret_val)
558 1.1 rin return ret_val;
559 1.1 rin
560 1.1 rin if (link) {
561 1.1 rin DEBUGOUT("Valid link established!!!\n");
562 1.1 rin hw->mac.ops.config_collision_dist(hw);
563 1.1 rin ret_val = igc_config_fc_after_link_up_generic(hw);
564 1.1 rin } else
565 1.1 rin DEBUGOUT("Unable to establish link!!!\n");
566 1.1 rin
567 1.1 rin return ret_val;
568 1.1 rin }
569 1.1 rin
570 1.1 rin /**
571 1.1 rin * igc_check_downshift_generic - Checks whether a downshift in speed occurred
572 1.1 rin * @hw: pointer to the HW structure
573 1.1 rin *
574 1.1 rin * Success returns 0, Failure returns 1
575 1.1 rin *
576 1.1 rin * A downshift is detected by querying the PHY link health.
577 1.1 rin **/
578 1.1 rin int
579 1.1 rin igc_check_downshift_generic(struct igc_hw *hw)
580 1.1 rin {
581 1.1 rin struct igc_phy_info *phy = &hw->phy;
582 1.1 rin int ret_val;
583 1.1 rin
584 1.1 rin DEBUGFUNC("igc_check_downshift_generic");
585 1.1 rin
586 1.1 rin switch (phy->type) {
587 1.1 rin case igc_phy_i225:
588 1.1 rin default:
589 1.1 rin /* speed downshift not supported */
590 1.1 rin phy->speed_downgraded = false;
591 1.1 rin return IGC_SUCCESS;
592 1.1 rin }
593 1.1 rin
594 1.1 rin return ret_val;
595 1.1 rin }
596 1.1 rin
597 1.1 rin /**
598 1.1 rin * igc_wait_autoneg - Wait for auto-neg completion
599 1.1 rin * @hw: pointer to the HW structure
600 1.1 rin *
601 1.1 rin * Waits for auto-negotiation to complete or for the auto-negotiation time
602 1.1 rin * limit to expire, which ever happens first.
603 1.1 rin **/
604 1.1 rin int
605 1.1 rin igc_wait_autoneg(struct igc_hw *hw)
606 1.1 rin {
607 1.1 rin uint16_t i, phy_status;
608 1.1 rin int ret_val = IGC_SUCCESS;
609 1.1 rin
610 1.1 rin DEBUGFUNC("igc_wait_autoneg");
611 1.1 rin
612 1.1 rin if (!hw->phy.ops.read_reg)
613 1.1 rin return IGC_SUCCESS;
614 1.1 rin
615 1.1 rin /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
616 1.1 rin for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
617 1.1 rin ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
618 1.1 rin if (ret_val)
619 1.1 rin break;
620 1.1 rin ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
621 1.1 rin if (ret_val)
622 1.1 rin break;
623 1.1 rin if (phy_status & MII_SR_AUTONEG_COMPLETE)
624 1.1 rin break;
625 1.1 rin msec_delay(100);
626 1.1 rin }
627 1.1 rin
628 1.1 rin /* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
629 1.1 rin * has completed.
630 1.1 rin */
631 1.1 rin return ret_val;
632 1.1 rin }
633 1.1 rin
634 1.1 rin /**
635 1.1 rin * igc_phy_has_link_generic - Polls PHY for link
636 1.1 rin * @hw: pointer to the HW structure
637 1.1 rin * @iterations: number of times to poll for link
638 1.1 rin * @usec_interval: delay between polling attempts
639 1.1 rin * @success: pointer to whether polling was successful or not
640 1.1 rin *
641 1.1 rin * Polls the PHY status register for link, 'iterations' number of times.
642 1.1 rin **/
643 1.1 rin int
644 1.1 rin igc_phy_has_link_generic(struct igc_hw *hw, uint32_t iterations,
645 1.1 rin uint32_t usec_interval, bool *success)
646 1.1 rin {
647 1.1 rin uint16_t i, phy_status;
648 1.1 rin int ret_val = IGC_SUCCESS;
649 1.1 rin
650 1.1 rin DEBUGFUNC("igc_phy_has_link_generic");
651 1.1 rin
652 1.1 rin if (!hw->phy.ops.read_reg)
653 1.1 rin return IGC_SUCCESS;
654 1.1 rin
655 1.1 rin for (i = 0; i < iterations; i++) {
656 1.1 rin /* Some PHYs require the PHY_STATUS register to be read
657 1.1 rin * twice due to the link bit being sticky. No harm doing
658 1.1 rin * it across the board.
659 1.1 rin */
660 1.1 rin ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
661 1.1 rin if (ret_val) {
662 1.1 rin /* If the first read fails, another entity may have
663 1.1 rin * ownership of the resources, wait and try again to
664 1.1 rin * see if they have relinquished the resources yet.
665 1.1 rin */
666 1.1 rin if (usec_interval >= 1000)
667 1.1 rin msec_delay(usec_interval/1000);
668 1.1 rin else
669 1.1 rin DELAY(usec_interval);
670 1.1 rin }
671 1.1 rin ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
672 1.1 rin if (ret_val)
673 1.1 rin break;
674 1.1 rin if (phy_status & MII_SR_LINK_STATUS)
675 1.1 rin break;
676 1.1 rin if (usec_interval >= 1000)
677 1.1 rin msec_delay(usec_interval/1000);
678 1.1 rin else
679 1.1 rin DELAY(usec_interval);
680 1.1 rin }
681 1.1 rin
682 1.1 rin *success = (i < iterations);
683 1.1 rin
684 1.1 rin return ret_val;
685 1.1 rin }
686 1.1 rin
687 1.1 rin /**
688 1.1 rin * igc_phy_hw_reset_generic - PHY hardware reset
689 1.1 rin * @hw: pointer to the HW structure
690 1.1 rin *
691 1.1 rin * Verify the reset block is not blocking us from resetting. Acquire
692 1.1 rin * semaphore (if necessary) and read/set/write the device control reset
693 1.1 rin * bit in the PHY. Wait the appropriate delay time for the device to
694 1.1 rin * reset and release the semaphore (if necessary).
695 1.1 rin **/
696 1.1 rin int
697 1.1 rin igc_phy_hw_reset_generic(struct igc_hw *hw)
698 1.1 rin {
699 1.1 rin struct igc_phy_info *phy = &hw->phy;
700 1.1 rin uint32_t ctrl, timeout = 10000, phpm = 0;
701 1.1 rin int ret_val;
702 1.1 rin
703 1.1 rin DEBUGFUNC("igc_phy_hw_reset_generic");
704 1.1 rin
705 1.1 rin if (phy->ops.check_reset_block) {
706 1.1 rin ret_val = phy->ops.check_reset_block(hw);
707 1.1 rin if (ret_val)
708 1.1 rin return IGC_SUCCESS;
709 1.1 rin }
710 1.1 rin
711 1.1 rin ret_val = phy->ops.acquire(hw);
712 1.1 rin if (ret_val)
713 1.1 rin return ret_val;
714 1.1 rin
715 1.1 rin phpm = IGC_READ_REG(hw, IGC_I225_PHPM);
716 1.1 rin
717 1.1 rin ctrl = IGC_READ_REG(hw, IGC_CTRL);
718 1.1 rin IGC_WRITE_REG(hw, IGC_CTRL, ctrl | IGC_CTRL_PHY_RST);
719 1.1 rin IGC_WRITE_FLUSH(hw);
720 1.1 rin
721 1.1 rin DELAY(phy->reset_delay_us);
722 1.1 rin
723 1.1 rin IGC_WRITE_REG(hw, IGC_CTRL, ctrl);
724 1.1 rin IGC_WRITE_FLUSH(hw);
725 1.1 rin
726 1.1 rin DELAY(150);
727 1.1 rin
728 1.1 rin do {
729 1.1 rin phpm = IGC_READ_REG(hw, IGC_I225_PHPM);
730 1.1 rin timeout--;
731 1.1 rin DELAY(1);
732 1.1 rin } while (!(phpm & IGC_I225_PHPM_RST_COMPL) && timeout);
733 1.1 rin
734 1.1 rin if (!timeout)
735 1.1 rin DEBUGOUT("Timeout expired after a phy reset\n");
736 1.1 rin
737 1.1 rin phy->ops.release(hw);
738 1.1 rin
739 1.1 rin return ret_val;
740 1.1 rin }
741 1.1 rin
742 1.1 rin /**
743 1.1 rin * igc_power_up_phy_copper - Restore copper link in case of PHY power down
744 1.1 rin * @hw: pointer to the HW structure
745 1.1 rin *
746 1.1 rin * In the case of a PHY power down to save power, or to turn off link during a
747 1.1 rin * driver unload, or wake on lan is not enabled, restore the link to previous
748 1.1 rin * settings.
749 1.1 rin **/
750 1.1 rin void
751 1.1 rin igc_power_up_phy_copper(struct igc_hw *hw)
752 1.1 rin {
753 1.1 rin uint16_t mii_reg = 0;
754 1.1 rin
755 1.1 rin /* The PHY will retain its settings across a power down/up cycle */
756 1.1 rin hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
757 1.1 rin mii_reg &= ~MII_CR_POWER_DOWN;
758 1.1 rin hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
759 1.1 rin DELAY(300);
760 1.1 rin }
761 1.1 rin
762 1.1 rin /**
763 1.1 rin * igc_power_down_phy_copper - Restore copper link in case of PHY power down
764 1.1 rin * @hw: pointer to the HW structure
765 1.1 rin *
766 1.1 rin * In the case of a PHY power down to save power, or to turn off link during a
767 1.1 rin * driver unload, or wake on lan is not enabled, restore the link to previous
768 1.1 rin * settings.
769 1.1 rin **/
770 1.1 rin void
771 1.1 rin igc_power_down_phy_copper(struct igc_hw *hw)
772 1.1 rin {
773 1.1 rin uint16_t mii_reg = 0;
774 1.1 rin
775 1.1 rin /* The PHY will retain its settings across a power down/up cycle */
776 1.1 rin hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
777 1.1 rin mii_reg |= MII_CR_POWER_DOWN;
778 1.1 rin hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
779 1.1 rin msec_delay(1);
780 1.1 rin }
781 1.1 rin
782 1.1 rin /**
783 1.1 rin * igc_write_phy_reg_gpy - Write GPY PHY register
784 1.1 rin * @hw: pointer to the HW structure
785 1.1 rin * @offset: register offset to write to
786 1.1 rin * @data: data to write at register offset
787 1.1 rin *
788 1.1 rin * Acquires semaphore, if necessary, then writes the data to PHY register
789 1.1 rin * at the offset. Release any acquired semaphores before exiting.
790 1.1 rin **/
791 1.1 rin int
792 1.1 rin igc_write_phy_reg_gpy(struct igc_hw *hw, uint32_t offset, uint16_t data)
793 1.1 rin {
794 1.1 rin uint8_t dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
795 1.1 rin int ret_val;
796 1.1 rin
797 1.1 rin DEBUGFUNC("igc_write_phy_reg_gpy");
798 1.1 rin
799 1.1 rin offset = offset & GPY_REG_MASK;
800 1.1 rin
801 1.1 rin if (!dev_addr) {
802 1.1 rin ret_val = hw->phy.ops.acquire(hw);
803 1.1 rin if (ret_val)
804 1.1 rin return ret_val;
805 1.1 rin ret_val = igc_write_phy_reg_mdic(hw, offset, data);
806 1.1 rin if (ret_val)
807 1.1 rin return ret_val;
808 1.1 rin hw->phy.ops.release(hw);
809 1.1 rin } else {
810 1.1 rin ret_val = igc_write_xmdio_reg(hw, (uint16_t)offset, dev_addr,
811 1.1 rin data);
812 1.1 rin }
813 1.1 rin
814 1.1 rin return ret_val;
815 1.1 rin }
816 1.1 rin
817 1.1 rin /**
818 1.1 rin * igc_read_phy_reg_gpy - Read GPY PHY register
819 1.1 rin * @hw: pointer to the HW structure
820 1.1 rin * @offset: lower half is register offset to read to
821 1.1 rin * upper half is MMD to use.
822 1.1 rin * @data: data to read at register offset
823 1.1 rin *
824 1.1 rin * Acquires semaphore, if necessary, then reads the data in the PHY register
825 1.1 rin * at the offset. Release any acquired semaphores before exiting.
826 1.1 rin **/
827 1.1 rin int
828 1.1 rin igc_read_phy_reg_gpy(struct igc_hw *hw, uint32_t offset, uint16_t *data)
829 1.1 rin {
830 1.1 rin uint8_t dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
831 1.1 rin int ret_val;
832 1.1 rin
833 1.1 rin DEBUGFUNC("igc_read_phy_reg_gpy");
834 1.1 rin
835 1.1 rin offset = offset & GPY_REG_MASK;
836 1.1 rin
837 1.1 rin if (!dev_addr) {
838 1.1 rin ret_val = hw->phy.ops.acquire(hw);
839 1.1 rin if (ret_val)
840 1.1 rin return ret_val;
841 1.1 rin ret_val = igc_read_phy_reg_mdic(hw, offset, data);
842 1.1 rin if (ret_val)
843 1.1 rin return ret_val;
844 1.1 rin hw->phy.ops.release(hw);
845 1.1 rin } else {
846 1.1 rin ret_val = igc_read_xmdio_reg(hw, (uint16_t)offset, dev_addr,
847 1.1 rin data);
848 1.1 rin }
849 1.1 rin
850 1.1 rin return ret_val;
851 1.1 rin }
852 1.1 rin
853 1.1 rin /**
854 1.1 rin * __igc_access_xmdio_reg - Read/write XMDIO register
855 1.1 rin * @hw: pointer to the HW structure
856 1.1 rin * @address: XMDIO address to program
857 1.1 rin * @dev_addr: device address to program
858 1.1 rin * @data: pointer to value to read/write from/to the XMDIO address
859 1.1 rin * @read: boolean flag to indicate read or write
860 1.1 rin **/
861 1.1 rin int
862 1.1 rin __igc_access_xmdio_reg(struct igc_hw *hw, uint16_t address, uint8_t dev_addr,
863 1.1 rin uint16_t *data, bool read)
864 1.1 rin {
865 1.1 rin int ret_val;
866 1.1 rin
867 1.1 rin DEBUGFUNC("__igc_access_xmdio_reg");
868 1.1 rin
869 1.1 rin ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, dev_addr);
870 1.1 rin if (ret_val)
871 1.1 rin return ret_val;
872 1.1 rin
873 1.1 rin ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, address);
874 1.1 rin if (ret_val)
875 1.1 rin return ret_val;
876 1.1 rin
877 1.1 rin ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, IGC_MMDAC_FUNC_DATA |
878 1.1 rin dev_addr);
879 1.1 rin if (ret_val)
880 1.1 rin return ret_val;
881 1.1 rin
882 1.1 rin if (read)
883 1.1 rin ret_val = hw->phy.ops.read_reg(hw, IGC_MMDAAD, data);
884 1.1 rin else
885 1.1 rin ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, *data);
886 1.1 rin if (ret_val)
887 1.1 rin return ret_val;
888 1.1 rin
889 1.1 rin /* Recalibrate the device back to 0 */
890 1.1 rin ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, 0);
891 1.1 rin if (ret_val)
892 1.1 rin return ret_val;
893 1.1 rin
894 1.1 rin return ret_val;
895 1.1 rin }
896 1.1 rin
897 1.1 rin /**
898 1.1 rin * igc_read_xmdio_reg - Read XMDIO register
899 1.1 rin * @hw: pointer to the HW structure
900 1.1 rin * @addr: XMDIO address to program
901 1.1 rin * @dev_addr: device address to program
902 1.1 rin * @data: value to be read from the EMI address
903 1.1 rin **/
904 1.1 rin int
905 1.1 rin igc_read_xmdio_reg(struct igc_hw *hw, uint16_t addr, uint8_t dev_addr,
906 1.1 rin uint16_t *data)
907 1.1 rin {
908 1.1 rin DEBUGFUNC("igc_read_xmdio_reg");
909 1.1 rin
910 1.1 rin return __igc_access_xmdio_reg(hw, addr, dev_addr, data, true);
911 1.1 rin }
912 1.1 rin
913 1.1 rin /**
914 1.1 rin * igc_write_xmdio_reg - Write XMDIO register
915 1.1 rin * @hw: pointer to the HW structure
916 1.1 rin * @addr: XMDIO address to program
917 1.1 rin * @dev_addr: device address to program
918 1.1 rin * @data: value to be written to the XMDIO address
919 1.1 rin **/
920 1.1 rin int
921 1.1 rin igc_write_xmdio_reg(struct igc_hw *hw, uint16_t addr, uint8_t dev_addr,
922 1.1 rin uint16_t data)
923 1.1 rin {
924 1.1 rin DEBUGFUNC("igc_write_xmdio_reg");
925 1.1 rin
926 1.1 rin return __igc_access_xmdio_reg(hw, addr, dev_addr, &data, false);
927 1.1 rin }
928