1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015-2020
5 #include "txgbe_type.h"
6 #include "txgbe_eeprom.h"
10 #define TXGBE_RAPTOR_RAR_ENTRIES 128
13 * txgbe_init_hw - Generic hardware initialization
14 * @hw: pointer to hardware structure
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
22 s32 txgbe_init_hw(struct txgbe_hw *hw)
26 DEBUGFUNC("txgbe_init_hw");
28 /* Reset the hardware */
29 status = hw->mac.reset_hw(hw);
30 if (status == 0 || status == TXGBE_ERR_SFP_NOT_PRESENT) {
32 status = hw->mac.start_hw(hw);
36 DEBUGOUT("Failed to initialize HW, STATUS = %d\n", status);
43 * txgbe_set_lan_id_multi_port - Set LAN id for PCIe multiple port devices
44 * @hw: pointer to the HW structure
46 * Determines the LAN function id by reading memory-mapped registers and swaps
47 * the port value if requested, and set MAC instance for devices.
49 void txgbe_set_lan_id_multi_port(struct txgbe_hw *hw)
51 struct txgbe_bus_info *bus = &hw->bus;
54 DEBUGFUNC("txgbe_set_lan_id_multi_port_pcie");
56 reg = rd32(hw, TXGBE_PORTSTAT);
57 bus->lan_id = TXGBE_PORTSTAT_ID(reg);
59 /* check for single port */
60 reg = rd32(hw, TXGBE_PWR);
61 if (TXGBE_PWR_LANID(reg) == TXGBE_PWR_LANID_SWAP)
64 bus->func = bus->lan_id;
68 * txgbe_validate_mac_addr - Validate MAC address
69 * @mac_addr: pointer to MAC address.
71 * Tests a MAC address to ensure it is a valid Individual Address.
73 s32 txgbe_validate_mac_addr(u8 *mac_addr)
77 DEBUGFUNC("txgbe_validate_mac_addr");
79 /* Make sure it is not a multicast address */
80 if (TXGBE_IS_MULTICAST(mac_addr)) {
81 status = TXGBE_ERR_INVALID_MAC_ADDR;
82 /* Not a broadcast address */
83 } else if (TXGBE_IS_BROADCAST(mac_addr)) {
84 status = TXGBE_ERR_INVALID_MAC_ADDR;
85 /* Reject the zero address */
86 } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
87 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
88 status = TXGBE_ERR_INVALID_MAC_ADDR;
94 * txgbe_clear_tx_pending - Clear pending TX work from the PCIe fifo
95 * @hw: pointer to the hardware structure
97 * The MACs can experience issues if TX work is still pending
98 * when a reset occurs. This function prevents this by flushing the PCIe
99 * buffers on the system.
101 void txgbe_clear_tx_pending(struct txgbe_hw *hw)
106 * If double reset is not requested then all transactions should
107 * already be clear and as such there is no work to do
109 if (!(hw->mac.flags & TXGBE_FLAGS_DOUBLE_RESET_REQUIRED))
112 hlreg0 = rd32(hw, TXGBE_PSRCTL);
113 wr32(hw, TXGBE_PSRCTL, hlreg0 | TXGBE_PSRCTL_LBENA);
115 /* Wait for a last completion before clearing buffers */
120 * Before proceeding, make sure that the PCIe block does not have
121 * transactions pending.
123 poll = (800 * 11) / 10;
124 for (i = 0; i < poll; i++)
127 /* Flush all writes and allow 20usec for all transactions to clear */
131 /* restore previous register values */
132 wr32(hw, TXGBE_PSRCTL, hlreg0);
136 * txgbe_init_shared_code - Initialize the shared code
137 * @hw: pointer to hardware structure
139 * This will assign function pointers and assign the MAC type and PHY code.
140 * Does not touch the hardware. This function must be called prior to any
141 * other function in the shared code. The txgbe_hw structure should be
142 * memset to 0 prior to calling this function. The following fields in
143 * hw structure should be filled in prior to calling this function:
144 * hw_addr, back, device_id, vendor_id, subsystem_device_id,
145 * subsystem_vendor_id, and revision_id
147 s32 txgbe_init_shared_code(struct txgbe_hw *hw)
151 DEBUGFUNC("txgbe_init_shared_code");
156 txgbe_set_mac_type(hw);
158 txgbe_init_ops_dummy(hw);
159 switch (hw->mac.type) {
160 case txgbe_mac_raptor:
161 status = txgbe_init_ops_pf(hw);
164 status = TXGBE_ERR_DEVICE_NOT_SUPPORTED;
167 hw->mac.max_link_up_time = TXGBE_LINK_UP_TIME;
169 hw->bus.set_lan_id(hw);
175 * txgbe_set_mac_type - Sets MAC type
176 * @hw: pointer to the HW structure
178 * This function sets the mac type of the adapter based on the
179 * vendor ID and device ID stored in the hw structure.
181 s32 txgbe_set_mac_type(struct txgbe_hw *hw)
185 DEBUGFUNC("txgbe_set_mac_type");
187 if (hw->vendor_id != PCI_VENDOR_ID_WANGXUN) {
188 DEBUGOUT("Unsupported vendor id: %x", hw->vendor_id);
189 return TXGBE_ERR_DEVICE_NOT_SUPPORTED;
192 switch (hw->device_id) {
193 case TXGBE_DEV_ID_RAPTOR_KR_KX_KX4:
194 hw->phy.media_type = txgbe_media_type_backplane;
195 hw->mac.type = txgbe_mac_raptor;
197 case TXGBE_DEV_ID_RAPTOR_XAUI:
198 case TXGBE_DEV_ID_RAPTOR_SGMII:
199 hw->phy.media_type = txgbe_media_type_copper;
200 hw->mac.type = txgbe_mac_raptor;
202 case TXGBE_DEV_ID_RAPTOR_SFP:
203 case TXGBE_DEV_ID_WX1820_SFP:
204 hw->phy.media_type = txgbe_media_type_fiber;
205 hw->mac.type = txgbe_mac_raptor;
207 case TXGBE_DEV_ID_RAPTOR_QSFP:
208 hw->phy.media_type = txgbe_media_type_fiber_qsfp;
209 hw->mac.type = txgbe_mac_raptor;
211 case TXGBE_DEV_ID_RAPTOR_VF:
212 case TXGBE_DEV_ID_RAPTOR_VF_HV:
213 hw->phy.media_type = txgbe_media_type_virtual;
214 hw->mac.type = txgbe_mac_raptor_vf;
217 err = TXGBE_ERR_DEVICE_NOT_SUPPORTED;
218 DEBUGOUT("Unsupported device id: %x", hw->device_id);
222 DEBUGOUT("found mac: %d media: %d, returns: %d\n",
223 hw->mac.type, hw->phy.media_type, err);
228 * txgbe_init_ops_pf - Inits func ptrs and MAC type
229 * @hw: pointer to hardware structure
231 * Initialize the function pointers and assign the MAC type.
232 * Does not touch the hardware.
234 s32 txgbe_init_ops_pf(struct txgbe_hw *hw)
236 struct txgbe_bus_info *bus = &hw->bus;
237 struct txgbe_mac_info *mac = &hw->mac;
238 struct txgbe_rom_info *rom = &hw->rom;
240 DEBUGFUNC("txgbe_init_ops_pf");
243 bus->set_lan_id = txgbe_set_lan_id_multi_port;
246 mac->init_hw = txgbe_init_hw;
247 mac->reset_hw = txgbe_reset_hw;
248 mac->num_rar_entries = TXGBE_RAPTOR_RAR_ENTRIES;
251 rom->init_params = txgbe_init_eeprom_params;
252 rom->read16 = txgbe_ee_read16;
253 rom->readw_buffer = txgbe_ee_readw_buffer;
254 rom->readw_sw = txgbe_ee_readw_sw;
255 rom->read32 = txgbe_ee_read32;
256 rom->write16 = txgbe_ee_write16;
257 rom->writew_buffer = txgbe_ee_writew_buffer;
258 rom->writew_sw = txgbe_ee_writew_sw;
259 rom->write32 = txgbe_ee_write32;
260 rom->validate_checksum = txgbe_validate_eeprom_checksum;
261 rom->update_checksum = txgbe_update_eeprom_checksum;
262 rom->calc_checksum = txgbe_calc_eeprom_checksum;
268 txgbe_check_flash_load(struct txgbe_hw *hw, u32 check_bit)
273 /* if there's flash existing */
274 if (!(rd32(hw, TXGBE_SPISTAT) & TXGBE_SPISTAT_BPFLASH)) {
275 /* wait hw load flash done */
276 for (i = 0; i < 10; i++) {
277 reg = rd32(hw, TXGBE_ILDRSTAT);
278 if (!(reg & check_bit)) {
285 err = TXGBE_ERR_FLASH_LOADING_FAILED;
291 * txgbe_reset_hw - Perform hardware reset
292 * @hw: pointer to hardware structure
294 * Resets the hardware by resetting the transmit and receive units, masks
295 * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
298 s32 txgbe_reset_hw(struct txgbe_hw *hw)
303 DEBUGFUNC("txgbe_reset_hw");
305 /* Call adapter stop to disable tx/rx and clear interrupts */
306 status = hw->mac.stop_hw(hw);
310 /* flush pending Tx transactions */
311 txgbe_clear_tx_pending(hw);
313 /* Identify PHY and related function pointers */
314 status = hw->phy.init(hw);
315 if (status == TXGBE_ERR_SFP_NOT_SUPPORTED)
318 /* Setup SFP module if there is one present. */
319 if (hw->phy.sfp_setup_needed) {
320 status = hw->mac.setup_sfp(hw);
321 hw->phy.sfp_setup_needed = false;
323 if (status == TXGBE_ERR_SFP_NOT_SUPPORTED)
327 if (!hw->phy.reset_disable)
330 /* remember AUTOC from before we reset */
331 autoc = hw->mac.autoc_read(hw);
335 * Issue global reset to the MAC. Needs to be SW reset if link is up.
336 * If link reset is used when link is up, it might reset the PHY when
337 * mng is using it. If link is down or the flag to force full link
338 * reset is set, then perform link reset.
340 if (txgbe_mng_present(hw)) {
343 wr32(hw, TXGBE_RST, TXGBE_RST_LAN(hw->bus.lan_id));
348 if (hw->bus.lan_id == 0) {
349 status = txgbe_check_flash_load(hw,
350 TXGBE_ILDRSTAT_SWRST_LAN0);
352 status = txgbe_check_flash_load(hw,
353 TXGBE_ILDRSTAT_SWRST_LAN1);
361 * Double resets are required for recovery from certain error
362 * conditions. Between resets, it is necessary to stall to
363 * allow time for any pending HW events to complete.
365 if (hw->mac.flags & TXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
366 hw->mac.flags &= ~TXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
371 * Store the original AUTOC/AUTOC2 values if they have not been
372 * stored off yet. Otherwise restore the stored original
373 * values since the reset operation sets back to defaults.
375 if (!hw->mac.orig_link_settings_stored) {
376 hw->mac.orig_autoc = hw->mac.autoc_read(hw);
377 hw->mac.autoc_write(hw, hw->mac.orig_autoc);
378 hw->mac.orig_link_settings_stored = true;
380 hw->mac.orig_autoc = autoc;
383 /* Store the permanent mac address */
384 hw->mac.get_mac_addr(hw, hw->mac.perm_addr);
387 * Store MAC address from RAR0, clear receive address registers, and
388 * clear the multicast table. Also reset num_rar_entries to 128,
389 * since we modify this value when programming the SAN MAC address.
391 hw->mac.num_rar_entries = 128;
392 hw->mac.init_rx_addrs(hw);
394 /* Store the permanent SAN mac address */
395 hw->mac.get_san_mac_addr(hw, hw->mac.san_addr);
397 /* Add the SAN MAC address to the RAR only if it's a valid address */
398 if (txgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
399 /* Save the SAN MAC RAR index */
400 hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
402 hw->mac.set_rar(hw, hw->mac.san_mac_rar_index,
403 hw->mac.san_addr, 0, true);
405 /* clear VMDq pool/queue selection for this RAR */
406 hw->mac.clear_vmdq(hw, hw->mac.san_mac_rar_index,
409 /* Reserve the last RAR for the SAN MAC address */
410 hw->mac.num_rar_entries--;
413 /* Store the alternative WWNN/WWPN prefix */
414 hw->mac.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
415 &hw->mac.wwpn_prefix);