1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3 * Copyright(c) 2010-2017 Intel Corporation
7 #include "ngbe_eeprom.h"
12 * ngbe_init_hw - Generic hardware initialization
13 * @hw: pointer to hardware structure
15 * Initialize the hardware by resetting the hardware, filling the bus info
16 * structure and media type, clears all on chip counters, initializes receive
17 * address registers, multicast table, VLAN filter table, calls routine to set
18 * up link and flow control settings, and leaves transmit and receive units
19 * disabled and uninitialized
21 s32 ngbe_init_hw(struct ngbe_hw *hw)
25 DEBUGFUNC("ngbe_init_hw");
27 /* Reset the hardware */
28 status = hw->mac.reset_hw(hw);
31 DEBUGOUT("Failed to initialize HW, STATUS = %d\n", status);
37 ngbe_reset_misc_em(struct ngbe_hw *hw)
41 wr32(hw, NGBE_ISBADDRL, hw->isb_dma & 0xFFFFFFFF);
42 wr32(hw, NGBE_ISBADDRH, hw->isb_dma >> 32);
44 /* receive packets that size > 2048 */
45 wr32m(hw, NGBE_MACRXCFG,
46 NGBE_MACRXCFG_JUMBO, NGBE_MACRXCFG_JUMBO);
48 wr32m(hw, NGBE_FRMSZ, NGBE_FRMSZ_MAX_MASK,
49 NGBE_FRMSZ_MAX(NGBE_FRAME_SIZE_DFT));
51 /* clear counters on read */
52 wr32m(hw, NGBE_MACCNTCTL,
53 NGBE_MACCNTCTL_RC, NGBE_MACCNTCTL_RC);
55 wr32m(hw, NGBE_RXFCCFG,
56 NGBE_RXFCCFG_FC, NGBE_RXFCCFG_FC);
57 wr32m(hw, NGBE_TXFCCFG,
58 NGBE_TXFCCFG_FC, NGBE_TXFCCFG_FC);
60 wr32m(hw, NGBE_MACRXFLT,
61 NGBE_MACRXFLT_PROMISC, NGBE_MACRXFLT_PROMISC);
63 wr32m(hw, NGBE_RSTSTAT,
64 NGBE_RSTSTAT_TMRINIT_MASK, NGBE_RSTSTAT_TMRINIT(30));
66 /* errata 4: initialize mng flex tbl and wakeup flex tbl*/
67 wr32(hw, NGBE_MNGFLEXSEL, 0);
68 for (i = 0; i < 16; i++) {
69 wr32(hw, NGBE_MNGFLEXDWL(i), 0);
70 wr32(hw, NGBE_MNGFLEXDWH(i), 0);
71 wr32(hw, NGBE_MNGFLEXMSK(i), 0);
73 wr32(hw, NGBE_LANFLEXSEL, 0);
74 for (i = 0; i < 16; i++) {
75 wr32(hw, NGBE_LANFLEXDWL(i), 0);
76 wr32(hw, NGBE_LANFLEXDWH(i), 0);
77 wr32(hw, NGBE_LANFLEXMSK(i), 0);
80 /* set pause frame dst mac addr */
81 wr32(hw, NGBE_RXPBPFCDMACL, 0xC2000001);
82 wr32(hw, NGBE_RXPBPFCDMACH, 0x0180);
84 wr32(hw, NGBE_MDIOMODE, 0xF);
86 wr32m(hw, NGBE_GPIE, NGBE_GPIE_MSIX, NGBE_GPIE_MSIX);
88 if ((hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_M88E1512_SFP ||
89 (hw->sub_system_id & NGBE_OEM_MASK) == NGBE_LY_YT8521S_SFP) {
90 /* gpio0 is used to power on/off control*/
91 wr32(hw, NGBE_GPIODIR, NGBE_GPIODIR_DDR(1));
92 wr32(hw, NGBE_GPIODATA, NGBE_GPIOBIT_0);
95 hw->mac.init_thermal_sensor_thresh(hw);
97 /* enable mac transmitter */
98 wr32m(hw, NGBE_MACTXCFG, NGBE_MACTXCFG_TE, NGBE_MACTXCFG_TE);
101 wr32m(hw, NGBE_MACTXCFG,
102 NGBE_MACTXCFG_SPEED_MASK, NGBE_MACTXCFG_SPEED_1G);
104 for (i = 0; i < 4; i++)
105 wr32m(hw, NGBE_IVAR(i), 0x80808080, 0);
109 * ngbe_reset_hw_em - Perform hardware reset
110 * @hw: pointer to hardware structure
112 * Resets the hardware by resetting the transmit and receive units, masks
113 * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
116 s32 ngbe_reset_hw_em(struct ngbe_hw *hw)
120 DEBUGFUNC("ngbe_reset_hw_em");
122 /* Call adapter stop to disable tx/rx and clear interrupts */
123 status = hw->mac.stop_hw(hw);
127 wr32(hw, NGBE_RST, NGBE_RST_LAN(hw->bus.lan_id));
131 ngbe_reset_misc_em(hw);
139 * ngbe_set_lan_id_multi_port - Set LAN id for PCIe multiple port devices
140 * @hw: pointer to the HW structure
142 * Determines the LAN function id by reading memory-mapped registers and swaps
143 * the port value if requested, and set MAC instance for devices.
145 void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw)
147 struct ngbe_bus_info *bus = &hw->bus;
150 DEBUGFUNC("ngbe_set_lan_id_multi_port");
152 reg = rd32(hw, NGBE_PORTSTAT);
153 bus->lan_id = NGBE_PORTSTAT_ID(reg);
154 bus->func = bus->lan_id;
158 * ngbe_stop_hw - Generic stop Tx/Rx units
159 * @hw: pointer to hardware structure
161 * Sets the adapter_stopped flag within ngbe_hw struct. Clears interrupts,
162 * disables transmit and receive units. The adapter_stopped flag is used by
163 * the shared code and drivers to determine if the adapter is in a stopped
164 * state and should not touch the hardware.
166 s32 ngbe_stop_hw(struct ngbe_hw *hw)
171 DEBUGFUNC("ngbe_stop_hw");
174 * Set the adapter_stopped flag so other driver functions stop touching
177 hw->adapter_stopped = true;
179 /* Disable the receive unit */
182 /* Clear interrupt mask to stop interrupts from being generated */
183 wr32(hw, NGBE_IENMISC, 0);
184 wr32(hw, NGBE_IMS(0), NGBE_IMS_MASK);
186 /* Clear any pending interrupts, flush previous writes */
187 wr32(hw, NGBE_ICRMISC, NGBE_ICRMISC_MASK);
188 wr32(hw, NGBE_ICR(0), NGBE_ICR_MASK);
190 /* Disable the transmit unit. Each queue must be disabled. */
191 for (i = 0; i < hw->mac.max_tx_queues; i++)
192 wr32(hw, NGBE_TXCFG(i), NGBE_TXCFG_FLUSH);
194 /* Disable the receive unit by stopping each queue */
195 for (i = 0; i < hw->mac.max_rx_queues; i++) {
196 reg_val = rd32(hw, NGBE_RXCFG(i));
197 reg_val &= ~NGBE_RXCFG_ENA;
198 wr32(hw, NGBE_RXCFG(i), reg_val);
201 /* flush all queues disables */
209 * ngbe_acquire_swfw_sync - Acquire SWFW semaphore
210 * @hw: pointer to hardware structure
211 * @mask: Mask to specify which semaphore to acquire
213 * Acquires the SWFW semaphore through the MNGSEM register for the specified
214 * function (CSR, PHY0, PHY1, EEPROM, Flash)
216 s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask)
219 u32 swmask = NGBE_MNGSEM_SW(mask);
220 u32 fwmask = NGBE_MNGSEM_FW(mask);
224 DEBUGFUNC("ngbe_acquire_swfw_sync");
226 for (i = 0; i < timeout; i++) {
228 * SW NVM semaphore bit is used for access to all
229 * SW_FW_SYNC bits (not just NVM)
231 if (ngbe_get_eeprom_semaphore(hw))
232 return NGBE_ERR_SWFW_SYNC;
234 mngsem = rd32(hw, NGBE_MNGSEM);
235 if (mngsem & (fwmask | swmask)) {
236 /* Resource is currently in use by FW or SW */
237 ngbe_release_eeprom_semaphore(hw);
241 wr32(hw, NGBE_MNGSEM, mngsem);
242 ngbe_release_eeprom_semaphore(hw);
247 /* If time expired clear the bits holding the lock and retry */
248 if (mngsem & (fwmask | swmask))
249 ngbe_release_swfw_sync(hw, mngsem & (fwmask | swmask));
252 return NGBE_ERR_SWFW_SYNC;
256 * ngbe_release_swfw_sync - Release SWFW semaphore
257 * @hw: pointer to hardware structure
258 * @mask: Mask to specify which semaphore to release
260 * Releases the SWFW semaphore through the MNGSEM register for the specified
261 * function (CSR, PHY0, PHY1, EEPROM, Flash)
263 void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask)
268 DEBUGFUNC("ngbe_release_swfw_sync");
270 ngbe_get_eeprom_semaphore(hw);
272 mngsem = rd32(hw, NGBE_MNGSEM);
274 wr32(hw, NGBE_MNGSEM, mngsem);
276 ngbe_release_eeprom_semaphore(hw);
280 * ngbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds
281 * @hw: pointer to hardware structure
283 * Inits the thermal sensor thresholds according to the NVM map
284 * and save off the threshold and location values into mac.thermal_sensor_data
286 s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw)
288 struct ngbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
290 DEBUGFUNC("ngbe_init_thermal_sensor_thresh");
292 memset(data, 0, sizeof(struct ngbe_thermal_sensor_data));
294 if (hw->bus.lan_id != 0)
295 return NGBE_NOT_IMPLEMENTED;
297 wr32(hw, NGBE_TSINTR,
298 NGBE_TSINTR_AEN | NGBE_TSINTR_DEN);
299 wr32(hw, NGBE_TSEN, NGBE_TSEN_ENA);
302 data->sensor[0].alarm_thresh = 115;
303 wr32(hw, NGBE_TSATHRE, 0x344);
304 data->sensor[0].dalarm_thresh = 110;
305 wr32(hw, NGBE_TSDTHRE, 0x330);
310 void ngbe_disable_rx(struct ngbe_hw *hw)
314 pfdtxgswc = rd32(hw, NGBE_PSRCTL);
315 if (pfdtxgswc & NGBE_PSRCTL_LBENA) {
316 pfdtxgswc &= ~NGBE_PSRCTL_LBENA;
317 wr32(hw, NGBE_PSRCTL, pfdtxgswc);
318 hw->mac.set_lben = true;
320 hw->mac.set_lben = false;
323 wr32m(hw, NGBE_PBRXCTL, NGBE_PBRXCTL_ENA, 0);
324 wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0);
328 * ngbe_set_mac_type - Sets MAC type
329 * @hw: pointer to the HW structure
331 * This function sets the mac type of the adapter based on the
332 * vendor ID and device ID stored in the hw structure.
334 s32 ngbe_set_mac_type(struct ngbe_hw *hw)
338 DEBUGFUNC("ngbe_set_mac_type");
340 if (hw->vendor_id != PCI_VENDOR_ID_WANGXUN) {
341 DEBUGOUT("Unsupported vendor id: %x", hw->vendor_id);
342 return NGBE_ERR_DEVICE_NOT_SUPPORTED;
345 switch (hw->sub_device_id) {
346 case NGBE_SUB_DEV_ID_EM_RTL_SGMII:
347 case NGBE_SUB_DEV_ID_EM_MVL_RGMII:
348 hw->phy.media_type = ngbe_media_type_copper;
349 hw->mac.type = ngbe_mac_em;
351 case NGBE_SUB_DEV_ID_EM_MVL_SFP:
352 case NGBE_SUB_DEV_ID_EM_YT8521S_SFP:
353 hw->phy.media_type = ngbe_media_type_fiber;
354 hw->mac.type = ngbe_mac_em;
356 case NGBE_SUB_DEV_ID_EM_VF:
357 hw->phy.media_type = ngbe_media_type_virtual;
358 hw->mac.type = ngbe_mac_em_vf;
361 err = NGBE_ERR_DEVICE_NOT_SUPPORTED;
362 hw->phy.media_type = ngbe_media_type_unknown;
363 hw->mac.type = ngbe_mac_unknown;
364 DEBUGOUT("Unsupported device id: %x", hw->device_id);
368 DEBUGOUT("found mac: %d media: %d, returns: %d\n",
369 hw->mac.type, hw->phy.media_type, err);
373 void ngbe_map_device_id(struct ngbe_hw *hw)
375 u16 oem = hw->sub_system_id & NGBE_OEM_MASK;
376 u16 internal = hw->sub_system_id & NGBE_INTERNAL_MASK;
379 /* move subsystem_device_id to device_id */
380 switch (hw->device_id) {
381 case NGBE_DEV_ID_EM_WX1860AL_W_VF:
382 case NGBE_DEV_ID_EM_WX1860A2_VF:
383 case NGBE_DEV_ID_EM_WX1860A2S_VF:
384 case NGBE_DEV_ID_EM_WX1860A4_VF:
385 case NGBE_DEV_ID_EM_WX1860A4S_VF:
386 case NGBE_DEV_ID_EM_WX1860AL2_VF:
387 case NGBE_DEV_ID_EM_WX1860AL2S_VF:
388 case NGBE_DEV_ID_EM_WX1860AL4_VF:
389 case NGBE_DEV_ID_EM_WX1860AL4S_VF:
390 case NGBE_DEV_ID_EM_WX1860NCSI_VF:
391 case NGBE_DEV_ID_EM_WX1860A1_VF:
392 case NGBE_DEV_ID_EM_WX1860A1L_VF:
393 hw->device_id = NGBE_DEV_ID_EM_VF;
394 hw->sub_device_id = NGBE_SUB_DEV_ID_EM_VF;
397 case NGBE_DEV_ID_EM_WX1860AL_W:
398 case NGBE_DEV_ID_EM_WX1860A2:
399 case NGBE_DEV_ID_EM_WX1860A2S:
400 case NGBE_DEV_ID_EM_WX1860A4:
401 case NGBE_DEV_ID_EM_WX1860A4S:
402 case NGBE_DEV_ID_EM_WX1860AL2:
403 case NGBE_DEV_ID_EM_WX1860AL2S:
404 case NGBE_DEV_ID_EM_WX1860AL4:
405 case NGBE_DEV_ID_EM_WX1860AL4S:
406 case NGBE_DEV_ID_EM_WX1860NCSI:
407 case NGBE_DEV_ID_EM_WX1860A1:
408 case NGBE_DEV_ID_EM_WX1860A1L:
409 hw->device_id = NGBE_DEV_ID_EM;
410 if (oem == NGBE_LY_M88E1512_SFP ||
411 internal == NGBE_INTERNAL_SFP)
412 hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_SFP;
413 else if (hw->sub_system_id == NGBE_SUB_DEV_ID_EM_M88E1512_RJ45)
414 hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_RGMII;
415 else if (oem == NGBE_YT8521S_SFP ||
416 oem == NGBE_LY_YT8521S_SFP)
417 hw->sub_device_id = NGBE_SUB_DEV_ID_EM_YT8521S_SFP;
419 hw->sub_device_id = NGBE_SUB_DEV_ID_EM_RTL_SGMII;
427 * ngbe_init_ops_pf - Inits func ptrs and MAC type
428 * @hw: pointer to hardware structure
430 * Initialize the function pointers and assign the MAC type.
431 * Does not touch the hardware.
433 s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
435 struct ngbe_bus_info *bus = &hw->bus;
436 struct ngbe_mac_info *mac = &hw->mac;
437 struct ngbe_rom_info *rom = &hw->rom;
439 DEBUGFUNC("ngbe_init_ops_pf");
442 bus->set_lan_id = ngbe_set_lan_id_multi_port;
445 mac->init_hw = ngbe_init_hw;
446 mac->reset_hw = ngbe_reset_hw_em;
447 mac->stop_hw = ngbe_stop_hw;
448 mac->acquire_swfw_sync = ngbe_acquire_swfw_sync;
449 mac->release_swfw_sync = ngbe_release_swfw_sync;
451 /* Manageability interface */
452 mac->init_thermal_sensor_thresh = ngbe_init_thermal_sensor_thresh;
455 rom->init_params = ngbe_init_eeprom_params;
456 rom->validate_checksum = ngbe_validate_eeprom_checksum_em;
458 mac->max_rx_queues = NGBE_EM_MAX_RX_QUEUES;
459 mac->max_tx_queues = NGBE_EM_MAX_TX_QUEUES;
465 * ngbe_init_shared_code - Initialize the shared code
466 * @hw: pointer to hardware structure
468 * This will assign function pointers and assign the MAC type and PHY code.
469 * Does not touch the hardware. This function must be called prior to any
470 * other function in the shared code. The ngbe_hw structure should be
471 * memset to 0 prior to calling this function. The following fields in
472 * hw structure should be filled in prior to calling this function:
473 * hw_addr, back, device_id, vendor_id, subsystem_device_id
475 s32 ngbe_init_shared_code(struct ngbe_hw *hw)
479 DEBUGFUNC("ngbe_init_shared_code");
484 ngbe_set_mac_type(hw);
486 ngbe_init_ops_dummy(hw);
487 switch (hw->mac.type) {
489 ngbe_init_ops_pf(hw);
492 status = NGBE_ERR_DEVICE_NOT_SUPPORTED;
496 hw->bus.set_lan_id(hw);