net/ngbe: setup PHY link
[dpdk.git] / drivers / net / ngbe / base / ngbe_hw.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3  * Copyright(c) 2010-2017 Intel Corporation
4  */
5
6 #include "ngbe_type.h"
7 #include "ngbe_phy.h"
8 #include "ngbe_eeprom.h"
9 #include "ngbe_mng.h"
10 #include "ngbe_hw.h"
11
12 /**
13  *  ngbe_init_hw - Generic hardware initialization
14  *  @hw: pointer to hardware structure
15  *
16  *  Initialize the hardware by resetting the hardware, filling the bus info
17  *  structure and media type, clears all on chip counters, initializes receive
18  *  address registers, multicast table, VLAN filter table, calls routine to set
19  *  up link and flow control settings, and leaves transmit and receive units
20  *  disabled and uninitialized
21  **/
22 s32 ngbe_init_hw(struct ngbe_hw *hw)
23 {
24         s32 status;
25
26         DEBUGFUNC("ngbe_init_hw");
27
28         /* Reset the hardware */
29         status = hw->mac.reset_hw(hw);
30
31         if (status != 0)
32                 DEBUGOUT("Failed to initialize HW, STATUS = %d\n", status);
33
34         return status;
35 }
36
37 static void
38 ngbe_reset_misc_em(struct ngbe_hw *hw)
39 {
40         int i;
41
42         wr32(hw, NGBE_ISBADDRL, hw->isb_dma & 0xFFFFFFFF);
43         wr32(hw, NGBE_ISBADDRH, hw->isb_dma >> 32);
44
45         /* receive packets that size > 2048 */
46         wr32m(hw, NGBE_MACRXCFG,
47                 NGBE_MACRXCFG_JUMBO, NGBE_MACRXCFG_JUMBO);
48
49         wr32m(hw, NGBE_FRMSZ, NGBE_FRMSZ_MAX_MASK,
50                 NGBE_FRMSZ_MAX(NGBE_FRAME_SIZE_DFT));
51
52         /* clear counters on read */
53         wr32m(hw, NGBE_MACCNTCTL,
54                 NGBE_MACCNTCTL_RC, NGBE_MACCNTCTL_RC);
55
56         wr32m(hw, NGBE_RXFCCFG,
57                 NGBE_RXFCCFG_FC, NGBE_RXFCCFG_FC);
58         wr32m(hw, NGBE_TXFCCFG,
59                 NGBE_TXFCCFG_FC, NGBE_TXFCCFG_FC);
60
61         wr32m(hw, NGBE_MACRXFLT,
62                 NGBE_MACRXFLT_PROMISC, NGBE_MACRXFLT_PROMISC);
63
64         wr32m(hw, NGBE_RSTSTAT,
65                 NGBE_RSTSTAT_TMRINIT_MASK, NGBE_RSTSTAT_TMRINIT(30));
66
67         /* errata 4: initialize mng flex tbl and wakeup flex tbl*/
68         wr32(hw, NGBE_MNGFLEXSEL, 0);
69         for (i = 0; i < 16; i++) {
70                 wr32(hw, NGBE_MNGFLEXDWL(i), 0);
71                 wr32(hw, NGBE_MNGFLEXDWH(i), 0);
72                 wr32(hw, NGBE_MNGFLEXMSK(i), 0);
73         }
74         wr32(hw, NGBE_LANFLEXSEL, 0);
75         for (i = 0; i < 16; i++) {
76                 wr32(hw, NGBE_LANFLEXDWL(i), 0);
77                 wr32(hw, NGBE_LANFLEXDWH(i), 0);
78                 wr32(hw, NGBE_LANFLEXMSK(i), 0);
79         }
80
81         /* set pause frame dst mac addr */
82         wr32(hw, NGBE_RXPBPFCDMACL, 0xC2000001);
83         wr32(hw, NGBE_RXPBPFCDMACH, 0x0180);
84
85         wr32(hw, NGBE_MDIOMODE, 0xF);
86
87         wr32m(hw, NGBE_GPIE, NGBE_GPIE_MSIX, NGBE_GPIE_MSIX);
88
89         if ((hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_M88E1512_SFP ||
90                 (hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_YT8521S_SFP) {
91                 /* gpio0 is used to power on/off control*/
92                 wr32(hw, NGBE_GPIODIR, NGBE_GPIODIR_DDR(1));
93                 wr32(hw, NGBE_GPIODATA, NGBE_GPIOBIT_0);
94         }
95
96         hw->mac.init_thermal_sensor_thresh(hw);
97
98         /* enable mac transmitter */
99         wr32m(hw, NGBE_MACTXCFG, NGBE_MACTXCFG_TE, NGBE_MACTXCFG_TE);
100
101         /* sellect GMII */
102         wr32m(hw, NGBE_MACTXCFG,
103                 NGBE_MACTXCFG_SPEED_MASK, NGBE_MACTXCFG_SPEED_1G);
104
105         for (i = 0; i < 4; i++)
106                 wr32m(hw, NGBE_IVAR(i), 0x80808080, 0);
107 }
108
109 /**
110  *  ngbe_reset_hw_em - Perform hardware reset
111  *  @hw: pointer to hardware structure
112  *
113  *  Resets the hardware by resetting the transmit and receive units, masks
114  *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
115  *  reset.
116  **/
117 s32 ngbe_reset_hw_em(struct ngbe_hw *hw)
118 {
119         s32 status;
120
121         DEBUGFUNC("ngbe_reset_hw_em");
122
123         /* Call adapter stop to disable tx/rx and clear interrupts */
124         status = hw->mac.stop_hw(hw);
125         if (status != 0)
126                 return status;
127
128         /* Identify PHY and related function pointers */
129         status = ngbe_init_phy(hw);
130         if (status)
131                 return status;
132
133         /* Reset PHY */
134         if (!hw->phy.reset_disable)
135                 hw->phy.reset_hw(hw);
136
137         wr32(hw, NGBE_RST, NGBE_RST_LAN(hw->bus.lan_id));
138         ngbe_flush(hw);
139         msec_delay(50);
140
141         ngbe_reset_misc_em(hw);
142
143         msec_delay(50);
144
145         /* Store the permanent mac address */
146         hw->mac.get_mac_addr(hw, hw->mac.perm_addr);
147
148         /*
149          * Store MAC address from RAR0, clear receive address registers, and
150          * clear the multicast table.
151          */
152         hw->mac.num_rar_entries = NGBE_EM_RAR_ENTRIES;
153         hw->mac.init_rx_addrs(hw);
154
155         return status;
156 }
157
158 /**
159  *  ngbe_get_mac_addr - Generic get MAC address
160  *  @hw: pointer to hardware structure
161  *  @mac_addr: Adapter MAC address
162  *
163  *  Reads the adapter's MAC address from first Receive Address Register (RAR0)
164  *  A reset of the adapter must be performed prior to calling this function
165  *  in order for the MAC address to have been loaded from the EEPROM into RAR0
166  **/
167 s32 ngbe_get_mac_addr(struct ngbe_hw *hw, u8 *mac_addr)
168 {
169         u32 rar_high;
170         u32 rar_low;
171         u16 i;
172
173         DEBUGFUNC("ngbe_get_mac_addr");
174
175         wr32(hw, NGBE_ETHADDRIDX, 0);
176         rar_high = rd32(hw, NGBE_ETHADDRH);
177         rar_low = rd32(hw, NGBE_ETHADDRL);
178
179         for (i = 0; i < 2; i++)
180                 mac_addr[i] = (u8)(rar_high >> (1 - i) * 8);
181
182         for (i = 0; i < 4; i++)
183                 mac_addr[i + 2] = (u8)(rar_low >> (3 - i) * 8);
184
185         return 0;
186 }
187
188 /**
189  *  ngbe_set_lan_id_multi_port - Set LAN id for PCIe multiple port devices
190  *  @hw: pointer to the HW structure
191  *
192  *  Determines the LAN function id by reading memory-mapped registers and swaps
193  *  the port value if requested, and set MAC instance for devices.
194  **/
195 void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw)
196 {
197         struct ngbe_bus_info *bus = &hw->bus;
198         u32 reg = 0;
199
200         DEBUGFUNC("ngbe_set_lan_id_multi_port");
201
202         reg = rd32(hw, NGBE_PORTSTAT);
203         bus->lan_id = NGBE_PORTSTAT_ID(reg);
204         bus->func = bus->lan_id;
205 }
206
207 /**
208  *  ngbe_stop_hw - Generic stop Tx/Rx units
209  *  @hw: pointer to hardware structure
210  *
211  *  Sets the adapter_stopped flag within ngbe_hw struct. Clears interrupts,
212  *  disables transmit and receive units. The adapter_stopped flag is used by
213  *  the shared code and drivers to determine if the adapter is in a stopped
214  *  state and should not touch the hardware.
215  **/
216 s32 ngbe_stop_hw(struct ngbe_hw *hw)
217 {
218         u32 reg_val;
219         u16 i;
220
221         DEBUGFUNC("ngbe_stop_hw");
222
223         /*
224          * Set the adapter_stopped flag so other driver functions stop touching
225          * the hardware
226          */
227         hw->adapter_stopped = true;
228
229         /* Disable the receive unit */
230         ngbe_disable_rx(hw);
231
232         /* Clear interrupt mask to stop interrupts from being generated */
233         wr32(hw, NGBE_IENMISC, 0);
234         wr32(hw, NGBE_IMS(0), NGBE_IMS_MASK);
235
236         /* Clear any pending interrupts, flush previous writes */
237         wr32(hw, NGBE_ICRMISC, NGBE_ICRMISC_MASK);
238         wr32(hw, NGBE_ICR(0), NGBE_ICR_MASK);
239
240         /* Disable the transmit unit.  Each queue must be disabled. */
241         for (i = 0; i < hw->mac.max_tx_queues; i++)
242                 wr32(hw, NGBE_TXCFG(i), NGBE_TXCFG_FLUSH);
243
244         /* Disable the receive unit by stopping each queue */
245         for (i = 0; i < hw->mac.max_rx_queues; i++) {
246                 reg_val = rd32(hw, NGBE_RXCFG(i));
247                 reg_val &= ~NGBE_RXCFG_ENA;
248                 wr32(hw, NGBE_RXCFG(i), reg_val);
249         }
250
251         /* flush all queues disables */
252         ngbe_flush(hw);
253         msec_delay(2);
254
255         return 0;
256 }
257
258 /**
259  *  ngbe_validate_mac_addr - Validate MAC address
260  *  @mac_addr: pointer to MAC address.
261  *
262  *  Tests a MAC address to ensure it is a valid Individual Address.
263  **/
264 s32 ngbe_validate_mac_addr(u8 *mac_addr)
265 {
266         s32 status = 0;
267
268         DEBUGFUNC("ngbe_validate_mac_addr");
269
270         /* Make sure it is not a multicast address */
271         if (NGBE_IS_MULTICAST((struct rte_ether_addr *)mac_addr)) {
272                 status = NGBE_ERR_INVALID_MAC_ADDR;
273         /* Not a broadcast address */
274         } else if (NGBE_IS_BROADCAST((struct rte_ether_addr *)mac_addr)) {
275                 status = NGBE_ERR_INVALID_MAC_ADDR;
276         /* Reject the zero address */
277         } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
278                    mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
279                 status = NGBE_ERR_INVALID_MAC_ADDR;
280         }
281         return status;
282 }
283
284 /**
285  *  ngbe_set_rar - Set Rx address register
286  *  @hw: pointer to hardware structure
287  *  @index: Receive address register to write
288  *  @addr: Address to put into receive address register
289  *  @vmdq: VMDq "set" or "pool" index
290  *  @enable_addr: set flag that address is active
291  *
292  *  Puts an ethernet address into a receive address register.
293  **/
294 s32 ngbe_set_rar(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
295                           u32 enable_addr)
296 {
297         u32 rar_low, rar_high;
298         u32 rar_entries = hw->mac.num_rar_entries;
299
300         DEBUGFUNC("ngbe_set_rar");
301
302         /* Make sure we are using a valid rar index range */
303         if (index >= rar_entries) {
304                 DEBUGOUT("RAR index %d is out of range.\n", index);
305                 return NGBE_ERR_INVALID_ARGUMENT;
306         }
307
308         /* setup VMDq pool selection before this RAR gets enabled */
309         hw->mac.set_vmdq(hw, index, vmdq);
310
311         /*
312          * HW expects these in little endian so we reverse the byte
313          * order from network order (big endian) to little endian
314          */
315         rar_low = NGBE_ETHADDRL_AD0(addr[5]) |
316                   NGBE_ETHADDRL_AD1(addr[4]) |
317                   NGBE_ETHADDRL_AD2(addr[3]) |
318                   NGBE_ETHADDRL_AD3(addr[2]);
319         /*
320          * Some parts put the VMDq setting in the extra RAH bits,
321          * so save everything except the lower 16 bits that hold part
322          * of the address and the address valid bit.
323          */
324         rar_high = rd32(hw, NGBE_ETHADDRH);
325         rar_high &= ~NGBE_ETHADDRH_AD_MASK;
326         rar_high |= (NGBE_ETHADDRH_AD4(addr[1]) |
327                      NGBE_ETHADDRH_AD5(addr[0]));
328
329         rar_high &= ~NGBE_ETHADDRH_VLD;
330         if (enable_addr != 0)
331                 rar_high |= NGBE_ETHADDRH_VLD;
332
333         wr32(hw, NGBE_ETHADDRIDX, index);
334         wr32(hw, NGBE_ETHADDRL, rar_low);
335         wr32(hw, NGBE_ETHADDRH, rar_high);
336
337         return 0;
338 }
339
340 /**
341  *  ngbe_clear_rar - Remove Rx address register
342  *  @hw: pointer to hardware structure
343  *  @index: Receive address register to write
344  *
345  *  Clears an ethernet address from a receive address register.
346  **/
347 s32 ngbe_clear_rar(struct ngbe_hw *hw, u32 index)
348 {
349         u32 rar_high;
350         u32 rar_entries = hw->mac.num_rar_entries;
351
352         DEBUGFUNC("ngbe_clear_rar");
353
354         /* Make sure we are using a valid rar index range */
355         if (index >= rar_entries) {
356                 DEBUGOUT("RAR index %d is out of range.\n", index);
357                 return NGBE_ERR_INVALID_ARGUMENT;
358         }
359
360         /*
361          * Some parts put the VMDq setting in the extra RAH bits,
362          * so save everything except the lower 16 bits that hold part
363          * of the address and the address valid bit.
364          */
365         wr32(hw, NGBE_ETHADDRIDX, index);
366         rar_high = rd32(hw, NGBE_ETHADDRH);
367         rar_high &= ~(NGBE_ETHADDRH_AD_MASK | NGBE_ETHADDRH_VLD);
368
369         wr32(hw, NGBE_ETHADDRL, 0);
370         wr32(hw, NGBE_ETHADDRH, rar_high);
371
372         /* clear VMDq pool/queue selection for this RAR */
373         hw->mac.clear_vmdq(hw, index, BIT_MASK32);
374
375         return 0;
376 }
377
378 /**
379  *  ngbe_init_rx_addrs - Initializes receive address filters.
380  *  @hw: pointer to hardware structure
381  *
382  *  Places the MAC address in receive address register 0 and clears the rest
383  *  of the receive address registers. Clears the multicast table. Assumes
384  *  the receiver is in reset when the routine is called.
385  **/
386 s32 ngbe_init_rx_addrs(struct ngbe_hw *hw)
387 {
388         u32 i;
389         u32 psrctl;
390         u32 rar_entries = hw->mac.num_rar_entries;
391
392         DEBUGFUNC("ngbe_init_rx_addrs");
393
394         /*
395          * If the current mac address is valid, assume it is a software override
396          * to the permanent address.
397          * Otherwise, use the permanent address from the eeprom.
398          */
399         if (ngbe_validate_mac_addr(hw->mac.addr) ==
400             NGBE_ERR_INVALID_MAC_ADDR) {
401                 /* Get the MAC address from the RAR0 for later reference */
402                 hw->mac.get_mac_addr(hw, hw->mac.addr);
403
404                 DEBUGOUT(" Keeping Current RAR0 Addr =%.2X %.2X %.2X ",
405                           hw->mac.addr[0], hw->mac.addr[1],
406                           hw->mac.addr[2]);
407                 DEBUGOUT("%.2X %.2X %.2X\n", hw->mac.addr[3],
408                           hw->mac.addr[4], hw->mac.addr[5]);
409         } else {
410                 /* Setup the receive address. */
411                 DEBUGOUT("Overriding MAC Address in RAR[0]\n");
412                 DEBUGOUT(" New MAC Addr =%.2X %.2X %.2X ",
413                           hw->mac.addr[0], hw->mac.addr[1],
414                           hw->mac.addr[2]);
415                 DEBUGOUT("%.2X %.2X %.2X\n", hw->mac.addr[3],
416                           hw->mac.addr[4], hw->mac.addr[5]);
417
418                 hw->mac.set_rar(hw, 0, hw->mac.addr, 0, true);
419         }
420
421         /* clear VMDq pool/queue selection for RAR 0 */
422         hw->mac.clear_vmdq(hw, 0, BIT_MASK32);
423
424         /* Zero out the other receive addresses. */
425         DEBUGOUT("Clearing RAR[1-%d]\n", rar_entries - 1);
426         for (i = 1; i < rar_entries; i++) {
427                 wr32(hw, NGBE_ETHADDRIDX, i);
428                 wr32(hw, NGBE_ETHADDRL, 0);
429                 wr32(hw, NGBE_ETHADDRH, 0);
430         }
431
432         /* Clear the MTA */
433         hw->addr_ctrl.mta_in_use = 0;
434         psrctl = rd32(hw, NGBE_PSRCTL);
435         psrctl &= ~(NGBE_PSRCTL_ADHF12_MASK | NGBE_PSRCTL_MCHFENA);
436         psrctl |= NGBE_PSRCTL_ADHF12(hw->mac.mc_filter_type);
437         wr32(hw, NGBE_PSRCTL, psrctl);
438
439         DEBUGOUT(" Clearing MTA\n");
440         for (i = 0; i < hw->mac.mcft_size; i++)
441                 wr32(hw, NGBE_MCADDRTBL(i), 0);
442
443         ngbe_init_uta_tables(hw);
444
445         return 0;
446 }
447
448 /**
449  *  ngbe_acquire_swfw_sync - Acquire SWFW semaphore
450  *  @hw: pointer to hardware structure
451  *  @mask: Mask to specify which semaphore to acquire
452  *
453  *  Acquires the SWFW semaphore through the MNGSEM register for the specified
454  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
455  **/
456 s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask)
457 {
458         u32 mngsem = 0;
459         u32 swmask = NGBE_MNGSEM_SW(mask);
460         u32 fwmask = NGBE_MNGSEM_FW(mask);
461         u32 timeout = 200;
462         u32 i;
463
464         DEBUGFUNC("ngbe_acquire_swfw_sync");
465
466         for (i = 0; i < timeout; i++) {
467                 /*
468                  * SW NVM semaphore bit is used for access to all
469                  * SW_FW_SYNC bits (not just NVM)
470                  */
471                 if (ngbe_get_eeprom_semaphore(hw))
472                         return NGBE_ERR_SWFW_SYNC;
473
474                 mngsem = rd32(hw, NGBE_MNGSEM);
475                 if (mngsem & (fwmask | swmask)) {
476                         /* Resource is currently in use by FW or SW */
477                         ngbe_release_eeprom_semaphore(hw);
478                         msec_delay(5);
479                 } else {
480                         mngsem |= swmask;
481                         wr32(hw, NGBE_MNGSEM, mngsem);
482                         ngbe_release_eeprom_semaphore(hw);
483                         return 0;
484                 }
485         }
486
487         /* If time expired clear the bits holding the lock and retry */
488         if (mngsem & (fwmask | swmask))
489                 ngbe_release_swfw_sync(hw, mngsem & (fwmask | swmask));
490
491         msec_delay(5);
492         return NGBE_ERR_SWFW_SYNC;
493 }
494
495 /**
496  *  ngbe_release_swfw_sync - Release SWFW semaphore
497  *  @hw: pointer to hardware structure
498  *  @mask: Mask to specify which semaphore to release
499  *
500  *  Releases the SWFW semaphore through the MNGSEM register for the specified
501  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
502  **/
503 void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask)
504 {
505         u32 mngsem;
506         u32 swmask = mask;
507
508         DEBUGFUNC("ngbe_release_swfw_sync");
509
510         ngbe_get_eeprom_semaphore(hw);
511
512         mngsem = rd32(hw, NGBE_MNGSEM);
513         mngsem &= ~swmask;
514         wr32(hw, NGBE_MNGSEM, mngsem);
515
516         ngbe_release_eeprom_semaphore(hw);
517 }
518
519 /**
520  *  ngbe_clear_vmdq - Disassociate a VMDq pool index from a rx address
521  *  @hw: pointer to hardware struct
522  *  @rar: receive address register index to disassociate
523  *  @vmdq: VMDq pool index to remove from the rar
524  **/
525 s32 ngbe_clear_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq)
526 {
527         u32 mpsar;
528         u32 rar_entries = hw->mac.num_rar_entries;
529
530         DEBUGFUNC("ngbe_clear_vmdq");
531
532         /* Make sure we are using a valid rar index range */
533         if (rar >= rar_entries) {
534                 DEBUGOUT("RAR index %d is out of range.\n", rar);
535                 return NGBE_ERR_INVALID_ARGUMENT;
536         }
537
538         wr32(hw, NGBE_ETHADDRIDX, rar);
539         mpsar = rd32(hw, NGBE_ETHADDRASS);
540
541         if (NGBE_REMOVED(hw->hw_addr))
542                 goto done;
543
544         if (!mpsar)
545                 goto done;
546
547         mpsar &= ~(1 << vmdq);
548         wr32(hw, NGBE_ETHADDRASS, mpsar);
549
550         /* was that the last pool using this rar? */
551         if (mpsar == 0 && rar != 0)
552                 hw->mac.clear_rar(hw, rar);
553 done:
554         return 0;
555 }
556
557 /**
558  *  ngbe_set_vmdq - Associate a VMDq pool index with a rx address
559  *  @hw: pointer to hardware struct
560  *  @rar: receive address register index to associate with a VMDq index
561  *  @vmdq: VMDq pool index
562  **/
563 s32 ngbe_set_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq)
564 {
565         u32 mpsar;
566         u32 rar_entries = hw->mac.num_rar_entries;
567
568         DEBUGFUNC("ngbe_set_vmdq");
569
570         /* Make sure we are using a valid rar index range */
571         if (rar >= rar_entries) {
572                 DEBUGOUT("RAR index %d is out of range.\n", rar);
573                 return NGBE_ERR_INVALID_ARGUMENT;
574         }
575
576         wr32(hw, NGBE_ETHADDRIDX, rar);
577
578         mpsar = rd32(hw, NGBE_ETHADDRASS);
579         mpsar |= 1 << vmdq;
580         wr32(hw, NGBE_ETHADDRASS, mpsar);
581
582         return 0;
583 }
584
585 /**
586  *  ngbe_init_uta_tables - Initialize the Unicast Table Array
587  *  @hw: pointer to hardware structure
588  **/
589 s32 ngbe_init_uta_tables(struct ngbe_hw *hw)
590 {
591         int i;
592
593         DEBUGFUNC("ngbe_init_uta_tables");
594         DEBUGOUT(" Clearing UTA\n");
595
596         for (i = 0; i < 128; i++)
597                 wr32(hw, NGBE_UCADDRTBL(i), 0);
598
599         return 0;
600 }
601
602 /**
603  *  ngbe_check_mac_link_em - Determine link and speed status
604  *  @hw: pointer to hardware structure
605  *  @speed: pointer to link speed
606  *  @link_up: true when link is up
607  *  @link_up_wait_to_complete: bool used to wait for link up or not
608  *
609  *  Reads the links register to determine if link is up and the current speed
610  **/
611 s32 ngbe_check_mac_link_em(struct ngbe_hw *hw, u32 *speed,
612                         bool *link_up, bool link_up_wait_to_complete)
613 {
614         u32 i, reg;
615         s32 status = 0;
616
617         DEBUGFUNC("ngbe_check_mac_link_em");
618
619         reg = rd32(hw, NGBE_GPIOINTSTAT);
620         wr32(hw, NGBE_GPIOEOI, reg);
621
622         if (link_up_wait_to_complete) {
623                 for (i = 0; i < hw->mac.max_link_up_time; i++) {
624                         status = hw->phy.check_link(hw, speed, link_up);
625                         if (*link_up)
626                                 break;
627                         msec_delay(100);
628                 }
629         } else {
630                 status = hw->phy.check_link(hw, speed, link_up);
631         }
632
633         return status;
634 }
635
636 s32 ngbe_setup_mac_link_em(struct ngbe_hw *hw,
637                                u32 speed,
638                                bool autoneg_wait_to_complete)
639 {
640         s32 status;
641
642         DEBUGFUNC("\n");
643
644         /* Setup the PHY according to input speed */
645         status = hw->phy.setup_link(hw, speed, autoneg_wait_to_complete);
646
647         return status;
648 }
649
650 /**
651  *  ngbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds
652  *  @hw: pointer to hardware structure
653  *
654  *  Inits the thermal sensor thresholds according to the NVM map
655  *  and save off the threshold and location values into mac.thermal_sensor_data
656  **/
657 s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw)
658 {
659         struct ngbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
660
661         DEBUGFUNC("ngbe_init_thermal_sensor_thresh");
662
663         memset(data, 0, sizeof(struct ngbe_thermal_sensor_data));
664
665         if (hw->bus.lan_id != 0)
666                 return NGBE_NOT_IMPLEMENTED;
667
668         wr32(hw, NGBE_TSINTR,
669                 NGBE_TSINTR_AEN | NGBE_TSINTR_DEN);
670         wr32(hw, NGBE_TSEN, NGBE_TSEN_ENA);
671
672
673         data->sensor[0].alarm_thresh = 115;
674         wr32(hw, NGBE_TSATHRE, 0x344);
675         data->sensor[0].dalarm_thresh = 110;
676         wr32(hw, NGBE_TSDTHRE, 0x330);
677
678         return 0;
679 }
680
681 s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw)
682 {
683         s32 status = 0;
684         u32 ts_state;
685
686         DEBUGFUNC("ngbe_mac_check_overtemp");
687
688         /* Check that the LASI temp alarm status was triggered */
689         ts_state = rd32(hw, NGBE_TSALM);
690
691         if (ts_state & NGBE_TSALM_HI)
692                 status = NGBE_ERR_UNDERTEMP;
693         else if (ts_state & NGBE_TSALM_LO)
694                 status = NGBE_ERR_OVERTEMP;
695
696         return status;
697 }
698
699 void ngbe_disable_rx(struct ngbe_hw *hw)
700 {
701         u32 pfdtxgswc;
702
703         pfdtxgswc = rd32(hw, NGBE_PSRCTL);
704         if (pfdtxgswc & NGBE_PSRCTL_LBENA) {
705                 pfdtxgswc &= ~NGBE_PSRCTL_LBENA;
706                 wr32(hw, NGBE_PSRCTL, pfdtxgswc);
707                 hw->mac.set_lben = true;
708         } else {
709                 hw->mac.set_lben = false;
710         }
711
712         wr32m(hw, NGBE_PBRXCTL, NGBE_PBRXCTL_ENA, 0);
713         wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0);
714 }
715
716 /**
717  *  ngbe_set_mac_type - Sets MAC type
718  *  @hw: pointer to the HW structure
719  *
720  *  This function sets the mac type of the adapter based on the
721  *  vendor ID and device ID stored in the hw structure.
722  **/
723 s32 ngbe_set_mac_type(struct ngbe_hw *hw)
724 {
725         s32 err = 0;
726
727         DEBUGFUNC("ngbe_set_mac_type");
728
729         if (hw->vendor_id != PCI_VENDOR_ID_WANGXUN) {
730                 DEBUGOUT("Unsupported vendor id: %x", hw->vendor_id);
731                 return NGBE_ERR_DEVICE_NOT_SUPPORTED;
732         }
733
734         switch (hw->sub_device_id) {
735         case NGBE_SUB_DEV_ID_EM_RTL_SGMII:
736         case NGBE_SUB_DEV_ID_EM_MVL_RGMII:
737                 hw->phy.media_type = ngbe_media_type_copper;
738                 hw->mac.type = ngbe_mac_em;
739                 break;
740         case NGBE_SUB_DEV_ID_EM_MVL_SFP:
741         case NGBE_SUB_DEV_ID_EM_YT8521S_SFP:
742                 hw->phy.media_type = ngbe_media_type_fiber;
743                 hw->mac.type = ngbe_mac_em;
744                 break;
745         case NGBE_SUB_DEV_ID_EM_VF:
746                 hw->phy.media_type = ngbe_media_type_virtual;
747                 hw->mac.type = ngbe_mac_em_vf;
748                 break;
749         default:
750                 err = NGBE_ERR_DEVICE_NOT_SUPPORTED;
751                 hw->phy.media_type = ngbe_media_type_unknown;
752                 hw->mac.type = ngbe_mac_unknown;
753                 DEBUGOUT("Unsupported device id: %x", hw->device_id);
754                 break;
755         }
756
757         DEBUGOUT("found mac: %d media: %d, returns: %d\n",
758                   hw->mac.type, hw->phy.media_type, err);
759         return err;
760 }
761
762 void ngbe_map_device_id(struct ngbe_hw *hw)
763 {
764         u16 oem = hw->sub_system_id & NGBE_OEM_MASK;
765         u16 internal = hw->sub_system_id & NGBE_INTERNAL_MASK;
766         hw->is_pf = true;
767
768         /* move subsystem_device_id to device_id */
769         switch (hw->device_id) {
770         case NGBE_DEV_ID_EM_WX1860AL_W_VF:
771         case NGBE_DEV_ID_EM_WX1860A2_VF:
772         case NGBE_DEV_ID_EM_WX1860A2S_VF:
773         case NGBE_DEV_ID_EM_WX1860A4_VF:
774         case NGBE_DEV_ID_EM_WX1860A4S_VF:
775         case NGBE_DEV_ID_EM_WX1860AL2_VF:
776         case NGBE_DEV_ID_EM_WX1860AL2S_VF:
777         case NGBE_DEV_ID_EM_WX1860AL4_VF:
778         case NGBE_DEV_ID_EM_WX1860AL4S_VF:
779         case NGBE_DEV_ID_EM_WX1860NCSI_VF:
780         case NGBE_DEV_ID_EM_WX1860A1_VF:
781         case NGBE_DEV_ID_EM_WX1860A1L_VF:
782                 hw->device_id = NGBE_DEV_ID_EM_VF;
783                 hw->sub_device_id = NGBE_SUB_DEV_ID_EM_VF;
784                 hw->is_pf = false;
785                 break;
786         case NGBE_DEV_ID_EM_WX1860AL_W:
787         case NGBE_DEV_ID_EM_WX1860A2:
788         case NGBE_DEV_ID_EM_WX1860A2S:
789         case NGBE_DEV_ID_EM_WX1860A4:
790         case NGBE_DEV_ID_EM_WX1860A4S:
791         case NGBE_DEV_ID_EM_WX1860AL2:
792         case NGBE_DEV_ID_EM_WX1860AL2S:
793         case NGBE_DEV_ID_EM_WX1860AL4:
794         case NGBE_DEV_ID_EM_WX1860AL4S:
795         case NGBE_DEV_ID_EM_WX1860NCSI:
796         case NGBE_DEV_ID_EM_WX1860A1:
797         case NGBE_DEV_ID_EM_WX1860A1L:
798                 hw->device_id = NGBE_DEV_ID_EM;
799                 if (oem == NGBE_LY_M88E1512_SFP ||
800                                 internal == NGBE_INTERNAL_SFP)
801                         hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_SFP;
802                 else if (hw->sub_system_id == NGBE_SUB_DEV_ID_EM_M88E1512_RJ45)
803                         hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_RGMII;
804                 else if (oem == NGBE_YT8521S_SFP ||
805                                 oem == NGBE_LY_YT8521S_SFP)
806                         hw->sub_device_id = NGBE_SUB_DEV_ID_EM_YT8521S_SFP;
807                 else
808                         hw->sub_device_id = NGBE_SUB_DEV_ID_EM_RTL_SGMII;
809                 break;
810         default:
811                 break;
812         }
813 }
814
815 /**
816  *  ngbe_init_ops_pf - Inits func ptrs and MAC type
817  *  @hw: pointer to hardware structure
818  *
819  *  Initialize the function pointers and assign the MAC type.
820  *  Does not touch the hardware.
821  **/
822 s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
823 {
824         struct ngbe_bus_info *bus = &hw->bus;
825         struct ngbe_mac_info *mac = &hw->mac;
826         struct ngbe_phy_info *phy = &hw->phy;
827         struct ngbe_rom_info *rom = &hw->rom;
828
829         DEBUGFUNC("ngbe_init_ops_pf");
830
831         /* BUS */
832         bus->set_lan_id = ngbe_set_lan_id_multi_port;
833
834         /* PHY */
835         phy->identify = ngbe_identify_phy;
836         phy->read_reg = ngbe_read_phy_reg;
837         phy->write_reg = ngbe_write_phy_reg;
838         phy->read_reg_unlocked = ngbe_read_phy_reg_mdi;
839         phy->write_reg_unlocked = ngbe_write_phy_reg_mdi;
840         phy->reset_hw = ngbe_reset_phy;
841
842         /* MAC */
843         mac->init_hw = ngbe_init_hw;
844         mac->reset_hw = ngbe_reset_hw_em;
845         mac->get_mac_addr = ngbe_get_mac_addr;
846         mac->stop_hw = ngbe_stop_hw;
847         mac->acquire_swfw_sync = ngbe_acquire_swfw_sync;
848         mac->release_swfw_sync = ngbe_release_swfw_sync;
849
850         /* RAR */
851         mac->set_rar = ngbe_set_rar;
852         mac->clear_rar = ngbe_clear_rar;
853         mac->init_rx_addrs = ngbe_init_rx_addrs;
854         mac->set_vmdq = ngbe_set_vmdq;
855         mac->clear_vmdq = ngbe_clear_vmdq;
856
857         /* Link */
858         mac->check_link = ngbe_check_mac_link_em;
859         mac->setup_link = ngbe_setup_mac_link_em;
860
861         /* Manageability interface */
862         mac->init_thermal_sensor_thresh = ngbe_init_thermal_sensor_thresh;
863         mac->check_overtemp = ngbe_mac_check_overtemp;
864
865         /* EEPROM */
866         rom->init_params = ngbe_init_eeprom_params;
867         rom->validate_checksum = ngbe_validate_eeprom_checksum_em;
868
869         mac->mcft_size          = NGBE_EM_MC_TBL_SIZE;
870         mac->num_rar_entries    = NGBE_EM_RAR_ENTRIES;
871         mac->max_rx_queues      = NGBE_EM_MAX_RX_QUEUES;
872         mac->max_tx_queues      = NGBE_EM_MAX_TX_QUEUES;
873
874         return 0;
875 }
876
877 /**
878  *  ngbe_init_shared_code - Initialize the shared code
879  *  @hw: pointer to hardware structure
880  *
881  *  This will assign function pointers and assign the MAC type and PHY code.
882  *  Does not touch the hardware. This function must be called prior to any
883  *  other function in the shared code. The ngbe_hw structure should be
884  *  memset to 0 prior to calling this function.  The following fields in
885  *  hw structure should be filled in prior to calling this function:
886  *  hw_addr, back, device_id, vendor_id, subsystem_device_id
887  **/
888 s32 ngbe_init_shared_code(struct ngbe_hw *hw)
889 {
890         s32 status = 0;
891
892         DEBUGFUNC("ngbe_init_shared_code");
893
894         /*
895          * Set the mac type
896          */
897         ngbe_set_mac_type(hw);
898
899         ngbe_init_ops_dummy(hw);
900         switch (hw->mac.type) {
901         case ngbe_mac_em:
902                 ngbe_init_ops_pf(hw);
903                 break;
904         default:
905                 status = NGBE_ERR_DEVICE_NOT_SUPPORTED;
906                 break;
907         }
908         hw->mac.max_link_up_time = NGBE_LINK_UP_TIME;
909
910         hw->bus.set_lan_id(hw);
911
912         return status;
913 }
914