168eb13a1SJiawen Wu /* SPDX-License-Identifier: BSD-3-Clause 268eb13a1SJiawen Wu * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd. 368eb13a1SJiawen Wu * Copyright(c) 2010-2017 Intel Corporation 468eb13a1SJiawen Wu */ 568eb13a1SJiawen Wu 668eb13a1SJiawen Wu #include "ngbe_type.h" 760229dcfSJiawen Wu #include "ngbe_mbx.h" 844e97550SJiawen Wu #include "ngbe_phy.h" 9f501a195SJiawen Wu #include "ngbe_eeprom.h" 10f501a195SJiawen Wu #include "ngbe_mng.h" 1168eb13a1SJiawen Wu #include "ngbe_hw.h" 12*950820f1SZaiyu Wang #include "ngbe_vf.h" 1368eb13a1SJiawen Wu 1491e64c0eSJiawen Wu static s32 ngbe_is_lldp(struct ngbe_hw *hw) 1591e64c0eSJiawen Wu { 1691e64c0eSJiawen Wu u32 tmp = 0, lldp_flash_data = 0, i; 1791e64c0eSJiawen Wu s32 err = 0; 1891e64c0eSJiawen Wu 1991e64c0eSJiawen Wu if ((hw->eeprom_id & NGBE_FW_MASK) >= NGBE_FW_GET_LLDP) { 2091e64c0eSJiawen Wu err = ngbe_hic_get_lldp(hw); 2191e64c0eSJiawen Wu if (err == 0) 2291e64c0eSJiawen Wu return 0; 2391e64c0eSJiawen Wu } 2491e64c0eSJiawen Wu 2591e64c0eSJiawen Wu for (i = 0; i < 1024; i++) { 2691e64c0eSJiawen Wu err = ngbe_flash_read_dword(hw, NGBE_LLDP_REG + i * 4, &tmp); 2791e64c0eSJiawen Wu if (err) 2891e64c0eSJiawen Wu return err; 2991e64c0eSJiawen Wu 3091e64c0eSJiawen Wu if (tmp == BIT_MASK32) 3191e64c0eSJiawen Wu break; 3291e64c0eSJiawen Wu lldp_flash_data = tmp; 3391e64c0eSJiawen Wu } 3491e64c0eSJiawen Wu 3591e64c0eSJiawen Wu if (lldp_flash_data & MS(hw->bus.lan_id, 1)) 3691e64c0eSJiawen Wu hw->lldp_enabled = true; 3791e64c0eSJiawen Wu else 3891e64c0eSJiawen Wu hw->lldp_enabled = false; 3991e64c0eSJiawen Wu 4091e64c0eSJiawen Wu return 0; 4191e64c0eSJiawen Wu } 4291e64c0eSJiawen Wu 4391e64c0eSJiawen Wu static void ngbe_disable_lldp(struct ngbe_hw *hw) 4491e64c0eSJiawen Wu { 4591e64c0eSJiawen Wu s32 err = 0; 4691e64c0eSJiawen Wu 4791e64c0eSJiawen Wu if ((hw->eeprom_id & NGBE_FW_MASK) < NGBE_FW_SUPPORT_LLDP) 4891e64c0eSJiawen Wu return; 4991e64c0eSJiawen Wu 5091e64c0eSJiawen Wu err = ngbe_is_lldp(hw); 5191e64c0eSJiawen Wu if (err) { 5291e64c0eSJiawen Wu PMD_INIT_LOG(INFO, "Can not get LLDP status."); 5391e64c0eSJiawen Wu } else if (hw->lldp_enabled) { 5491e64c0eSJiawen Wu err = ngbe_hic_set_lldp(hw, false); 5591e64c0eSJiawen Wu if (!err) 5691e64c0eSJiawen Wu PMD_INIT_LOG(INFO, 5791e64c0eSJiawen Wu "LLDP detected on port %d, turn it off by default.", 5891e64c0eSJiawen Wu hw->port_id); 5991e64c0eSJiawen Wu else 6091e64c0eSJiawen Wu PMD_INIT_LOG(INFO, "Can not set LLDP status."); 6191e64c0eSJiawen Wu } 6291e64c0eSJiawen Wu } 6391e64c0eSJiawen Wu 6468eb13a1SJiawen Wu /** 653518df57SJiawen Wu * ngbe_start_hw - Prepare hardware for Tx/Rx 663518df57SJiawen Wu * @hw: pointer to hardware structure 673518df57SJiawen Wu * 683518df57SJiawen Wu * Starts the hardware. 693518df57SJiawen Wu **/ 703518df57SJiawen Wu s32 ngbe_start_hw(struct ngbe_hw *hw) 713518df57SJiawen Wu { 72f40e9f0eSJiawen Wu s32 err; 73f40e9f0eSJiawen Wu 7459b46438SJiawen Wu /* Clear the VLAN filter table */ 7559b46438SJiawen Wu hw->mac.clear_vfta(hw); 7659b46438SJiawen Wu 77fdb1e851SJiawen Wu /* Clear statistics registers */ 78fdb1e851SJiawen Wu hw->mac.clear_hw_cntrs(hw); 79fdb1e851SJiawen Wu 80f40e9f0eSJiawen Wu /* Setup flow control */ 81f40e9f0eSJiawen Wu err = hw->mac.setup_fc(hw); 82f40e9f0eSJiawen Wu if (err != 0 && err != NGBE_NOT_IMPLEMENTED) { 83c811e6a4SJiawen Wu DEBUGOUT("Flow control setup failed, returning %d", err); 84f40e9f0eSJiawen Wu return err; 85f40e9f0eSJiawen Wu } 86f40e9f0eSJiawen Wu 873518df57SJiawen Wu /* Clear adapter stopped flag */ 883518df57SJiawen Wu hw->adapter_stopped = false; 893518df57SJiawen Wu 903518df57SJiawen Wu return 0; 913518df57SJiawen Wu } 923518df57SJiawen Wu 933518df57SJiawen Wu /** 9478710873SJiawen Wu * ngbe_init_hw - Generic hardware initialization 9578710873SJiawen Wu * @hw: pointer to hardware structure 9678710873SJiawen Wu * 9778710873SJiawen Wu * Initialize the hardware by resetting the hardware, filling the bus info 9878710873SJiawen Wu * structure and media type, clears all on chip counters, initializes receive 9978710873SJiawen Wu * address registers, multicast table, VLAN filter table, calls routine to set 10078710873SJiawen Wu * up link and flow control settings, and leaves transmit and receive units 10178710873SJiawen Wu * disabled and uninitialized 10278710873SJiawen Wu **/ 10378710873SJiawen Wu s32 ngbe_init_hw(struct ngbe_hw *hw) 10478710873SJiawen Wu { 10578710873SJiawen Wu s32 status; 10678710873SJiawen Wu 107696a8211SJiawen Wu ngbe_read_efuse(hw); 108506abd4aSJiawen Wu ngbe_save_eeprom_version(hw); 10991e64c0eSJiawen Wu ngbe_disable_lldp(hw); 110506abd4aSJiawen Wu 11178710873SJiawen Wu /* Reset the hardware */ 11278710873SJiawen Wu status = hw->mac.reset_hw(hw); 1133518df57SJiawen Wu if (status == 0) { 1143518df57SJiawen Wu /* Start the HW */ 1153518df57SJiawen Wu status = hw->mac.start_hw(hw); 1163518df57SJiawen Wu } 11778710873SJiawen Wu 11878710873SJiawen Wu if (status != 0) 119c811e6a4SJiawen Wu DEBUGOUT("Failed to initialize HW, STATUS = %d", status); 12078710873SJiawen Wu 12178710873SJiawen Wu return status; 12278710873SJiawen Wu } 12378710873SJiawen Wu 12478710873SJiawen Wu static void 12578710873SJiawen Wu ngbe_reset_misc_em(struct ngbe_hw *hw) 12678710873SJiawen Wu { 12778710873SJiawen Wu int i; 12878710873SJiawen Wu 12978710873SJiawen Wu wr32(hw, NGBE_ISBADDRL, hw->isb_dma & 0xFFFFFFFF); 13078710873SJiawen Wu wr32(hw, NGBE_ISBADDRH, hw->isb_dma >> 32); 13178710873SJiawen Wu 13278710873SJiawen Wu /* receive packets that size > 2048 */ 13378710873SJiawen Wu wr32m(hw, NGBE_MACRXCFG, 13478710873SJiawen Wu NGBE_MACRXCFG_JUMBO, NGBE_MACRXCFG_JUMBO); 13578710873SJiawen Wu 13678710873SJiawen Wu wr32m(hw, NGBE_FRMSZ, NGBE_FRMSZ_MAX_MASK, 13778710873SJiawen Wu NGBE_FRMSZ_MAX(NGBE_FRAME_SIZE_DFT)); 13878710873SJiawen Wu 13978710873SJiawen Wu /* clear counters on read */ 14078710873SJiawen Wu wr32m(hw, NGBE_MACCNTCTL, 14178710873SJiawen Wu NGBE_MACCNTCTL_RC, NGBE_MACCNTCTL_RC); 14278710873SJiawen Wu 14378710873SJiawen Wu wr32m(hw, NGBE_RXFCCFG, 14478710873SJiawen Wu NGBE_RXFCCFG_FC, NGBE_RXFCCFG_FC); 14578710873SJiawen Wu wr32m(hw, NGBE_TXFCCFG, 14678710873SJiawen Wu NGBE_TXFCCFG_FC, NGBE_TXFCCFG_FC); 14778710873SJiawen Wu 14878710873SJiawen Wu wr32m(hw, NGBE_MACRXFLT, 14978710873SJiawen Wu NGBE_MACRXFLT_PROMISC, NGBE_MACRXFLT_PROMISC); 15078710873SJiawen Wu 15178710873SJiawen Wu wr32m(hw, NGBE_RSTSTAT, 15278710873SJiawen Wu NGBE_RSTSTAT_TMRINIT_MASK, NGBE_RSTSTAT_TMRINIT(30)); 15378710873SJiawen Wu 15478710873SJiawen Wu /* errata 4: initialize mng flex tbl and wakeup flex tbl*/ 15578710873SJiawen Wu wr32(hw, NGBE_MNGFLEXSEL, 0); 15678710873SJiawen Wu for (i = 0; i < 16; i++) { 15778710873SJiawen Wu wr32(hw, NGBE_MNGFLEXDWL(i), 0); 15878710873SJiawen Wu wr32(hw, NGBE_MNGFLEXDWH(i), 0); 15978710873SJiawen Wu wr32(hw, NGBE_MNGFLEXMSK(i), 0); 16078710873SJiawen Wu } 16178710873SJiawen Wu wr32(hw, NGBE_LANFLEXSEL, 0); 16278710873SJiawen Wu for (i = 0; i < 16; i++) { 16378710873SJiawen Wu wr32(hw, NGBE_LANFLEXDWL(i), 0); 16478710873SJiawen Wu wr32(hw, NGBE_LANFLEXDWH(i), 0); 16578710873SJiawen Wu wr32(hw, NGBE_LANFLEXMSK(i), 0); 16678710873SJiawen Wu } 16778710873SJiawen Wu 16878710873SJiawen Wu /* set pause frame dst mac addr */ 16978710873SJiawen Wu wr32(hw, NGBE_RXPBPFCDMACL, 0xC2000001); 17078710873SJiawen Wu wr32(hw, NGBE_RXPBPFCDMACH, 0x0180); 17178710873SJiawen Wu 17278710873SJiawen Wu wr32(hw, NGBE_MDIOMODE, 0xF); 17378710873SJiawen Wu 17478710873SJiawen Wu wr32m(hw, NGBE_GPIE, NGBE_GPIE_MSIX, NGBE_GPIE_MSIX); 17578710873SJiawen Wu 1761c44384fSJiawen Wu if (hw->gpio_ctl) { 17778710873SJiawen Wu /* gpio0 is used to power on/off control*/ 17878710873SJiawen Wu wr32(hw, NGBE_GPIODIR, NGBE_GPIODIR_DDR(1)); 17978710873SJiawen Wu wr32(hw, NGBE_GPIODATA, NGBE_GPIOBIT_0); 18078710873SJiawen Wu } 18178710873SJiawen Wu 18278710873SJiawen Wu hw->mac.init_thermal_sensor_thresh(hw); 18378710873SJiawen Wu 18478710873SJiawen Wu /* enable mac transmitter */ 18578710873SJiawen Wu wr32m(hw, NGBE_MACTXCFG, NGBE_MACTXCFG_TE, NGBE_MACTXCFG_TE); 18678710873SJiawen Wu 18778710873SJiawen Wu /* sellect GMII */ 18878710873SJiawen Wu wr32m(hw, NGBE_MACTXCFG, 18978710873SJiawen Wu NGBE_MACTXCFG_SPEED_MASK, NGBE_MACTXCFG_SPEED_1G); 19078710873SJiawen Wu 19178710873SJiawen Wu for (i = 0; i < 4; i++) 19278710873SJiawen Wu wr32m(hw, NGBE_IVAR(i), 0x80808080, 0); 19378710873SJiawen Wu } 19478710873SJiawen Wu 19578710873SJiawen Wu /** 19678710873SJiawen Wu * ngbe_reset_hw_em - Perform hardware reset 19778710873SJiawen Wu * @hw: pointer to hardware structure 19878710873SJiawen Wu * 19978710873SJiawen Wu * Resets the hardware by resetting the transmit and receive units, masks 20078710873SJiawen Wu * and clears all interrupts, perform a PHY reset, and perform a link (MAC) 20178710873SJiawen Wu * reset. 20278710873SJiawen Wu **/ 20378710873SJiawen Wu s32 ngbe_reset_hw_em(struct ngbe_hw *hw) 20478710873SJiawen Wu { 20578710873SJiawen Wu s32 status; 20678710873SJiawen Wu 20778710873SJiawen Wu /* Call adapter stop to disable tx/rx and clear interrupts */ 20878710873SJiawen Wu status = hw->mac.stop_hw(hw); 20978710873SJiawen Wu if (status != 0) 21078710873SJiawen Wu return status; 21178710873SJiawen Wu 21244e97550SJiawen Wu /* Identify PHY and related function pointers */ 21344e97550SJiawen Wu status = ngbe_init_phy(hw); 21444e97550SJiawen Wu if (status) 21544e97550SJiawen Wu return status; 21644e97550SJiawen Wu 21744e97550SJiawen Wu /* Reset PHY */ 21844e97550SJiawen Wu if (!hw->phy.reset_disable) 21944e97550SJiawen Wu hw->phy.reset_hw(hw); 22044e97550SJiawen Wu 22178710873SJiawen Wu wr32(hw, NGBE_RST, NGBE_RST_LAN(hw->bus.lan_id)); 22278710873SJiawen Wu ngbe_flush(hw); 22378710873SJiawen Wu msec_delay(50); 22478710873SJiawen Wu 22578710873SJiawen Wu ngbe_reset_misc_em(hw); 226fdb1e851SJiawen Wu hw->mac.clear_hw_cntrs(hw); 22778710873SJiawen Wu 2285f1ab0d5SJiawen Wu if (!(((hw->sub_device_id & NGBE_OEM_MASK) == NGBE_RGMII_FPGA) || 2295f1ab0d5SJiawen Wu hw->ncsi_enabled || hw->wol_enabled)) 23001d94f0fSJiawen Wu hw->phy.set_phy_power(hw, false); 23101d94f0fSJiawen Wu 23278710873SJiawen Wu msec_delay(50); 23378710873SJiawen Wu 234539d55daSJiawen Wu /* Store the permanent mac address */ 235539d55daSJiawen Wu hw->mac.get_mac_addr(hw, hw->mac.perm_addr); 236539d55daSJiawen Wu 237539d55daSJiawen Wu /* 238539d55daSJiawen Wu * Store MAC address from RAR0, clear receive address registers, and 239539d55daSJiawen Wu * clear the multicast table. 240539d55daSJiawen Wu */ 241539d55daSJiawen Wu hw->mac.num_rar_entries = NGBE_EM_RAR_ENTRIES; 242539d55daSJiawen Wu hw->mac.init_rx_addrs(hw); 243539d55daSJiawen Wu 24478710873SJiawen Wu return status; 24578710873SJiawen Wu } 24678710873SJiawen Wu 24778710873SJiawen Wu /** 248fdb1e851SJiawen Wu * ngbe_clear_hw_cntrs - Generic clear hardware counters 249fdb1e851SJiawen Wu * @hw: pointer to hardware structure 250fdb1e851SJiawen Wu * 251fdb1e851SJiawen Wu * Clears all hardware statistics counters by reading them from the hardware 252fdb1e851SJiawen Wu * Statistics counters are clear on read. 253fdb1e851SJiawen Wu **/ 254fdb1e851SJiawen Wu s32 ngbe_clear_hw_cntrs(struct ngbe_hw *hw) 255fdb1e851SJiawen Wu { 256fdb1e851SJiawen Wu u16 i = 0; 257fdb1e851SJiawen Wu 258fdb1e851SJiawen Wu /* QP Stats */ 259fdb1e851SJiawen Wu /* don't write clear queue stats */ 260fdb1e851SJiawen Wu for (i = 0; i < NGBE_MAX_QP; i++) { 261fdb1e851SJiawen Wu hw->qp_last[i].rx_qp_packets = 0; 262fdb1e851SJiawen Wu hw->qp_last[i].tx_qp_packets = 0; 263fdb1e851SJiawen Wu hw->qp_last[i].rx_qp_bytes = 0; 264fdb1e851SJiawen Wu hw->qp_last[i].tx_qp_bytes = 0; 265fdb1e851SJiawen Wu hw->qp_last[i].rx_qp_mc_packets = 0; 266fdb1e851SJiawen Wu hw->qp_last[i].tx_qp_mc_packets = 0; 267fdb1e851SJiawen Wu hw->qp_last[i].rx_qp_bc_packets = 0; 268fdb1e851SJiawen Wu hw->qp_last[i].tx_qp_bc_packets = 0; 269fdb1e851SJiawen Wu } 270fdb1e851SJiawen Wu 271fdb1e851SJiawen Wu /* PB Stats */ 272fdb1e851SJiawen Wu rd32(hw, NGBE_PBRXLNKXON); 273fdb1e851SJiawen Wu rd32(hw, NGBE_PBRXLNKXOFF); 274fdb1e851SJiawen Wu rd32(hw, NGBE_PBTXLNKXON); 275fdb1e851SJiawen Wu rd32(hw, NGBE_PBTXLNKXOFF); 276fdb1e851SJiawen Wu 277fdb1e851SJiawen Wu /* DMA Stats */ 278fdb1e851SJiawen Wu rd32(hw, NGBE_DMARXPKT); 279fdb1e851SJiawen Wu rd32(hw, NGBE_DMATXPKT); 280fdb1e851SJiawen Wu 281fdb1e851SJiawen Wu rd64(hw, NGBE_DMARXOCTL); 282fdb1e851SJiawen Wu rd64(hw, NGBE_DMATXOCTL); 283fdb1e851SJiawen Wu 284fdb1e851SJiawen Wu /* MAC Stats */ 285fdb1e851SJiawen Wu rd64(hw, NGBE_MACRXERRCRCL); 286fdb1e851SJiawen Wu rd64(hw, NGBE_MACRXMPKTL); 287fdb1e851SJiawen Wu rd64(hw, NGBE_MACTXMPKTL); 288fdb1e851SJiawen Wu 289fdb1e851SJiawen Wu rd64(hw, NGBE_MACRXPKTL); 290fdb1e851SJiawen Wu rd64(hw, NGBE_MACTXPKTL); 291fdb1e851SJiawen Wu rd64(hw, NGBE_MACRXGBOCTL); 292fdb1e851SJiawen Wu 293fdb1e851SJiawen Wu rd64(hw, NGBE_MACRXOCTL); 294fdb1e851SJiawen Wu rd32(hw, NGBE_MACTXOCTL); 295fdb1e851SJiawen Wu 296fdb1e851SJiawen Wu rd64(hw, NGBE_MACRX1TO64L); 297fdb1e851SJiawen Wu rd64(hw, NGBE_MACRX65TO127L); 298fdb1e851SJiawen Wu rd64(hw, NGBE_MACRX128TO255L); 299fdb1e851SJiawen Wu rd64(hw, NGBE_MACRX256TO511L); 300fdb1e851SJiawen Wu rd64(hw, NGBE_MACRX512TO1023L); 301fdb1e851SJiawen Wu rd64(hw, NGBE_MACRX1024TOMAXL); 302fdb1e851SJiawen Wu rd64(hw, NGBE_MACTX1TO64L); 303fdb1e851SJiawen Wu rd64(hw, NGBE_MACTX65TO127L); 304fdb1e851SJiawen Wu rd64(hw, NGBE_MACTX128TO255L); 305fdb1e851SJiawen Wu rd64(hw, NGBE_MACTX256TO511L); 306fdb1e851SJiawen Wu rd64(hw, NGBE_MACTX512TO1023L); 307fdb1e851SJiawen Wu rd64(hw, NGBE_MACTX1024TOMAXL); 308fdb1e851SJiawen Wu 309fdb1e851SJiawen Wu rd64(hw, NGBE_MACRXERRLENL); 310fdb1e851SJiawen Wu rd32(hw, NGBE_MACRXOVERSIZE); 311fdb1e851SJiawen Wu rd32(hw, NGBE_MACRXJABBER); 312fdb1e851SJiawen Wu 313fdb1e851SJiawen Wu /* MACsec Stats */ 314fdb1e851SJiawen Wu rd32(hw, NGBE_LSECTX_UTPKT); 315fdb1e851SJiawen Wu rd32(hw, NGBE_LSECTX_ENCPKT); 316fdb1e851SJiawen Wu rd32(hw, NGBE_LSECTX_PROTPKT); 317fdb1e851SJiawen Wu rd32(hw, NGBE_LSECTX_ENCOCT); 318fdb1e851SJiawen Wu rd32(hw, NGBE_LSECTX_PROTOCT); 319fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_UTPKT); 320fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_BTPKT); 321fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_NOSCIPKT); 322fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_UNSCIPKT); 323fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_DECOCT); 324fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_VLDOCT); 325fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_UNCHKPKT); 326fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_DLYPKT); 327fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_LATEPKT); 328fdb1e851SJiawen Wu for (i = 0; i < 2; i++) { 329fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_OKPKT(i)); 330fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_INVPKT(i)); 331fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_BADPKT(i)); 332fdb1e851SJiawen Wu } 333fdb1e851SJiawen Wu for (i = 0; i < 4; i++) { 334fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_INVSAPKT(i)); 335fdb1e851SJiawen Wu rd32(hw, NGBE_LSECRX_BADSAPKT(i)); 336fdb1e851SJiawen Wu } 337fdb1e851SJiawen Wu 338fdb1e851SJiawen Wu return 0; 339fdb1e851SJiawen Wu } 340fdb1e851SJiawen Wu 341fdb1e851SJiawen Wu /** 342539d55daSJiawen Wu * ngbe_get_mac_addr - Generic get MAC address 343539d55daSJiawen Wu * @hw: pointer to hardware structure 344539d55daSJiawen Wu * @mac_addr: Adapter MAC address 345539d55daSJiawen Wu * 346539d55daSJiawen Wu * Reads the adapter's MAC address from first Receive Address Register (RAR0) 347539d55daSJiawen Wu * A reset of the adapter must be performed prior to calling this function 348539d55daSJiawen Wu * in order for the MAC address to have been loaded from the EEPROM into RAR0 349539d55daSJiawen Wu **/ 350539d55daSJiawen Wu s32 ngbe_get_mac_addr(struct ngbe_hw *hw, u8 *mac_addr) 351539d55daSJiawen Wu { 352539d55daSJiawen Wu u32 rar_high; 353539d55daSJiawen Wu u32 rar_low; 354539d55daSJiawen Wu u16 i; 355539d55daSJiawen Wu 356539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRIDX, 0); 357539d55daSJiawen Wu rar_high = rd32(hw, NGBE_ETHADDRH); 358539d55daSJiawen Wu rar_low = rd32(hw, NGBE_ETHADDRL); 359539d55daSJiawen Wu 360539d55daSJiawen Wu for (i = 0; i < 2; i++) 361539d55daSJiawen Wu mac_addr[i] = (u8)(rar_high >> (1 - i) * 8); 362539d55daSJiawen Wu 363539d55daSJiawen Wu for (i = 0; i < 4; i++) 364539d55daSJiawen Wu mac_addr[i + 2] = (u8)(rar_low >> (3 - i) * 8); 365539d55daSJiawen Wu 366539d55daSJiawen Wu return 0; 367539d55daSJiawen Wu } 368539d55daSJiawen Wu 369539d55daSJiawen Wu /** 37068eb13a1SJiawen Wu * ngbe_set_lan_id_multi_port - Set LAN id for PCIe multiple port devices 37168eb13a1SJiawen Wu * @hw: pointer to the HW structure 37268eb13a1SJiawen Wu * 37368eb13a1SJiawen Wu * Determines the LAN function id by reading memory-mapped registers and swaps 37468eb13a1SJiawen Wu * the port value if requested, and set MAC instance for devices. 37568eb13a1SJiawen Wu **/ 37668eb13a1SJiawen Wu void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw) 37768eb13a1SJiawen Wu { 37868eb13a1SJiawen Wu struct ngbe_bus_info *bus = &hw->bus; 37968eb13a1SJiawen Wu u32 reg = 0; 38068eb13a1SJiawen Wu 38168eb13a1SJiawen Wu reg = rd32(hw, NGBE_PORTSTAT); 38268eb13a1SJiawen Wu bus->lan_id = NGBE_PORTSTAT_ID(reg); 38368eb13a1SJiawen Wu bus->func = bus->lan_id; 38468eb13a1SJiawen Wu } 38568eb13a1SJiawen Wu 38668eb13a1SJiawen Wu /** 38778710873SJiawen Wu * ngbe_stop_hw - Generic stop Tx/Rx units 38878710873SJiawen Wu * @hw: pointer to hardware structure 38978710873SJiawen Wu * 39078710873SJiawen Wu * Sets the adapter_stopped flag within ngbe_hw struct. Clears interrupts, 39178710873SJiawen Wu * disables transmit and receive units. The adapter_stopped flag is used by 39278710873SJiawen Wu * the shared code and drivers to determine if the adapter is in a stopped 39378710873SJiawen Wu * state and should not touch the hardware. 39478710873SJiawen Wu **/ 39578710873SJiawen Wu s32 ngbe_stop_hw(struct ngbe_hw *hw) 39678710873SJiawen Wu { 39778710873SJiawen Wu u16 i; 398ac6c5e9aSJiawen Wu s32 status = 0; 39978710873SJiawen Wu 40078710873SJiawen Wu /* 40178710873SJiawen Wu * Set the adapter_stopped flag so other driver functions stop touching 40278710873SJiawen Wu * the hardware 40378710873SJiawen Wu */ 40478710873SJiawen Wu hw->adapter_stopped = true; 40578710873SJiawen Wu 40678710873SJiawen Wu /* Disable the receive unit */ 40778710873SJiawen Wu ngbe_disable_rx(hw); 40878710873SJiawen Wu 40978710873SJiawen Wu /* Clear interrupt mask to stop interrupts from being generated */ 41078710873SJiawen Wu wr32(hw, NGBE_IENMISC, 0); 41178710873SJiawen Wu wr32(hw, NGBE_IMS(0), NGBE_IMS_MASK); 41278710873SJiawen Wu 41378710873SJiawen Wu /* Clear any pending interrupts, flush previous writes */ 41478710873SJiawen Wu wr32(hw, NGBE_ICRMISC, NGBE_ICRMISC_MASK); 41578710873SJiawen Wu wr32(hw, NGBE_ICR(0), NGBE_ICR_MASK); 41678710873SJiawen Wu 417ac6c5e9aSJiawen Wu wr32(hw, NGBE_BMECTL, 0x3); 41878710873SJiawen Wu 41978710873SJiawen Wu /* Disable the receive unit by stopping each queue */ 420ac6c5e9aSJiawen Wu for (i = 0; i < hw->mac.max_rx_queues; i++) 421ac6c5e9aSJiawen Wu wr32(hw, NGBE_RXCFG(i), 0); 422ac6c5e9aSJiawen Wu 423ac6c5e9aSJiawen Wu /* flush all queues disables */ 424ac6c5e9aSJiawen Wu ngbe_flush(hw); 425ac6c5e9aSJiawen Wu msec_delay(2); 426ac6c5e9aSJiawen Wu 427ac6c5e9aSJiawen Wu /* 428ac6c5e9aSJiawen Wu * Prevent the PCI-E bus from hanging by disabling PCI-E master 429ac6c5e9aSJiawen Wu * access and verify no pending requests 430ac6c5e9aSJiawen Wu */ 431ac6c5e9aSJiawen Wu status = ngbe_set_pcie_master(hw, false); 432ac6c5e9aSJiawen Wu if (status) 433ac6c5e9aSJiawen Wu return status; 434ac6c5e9aSJiawen Wu 435ac6c5e9aSJiawen Wu /* Disable the transmit unit. Each queue must be disabled. */ 436ac6c5e9aSJiawen Wu for (i = 0; i < hw->mac.max_tx_queues; i++) 437ac6c5e9aSJiawen Wu wr32(hw, NGBE_TXCFG(i), 0); 43878710873SJiawen Wu 43978710873SJiawen Wu /* flush all queues disables */ 44078710873SJiawen Wu ngbe_flush(hw); 44178710873SJiawen Wu msec_delay(2); 44278710873SJiawen Wu 44378710873SJiawen Wu return 0; 44478710873SJiawen Wu } 44578710873SJiawen Wu 44678710873SJiawen Wu /** 4474db3db29SJiawen Wu * ngbe_led_on - Turns on the software controllable LEDs. 4484db3db29SJiawen Wu * @hw: pointer to hardware structure 4494db3db29SJiawen Wu * @index: led number to turn on 4504db3db29SJiawen Wu **/ 4514db3db29SJiawen Wu s32 ngbe_led_on(struct ngbe_hw *hw, u32 index) 4524db3db29SJiawen Wu { 4534db3db29SJiawen Wu u32 led_reg = rd32(hw, NGBE_LEDCTL); 4544db3db29SJiawen Wu 4554db3db29SJiawen Wu if (index > 3) 4564db3db29SJiawen Wu return NGBE_ERR_PARAM; 4574db3db29SJiawen Wu 4584db3db29SJiawen Wu /* To turn on the LED, set mode to ON. */ 4594db3db29SJiawen Wu led_reg |= NGBE_LEDCTL_100M; 4604db3db29SJiawen Wu wr32(hw, NGBE_LEDCTL, led_reg); 4614db3db29SJiawen Wu ngbe_flush(hw); 4624db3db29SJiawen Wu 4634db3db29SJiawen Wu return 0; 4644db3db29SJiawen Wu } 4654db3db29SJiawen Wu 4664db3db29SJiawen Wu /** 4674db3db29SJiawen Wu * ngbe_led_off - Turns off the software controllable LEDs. 4684db3db29SJiawen Wu * @hw: pointer to hardware structure 4694db3db29SJiawen Wu * @index: led number to turn off 4704db3db29SJiawen Wu **/ 4714db3db29SJiawen Wu s32 ngbe_led_off(struct ngbe_hw *hw, u32 index) 4724db3db29SJiawen Wu { 4734db3db29SJiawen Wu u32 led_reg = rd32(hw, NGBE_LEDCTL); 4744db3db29SJiawen Wu 4754db3db29SJiawen Wu if (index > 3) 4764db3db29SJiawen Wu return NGBE_ERR_PARAM; 4774db3db29SJiawen Wu 4784db3db29SJiawen Wu /* To turn off the LED, set mode to OFF. */ 4794db3db29SJiawen Wu led_reg &= ~NGBE_LEDCTL_100M; 4804db3db29SJiawen Wu wr32(hw, NGBE_LEDCTL, led_reg); 4814db3db29SJiawen Wu ngbe_flush(hw); 4824db3db29SJiawen Wu 4834db3db29SJiawen Wu return 0; 4844db3db29SJiawen Wu } 4854db3db29SJiawen Wu 4864db3db29SJiawen Wu /** 487539d55daSJiawen Wu * ngbe_validate_mac_addr - Validate MAC address 488539d55daSJiawen Wu * @mac_addr: pointer to MAC address. 489539d55daSJiawen Wu * 490539d55daSJiawen Wu * Tests a MAC address to ensure it is a valid Individual Address. 491539d55daSJiawen Wu **/ 492539d55daSJiawen Wu s32 ngbe_validate_mac_addr(u8 *mac_addr) 493539d55daSJiawen Wu { 494539d55daSJiawen Wu s32 status = 0; 495539d55daSJiawen Wu 496539d55daSJiawen Wu /* Make sure it is not a multicast address */ 497539d55daSJiawen Wu if (NGBE_IS_MULTICAST((struct rte_ether_addr *)mac_addr)) { 498539d55daSJiawen Wu status = NGBE_ERR_INVALID_MAC_ADDR; 499539d55daSJiawen Wu /* Not a broadcast address */ 500539d55daSJiawen Wu } else if (NGBE_IS_BROADCAST((struct rte_ether_addr *)mac_addr)) { 501539d55daSJiawen Wu status = NGBE_ERR_INVALID_MAC_ADDR; 502539d55daSJiawen Wu /* Reject the zero address */ 503539d55daSJiawen Wu } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && 504539d55daSJiawen Wu mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) { 505539d55daSJiawen Wu status = NGBE_ERR_INVALID_MAC_ADDR; 506539d55daSJiawen Wu } 507539d55daSJiawen Wu return status; 508539d55daSJiawen Wu } 509539d55daSJiawen Wu 510539d55daSJiawen Wu /** 511539d55daSJiawen Wu * ngbe_set_rar - Set Rx address register 512539d55daSJiawen Wu * @hw: pointer to hardware structure 513539d55daSJiawen Wu * @index: Receive address register to write 514539d55daSJiawen Wu * @addr: Address to put into receive address register 515539d55daSJiawen Wu * @vmdq: VMDq "set" or "pool" index 516539d55daSJiawen Wu * @enable_addr: set flag that address is active 517539d55daSJiawen Wu * 518539d55daSJiawen Wu * Puts an ethernet address into a receive address register. 519539d55daSJiawen Wu **/ 520539d55daSJiawen Wu s32 ngbe_set_rar(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, 521539d55daSJiawen Wu u32 enable_addr) 522539d55daSJiawen Wu { 523539d55daSJiawen Wu u32 rar_low, rar_high; 524539d55daSJiawen Wu u32 rar_entries = hw->mac.num_rar_entries; 525539d55daSJiawen Wu 526539d55daSJiawen Wu /* Make sure we are using a valid rar index range */ 527539d55daSJiawen Wu if (index >= rar_entries) { 528c811e6a4SJiawen Wu DEBUGOUT("RAR index %d is out of range.", index); 529539d55daSJiawen Wu return NGBE_ERR_INVALID_ARGUMENT; 530539d55daSJiawen Wu } 531539d55daSJiawen Wu 532539d55daSJiawen Wu /* setup VMDq pool selection before this RAR gets enabled */ 533539d55daSJiawen Wu hw->mac.set_vmdq(hw, index, vmdq); 534539d55daSJiawen Wu 535539d55daSJiawen Wu /* 536539d55daSJiawen Wu * HW expects these in little endian so we reverse the byte 537539d55daSJiawen Wu * order from network order (big endian) to little endian 538539d55daSJiawen Wu */ 539539d55daSJiawen Wu rar_low = NGBE_ETHADDRL_AD0(addr[5]) | 540539d55daSJiawen Wu NGBE_ETHADDRL_AD1(addr[4]) | 541539d55daSJiawen Wu NGBE_ETHADDRL_AD2(addr[3]) | 542539d55daSJiawen Wu NGBE_ETHADDRL_AD3(addr[2]); 543539d55daSJiawen Wu /* 544539d55daSJiawen Wu * Some parts put the VMDq setting in the extra RAH bits, 545539d55daSJiawen Wu * so save everything except the lower 16 bits that hold part 546539d55daSJiawen Wu * of the address and the address valid bit. 547539d55daSJiawen Wu */ 548539d55daSJiawen Wu rar_high = rd32(hw, NGBE_ETHADDRH); 549539d55daSJiawen Wu rar_high &= ~NGBE_ETHADDRH_AD_MASK; 550539d55daSJiawen Wu rar_high |= (NGBE_ETHADDRH_AD4(addr[1]) | 551539d55daSJiawen Wu NGBE_ETHADDRH_AD5(addr[0])); 552539d55daSJiawen Wu 553539d55daSJiawen Wu rar_high &= ~NGBE_ETHADDRH_VLD; 554539d55daSJiawen Wu if (enable_addr != 0) 555539d55daSJiawen Wu rar_high |= NGBE_ETHADDRH_VLD; 556539d55daSJiawen Wu 557539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRIDX, index); 558539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRL, rar_low); 559539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRH, rar_high); 560539d55daSJiawen Wu 561539d55daSJiawen Wu return 0; 562539d55daSJiawen Wu } 563539d55daSJiawen Wu 564539d55daSJiawen Wu /** 565539d55daSJiawen Wu * ngbe_clear_rar - Remove Rx address register 566539d55daSJiawen Wu * @hw: pointer to hardware structure 567539d55daSJiawen Wu * @index: Receive address register to write 568539d55daSJiawen Wu * 569539d55daSJiawen Wu * Clears an ethernet address from a receive address register. 570539d55daSJiawen Wu **/ 571539d55daSJiawen Wu s32 ngbe_clear_rar(struct ngbe_hw *hw, u32 index) 572539d55daSJiawen Wu { 573539d55daSJiawen Wu u32 rar_high; 574539d55daSJiawen Wu u32 rar_entries = hw->mac.num_rar_entries; 575539d55daSJiawen Wu 576539d55daSJiawen Wu /* Make sure we are using a valid rar index range */ 577539d55daSJiawen Wu if (index >= rar_entries) { 578c811e6a4SJiawen Wu DEBUGOUT("RAR index %d is out of range.", index); 579539d55daSJiawen Wu return NGBE_ERR_INVALID_ARGUMENT; 580539d55daSJiawen Wu } 581539d55daSJiawen Wu 582539d55daSJiawen Wu /* 583539d55daSJiawen Wu * Some parts put the VMDq setting in the extra RAH bits, 584539d55daSJiawen Wu * so save everything except the lower 16 bits that hold part 585539d55daSJiawen Wu * of the address and the address valid bit. 586539d55daSJiawen Wu */ 587539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRIDX, index); 588539d55daSJiawen Wu rar_high = rd32(hw, NGBE_ETHADDRH); 589539d55daSJiawen Wu rar_high &= ~(NGBE_ETHADDRH_AD_MASK | NGBE_ETHADDRH_VLD); 590539d55daSJiawen Wu 591539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRL, 0); 592539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRH, rar_high); 593539d55daSJiawen Wu 594539d55daSJiawen Wu /* clear VMDq pool/queue selection for this RAR */ 595539d55daSJiawen Wu hw->mac.clear_vmdq(hw, index, BIT_MASK32); 596539d55daSJiawen Wu 597539d55daSJiawen Wu return 0; 598539d55daSJiawen Wu } 599539d55daSJiawen Wu 600539d55daSJiawen Wu /** 601539d55daSJiawen Wu * ngbe_init_rx_addrs - Initializes receive address filters. 602539d55daSJiawen Wu * @hw: pointer to hardware structure 603539d55daSJiawen Wu * 604539d55daSJiawen Wu * Places the MAC address in receive address register 0 and clears the rest 605539d55daSJiawen Wu * of the receive address registers. Clears the multicast table. Assumes 606539d55daSJiawen Wu * the receiver is in reset when the routine is called. 607539d55daSJiawen Wu **/ 608539d55daSJiawen Wu s32 ngbe_init_rx_addrs(struct ngbe_hw *hw) 609539d55daSJiawen Wu { 610539d55daSJiawen Wu u32 i; 611539d55daSJiawen Wu u32 psrctl; 612539d55daSJiawen Wu u32 rar_entries = hw->mac.num_rar_entries; 613539d55daSJiawen Wu 614539d55daSJiawen Wu /* 615539d55daSJiawen Wu * If the current mac address is valid, assume it is a software override 616539d55daSJiawen Wu * to the permanent address. 617539d55daSJiawen Wu * Otherwise, use the permanent address from the eeprom. 618539d55daSJiawen Wu */ 619539d55daSJiawen Wu if (ngbe_validate_mac_addr(hw->mac.addr) == 620539d55daSJiawen Wu NGBE_ERR_INVALID_MAC_ADDR) { 621539d55daSJiawen Wu /* Get the MAC address from the RAR0 for later reference */ 622539d55daSJiawen Wu hw->mac.get_mac_addr(hw, hw->mac.addr); 623539d55daSJiawen Wu 624c811e6a4SJiawen Wu DEBUGOUT(" Keeping Current RAR0 Addr = " 625c811e6a4SJiawen Wu RTE_ETHER_ADDR_PRT_FMT, 626539d55daSJiawen Wu hw->mac.addr[0], hw->mac.addr[1], 627c811e6a4SJiawen Wu hw->mac.addr[2], hw->mac.addr[3], 628539d55daSJiawen Wu hw->mac.addr[4], hw->mac.addr[5]); 629539d55daSJiawen Wu } else { 630539d55daSJiawen Wu /* Setup the receive address. */ 631c811e6a4SJiawen Wu DEBUGOUT("Overriding MAC Address in RAR[0]"); 632c811e6a4SJiawen Wu DEBUGOUT(" New MAC Addr = " 633c811e6a4SJiawen Wu RTE_ETHER_ADDR_PRT_FMT, 634539d55daSJiawen Wu hw->mac.addr[0], hw->mac.addr[1], 635c811e6a4SJiawen Wu hw->mac.addr[2], hw->mac.addr[3], 636539d55daSJiawen Wu hw->mac.addr[4], hw->mac.addr[5]); 637539d55daSJiawen Wu 638539d55daSJiawen Wu hw->mac.set_rar(hw, 0, hw->mac.addr, 0, true); 639539d55daSJiawen Wu } 640539d55daSJiawen Wu 641539d55daSJiawen Wu /* clear VMDq pool/queue selection for RAR 0 */ 642539d55daSJiawen Wu hw->mac.clear_vmdq(hw, 0, BIT_MASK32); 643539d55daSJiawen Wu 644539d55daSJiawen Wu /* Zero out the other receive addresses. */ 645c811e6a4SJiawen Wu DEBUGOUT("Clearing RAR[1-%d]", rar_entries - 1); 646539d55daSJiawen Wu for (i = 1; i < rar_entries; i++) { 647539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRIDX, i); 648539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRL, 0); 649539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRH, 0); 650539d55daSJiawen Wu } 651539d55daSJiawen Wu 652539d55daSJiawen Wu /* Clear the MTA */ 653539d55daSJiawen Wu hw->addr_ctrl.mta_in_use = 0; 654539d55daSJiawen Wu psrctl = rd32(hw, NGBE_PSRCTL); 655539d55daSJiawen Wu psrctl &= ~(NGBE_PSRCTL_ADHF12_MASK | NGBE_PSRCTL_MCHFENA); 656539d55daSJiawen Wu psrctl |= NGBE_PSRCTL_ADHF12(hw->mac.mc_filter_type); 657539d55daSJiawen Wu wr32(hw, NGBE_PSRCTL, psrctl); 658539d55daSJiawen Wu 659c811e6a4SJiawen Wu DEBUGOUT(" Clearing MTA"); 660539d55daSJiawen Wu for (i = 0; i < hw->mac.mcft_size; i++) 661539d55daSJiawen Wu wr32(hw, NGBE_MCADDRTBL(i), 0); 662539d55daSJiawen Wu 663539d55daSJiawen Wu ngbe_init_uta_tables(hw); 664539d55daSJiawen Wu 665539d55daSJiawen Wu return 0; 666539d55daSJiawen Wu } 667539d55daSJiawen Wu 668539d55daSJiawen Wu /** 669dee93977SJiawen Wu * ngbe_mta_vector - Determines bit-vector in multicast table to set 670dee93977SJiawen Wu * @hw: pointer to hardware structure 671dee93977SJiawen Wu * @mc_addr: the multicast address 672dee93977SJiawen Wu * 673dee93977SJiawen Wu * Extracts the 12 bits, from a multicast address, to determine which 674dee93977SJiawen Wu * bit-vector to set in the multicast table. The hardware uses 12 bits, from 675dee93977SJiawen Wu * incoming rx multicast addresses, to determine the bit-vector to check in 676dee93977SJiawen Wu * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set 677dee93977SJiawen Wu * by the MO field of the PSRCTRL. The MO field is set during initialization 678dee93977SJiawen Wu * to mc_filter_type. 679dee93977SJiawen Wu **/ 680dee93977SJiawen Wu static s32 ngbe_mta_vector(struct ngbe_hw *hw, u8 *mc_addr) 681dee93977SJiawen Wu { 682dee93977SJiawen Wu u32 vector = 0; 683dee93977SJiawen Wu 684dee93977SJiawen Wu switch (hw->mac.mc_filter_type) { 685dee93977SJiawen Wu case 0: /* use bits [47:36] of the address */ 686dee93977SJiawen Wu vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); 687dee93977SJiawen Wu break; 688dee93977SJiawen Wu case 1: /* use bits [46:35] of the address */ 689dee93977SJiawen Wu vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); 690dee93977SJiawen Wu break; 691dee93977SJiawen Wu case 2: /* use bits [45:34] of the address */ 692dee93977SJiawen Wu vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); 693dee93977SJiawen Wu break; 694dee93977SJiawen Wu case 3: /* use bits [43:32] of the address */ 695dee93977SJiawen Wu vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); 696dee93977SJiawen Wu break; 697dee93977SJiawen Wu default: /* Invalid mc_filter_type */ 698c811e6a4SJiawen Wu DEBUGOUT("MC filter type param set incorrectly"); 699dee93977SJiawen Wu ASSERT(0); 700dee93977SJiawen Wu break; 701dee93977SJiawen Wu } 702dee93977SJiawen Wu 703dee93977SJiawen Wu /* vector can only be 12-bits or boundary will be exceeded */ 704dee93977SJiawen Wu vector &= 0xFFF; 705dee93977SJiawen Wu return vector; 706dee93977SJiawen Wu } 707dee93977SJiawen Wu 708dee93977SJiawen Wu /** 709dee93977SJiawen Wu * ngbe_set_mta - Set bit-vector in multicast table 710dee93977SJiawen Wu * @hw: pointer to hardware structure 711dee93977SJiawen Wu * @mc_addr: Multicast address 712dee93977SJiawen Wu * 713dee93977SJiawen Wu * Sets the bit-vector in the multicast table. 714dee93977SJiawen Wu **/ 715dee93977SJiawen Wu void ngbe_set_mta(struct ngbe_hw *hw, u8 *mc_addr) 716dee93977SJiawen Wu { 717dee93977SJiawen Wu u32 vector; 718dee93977SJiawen Wu u32 vector_bit; 719dee93977SJiawen Wu u32 vector_reg; 720dee93977SJiawen Wu 721dee93977SJiawen Wu hw->addr_ctrl.mta_in_use++; 722dee93977SJiawen Wu 723dee93977SJiawen Wu vector = ngbe_mta_vector(hw, mc_addr); 724c811e6a4SJiawen Wu DEBUGOUT(" bit-vector = 0x%03X", vector); 725dee93977SJiawen Wu 726dee93977SJiawen Wu /* 727dee93977SJiawen Wu * The MTA is a register array of 128 32-bit registers. It is treated 728dee93977SJiawen Wu * like an array of 4096 bits. We want to set bit 729dee93977SJiawen Wu * BitArray[vector_value]. So we figure out what register the bit is 730dee93977SJiawen Wu * in, read it, OR in the new bit, then write back the new value. The 731dee93977SJiawen Wu * register is determined by the upper 7 bits of the vector value and 732dee93977SJiawen Wu * the bit within that register are determined by the lower 5 bits of 733dee93977SJiawen Wu * the value. 734dee93977SJiawen Wu */ 735dee93977SJiawen Wu vector_reg = (vector >> 5) & 0x7F; 736dee93977SJiawen Wu vector_bit = vector & 0x1F; 737dee93977SJiawen Wu hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit); 738dee93977SJiawen Wu } 739dee93977SJiawen Wu 740dee93977SJiawen Wu /** 741dee93977SJiawen Wu * ngbe_update_mc_addr_list - Updates MAC list of multicast addresses 742dee93977SJiawen Wu * @hw: pointer to hardware structure 743dee93977SJiawen Wu * @mc_addr_list: the list of new multicast addresses 744dee93977SJiawen Wu * @mc_addr_count: number of addresses 745dee93977SJiawen Wu * @next: iterator function to walk the multicast address list 746dee93977SJiawen Wu * @clear: flag, when set clears the table beforehand 747dee93977SJiawen Wu * 748dee93977SJiawen Wu * When the clear flag is set, the given list replaces any existing list. 749dee93977SJiawen Wu * Hashes the given addresses into the multicast table. 750dee93977SJiawen Wu **/ 751dee93977SJiawen Wu s32 ngbe_update_mc_addr_list(struct ngbe_hw *hw, u8 *mc_addr_list, 752dee93977SJiawen Wu u32 mc_addr_count, ngbe_mc_addr_itr next, 753dee93977SJiawen Wu bool clear) 754dee93977SJiawen Wu { 755dee93977SJiawen Wu u32 i; 756dee93977SJiawen Wu u32 vmdq; 757dee93977SJiawen Wu 758dee93977SJiawen Wu /* 759dee93977SJiawen Wu * Set the new number of MC addresses that we are being requested to 760dee93977SJiawen Wu * use. 761dee93977SJiawen Wu */ 762dee93977SJiawen Wu hw->addr_ctrl.num_mc_addrs = mc_addr_count; 763dee93977SJiawen Wu hw->addr_ctrl.mta_in_use = 0; 764dee93977SJiawen Wu 765dee93977SJiawen Wu /* Clear mta_shadow */ 766dee93977SJiawen Wu if (clear) { 767c811e6a4SJiawen Wu DEBUGOUT(" Clearing MTA"); 768dee93977SJiawen Wu memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); 769dee93977SJiawen Wu } 770dee93977SJiawen Wu 771dee93977SJiawen Wu /* Update mta_shadow */ 772dee93977SJiawen Wu for (i = 0; i < mc_addr_count; i++) { 773c811e6a4SJiawen Wu DEBUGOUT(" Adding the multicast addresses:"); 774dee93977SJiawen Wu ngbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq)); 775dee93977SJiawen Wu } 776dee93977SJiawen Wu 777dee93977SJiawen Wu /* Enable mta */ 778dee93977SJiawen Wu for (i = 0; i < hw->mac.mcft_size; i++) 779dee93977SJiawen Wu wr32a(hw, NGBE_MCADDRTBL(0), i, 780dee93977SJiawen Wu hw->mac.mta_shadow[i]); 781dee93977SJiawen Wu 782dee93977SJiawen Wu if (hw->addr_ctrl.mta_in_use > 0) { 783dee93977SJiawen Wu u32 psrctl = rd32(hw, NGBE_PSRCTL); 784dee93977SJiawen Wu psrctl &= ~(NGBE_PSRCTL_ADHF12_MASK | NGBE_PSRCTL_MCHFENA); 785dee93977SJiawen Wu psrctl |= NGBE_PSRCTL_MCHFENA | 786dee93977SJiawen Wu NGBE_PSRCTL_ADHF12(hw->mac.mc_filter_type); 787dee93977SJiawen Wu wr32(hw, NGBE_PSRCTL, psrctl); 788dee93977SJiawen Wu } 789dee93977SJiawen Wu 790c811e6a4SJiawen Wu DEBUGOUT("ngbe update mc addr list complete"); 791dee93977SJiawen Wu return 0; 792dee93977SJiawen Wu } 793dee93977SJiawen Wu 794dee93977SJiawen Wu /** 795f40e9f0eSJiawen Wu * ngbe_setup_fc_em - Set up flow control 796f40e9f0eSJiawen Wu * @hw: pointer to hardware structure 797f40e9f0eSJiawen Wu * 798f40e9f0eSJiawen Wu * Called at init time to set up flow control. 799f40e9f0eSJiawen Wu **/ 800f40e9f0eSJiawen Wu s32 ngbe_setup_fc_em(struct ngbe_hw *hw) 801f40e9f0eSJiawen Wu { 802f40e9f0eSJiawen Wu s32 err = 0; 803f40e9f0eSJiawen Wu u16 reg_cu = 0; 804f40e9f0eSJiawen Wu 805f40e9f0eSJiawen Wu /* Validate the requested mode */ 806f40e9f0eSJiawen Wu if (hw->fc.strict_ieee && hw->fc.requested_mode == ngbe_fc_rx_pause) { 807c811e6a4SJiawen Wu DEBUGOUT("ngbe_fc_rx_pause not valid in strict IEEE mode"); 808f40e9f0eSJiawen Wu err = NGBE_ERR_INVALID_LINK_SETTINGS; 809f40e9f0eSJiawen Wu goto out; 810f40e9f0eSJiawen Wu } 811f40e9f0eSJiawen Wu 812f40e9f0eSJiawen Wu /* 813f40e9f0eSJiawen Wu * 1gig parts do not have a word in the EEPROM to determine the 814f40e9f0eSJiawen Wu * default flow control setting, so we explicitly set it to full. 815f40e9f0eSJiawen Wu */ 816f40e9f0eSJiawen Wu if (hw->fc.requested_mode == ngbe_fc_default) 817f40e9f0eSJiawen Wu hw->fc.requested_mode = ngbe_fc_full; 818f40e9f0eSJiawen Wu 819f40e9f0eSJiawen Wu /* 820f40e9f0eSJiawen Wu * The possible values of fc.requested_mode are: 821f40e9f0eSJiawen Wu * 0: Flow control is completely disabled 822f40e9f0eSJiawen Wu * 1: Rx flow control is enabled (we can receive pause frames, 823f40e9f0eSJiawen Wu * but not send pause frames). 824f40e9f0eSJiawen Wu * 2: Tx flow control is enabled (we can send pause frames but 825f40e9f0eSJiawen Wu * we do not support receiving pause frames). 826f40e9f0eSJiawen Wu * 3: Both Rx and Tx flow control (symmetric) are enabled. 827f40e9f0eSJiawen Wu * other: Invalid. 828f40e9f0eSJiawen Wu */ 829f40e9f0eSJiawen Wu switch (hw->fc.requested_mode) { 830f40e9f0eSJiawen Wu case ngbe_fc_none: 831f40e9f0eSJiawen Wu /* Flow control completely disabled by software override. */ 832f40e9f0eSJiawen Wu break; 833f40e9f0eSJiawen Wu case ngbe_fc_tx_pause: 834f40e9f0eSJiawen Wu /* 835f40e9f0eSJiawen Wu * Tx Flow control is enabled, and Rx Flow control is 836f40e9f0eSJiawen Wu * disabled by software override. 837f40e9f0eSJiawen Wu */ 838f40e9f0eSJiawen Wu if (hw->phy.type == ngbe_phy_mvl_sfi || 839f40e9f0eSJiawen Wu hw->phy.type == ngbe_phy_yt8521s_sfi) 840f40e9f0eSJiawen Wu reg_cu |= MVL_FANA_ASM_PAUSE; 841f40e9f0eSJiawen Wu else 842f40e9f0eSJiawen Wu reg_cu |= 0x800; /*need to merge rtl and mvl on page 0*/ 843f40e9f0eSJiawen Wu break; 844f40e9f0eSJiawen Wu case ngbe_fc_rx_pause: 845f40e9f0eSJiawen Wu /* 846f40e9f0eSJiawen Wu * Rx Flow control is enabled and Tx Flow control is 847f40e9f0eSJiawen Wu * disabled by software override. Since there really 848f40e9f0eSJiawen Wu * isn't a way to advertise that we are capable of RX 849f40e9f0eSJiawen Wu * Pause ONLY, we will advertise that we support both 850f40e9f0eSJiawen Wu * symmetric and asymmetric Rx PAUSE, as such we fall 851f40e9f0eSJiawen Wu * through to the fc_full statement. Later, we will 852f40e9f0eSJiawen Wu * disable the adapter's ability to send PAUSE frames. 853f40e9f0eSJiawen Wu */ 854f40e9f0eSJiawen Wu case ngbe_fc_full: 855f40e9f0eSJiawen Wu /* Flow control (both Rx and Tx) is enabled by SW override. */ 856f40e9f0eSJiawen Wu if (hw->phy.type == ngbe_phy_mvl_sfi || 857f40e9f0eSJiawen Wu hw->phy.type == ngbe_phy_yt8521s_sfi) 858f40e9f0eSJiawen Wu reg_cu |= MVL_FANA_SYM_PAUSE; 859f40e9f0eSJiawen Wu else 860f40e9f0eSJiawen Wu reg_cu |= 0xC00; /*need to merge rtl and mvl on page 0*/ 861f40e9f0eSJiawen Wu break; 862f40e9f0eSJiawen Wu default: 863c811e6a4SJiawen Wu DEBUGOUT("Flow control param set incorrectly"); 864f40e9f0eSJiawen Wu err = NGBE_ERR_CONFIG; 865f40e9f0eSJiawen Wu goto out; 866f40e9f0eSJiawen Wu } 867f40e9f0eSJiawen Wu 868f40e9f0eSJiawen Wu err = hw->phy.set_pause_adv(hw, reg_cu); 869f40e9f0eSJiawen Wu 870f40e9f0eSJiawen Wu out: 871f40e9f0eSJiawen Wu return err; 872f40e9f0eSJiawen Wu } 873f40e9f0eSJiawen Wu 874f40e9f0eSJiawen Wu /** 875f40e9f0eSJiawen Wu * ngbe_fc_enable - Enable flow control 876f40e9f0eSJiawen Wu * @hw: pointer to hardware structure 877f40e9f0eSJiawen Wu * 878f40e9f0eSJiawen Wu * Enable flow control according to the current settings. 879f40e9f0eSJiawen Wu **/ 880f40e9f0eSJiawen Wu s32 ngbe_fc_enable(struct ngbe_hw *hw) 881f40e9f0eSJiawen Wu { 882f40e9f0eSJiawen Wu s32 err = 0; 883f40e9f0eSJiawen Wu u32 mflcn_reg, fccfg_reg; 884f40e9f0eSJiawen Wu u32 pause_time; 885f40e9f0eSJiawen Wu u32 fcrtl, fcrth; 886f40e9f0eSJiawen Wu 887f40e9f0eSJiawen Wu /* Validate the water mark configuration */ 888f40e9f0eSJiawen Wu if (!hw->fc.pause_time) { 889f40e9f0eSJiawen Wu err = NGBE_ERR_INVALID_LINK_SETTINGS; 890f40e9f0eSJiawen Wu goto out; 891f40e9f0eSJiawen Wu } 892f40e9f0eSJiawen Wu 893f40e9f0eSJiawen Wu /* Low water mark of zero causes XOFF floods */ 894f40e9f0eSJiawen Wu if ((hw->fc.current_mode & ngbe_fc_tx_pause) && hw->fc.high_water) { 895f40e9f0eSJiawen Wu if (!hw->fc.low_water || 896f40e9f0eSJiawen Wu hw->fc.low_water >= hw->fc.high_water) { 897c811e6a4SJiawen Wu DEBUGOUT("Invalid water mark configuration"); 898f40e9f0eSJiawen Wu err = NGBE_ERR_INVALID_LINK_SETTINGS; 899f40e9f0eSJiawen Wu goto out; 900f40e9f0eSJiawen Wu } 901f40e9f0eSJiawen Wu } 902f40e9f0eSJiawen Wu 903f40e9f0eSJiawen Wu /* Negotiate the fc mode to use */ 904f40e9f0eSJiawen Wu hw->mac.fc_autoneg(hw); 905f40e9f0eSJiawen Wu 906f40e9f0eSJiawen Wu /* Disable any previous flow control settings */ 907f40e9f0eSJiawen Wu mflcn_reg = rd32(hw, NGBE_RXFCCFG); 908f40e9f0eSJiawen Wu mflcn_reg &= ~NGBE_RXFCCFG_FC; 909f40e9f0eSJiawen Wu 910f40e9f0eSJiawen Wu fccfg_reg = rd32(hw, NGBE_TXFCCFG); 911f40e9f0eSJiawen Wu fccfg_reg &= ~NGBE_TXFCCFG_FC; 912f40e9f0eSJiawen Wu /* 913f40e9f0eSJiawen Wu * The possible values of fc.current_mode are: 914f40e9f0eSJiawen Wu * 0: Flow control is completely disabled 915f40e9f0eSJiawen Wu * 1: Rx flow control is enabled (we can receive pause frames, 916f40e9f0eSJiawen Wu * but not send pause frames). 917f40e9f0eSJiawen Wu * 2: Tx flow control is enabled (we can send pause frames but 918f40e9f0eSJiawen Wu * we do not support receiving pause frames). 919f40e9f0eSJiawen Wu * 3: Both Rx and Tx flow control (symmetric) are enabled. 920f40e9f0eSJiawen Wu * other: Invalid. 921f40e9f0eSJiawen Wu */ 922f40e9f0eSJiawen Wu switch (hw->fc.current_mode) { 923f40e9f0eSJiawen Wu case ngbe_fc_none: 924f40e9f0eSJiawen Wu /* 925f40e9f0eSJiawen Wu * Flow control is disabled by software override or autoneg. 926f40e9f0eSJiawen Wu * The code below will actually disable it in the HW. 927f40e9f0eSJiawen Wu */ 928f40e9f0eSJiawen Wu break; 929f40e9f0eSJiawen Wu case ngbe_fc_rx_pause: 930f40e9f0eSJiawen Wu /* 931f40e9f0eSJiawen Wu * Rx Flow control is enabled and Tx Flow control is 932f40e9f0eSJiawen Wu * disabled by software override. Since there really 933f40e9f0eSJiawen Wu * isn't a way to advertise that we are capable of RX 934f40e9f0eSJiawen Wu * Pause ONLY, we will advertise that we support both 935f40e9f0eSJiawen Wu * symmetric and asymmetric Rx PAUSE. Later, we will 936f40e9f0eSJiawen Wu * disable the adapter's ability to send PAUSE frames. 937f40e9f0eSJiawen Wu */ 938f40e9f0eSJiawen Wu mflcn_reg |= NGBE_RXFCCFG_FC; 939f40e9f0eSJiawen Wu break; 940f40e9f0eSJiawen Wu case ngbe_fc_tx_pause: 941f40e9f0eSJiawen Wu /* 942f40e9f0eSJiawen Wu * Tx Flow control is enabled, and Rx Flow control is 943f40e9f0eSJiawen Wu * disabled by software override. 944f40e9f0eSJiawen Wu */ 945f40e9f0eSJiawen Wu fccfg_reg |= NGBE_TXFCCFG_FC; 946f40e9f0eSJiawen Wu break; 947f40e9f0eSJiawen Wu case ngbe_fc_full: 948f40e9f0eSJiawen Wu /* Flow control (both Rx and Tx) is enabled by SW override. */ 949f40e9f0eSJiawen Wu mflcn_reg |= NGBE_RXFCCFG_FC; 950f40e9f0eSJiawen Wu fccfg_reg |= NGBE_TXFCCFG_FC; 951f40e9f0eSJiawen Wu break; 952f40e9f0eSJiawen Wu default: 953c811e6a4SJiawen Wu DEBUGOUT("Flow control param set incorrectly"); 954f40e9f0eSJiawen Wu err = NGBE_ERR_CONFIG; 955f40e9f0eSJiawen Wu goto out; 956f40e9f0eSJiawen Wu } 957f40e9f0eSJiawen Wu 958f40e9f0eSJiawen Wu /* Set 802.3x based flow control settings. */ 959f40e9f0eSJiawen Wu wr32(hw, NGBE_RXFCCFG, mflcn_reg); 960f40e9f0eSJiawen Wu wr32(hw, NGBE_TXFCCFG, fccfg_reg); 961f40e9f0eSJiawen Wu 962f40e9f0eSJiawen Wu /* Set up and enable Rx high/low water mark thresholds, enable XON. */ 963f40e9f0eSJiawen Wu if ((hw->fc.current_mode & ngbe_fc_tx_pause) && 964f40e9f0eSJiawen Wu hw->fc.high_water) { 965f40e9f0eSJiawen Wu fcrtl = NGBE_FCWTRLO_TH(hw->fc.low_water) | 966f40e9f0eSJiawen Wu NGBE_FCWTRLO_XON; 967f40e9f0eSJiawen Wu fcrth = NGBE_FCWTRHI_TH(hw->fc.high_water) | 968f40e9f0eSJiawen Wu NGBE_FCWTRHI_XOFF; 969f40e9f0eSJiawen Wu } else { 970f40e9f0eSJiawen Wu /* 971f40e9f0eSJiawen Wu * In order to prevent Tx hangs when the internal Tx 972f40e9f0eSJiawen Wu * switch is enabled we must set the high water mark 973f40e9f0eSJiawen Wu * to the Rx packet buffer size - 24KB. This allows 974f40e9f0eSJiawen Wu * the Tx switch to function even under heavy Rx 975f40e9f0eSJiawen Wu * workloads. 976f40e9f0eSJiawen Wu */ 977f40e9f0eSJiawen Wu fcrtl = 0; 978f40e9f0eSJiawen Wu fcrth = rd32(hw, NGBE_PBRXSIZE) - 24576; 979f40e9f0eSJiawen Wu } 980f40e9f0eSJiawen Wu wr32(hw, NGBE_FCWTRLO, fcrtl); 981f40e9f0eSJiawen Wu wr32(hw, NGBE_FCWTRHI, fcrth); 982f40e9f0eSJiawen Wu 983f40e9f0eSJiawen Wu /* Configure pause time */ 984f40e9f0eSJiawen Wu pause_time = NGBE_RXFCFSH_TIME(hw->fc.pause_time); 985f40e9f0eSJiawen Wu wr32(hw, NGBE_FCXOFFTM, pause_time * 0x00010000); 986f40e9f0eSJiawen Wu 987f40e9f0eSJiawen Wu /* Configure flow control refresh threshold value */ 988f40e9f0eSJiawen Wu wr32(hw, NGBE_RXFCRFSH, hw->fc.pause_time / 2); 989f40e9f0eSJiawen Wu 990f40e9f0eSJiawen Wu out: 991f40e9f0eSJiawen Wu return err; 992f40e9f0eSJiawen Wu } 993f40e9f0eSJiawen Wu 994f40e9f0eSJiawen Wu /** 995f40e9f0eSJiawen Wu * ngbe_negotiate_fc - Negotiate flow control 996f40e9f0eSJiawen Wu * @hw: pointer to hardware structure 997f40e9f0eSJiawen Wu * @adv_reg: flow control advertised settings 998f40e9f0eSJiawen Wu * @lp_reg: link partner's flow control settings 999f40e9f0eSJiawen Wu * @adv_sym: symmetric pause bit in advertisement 1000f40e9f0eSJiawen Wu * @adv_asm: asymmetric pause bit in advertisement 1001f40e9f0eSJiawen Wu * @lp_sym: symmetric pause bit in link partner advertisement 1002f40e9f0eSJiawen Wu * @lp_asm: asymmetric pause bit in link partner advertisement 1003f40e9f0eSJiawen Wu * 1004f40e9f0eSJiawen Wu * Find the intersection between advertised settings and link partner's 1005f40e9f0eSJiawen Wu * advertised settings 1006f40e9f0eSJiawen Wu **/ 1007f40e9f0eSJiawen Wu s32 ngbe_negotiate_fc(struct ngbe_hw *hw, u32 adv_reg, u32 lp_reg, 1008f40e9f0eSJiawen Wu u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) 1009f40e9f0eSJiawen Wu { 1010f40e9f0eSJiawen Wu if ((!(adv_reg)) || (!(lp_reg))) { 1011c811e6a4SJiawen Wu DEBUGOUT("Local or link partner's advertised flow control settings are NULL. Local: %x, link partner: %x", 1012f40e9f0eSJiawen Wu adv_reg, lp_reg); 1013f40e9f0eSJiawen Wu return NGBE_ERR_FC_NOT_NEGOTIATED; 1014f40e9f0eSJiawen Wu } 1015f40e9f0eSJiawen Wu 1016f40e9f0eSJiawen Wu if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { 1017f40e9f0eSJiawen Wu /* 1018f40e9f0eSJiawen Wu * Now we need to check if the user selected Rx ONLY 1019f40e9f0eSJiawen Wu * of pause frames. In this case, we had to advertise 1020f40e9f0eSJiawen Wu * FULL flow control because we could not advertise RX 1021f40e9f0eSJiawen Wu * ONLY. Hence, we must now check to see if we need to 1022f40e9f0eSJiawen Wu * turn OFF the TRANSMISSION of PAUSE frames. 1023f40e9f0eSJiawen Wu */ 1024f40e9f0eSJiawen Wu if (hw->fc.requested_mode == ngbe_fc_full) { 1025f40e9f0eSJiawen Wu hw->fc.current_mode = ngbe_fc_full; 1026c811e6a4SJiawen Wu DEBUGOUT("Flow Control = FULL."); 1027f40e9f0eSJiawen Wu } else { 1028f40e9f0eSJiawen Wu hw->fc.current_mode = ngbe_fc_rx_pause; 1029c811e6a4SJiawen Wu DEBUGOUT("Flow Control=RX PAUSE frames only"); 1030f40e9f0eSJiawen Wu } 1031f40e9f0eSJiawen Wu } else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) && 1032f40e9f0eSJiawen Wu (lp_reg & lp_sym) && (lp_reg & lp_asm)) { 1033f40e9f0eSJiawen Wu hw->fc.current_mode = ngbe_fc_tx_pause; 1034c811e6a4SJiawen Wu DEBUGOUT("Flow Control = TX PAUSE frames only."); 1035f40e9f0eSJiawen Wu } else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) && 1036f40e9f0eSJiawen Wu !(lp_reg & lp_sym) && (lp_reg & lp_asm)) { 1037f40e9f0eSJiawen Wu hw->fc.current_mode = ngbe_fc_rx_pause; 1038c811e6a4SJiawen Wu DEBUGOUT("Flow Control = RX PAUSE frames only."); 1039f40e9f0eSJiawen Wu } else { 1040f40e9f0eSJiawen Wu hw->fc.current_mode = ngbe_fc_none; 1041c811e6a4SJiawen Wu DEBUGOUT("Flow Control = NONE."); 1042f40e9f0eSJiawen Wu } 1043f40e9f0eSJiawen Wu return 0; 1044f40e9f0eSJiawen Wu } 1045f40e9f0eSJiawen Wu 1046f40e9f0eSJiawen Wu /** 1047f40e9f0eSJiawen Wu * ngbe_fc_autoneg_em - Enable flow control IEEE clause 37 1048f40e9f0eSJiawen Wu * @hw: pointer to hardware structure 1049f40e9f0eSJiawen Wu * 1050f40e9f0eSJiawen Wu * Enable flow control according to IEEE clause 37. 1051f40e9f0eSJiawen Wu **/ 1052f40e9f0eSJiawen Wu STATIC s32 ngbe_fc_autoneg_em(struct ngbe_hw *hw) 1053f40e9f0eSJiawen Wu { 1054f40e9f0eSJiawen Wu u8 technology_ability_reg = 0; 1055f40e9f0eSJiawen Wu u8 lp_technology_ability_reg = 0; 1056f40e9f0eSJiawen Wu 1057f40e9f0eSJiawen Wu hw->phy.get_adv_pause(hw, &technology_ability_reg); 1058f40e9f0eSJiawen Wu hw->phy.get_lp_adv_pause(hw, &lp_technology_ability_reg); 1059f40e9f0eSJiawen Wu 1060f40e9f0eSJiawen Wu return ngbe_negotiate_fc(hw, (u32)technology_ability_reg, 1061f40e9f0eSJiawen Wu (u32)lp_technology_ability_reg, 1062f40e9f0eSJiawen Wu NGBE_TAF_SYM_PAUSE, NGBE_TAF_ASM_PAUSE, 1063f40e9f0eSJiawen Wu NGBE_TAF_SYM_PAUSE, NGBE_TAF_ASM_PAUSE); 1064f40e9f0eSJiawen Wu } 1065f40e9f0eSJiawen Wu 1066f40e9f0eSJiawen Wu /** 1067f40e9f0eSJiawen Wu * ngbe_fc_autoneg - Configure flow control 1068f40e9f0eSJiawen Wu * @hw: pointer to hardware structure 1069f40e9f0eSJiawen Wu * 1070f40e9f0eSJiawen Wu * Compares our advertised flow control capabilities to those advertised by 1071f40e9f0eSJiawen Wu * our link partner, and determines the proper flow control mode to use. 1072f40e9f0eSJiawen Wu **/ 1073f40e9f0eSJiawen Wu void ngbe_fc_autoneg(struct ngbe_hw *hw) 1074f40e9f0eSJiawen Wu { 1075f40e9f0eSJiawen Wu s32 err = NGBE_ERR_FC_NOT_NEGOTIATED; 1076f40e9f0eSJiawen Wu u32 speed; 1077f40e9f0eSJiawen Wu bool link_up; 1078f40e9f0eSJiawen Wu 1079f40e9f0eSJiawen Wu /* 1080f40e9f0eSJiawen Wu * AN should have completed when the cable was plugged in. 1081f40e9f0eSJiawen Wu * Look for reasons to bail out. Bail out if: 1082f40e9f0eSJiawen Wu * - FC autoneg is disabled, or if 1083f40e9f0eSJiawen Wu * - link is not up. 1084f40e9f0eSJiawen Wu */ 1085f40e9f0eSJiawen Wu if (hw->fc.disable_fc_autoneg) { 1086f40e9f0eSJiawen Wu DEBUGOUT("Flow control autoneg is disabled"); 1087f40e9f0eSJiawen Wu goto out; 1088f40e9f0eSJiawen Wu } 1089f40e9f0eSJiawen Wu 1090f40e9f0eSJiawen Wu hw->mac.check_link(hw, &speed, &link_up, false); 1091f40e9f0eSJiawen Wu if (!link_up) { 1092f40e9f0eSJiawen Wu DEBUGOUT("The link is down"); 1093f40e9f0eSJiawen Wu goto out; 1094f40e9f0eSJiawen Wu } 1095f40e9f0eSJiawen Wu 1096f40e9f0eSJiawen Wu err = ngbe_fc_autoneg_em(hw); 1097f40e9f0eSJiawen Wu 1098f40e9f0eSJiawen Wu out: 1099f40e9f0eSJiawen Wu if (err == 0) { 1100f40e9f0eSJiawen Wu hw->fc.fc_was_autonegged = true; 1101f40e9f0eSJiawen Wu } else { 1102f40e9f0eSJiawen Wu hw->fc.fc_was_autonegged = false; 1103f40e9f0eSJiawen Wu hw->fc.current_mode = hw->fc.requested_mode; 1104f40e9f0eSJiawen Wu } 1105f40e9f0eSJiawen Wu } 1106f40e9f0eSJiawen Wu 1107f40e9f0eSJiawen Wu /** 1108ac6c5e9aSJiawen Wu * ngbe_set_pcie_master - Disable or Enable PCI-express master access 1109ac6c5e9aSJiawen Wu * @hw: pointer to hardware structure 1110ac6c5e9aSJiawen Wu * 1111ac6c5e9aSJiawen Wu * Disables PCI-Express master access and verifies there are no pending 1112ac6c5e9aSJiawen Wu * requests. NGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable 1113ac6c5e9aSJiawen Wu * bit hasn't caused the master requests to be disabled, else 0 1114ac6c5e9aSJiawen Wu * is returned signifying master requests disabled. 1115ac6c5e9aSJiawen Wu **/ 1116ac6c5e9aSJiawen Wu s32 ngbe_set_pcie_master(struct ngbe_hw *hw, bool enable) 1117ac6c5e9aSJiawen Wu { 11180aeb133cSJiawen Wu struct rte_pci_device *pci_dev = (struct rte_pci_device *)hw->back; 1119ac6c5e9aSJiawen Wu s32 status = 0; 11200aeb133cSJiawen Wu u32 i; 1121ac6c5e9aSJiawen Wu 1122b3d590a0SDavid Marchand if (rte_pci_set_bus_master(pci_dev, enable) < 0) { 1123f665790aSDavid Marchand DEBUGOUT("Cannot configure PCI bus master"); 11240aeb133cSJiawen Wu return -1; 11250aeb133cSJiawen Wu } 1126ac6c5e9aSJiawen Wu 1127ac6c5e9aSJiawen Wu if (enable) 1128ac6c5e9aSJiawen Wu goto out; 1129ac6c5e9aSJiawen Wu 1130ac6c5e9aSJiawen Wu /* Exit if master requests are blocked */ 1131ac6c5e9aSJiawen Wu if (!(rd32(hw, NGBE_BMEPEND)) || 1132ac6c5e9aSJiawen Wu NGBE_REMOVED(hw->hw_addr)) 1133ac6c5e9aSJiawen Wu goto out; 1134ac6c5e9aSJiawen Wu 1135ac6c5e9aSJiawen Wu /* Poll for master request bit to clear */ 1136ac6c5e9aSJiawen Wu for (i = 0; i < NGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { 1137ac6c5e9aSJiawen Wu usec_delay(100); 1138ac6c5e9aSJiawen Wu if (!(rd32(hw, NGBE_BMEPEND))) 1139ac6c5e9aSJiawen Wu goto out; 1140ac6c5e9aSJiawen Wu } 1141ac6c5e9aSJiawen Wu 1142c811e6a4SJiawen Wu DEBUGOUT("PCIe transaction pending bit also did not clear."); 1143ac6c5e9aSJiawen Wu status = NGBE_ERR_MASTER_REQUESTS_PENDING; 1144ac6c5e9aSJiawen Wu 1145ac6c5e9aSJiawen Wu out: 1146ac6c5e9aSJiawen Wu return status; 1147ac6c5e9aSJiawen Wu } 1148ac6c5e9aSJiawen Wu 1149ac6c5e9aSJiawen Wu /** 1150f501a195SJiawen Wu * ngbe_acquire_swfw_sync - Acquire SWFW semaphore 1151f501a195SJiawen Wu * @hw: pointer to hardware structure 1152f501a195SJiawen Wu * @mask: Mask to specify which semaphore to acquire 1153f501a195SJiawen Wu * 1154f501a195SJiawen Wu * Acquires the SWFW semaphore through the MNGSEM register for the specified 1155f501a195SJiawen Wu * function (CSR, PHY0, PHY1, EEPROM, Flash) 1156f501a195SJiawen Wu **/ 1157f501a195SJiawen Wu s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask) 1158f501a195SJiawen Wu { 1159f501a195SJiawen Wu u32 mngsem = 0; 116091bc12c5SJiawen Wu u32 fwsm = 0; 1161f501a195SJiawen Wu u32 swmask = NGBE_MNGSEM_SW(mask); 1162f501a195SJiawen Wu u32 fwmask = NGBE_MNGSEM_FW(mask); 1163f501a195SJiawen Wu u32 timeout = 200; 1164f501a195SJiawen Wu u32 i; 1165f501a195SJiawen Wu 1166f501a195SJiawen Wu for (i = 0; i < timeout; i++) { 1167f501a195SJiawen Wu /* 1168f501a195SJiawen Wu * SW NVM semaphore bit is used for access to all 1169f501a195SJiawen Wu * SW_FW_SYNC bits (not just NVM) 1170f501a195SJiawen Wu */ 1171f501a195SJiawen Wu if (ngbe_get_eeprom_semaphore(hw)) 1172f501a195SJiawen Wu return NGBE_ERR_SWFW_SYNC; 1173f501a195SJiawen Wu 1174f501a195SJiawen Wu mngsem = rd32(hw, NGBE_MNGSEM); 1175f501a195SJiawen Wu if (mngsem & (fwmask | swmask)) { 1176f501a195SJiawen Wu /* Resource is currently in use by FW or SW */ 1177f501a195SJiawen Wu ngbe_release_eeprom_semaphore(hw); 1178f501a195SJiawen Wu msec_delay(5); 1179f501a195SJiawen Wu } else { 1180f501a195SJiawen Wu mngsem |= swmask; 1181f501a195SJiawen Wu wr32(hw, NGBE_MNGSEM, mngsem); 1182f501a195SJiawen Wu ngbe_release_eeprom_semaphore(hw); 1183f501a195SJiawen Wu return 0; 1184f501a195SJiawen Wu } 1185f501a195SJiawen Wu } 1186f501a195SJiawen Wu 118791bc12c5SJiawen Wu fwsm = rd32(hw, NGBE_MNGFWSYNC); 1188c811e6a4SJiawen Wu DEBUGOUT("SWFW semaphore not granted: MNG_SWFW_SYNC = 0x%x, MNG_FW_SM = 0x%x", 118991bc12c5SJiawen Wu mngsem, fwsm); 1190f501a195SJiawen Wu 1191f501a195SJiawen Wu msec_delay(5); 1192f501a195SJiawen Wu return NGBE_ERR_SWFW_SYNC; 1193f501a195SJiawen Wu } 1194f501a195SJiawen Wu 1195f501a195SJiawen Wu /** 1196f501a195SJiawen Wu * ngbe_release_swfw_sync - Release SWFW semaphore 1197f501a195SJiawen Wu * @hw: pointer to hardware structure 1198f501a195SJiawen Wu * @mask: Mask to specify which semaphore to release 1199f501a195SJiawen Wu * 1200f501a195SJiawen Wu * Releases the SWFW semaphore through the MNGSEM register for the specified 1201f501a195SJiawen Wu * function (CSR, PHY0, PHY1, EEPROM, Flash) 1202f501a195SJiawen Wu **/ 1203f501a195SJiawen Wu void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask) 1204f501a195SJiawen Wu { 1205f501a195SJiawen Wu u32 mngsem; 1206f501a195SJiawen Wu u32 swmask = mask; 1207f501a195SJiawen Wu 1208f501a195SJiawen Wu ngbe_get_eeprom_semaphore(hw); 1209f501a195SJiawen Wu 1210f501a195SJiawen Wu mngsem = rd32(hw, NGBE_MNGSEM); 1211f501a195SJiawen Wu mngsem &= ~swmask; 1212f501a195SJiawen Wu wr32(hw, NGBE_MNGSEM, mngsem); 1213f501a195SJiawen Wu 1214f501a195SJiawen Wu ngbe_release_eeprom_semaphore(hw); 1215f501a195SJiawen Wu } 1216f501a195SJiawen Wu 1217f501a195SJiawen Wu /** 121862fc35e6SJiawen Wu * ngbe_disable_sec_rx_path - Stops the receive data path 121962fc35e6SJiawen Wu * @hw: pointer to hardware structure 122062fc35e6SJiawen Wu * 122162fc35e6SJiawen Wu * Stops the receive data path and waits for the HW to internally empty 122262fc35e6SJiawen Wu * the Rx security block 122362fc35e6SJiawen Wu **/ 122462fc35e6SJiawen Wu s32 ngbe_disable_sec_rx_path(struct ngbe_hw *hw) 122562fc35e6SJiawen Wu { 122662fc35e6SJiawen Wu #define NGBE_MAX_SECRX_POLL 4000 122762fc35e6SJiawen Wu 122862fc35e6SJiawen Wu int i; 122962fc35e6SJiawen Wu u32 secrxreg; 123062fc35e6SJiawen Wu 123162fc35e6SJiawen Wu secrxreg = rd32(hw, NGBE_SECRXCTL); 123262fc35e6SJiawen Wu secrxreg |= NGBE_SECRXCTL_XDSA; 123362fc35e6SJiawen Wu wr32(hw, NGBE_SECRXCTL, secrxreg); 123462fc35e6SJiawen Wu for (i = 0; i < NGBE_MAX_SECRX_POLL; i++) { 123562fc35e6SJiawen Wu secrxreg = rd32(hw, NGBE_SECRXSTAT); 123662fc35e6SJiawen Wu if (!(secrxreg & NGBE_SECRXSTAT_RDY)) 123762fc35e6SJiawen Wu /* Use interrupt-safe sleep just in case */ 123862fc35e6SJiawen Wu usec_delay(10); 123962fc35e6SJiawen Wu else 124062fc35e6SJiawen Wu break; 124162fc35e6SJiawen Wu } 124262fc35e6SJiawen Wu 124362fc35e6SJiawen Wu /* For informational purposes only */ 124462fc35e6SJiawen Wu if (i >= NGBE_MAX_SECRX_POLL) 1245c811e6a4SJiawen Wu DEBUGOUT("Rx unit being enabled before security path fully disabled. Continuing with init."); 124662fc35e6SJiawen Wu 124762fc35e6SJiawen Wu return 0; 124862fc35e6SJiawen Wu } 124962fc35e6SJiawen Wu 125062fc35e6SJiawen Wu /** 125162fc35e6SJiawen Wu * ngbe_enable_sec_rx_path - Enables the receive data path 125262fc35e6SJiawen Wu * @hw: pointer to hardware structure 125362fc35e6SJiawen Wu * 125462fc35e6SJiawen Wu * Enables the receive data path. 125562fc35e6SJiawen Wu **/ 125662fc35e6SJiawen Wu s32 ngbe_enable_sec_rx_path(struct ngbe_hw *hw) 125762fc35e6SJiawen Wu { 125862fc35e6SJiawen Wu u32 secrxreg; 125962fc35e6SJiawen Wu 126062fc35e6SJiawen Wu secrxreg = rd32(hw, NGBE_SECRXCTL); 126162fc35e6SJiawen Wu secrxreg &= ~NGBE_SECRXCTL_XDSA; 126262fc35e6SJiawen Wu wr32(hw, NGBE_SECRXCTL, secrxreg); 126362fc35e6SJiawen Wu ngbe_flush(hw); 126462fc35e6SJiawen Wu 126562fc35e6SJiawen Wu return 0; 126662fc35e6SJiawen Wu } 126762fc35e6SJiawen Wu 126862fc35e6SJiawen Wu /** 1269539d55daSJiawen Wu * ngbe_clear_vmdq - Disassociate a VMDq pool index from a rx address 1270539d55daSJiawen Wu * @hw: pointer to hardware struct 1271539d55daSJiawen Wu * @rar: receive address register index to disassociate 1272539d55daSJiawen Wu * @vmdq: VMDq pool index to remove from the rar 1273539d55daSJiawen Wu **/ 1274539d55daSJiawen Wu s32 ngbe_clear_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq) 1275539d55daSJiawen Wu { 1276539d55daSJiawen Wu u32 mpsar; 1277539d55daSJiawen Wu u32 rar_entries = hw->mac.num_rar_entries; 1278539d55daSJiawen Wu 1279539d55daSJiawen Wu /* Make sure we are using a valid rar index range */ 1280539d55daSJiawen Wu if (rar >= rar_entries) { 1281c811e6a4SJiawen Wu DEBUGOUT("RAR index %d is out of range.", rar); 1282539d55daSJiawen Wu return NGBE_ERR_INVALID_ARGUMENT; 1283539d55daSJiawen Wu } 1284539d55daSJiawen Wu 1285539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRIDX, rar); 1286539d55daSJiawen Wu mpsar = rd32(hw, NGBE_ETHADDRASS); 1287539d55daSJiawen Wu 1288539d55daSJiawen Wu if (NGBE_REMOVED(hw->hw_addr)) 1289539d55daSJiawen Wu goto done; 1290539d55daSJiawen Wu 1291539d55daSJiawen Wu if (!mpsar) 1292539d55daSJiawen Wu goto done; 1293539d55daSJiawen Wu 1294539d55daSJiawen Wu mpsar &= ~(1 << vmdq); 1295539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRASS, mpsar); 1296539d55daSJiawen Wu 1297539d55daSJiawen Wu /* was that the last pool using this rar? */ 1298539d55daSJiawen Wu if (mpsar == 0 && rar != 0) 1299539d55daSJiawen Wu hw->mac.clear_rar(hw, rar); 1300539d55daSJiawen Wu done: 1301539d55daSJiawen Wu return 0; 1302539d55daSJiawen Wu } 1303539d55daSJiawen Wu 1304539d55daSJiawen Wu /** 1305539d55daSJiawen Wu * ngbe_set_vmdq - Associate a VMDq pool index with a rx address 1306539d55daSJiawen Wu * @hw: pointer to hardware struct 1307539d55daSJiawen Wu * @rar: receive address register index to associate with a VMDq index 1308539d55daSJiawen Wu * @vmdq: VMDq pool index 1309539d55daSJiawen Wu **/ 1310539d55daSJiawen Wu s32 ngbe_set_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq) 1311539d55daSJiawen Wu { 1312539d55daSJiawen Wu u32 mpsar; 1313539d55daSJiawen Wu u32 rar_entries = hw->mac.num_rar_entries; 1314539d55daSJiawen Wu 1315539d55daSJiawen Wu /* Make sure we are using a valid rar index range */ 1316539d55daSJiawen Wu if (rar >= rar_entries) { 1317c811e6a4SJiawen Wu DEBUGOUT("RAR index %d is out of range.", rar); 1318539d55daSJiawen Wu return NGBE_ERR_INVALID_ARGUMENT; 1319539d55daSJiawen Wu } 1320539d55daSJiawen Wu 1321539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRIDX, rar); 1322539d55daSJiawen Wu 1323539d55daSJiawen Wu mpsar = rd32(hw, NGBE_ETHADDRASS); 1324539d55daSJiawen Wu mpsar |= 1 << vmdq; 1325539d55daSJiawen Wu wr32(hw, NGBE_ETHADDRASS, mpsar); 1326539d55daSJiawen Wu 1327539d55daSJiawen Wu return 0; 1328539d55daSJiawen Wu } 1329539d55daSJiawen Wu 1330539d55daSJiawen Wu /** 1331539d55daSJiawen Wu * ngbe_init_uta_tables - Initialize the Unicast Table Array 1332539d55daSJiawen Wu * @hw: pointer to hardware structure 1333539d55daSJiawen Wu **/ 1334539d55daSJiawen Wu s32 ngbe_init_uta_tables(struct ngbe_hw *hw) 1335539d55daSJiawen Wu { 1336539d55daSJiawen Wu int i; 1337539d55daSJiawen Wu 1338c811e6a4SJiawen Wu DEBUGOUT(" Clearing UTA"); 1339539d55daSJiawen Wu 1340539d55daSJiawen Wu for (i = 0; i < 128; i++) 1341539d55daSJiawen Wu wr32(hw, NGBE_UCADDRTBL(i), 0); 1342539d55daSJiawen Wu 1343539d55daSJiawen Wu return 0; 1344539d55daSJiawen Wu } 1345539d55daSJiawen Wu 1346539d55daSJiawen Wu /** 1347e2a289a7SJiawen Wu * ngbe_find_vlvf_slot - find the vlanid or the first empty slot 1348e2a289a7SJiawen Wu * @hw: pointer to hardware structure 1349e2a289a7SJiawen Wu * @vlan: VLAN id to write to VLAN filter 1350e2a289a7SJiawen Wu * @vlvf_bypass: true to find vlanid only, false returns first empty slot if 1351e2a289a7SJiawen Wu * vlanid not found 1352e2a289a7SJiawen Wu * 1353e2a289a7SJiawen Wu * 1354e2a289a7SJiawen Wu * return the VLVF index where this VLAN id should be placed 1355e2a289a7SJiawen Wu * 1356e2a289a7SJiawen Wu **/ 1357e2a289a7SJiawen Wu s32 ngbe_find_vlvf_slot(struct ngbe_hw *hw, u32 vlan, bool vlvf_bypass) 1358e2a289a7SJiawen Wu { 1359e2a289a7SJiawen Wu s32 regindex, first_empty_slot; 1360e2a289a7SJiawen Wu u32 bits; 1361e2a289a7SJiawen Wu 1362e2a289a7SJiawen Wu /* short cut the special case */ 1363e2a289a7SJiawen Wu if (vlan == 0) 1364e2a289a7SJiawen Wu return 0; 1365e2a289a7SJiawen Wu 1366e2a289a7SJiawen Wu /* if vlvf_bypass is set we don't want to use an empty slot, we 1367e2a289a7SJiawen Wu * will simply bypass the VLVF if there are no entries present in the 1368e2a289a7SJiawen Wu * VLVF that contain our VLAN 1369e2a289a7SJiawen Wu */ 1370e2a289a7SJiawen Wu first_empty_slot = vlvf_bypass ? NGBE_ERR_NO_SPACE : 0; 1371e2a289a7SJiawen Wu 1372e2a289a7SJiawen Wu /* add VLAN enable bit for comparison */ 1373e2a289a7SJiawen Wu vlan |= NGBE_PSRVLAN_EA; 1374e2a289a7SJiawen Wu 1375e2a289a7SJiawen Wu /* Search for the vlan id in the VLVF entries. Save off the first empty 1376e2a289a7SJiawen Wu * slot found along the way. 1377e2a289a7SJiawen Wu * 1378e2a289a7SJiawen Wu * pre-decrement loop covering (NGBE_NUM_POOL - 1) .. 1 1379e2a289a7SJiawen Wu */ 1380e2a289a7SJiawen Wu for (regindex = NGBE_NUM_POOL; --regindex;) { 1381e2a289a7SJiawen Wu wr32(hw, NGBE_PSRVLANIDX, regindex); 1382e2a289a7SJiawen Wu bits = rd32(hw, NGBE_PSRVLAN); 1383e2a289a7SJiawen Wu if (bits == vlan) 1384e2a289a7SJiawen Wu return regindex; 1385e2a289a7SJiawen Wu if (!first_empty_slot && !bits) 1386e2a289a7SJiawen Wu first_empty_slot = regindex; 1387e2a289a7SJiawen Wu } 1388e2a289a7SJiawen Wu 1389e2a289a7SJiawen Wu /* If we are here then we didn't find the VLAN. Return first empty 1390e2a289a7SJiawen Wu * slot we found during our search, else error. 1391e2a289a7SJiawen Wu */ 1392e2a289a7SJiawen Wu if (!first_empty_slot) 1393c811e6a4SJiawen Wu DEBUGOUT("No space in VLVF."); 1394e2a289a7SJiawen Wu 1395e2a289a7SJiawen Wu return first_empty_slot ? first_empty_slot : NGBE_ERR_NO_SPACE; 1396e2a289a7SJiawen Wu } 1397e2a289a7SJiawen Wu 1398e2a289a7SJiawen Wu /** 1399e2a289a7SJiawen Wu * ngbe_set_vfta - Set VLAN filter table 1400e2a289a7SJiawen Wu * @hw: pointer to hardware structure 1401e2a289a7SJiawen Wu * @vlan: VLAN id to write to VLAN filter 1402e2a289a7SJiawen Wu * @vind: VMDq output index that maps queue to VLAN id in VLVFB 1403e2a289a7SJiawen Wu * @vlan_on: boolean flag to turn on/off VLAN 1404e2a289a7SJiawen Wu * @vlvf_bypass: boolean flag indicating updating default pool is okay 1405e2a289a7SJiawen Wu * 1406e2a289a7SJiawen Wu * Turn on/off specified VLAN in the VLAN filter table. 1407e2a289a7SJiawen Wu **/ 1408e2a289a7SJiawen Wu s32 ngbe_set_vfta(struct ngbe_hw *hw, u32 vlan, u32 vind, 1409e2a289a7SJiawen Wu bool vlan_on, bool vlvf_bypass) 1410e2a289a7SJiawen Wu { 1411e2a289a7SJiawen Wu u32 regidx, vfta_delta, vfta; 1412e2a289a7SJiawen Wu s32 err; 1413e2a289a7SJiawen Wu 1414e2a289a7SJiawen Wu if (vlan > 4095 || vind > 63) 1415e2a289a7SJiawen Wu return NGBE_ERR_PARAM; 1416e2a289a7SJiawen Wu 1417e2a289a7SJiawen Wu /* 1418e2a289a7SJiawen Wu * this is a 2 part operation - first the VFTA, then the 1419e2a289a7SJiawen Wu * VLVF and VLVFB if VT Mode is set 1420e2a289a7SJiawen Wu * We don't write the VFTA until we know the VLVF part succeeded. 1421e2a289a7SJiawen Wu */ 1422e2a289a7SJiawen Wu 1423e2a289a7SJiawen Wu /* Part 1 1424e2a289a7SJiawen Wu * The VFTA is a bitstring made up of 128 32-bit registers 1425e2a289a7SJiawen Wu * that enable the particular VLAN id, much like the MTA: 1426e2a289a7SJiawen Wu * bits[11-5]: which register 1427e2a289a7SJiawen Wu * bits[4-0]: which bit in the register 1428e2a289a7SJiawen Wu */ 1429e2a289a7SJiawen Wu regidx = vlan / 32; 1430e2a289a7SJiawen Wu vfta_delta = 1 << (vlan % 32); 1431e2a289a7SJiawen Wu vfta = rd32(hw, NGBE_VLANTBL(regidx)); 1432e2a289a7SJiawen Wu 1433e2a289a7SJiawen Wu /* 1434e2a289a7SJiawen Wu * vfta_delta represents the difference between the current value 1435e2a289a7SJiawen Wu * of vfta and the value we want in the register. Since the diff 1436e2a289a7SJiawen Wu * is an XOR mask we can just update the vfta using an XOR 1437e2a289a7SJiawen Wu */ 1438e2a289a7SJiawen Wu vfta_delta &= vlan_on ? ~vfta : vfta; 1439e2a289a7SJiawen Wu vfta ^= vfta_delta; 1440e2a289a7SJiawen Wu 1441e2a289a7SJiawen Wu /* Part 2 1442e2a289a7SJiawen Wu * Call ngbe_set_vlvf to set VLVFB and VLVF 1443e2a289a7SJiawen Wu */ 1444e2a289a7SJiawen Wu err = ngbe_set_vlvf(hw, vlan, vind, vlan_on, &vfta_delta, 1445e2a289a7SJiawen Wu vfta, vlvf_bypass); 1446e2a289a7SJiawen Wu if (err != 0) { 1447e2a289a7SJiawen Wu if (vlvf_bypass) 1448e2a289a7SJiawen Wu goto vfta_update; 1449e2a289a7SJiawen Wu return err; 1450e2a289a7SJiawen Wu } 1451e2a289a7SJiawen Wu 1452e2a289a7SJiawen Wu vfta_update: 1453e2a289a7SJiawen Wu /* Update VFTA now that we are ready for traffic */ 1454e2a289a7SJiawen Wu if (vfta_delta) 1455e2a289a7SJiawen Wu wr32(hw, NGBE_VLANTBL(regidx), vfta); 1456e2a289a7SJiawen Wu 1457e2a289a7SJiawen Wu return 0; 1458e2a289a7SJiawen Wu } 1459e2a289a7SJiawen Wu 1460e2a289a7SJiawen Wu /** 1461e2a289a7SJiawen Wu * ngbe_set_vlvf - Set VLAN Pool Filter 1462e2a289a7SJiawen Wu * @hw: pointer to hardware structure 1463e2a289a7SJiawen Wu * @vlan: VLAN id to write to VLAN filter 1464e2a289a7SJiawen Wu * @vind: VMDq output index that maps queue to VLAN id in PSRVLANPLM 1465e2a289a7SJiawen Wu * @vlan_on: boolean flag to turn on/off VLAN in PSRVLAN 1466e2a289a7SJiawen Wu * @vfta_delta: pointer to the difference between the current value 1467e2a289a7SJiawen Wu * of PSRVLANPLM and the desired value 1468e2a289a7SJiawen Wu * @vfta: the desired value of the VFTA 1469e2a289a7SJiawen Wu * @vlvf_bypass: boolean flag indicating updating default pool is okay 1470e2a289a7SJiawen Wu * 1471e2a289a7SJiawen Wu * Turn on/off specified bit in VLVF table. 1472e2a289a7SJiawen Wu **/ 1473e2a289a7SJiawen Wu s32 ngbe_set_vlvf(struct ngbe_hw *hw, u32 vlan, u32 vind, 1474e2a289a7SJiawen Wu bool vlan_on, u32 *vfta_delta, u32 vfta, 1475e2a289a7SJiawen Wu bool vlvf_bypass) 1476e2a289a7SJiawen Wu { 1477e2a289a7SJiawen Wu u32 bits; 1478e2a289a7SJiawen Wu u32 portctl; 1479e2a289a7SJiawen Wu s32 vlvf_index; 1480e2a289a7SJiawen Wu 1481e2a289a7SJiawen Wu if (vlan > 4095 || vind > 63) 1482e2a289a7SJiawen Wu return NGBE_ERR_PARAM; 1483e2a289a7SJiawen Wu 1484e2a289a7SJiawen Wu /* If VT Mode is set 1485e2a289a7SJiawen Wu * Either vlan_on 1486e2a289a7SJiawen Wu * make sure the vlan is in PSRVLAN 1487e2a289a7SJiawen Wu * set the vind bit in the matching PSRVLANPLM 1488e2a289a7SJiawen Wu * Or !vlan_on 1489e2a289a7SJiawen Wu * clear the pool bit and possibly the vind 1490e2a289a7SJiawen Wu */ 1491e2a289a7SJiawen Wu portctl = rd32(hw, NGBE_PORTCTL); 1492e2a289a7SJiawen Wu if (!(portctl & NGBE_PORTCTL_NUMVT_MASK)) 1493e2a289a7SJiawen Wu return 0; 1494e2a289a7SJiawen Wu 1495e2a289a7SJiawen Wu vlvf_index = ngbe_find_vlvf_slot(hw, vlan, vlvf_bypass); 1496e2a289a7SJiawen Wu if (vlvf_index < 0) 1497e2a289a7SJiawen Wu return vlvf_index; 1498e2a289a7SJiawen Wu 1499e2a289a7SJiawen Wu wr32(hw, NGBE_PSRVLANIDX, vlvf_index); 1500e2a289a7SJiawen Wu bits = rd32(hw, NGBE_PSRVLANPLM(vind / 32)); 1501e2a289a7SJiawen Wu 1502e2a289a7SJiawen Wu /* set the pool bit */ 1503e2a289a7SJiawen Wu bits |= 1 << (vind % 32); 1504e2a289a7SJiawen Wu if (vlan_on) 1505e2a289a7SJiawen Wu goto vlvf_update; 1506e2a289a7SJiawen Wu 1507e2a289a7SJiawen Wu /* clear the pool bit */ 1508e2a289a7SJiawen Wu bits ^= 1 << (vind % 32); 1509e2a289a7SJiawen Wu 1510e2a289a7SJiawen Wu if (!bits && 1511e2a289a7SJiawen Wu !rd32(hw, NGBE_PSRVLANPLM(vind / 32))) { 1512e2a289a7SJiawen Wu /* Clear PSRVLANPLM first, then disable PSRVLAN. Otherwise 1513e2a289a7SJiawen Wu * we run the risk of stray packets leaking into 1514e2a289a7SJiawen Wu * the PF via the default pool 1515e2a289a7SJiawen Wu */ 1516e2a289a7SJiawen Wu if (*vfta_delta) 1517e2a289a7SJiawen Wu wr32(hw, NGBE_PSRVLANPLM(vlan / 32), vfta); 1518e2a289a7SJiawen Wu 1519e2a289a7SJiawen Wu /* disable VLVF and clear remaining bit from pool */ 1520e2a289a7SJiawen Wu wr32(hw, NGBE_PSRVLAN, 0); 1521e2a289a7SJiawen Wu wr32(hw, NGBE_PSRVLANPLM(vind / 32), 0); 1522e2a289a7SJiawen Wu 1523e2a289a7SJiawen Wu return 0; 1524e2a289a7SJiawen Wu } 1525e2a289a7SJiawen Wu 1526e2a289a7SJiawen Wu /* If there are still bits set in the PSRVLANPLM registers 1527e2a289a7SJiawen Wu * for the VLAN ID indicated we need to see if the 1528e2a289a7SJiawen Wu * caller is requesting that we clear the PSRVLANPLM entry bit. 1529e2a289a7SJiawen Wu * If the caller has requested that we clear the PSRVLANPLM 1530e2a289a7SJiawen Wu * entry bit but there are still pools/VFs using this VLAN 1531e2a289a7SJiawen Wu * ID entry then ignore the request. We're not worried 1532e2a289a7SJiawen Wu * about the case where we're turning the PSRVLANPLM VLAN ID 1533e2a289a7SJiawen Wu * entry bit on, only when requested to turn it off as 1534e2a289a7SJiawen Wu * there may be multiple pools and/or VFs using the 1535e2a289a7SJiawen Wu * VLAN ID entry. In that case we cannot clear the 1536e2a289a7SJiawen Wu * PSRVLANPLM bit until all pools/VFs using that VLAN ID have also 1537e2a289a7SJiawen Wu * been cleared. This will be indicated by "bits" being 1538e2a289a7SJiawen Wu * zero. 1539e2a289a7SJiawen Wu */ 1540e2a289a7SJiawen Wu *vfta_delta = 0; 1541e2a289a7SJiawen Wu 1542e2a289a7SJiawen Wu vlvf_update: 1543e2a289a7SJiawen Wu /* record pool change and enable VLAN ID if not already enabled */ 1544e2a289a7SJiawen Wu wr32(hw, NGBE_PSRVLANPLM(vind / 32), bits); 1545e2a289a7SJiawen Wu wr32(hw, NGBE_PSRVLAN, NGBE_PSRVLAN_EA | vlan); 1546e2a289a7SJiawen Wu 1547e2a289a7SJiawen Wu return 0; 1548e2a289a7SJiawen Wu } 1549e2a289a7SJiawen Wu 1550e2a289a7SJiawen Wu /** 155159b46438SJiawen Wu * ngbe_clear_vfta - Clear VLAN filter table 155259b46438SJiawen Wu * @hw: pointer to hardware structure 155359b46438SJiawen Wu * 155459b46438SJiawen Wu * Clears the VLAN filer table, and the VMDq index associated with the filter 155559b46438SJiawen Wu **/ 155659b46438SJiawen Wu s32 ngbe_clear_vfta(struct ngbe_hw *hw) 155759b46438SJiawen Wu { 155859b46438SJiawen Wu u32 offset; 155959b46438SJiawen Wu 156059b46438SJiawen Wu for (offset = 0; offset < hw->mac.vft_size; offset++) 156159b46438SJiawen Wu wr32(hw, NGBE_VLANTBL(offset), 0); 156259b46438SJiawen Wu 156359b46438SJiawen Wu for (offset = 0; offset < NGBE_NUM_POOL; offset++) { 156459b46438SJiawen Wu wr32(hw, NGBE_PSRVLANIDX, offset); 156559b46438SJiawen Wu wr32(hw, NGBE_PSRVLAN, 0); 156659b46438SJiawen Wu wr32(hw, NGBE_PSRVLANPLM(0), 0); 156759b46438SJiawen Wu } 156859b46438SJiawen Wu 156959b46438SJiawen Wu return 0; 157059b46438SJiawen Wu } 157159b46438SJiawen Wu 157259b46438SJiawen Wu /** 15733d0af706SJiawen Wu * ngbe_check_mac_link_em - Determine link and speed status 15743d0af706SJiawen Wu * @hw: pointer to hardware structure 15753d0af706SJiawen Wu * @speed: pointer to link speed 15763d0af706SJiawen Wu * @link_up: true when link is up 15773d0af706SJiawen Wu * @link_up_wait_to_complete: bool used to wait for link up or not 15783d0af706SJiawen Wu * 15793d0af706SJiawen Wu * Reads the links register to determine if link is up and the current speed 15803d0af706SJiawen Wu **/ 15813d0af706SJiawen Wu s32 ngbe_check_mac_link_em(struct ngbe_hw *hw, u32 *speed, 15823d0af706SJiawen Wu bool *link_up, bool link_up_wait_to_complete) 15833d0af706SJiawen Wu { 158421f702d5SJiawen Wu u32 i; 15853d0af706SJiawen Wu s32 status = 0; 15863d0af706SJiawen Wu 158721f702d5SJiawen Wu if (hw->lsc) { 158821f702d5SJiawen Wu u32 reg; 158921f702d5SJiawen Wu 15903d0af706SJiawen Wu reg = rd32(hw, NGBE_GPIOINTSTAT); 15913d0af706SJiawen Wu wr32(hw, NGBE_GPIOEOI, reg); 159221f702d5SJiawen Wu } 15933d0af706SJiawen Wu 15943d0af706SJiawen Wu if (link_up_wait_to_complete) { 15953d0af706SJiawen Wu for (i = 0; i < hw->mac.max_link_up_time; i++) { 15963d0af706SJiawen Wu status = hw->phy.check_link(hw, speed, link_up); 15973d0af706SJiawen Wu if (*link_up) 15983d0af706SJiawen Wu break; 15993d0af706SJiawen Wu msec_delay(100); 16003d0af706SJiawen Wu } 16013d0af706SJiawen Wu } else { 16023d0af706SJiawen Wu status = hw->phy.check_link(hw, speed, link_up); 16033d0af706SJiawen Wu } 16043d0af706SJiawen Wu 16053d0af706SJiawen Wu return status; 16063d0af706SJiawen Wu } 16073d0af706SJiawen Wu 16083518df57SJiawen Wu s32 ngbe_get_link_capabilities_em(struct ngbe_hw *hw, 16093518df57SJiawen Wu u32 *speed, 16103518df57SJiawen Wu bool *autoneg) 16113518df57SJiawen Wu { 16123518df57SJiawen Wu s32 status = 0; 16131c44384fSJiawen Wu u16 value = 0; 16143518df57SJiawen Wu 16153518df57SJiawen Wu hw->mac.autoneg = *autoneg; 16163518df57SJiawen Wu 16171c44384fSJiawen Wu if (hw->phy.type == ngbe_phy_rtl) { 16183518df57SJiawen Wu *speed = NGBE_LINK_SPEED_1GB_FULL | 16193518df57SJiawen Wu NGBE_LINK_SPEED_100M_FULL | 16203518df57SJiawen Wu NGBE_LINK_SPEED_10M_FULL; 16211c44384fSJiawen Wu } 16221c44384fSJiawen Wu 16231c44384fSJiawen Wu if (hw->phy.type == ngbe_phy_yt8521s_sfi) { 16241c44384fSJiawen Wu ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value); 16251c44384fSJiawen Wu if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(1)) 16261c44384fSJiawen Wu *speed = NGBE_LINK_SPEED_1GB_FULL; 16273518df57SJiawen Wu } 16283518df57SJiawen Wu 16293518df57SJiawen Wu return status; 16303518df57SJiawen Wu } 16313518df57SJiawen Wu 16323d0af706SJiawen Wu s32 ngbe_setup_mac_link_em(struct ngbe_hw *hw, 16333d0af706SJiawen Wu u32 speed, 16343d0af706SJiawen Wu bool autoneg_wait_to_complete) 16353d0af706SJiawen Wu { 16363d0af706SJiawen Wu s32 status; 16373d0af706SJiawen Wu 16383d0af706SJiawen Wu /* Setup the PHY according to input speed */ 16393d0af706SJiawen Wu status = hw->phy.setup_link(hw, speed, autoneg_wait_to_complete); 16403d0af706SJiawen Wu 16413d0af706SJiawen Wu return status; 16423d0af706SJiawen Wu } 16433d0af706SJiawen Wu 16443d0af706SJiawen Wu /** 164560229dcfSJiawen Wu * ngbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing 164660229dcfSJiawen Wu * @hw: pointer to hardware structure 164760229dcfSJiawen Wu * @enable: enable or disable switch for MAC anti-spoofing 164860229dcfSJiawen Wu * @vf: Virtual Function pool - VF Pool to set for MAC anti-spoofing 164960229dcfSJiawen Wu * 165060229dcfSJiawen Wu **/ 165160229dcfSJiawen Wu void ngbe_set_mac_anti_spoofing(struct ngbe_hw *hw, bool enable, int vf) 165260229dcfSJiawen Wu { 165360229dcfSJiawen Wu u32 pfvfspoof; 165460229dcfSJiawen Wu 165560229dcfSJiawen Wu pfvfspoof = rd32(hw, NGBE_POOLTXASMAC); 165660229dcfSJiawen Wu if (enable) 165760229dcfSJiawen Wu pfvfspoof |= (1 << vf); 165860229dcfSJiawen Wu else 165960229dcfSJiawen Wu pfvfspoof &= ~(1 << vf); 166060229dcfSJiawen Wu wr32(hw, NGBE_POOLTXASMAC, pfvfspoof); 166160229dcfSJiawen Wu } 166260229dcfSJiawen Wu 166360229dcfSJiawen Wu /** 1664ccdeca8eSJiawen Wu * ngbe_set_pba - Initialize Rx packet buffer 1665ccdeca8eSJiawen Wu * @hw: pointer to hardware structure 1666ccdeca8eSJiawen Wu * @headroom: reserve n KB of headroom 1667ccdeca8eSJiawen Wu **/ 1668ccdeca8eSJiawen Wu void ngbe_set_pba(struct ngbe_hw *hw) 1669ccdeca8eSJiawen Wu { 1670ccdeca8eSJiawen Wu u32 rxpktsize = hw->mac.rx_pb_size; 1671ccdeca8eSJiawen Wu u32 txpktsize, txpbthresh; 1672ccdeca8eSJiawen Wu 1673ccdeca8eSJiawen Wu /* Reserve 256 KB of headroom */ 1674ccdeca8eSJiawen Wu rxpktsize -= 256; 1675ccdeca8eSJiawen Wu 1676ccdeca8eSJiawen Wu rxpktsize <<= 10; 1677ccdeca8eSJiawen Wu wr32(hw, NGBE_PBRXSIZE, rxpktsize); 1678ccdeca8eSJiawen Wu 1679ccdeca8eSJiawen Wu /* Only support an equally distributed Tx packet buffer strategy. */ 1680ccdeca8eSJiawen Wu txpktsize = NGBE_PBTXSIZE_MAX; 1681ccdeca8eSJiawen Wu txpbthresh = (txpktsize / 1024) - NGBE_TXPKT_SIZE_MAX; 1682ccdeca8eSJiawen Wu 1683ccdeca8eSJiawen Wu wr32(hw, NGBE_PBTXSIZE, txpktsize); 1684ccdeca8eSJiawen Wu wr32(hw, NGBE_PBTXDMATH, txpbthresh); 1685ccdeca8eSJiawen Wu } 1686ccdeca8eSJiawen Wu 1687ccdeca8eSJiawen Wu /** 168860229dcfSJiawen Wu * ngbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing 168960229dcfSJiawen Wu * @hw: pointer to hardware structure 169060229dcfSJiawen Wu * @enable: enable or disable switch for VLAN anti-spoofing 169160229dcfSJiawen Wu * @vf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing 169260229dcfSJiawen Wu * 169360229dcfSJiawen Wu **/ 169460229dcfSJiawen Wu void ngbe_set_vlan_anti_spoofing(struct ngbe_hw *hw, bool enable, int vf) 169560229dcfSJiawen Wu { 169660229dcfSJiawen Wu u32 pfvfspoof; 169760229dcfSJiawen Wu 169860229dcfSJiawen Wu pfvfspoof = rd32(hw, NGBE_POOLTXASVLAN); 169960229dcfSJiawen Wu if (enable) 170060229dcfSJiawen Wu pfvfspoof |= (1 << vf); 170160229dcfSJiawen Wu else 170260229dcfSJiawen Wu pfvfspoof &= ~(1 << vf); 170360229dcfSJiawen Wu wr32(hw, NGBE_POOLTXASVLAN, pfvfspoof); 170460229dcfSJiawen Wu } 170560229dcfSJiawen Wu 170660229dcfSJiawen Wu /** 170778710873SJiawen Wu * ngbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds 170878710873SJiawen Wu * @hw: pointer to hardware structure 170978710873SJiawen Wu * 171078710873SJiawen Wu * Inits the thermal sensor thresholds according to the NVM map 171178710873SJiawen Wu * and save off the threshold and location values into mac.thermal_sensor_data 171278710873SJiawen Wu **/ 171378710873SJiawen Wu s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw) 171478710873SJiawen Wu { 171578710873SJiawen Wu struct ngbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data; 171678710873SJiawen Wu 171778710873SJiawen Wu memset(data, 0, sizeof(struct ngbe_thermal_sensor_data)); 171878710873SJiawen Wu 171978710873SJiawen Wu if (hw->bus.lan_id != 0) 172078710873SJiawen Wu return NGBE_NOT_IMPLEMENTED; 172178710873SJiawen Wu 172278710873SJiawen Wu wr32(hw, NGBE_TSINTR, 172378710873SJiawen Wu NGBE_TSINTR_AEN | NGBE_TSINTR_DEN); 172478710873SJiawen Wu wr32(hw, NGBE_TSEN, NGBE_TSEN_ENA); 172578710873SJiawen Wu 172678710873SJiawen Wu 172778710873SJiawen Wu data->sensor[0].alarm_thresh = 115; 172878710873SJiawen Wu wr32(hw, NGBE_TSATHRE, 0x344); 172978710873SJiawen Wu data->sensor[0].dalarm_thresh = 110; 173078710873SJiawen Wu wr32(hw, NGBE_TSDTHRE, 0x330); 173178710873SJiawen Wu 173278710873SJiawen Wu return 0; 173378710873SJiawen Wu } 173478710873SJiawen Wu 173544e97550SJiawen Wu s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw) 173644e97550SJiawen Wu { 173744e97550SJiawen Wu s32 status = 0; 173844e97550SJiawen Wu u32 ts_state; 173944e97550SJiawen Wu 174044e97550SJiawen Wu /* Check that the LASI temp alarm status was triggered */ 174144e97550SJiawen Wu ts_state = rd32(hw, NGBE_TSALM); 174244e97550SJiawen Wu 174344e97550SJiawen Wu if (ts_state & NGBE_TSALM_HI) 174444e97550SJiawen Wu status = NGBE_ERR_UNDERTEMP; 174544e97550SJiawen Wu else if (ts_state & NGBE_TSALM_LO) 174644e97550SJiawen Wu status = NGBE_ERR_OVERTEMP; 174744e97550SJiawen Wu 174844e97550SJiawen Wu return status; 174944e97550SJiawen Wu } 175044e97550SJiawen Wu 175178710873SJiawen Wu void ngbe_disable_rx(struct ngbe_hw *hw) 175278710873SJiawen Wu { 175378710873SJiawen Wu u32 pfdtxgswc; 175478710873SJiawen Wu 175578710873SJiawen Wu pfdtxgswc = rd32(hw, NGBE_PSRCTL); 175678710873SJiawen Wu if (pfdtxgswc & NGBE_PSRCTL_LBENA) { 175778710873SJiawen Wu pfdtxgswc &= ~NGBE_PSRCTL_LBENA; 175878710873SJiawen Wu wr32(hw, NGBE_PSRCTL, pfdtxgswc); 175978710873SJiawen Wu hw->mac.set_lben = true; 176078710873SJiawen Wu } else { 176178710873SJiawen Wu hw->mac.set_lben = false; 176278710873SJiawen Wu } 176378710873SJiawen Wu 176478710873SJiawen Wu wr32m(hw, NGBE_PBRXCTL, NGBE_PBRXCTL_ENA, 0); 17655f1ab0d5SJiawen Wu if (!(hw->ncsi_enabled || hw->wol_enabled)) 176678710873SJiawen Wu wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, 0); 176778710873SJiawen Wu } 176878710873SJiawen Wu 176962fc35e6SJiawen Wu void ngbe_enable_rx(struct ngbe_hw *hw) 177062fc35e6SJiawen Wu { 177162fc35e6SJiawen Wu u32 pfdtxgswc; 177262fc35e6SJiawen Wu 177362fc35e6SJiawen Wu wr32m(hw, NGBE_MACRXCFG, NGBE_MACRXCFG_ENA, NGBE_MACRXCFG_ENA); 177462fc35e6SJiawen Wu wr32m(hw, NGBE_PBRXCTL, NGBE_PBRXCTL_ENA, NGBE_PBRXCTL_ENA); 177562fc35e6SJiawen Wu 177662fc35e6SJiawen Wu if (hw->mac.set_lben) { 177762fc35e6SJiawen Wu pfdtxgswc = rd32(hw, NGBE_PSRCTL); 177862fc35e6SJiawen Wu pfdtxgswc |= NGBE_PSRCTL_LBENA; 177962fc35e6SJiawen Wu wr32(hw, NGBE_PSRCTL, pfdtxgswc); 178062fc35e6SJiawen Wu hw->mac.set_lben = false; 178162fc35e6SJiawen Wu } 178262fc35e6SJiawen Wu } 178362fc35e6SJiawen Wu 178478710873SJiawen Wu /** 178568eb13a1SJiawen Wu * ngbe_set_mac_type - Sets MAC type 178668eb13a1SJiawen Wu * @hw: pointer to the HW structure 178768eb13a1SJiawen Wu * 178868eb13a1SJiawen Wu * This function sets the mac type of the adapter based on the 178968eb13a1SJiawen Wu * vendor ID and device ID stored in the hw structure. 179068eb13a1SJiawen Wu **/ 179168eb13a1SJiawen Wu s32 ngbe_set_mac_type(struct ngbe_hw *hw) 179268eb13a1SJiawen Wu { 179368eb13a1SJiawen Wu s32 err = 0; 179468eb13a1SJiawen Wu 179568eb13a1SJiawen Wu if (hw->vendor_id != PCI_VENDOR_ID_WANGXUN) { 179668eb13a1SJiawen Wu DEBUGOUT("Unsupported vendor id: %x", hw->vendor_id); 179768eb13a1SJiawen Wu return NGBE_ERR_DEVICE_NOT_SUPPORTED; 179868eb13a1SJiawen Wu } 179968eb13a1SJiawen Wu 180068eb13a1SJiawen Wu switch (hw->sub_device_id) { 180168eb13a1SJiawen Wu case NGBE_SUB_DEV_ID_EM_RTL_SGMII: 180268eb13a1SJiawen Wu case NGBE_SUB_DEV_ID_EM_MVL_RGMII: 180368eb13a1SJiawen Wu hw->phy.media_type = ngbe_media_type_copper; 180468eb13a1SJiawen Wu hw->mac.type = ngbe_mac_em; 18051c44384fSJiawen Wu hw->mac.link_type = ngbe_link_copper; 18061c44384fSJiawen Wu break; 18071c44384fSJiawen Wu case NGBE_SUB_DEV_ID_EM_RTL_YT8521S_SFP: 18081c44384fSJiawen Wu hw->phy.media_type = ngbe_media_type_copper; 18091c44384fSJiawen Wu hw->mac.type = ngbe_mac_em; 18101c44384fSJiawen Wu hw->mac.link_type = ngbe_link_fiber; 181168eb13a1SJiawen Wu break; 181268eb13a1SJiawen Wu case NGBE_SUB_DEV_ID_EM_MVL_SFP: 181368eb13a1SJiawen Wu case NGBE_SUB_DEV_ID_EM_YT8521S_SFP: 181468eb13a1SJiawen Wu hw->phy.media_type = ngbe_media_type_fiber; 181568eb13a1SJiawen Wu hw->mac.type = ngbe_mac_em; 18161c44384fSJiawen Wu hw->mac.link_type = ngbe_link_fiber; 18171c44384fSJiawen Wu break; 18181c44384fSJiawen Wu case NGBE_SUB_DEV_ID_EM_MVL_MIX: 18191c44384fSJiawen Wu hw->phy.media_type = ngbe_media_type_unknown; 18201c44384fSJiawen Wu hw->mac.type = ngbe_mac_em; 18211c44384fSJiawen Wu hw->mac.link_type = ngbe_link_type_unknown; 182268eb13a1SJiawen Wu break; 182368eb13a1SJiawen Wu case NGBE_SUB_DEV_ID_EM_VF: 182468eb13a1SJiawen Wu hw->phy.media_type = ngbe_media_type_virtual; 182568eb13a1SJiawen Wu hw->mac.type = ngbe_mac_em_vf; 182668eb13a1SJiawen Wu break; 182768eb13a1SJiawen Wu default: 182868eb13a1SJiawen Wu err = NGBE_ERR_DEVICE_NOT_SUPPORTED; 182968eb13a1SJiawen Wu hw->phy.media_type = ngbe_media_type_unknown; 183068eb13a1SJiawen Wu hw->mac.type = ngbe_mac_unknown; 183168eb13a1SJiawen Wu DEBUGOUT("Unsupported device id: %x", hw->device_id); 183268eb13a1SJiawen Wu break; 183368eb13a1SJiawen Wu } 183468eb13a1SJiawen Wu 1835c811e6a4SJiawen Wu DEBUGOUT("found mac: %d media: %d, returns: %d", 183668eb13a1SJiawen Wu hw->mac.type, hw->phy.media_type, err); 183768eb13a1SJiawen Wu return err; 183868eb13a1SJiawen Wu } 183968eb13a1SJiawen Wu 184062fc35e6SJiawen Wu /** 184162fc35e6SJiawen Wu * ngbe_enable_rx_dma - Enable the Rx DMA unit 184262fc35e6SJiawen Wu * @hw: pointer to hardware structure 184362fc35e6SJiawen Wu * @regval: register value to write to RXCTRL 184462fc35e6SJiawen Wu * 184562fc35e6SJiawen Wu * Enables the Rx DMA unit 184662fc35e6SJiawen Wu **/ 184762fc35e6SJiawen Wu s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval) 184862fc35e6SJiawen Wu { 184962fc35e6SJiawen Wu /* 185062fc35e6SJiawen Wu * Workaround silicon errata when enabling the Rx datapath. 185162fc35e6SJiawen Wu * If traffic is incoming before we enable the Rx unit, it could hang 185262fc35e6SJiawen Wu * the Rx DMA unit. Therefore, make sure the security engine is 185362fc35e6SJiawen Wu * completely disabled prior to enabling the Rx unit. 185462fc35e6SJiawen Wu */ 185562fc35e6SJiawen Wu hw->mac.disable_sec_rx_path(hw); 185662fc35e6SJiawen Wu 185762fc35e6SJiawen Wu if (regval & NGBE_PBRXCTL_ENA) 185862fc35e6SJiawen Wu ngbe_enable_rx(hw); 185962fc35e6SJiawen Wu else 186062fc35e6SJiawen Wu ngbe_disable_rx(hw); 186162fc35e6SJiawen Wu 186262fc35e6SJiawen Wu hw->mac.enable_sec_rx_path(hw); 186362fc35e6SJiawen Wu 186462fc35e6SJiawen Wu return 0; 186562fc35e6SJiawen Wu } 186662fc35e6SJiawen Wu 18676dcfb19fSJiawen Wu /* cmd_addr is used for some special command: 18686dcfb19fSJiawen Wu * 1. to be sector address, when implemented erase sector command 18696dcfb19fSJiawen Wu * 2. to be flash address when implemented read, write flash address 1870240422edSJiawen Wu * 187191e64c0eSJiawen Wu * Return 0 on success, return NGBE_ERR_TIMEOUT on failure. 18726dcfb19fSJiawen Wu */ 187391e64c0eSJiawen Wu s32 ngbe_fmgr_cmd_op(struct ngbe_hw *hw, u32 cmd, u32 cmd_addr) 18746dcfb19fSJiawen Wu { 1875240422edSJiawen Wu u32 cmd_val, i; 18766dcfb19fSJiawen Wu 18776dcfb19fSJiawen Wu cmd_val = NGBE_SPICMD_CMD(cmd) | NGBE_SPICMD_CLK(3) | cmd_addr; 18786dcfb19fSJiawen Wu wr32(hw, NGBE_SPICMD, cmd_val); 18796dcfb19fSJiawen Wu 1880240422edSJiawen Wu for (i = 0; i < NGBE_SPI_TIMEOUT; i++) { 18816dcfb19fSJiawen Wu if (rd32(hw, NGBE_SPISTAT) & NGBE_SPISTAT_OPDONE) 18826dcfb19fSJiawen Wu break; 18836dcfb19fSJiawen Wu 18846dcfb19fSJiawen Wu usec_delay(10); 18856dcfb19fSJiawen Wu } 1886240422edSJiawen Wu if (i == NGBE_SPI_TIMEOUT) 188791e64c0eSJiawen Wu return NGBE_ERR_TIMEOUT; 18886dcfb19fSJiawen Wu 18896dcfb19fSJiawen Wu return 0; 18906dcfb19fSJiawen Wu } 18916dcfb19fSJiawen Wu 189291e64c0eSJiawen Wu s32 ngbe_flash_read_dword(struct ngbe_hw *hw, u32 addr, u32 *data) 18936dcfb19fSJiawen Wu { 189491e64c0eSJiawen Wu s32 status; 18956dcfb19fSJiawen Wu 18966dcfb19fSJiawen Wu status = ngbe_fmgr_cmd_op(hw, 1, addr); 189791e64c0eSJiawen Wu if (status < 0) { 18986dcfb19fSJiawen Wu DEBUGOUT("Read flash timeout."); 18996dcfb19fSJiawen Wu return status; 19006dcfb19fSJiawen Wu } 19016dcfb19fSJiawen Wu 190291e64c0eSJiawen Wu *data = rd32(hw, NGBE_SPIDAT); 190391e64c0eSJiawen Wu 190491e64c0eSJiawen Wu return 0; 19056dcfb19fSJiawen Wu } 19066dcfb19fSJiawen Wu 1907696a8211SJiawen Wu void ngbe_read_efuse(struct ngbe_hw *hw) 1908696a8211SJiawen Wu { 190991e64c0eSJiawen Wu u32 efuse[2] = {0, 0}; 1910696a8211SJiawen Wu u8 lan_id = hw->bus.lan_id; 1911696a8211SJiawen Wu 191291e64c0eSJiawen Wu ngbe_flash_read_dword(hw, 0xfe010 + lan_id * 8, &efuse[0]); 191391e64c0eSJiawen Wu ngbe_flash_read_dword(hw, 0xfe010 + lan_id * 8 + 4, &efuse[1]); 1914696a8211SJiawen Wu 191591e64c0eSJiawen Wu DEBUGOUT("port %d efuse[0] = %08x, efuse[1] = %08x", 1916696a8211SJiawen Wu lan_id, efuse[0], efuse[1]); 1917696a8211SJiawen Wu 1918696a8211SJiawen Wu hw->gphy_efuse[0] = efuse[0]; 1919696a8211SJiawen Wu hw->gphy_efuse[1] = efuse[1]; 1920696a8211SJiawen Wu } 1921696a8211SJiawen Wu 192268eb13a1SJiawen Wu void ngbe_map_device_id(struct ngbe_hw *hw) 192368eb13a1SJiawen Wu { 192468eb13a1SJiawen Wu u16 oem = hw->sub_system_id & NGBE_OEM_MASK; 19251c44384fSJiawen Wu 192668eb13a1SJiawen Wu hw->is_pf = true; 192768eb13a1SJiawen Wu 192868eb13a1SJiawen Wu /* move subsystem_device_id to device_id */ 192968eb13a1SJiawen Wu switch (hw->device_id) { 193068eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860AL_W_VF: 193168eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A2_VF: 193268eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A2S_VF: 193368eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A4_VF: 193468eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A4S_VF: 193568eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860AL2_VF: 193668eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860AL2S_VF: 193768eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860AL4_VF: 193868eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860AL4S_VF: 193968eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860NCSI_VF: 194068eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A1_VF: 194168eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A1L_VF: 194268eb13a1SJiawen Wu hw->device_id = NGBE_DEV_ID_EM_VF; 194368eb13a1SJiawen Wu hw->sub_device_id = NGBE_SUB_DEV_ID_EM_VF; 194468eb13a1SJiawen Wu hw->is_pf = false; 194568eb13a1SJiawen Wu break; 194668eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860AL_W: 194768eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A2: 194868eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A2S: 194968eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A4: 195068eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A4S: 195168eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860AL2: 195268eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860AL2S: 195368eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860AL4: 195468eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860AL4S: 195568eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860NCSI: 195668eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A1: 195768eb13a1SJiawen Wu case NGBE_DEV_ID_EM_WX1860A1L: 195868eb13a1SJiawen Wu hw->device_id = NGBE_DEV_ID_EM; 19591c44384fSJiawen Wu if (oem == NGBE_M88E1512_SFP || oem == NGBE_LY_M88E1512_SFP) 196068eb13a1SJiawen Wu hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_SFP; 19611c44384fSJiawen Wu else if (oem == NGBE_M88E1512_RJ45 || 19621c44384fSJiawen Wu (hw->sub_system_id == NGBE_SUB_DEV_ID_EM_M88E1512_RJ45)) 196368eb13a1SJiawen Wu hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_RGMII; 19641c44384fSJiawen Wu else if (oem == NGBE_M88E1512_MIX) 19651c44384fSJiawen Wu hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_MIX; 196668eb13a1SJiawen Wu else if (oem == NGBE_YT8521S_SFP || 19671c44384fSJiawen Wu oem == NGBE_YT8521S_SFP_GPIO || 196868eb13a1SJiawen Wu oem == NGBE_LY_YT8521S_SFP) 196968eb13a1SJiawen Wu hw->sub_device_id = NGBE_SUB_DEV_ID_EM_YT8521S_SFP; 19701c44384fSJiawen Wu else if (oem == NGBE_INTERNAL_YT8521S_SFP || 19711c44384fSJiawen Wu oem == NGBE_INTERNAL_YT8521S_SFP_GPIO) 19721c44384fSJiawen Wu hw->sub_device_id = NGBE_SUB_DEV_ID_EM_RTL_YT8521S_SFP; 197368eb13a1SJiawen Wu else 197468eb13a1SJiawen Wu hw->sub_device_id = NGBE_SUB_DEV_ID_EM_RTL_SGMII; 197568eb13a1SJiawen Wu break; 197668eb13a1SJiawen Wu default: 197768eb13a1SJiawen Wu break; 197868eb13a1SJiawen Wu } 19791c44384fSJiawen Wu 19801c44384fSJiawen Wu if (oem == NGBE_LY_M88E1512_SFP || oem == NGBE_YT8521S_SFP_GPIO || 19811c44384fSJiawen Wu oem == NGBE_INTERNAL_YT8521S_SFP_GPIO || 19821c44384fSJiawen Wu oem == NGBE_LY_YT8521S_SFP) 19831c44384fSJiawen Wu hw->gpio_ctl = true; 19845f1ab0d5SJiawen Wu 19855f1ab0d5SJiawen Wu hw->wol_enabled = (hw->sub_system_id & NGBE_WOL_SUP_MASK) ? true : false; 19865f1ab0d5SJiawen Wu hw->ncsi_enabled = (hw->sub_system_id & NGBE_NCSI_SUP_MASK || 19875f1ab0d5SJiawen Wu hw->sub_system_id & NGBE_OCP_CARD) ? true : false; 198868eb13a1SJiawen Wu } 198968eb13a1SJiawen Wu 199068eb13a1SJiawen Wu /** 199168eb13a1SJiawen Wu * ngbe_init_ops_pf - Inits func ptrs and MAC type 199268eb13a1SJiawen Wu * @hw: pointer to hardware structure 199368eb13a1SJiawen Wu * 199468eb13a1SJiawen Wu * Initialize the function pointers and assign the MAC type. 199568eb13a1SJiawen Wu * Does not touch the hardware. 199668eb13a1SJiawen Wu **/ 199768eb13a1SJiawen Wu s32 ngbe_init_ops_pf(struct ngbe_hw *hw) 199868eb13a1SJiawen Wu { 199968eb13a1SJiawen Wu struct ngbe_bus_info *bus = &hw->bus; 2000f501a195SJiawen Wu struct ngbe_mac_info *mac = &hw->mac; 200144e97550SJiawen Wu struct ngbe_phy_info *phy = &hw->phy; 2002f501a195SJiawen Wu struct ngbe_rom_info *rom = &hw->rom; 200360229dcfSJiawen Wu struct ngbe_mbx_info *mbx = &hw->mbx; 200468eb13a1SJiawen Wu 200568eb13a1SJiawen Wu /* BUS */ 200668eb13a1SJiawen Wu bus->set_lan_id = ngbe_set_lan_id_multi_port; 200768eb13a1SJiawen Wu 200844e97550SJiawen Wu /* PHY */ 200944e97550SJiawen Wu phy->identify = ngbe_identify_phy; 201044e97550SJiawen Wu phy->read_reg = ngbe_read_phy_reg; 201144e97550SJiawen Wu phy->write_reg = ngbe_write_phy_reg; 201244e97550SJiawen Wu phy->read_reg_unlocked = ngbe_read_phy_reg_mdi; 201344e97550SJiawen Wu phy->write_reg_unlocked = ngbe_write_phy_reg_mdi; 201444e97550SJiawen Wu phy->reset_hw = ngbe_reset_phy; 2015fbd5ceb0SJiawen Wu phy->led_oem_chk = ngbe_phy_led_oem_chk; 201644e97550SJiawen Wu 2017f501a195SJiawen Wu /* MAC */ 201878710873SJiawen Wu mac->init_hw = ngbe_init_hw; 201978710873SJiawen Wu mac->reset_hw = ngbe_reset_hw_em; 20203518df57SJiawen Wu mac->start_hw = ngbe_start_hw; 2021fdb1e851SJiawen Wu mac->clear_hw_cntrs = ngbe_clear_hw_cntrs; 202262fc35e6SJiawen Wu mac->enable_rx_dma = ngbe_enable_rx_dma; 2023539d55daSJiawen Wu mac->get_mac_addr = ngbe_get_mac_addr; 202478710873SJiawen Wu mac->stop_hw = ngbe_stop_hw; 2025f501a195SJiawen Wu mac->acquire_swfw_sync = ngbe_acquire_swfw_sync; 2026f501a195SJiawen Wu mac->release_swfw_sync = ngbe_release_swfw_sync; 2027f501a195SJiawen Wu 202862fc35e6SJiawen Wu mac->disable_sec_rx_path = ngbe_disable_sec_rx_path; 202962fc35e6SJiawen Wu mac->enable_sec_rx_path = ngbe_enable_sec_rx_path; 2030e2a289a7SJiawen Wu 20314db3db29SJiawen Wu /* LEDs */ 20324db3db29SJiawen Wu mac->led_on = ngbe_led_on; 20334db3db29SJiawen Wu mac->led_off = ngbe_led_off; 20344db3db29SJiawen Wu 2035dee93977SJiawen Wu /* RAR, VLAN, Multicast */ 2036539d55daSJiawen Wu mac->set_rar = ngbe_set_rar; 2037539d55daSJiawen Wu mac->clear_rar = ngbe_clear_rar; 2038539d55daSJiawen Wu mac->init_rx_addrs = ngbe_init_rx_addrs; 2039dee93977SJiawen Wu mac->update_mc_addr_list = ngbe_update_mc_addr_list; 2040539d55daSJiawen Wu mac->set_vmdq = ngbe_set_vmdq; 2041539d55daSJiawen Wu mac->clear_vmdq = ngbe_clear_vmdq; 2042e2a289a7SJiawen Wu mac->set_vfta = ngbe_set_vfta; 2043e2a289a7SJiawen Wu mac->set_vlvf = ngbe_set_vlvf; 204459b46438SJiawen Wu mac->clear_vfta = ngbe_clear_vfta; 204560229dcfSJiawen Wu mac->set_mac_anti_spoofing = ngbe_set_mac_anti_spoofing; 204660229dcfSJiawen Wu mac->set_vlan_anti_spoofing = ngbe_set_vlan_anti_spoofing; 2047539d55daSJiawen Wu 2048f40e9f0eSJiawen Wu /* Flow Control */ 2049f40e9f0eSJiawen Wu mac->fc_enable = ngbe_fc_enable; 2050f40e9f0eSJiawen Wu mac->fc_autoneg = ngbe_fc_autoneg; 2051f40e9f0eSJiawen Wu mac->setup_fc = ngbe_setup_fc_em; 2052f40e9f0eSJiawen Wu 20533d0af706SJiawen Wu /* Link */ 20543518df57SJiawen Wu mac->get_link_capabilities = ngbe_get_link_capabilities_em; 20553d0af706SJiawen Wu mac->check_link = ngbe_check_mac_link_em; 20563d0af706SJiawen Wu mac->setup_link = ngbe_setup_mac_link_em; 20573d0af706SJiawen Wu 2058ccdeca8eSJiawen Wu mac->setup_pba = ngbe_set_pba; 2059ccdeca8eSJiawen Wu 206078710873SJiawen Wu /* Manageability interface */ 206178710873SJiawen Wu mac->init_thermal_sensor_thresh = ngbe_init_thermal_sensor_thresh; 206244e97550SJiawen Wu mac->check_overtemp = ngbe_mac_check_overtemp; 206378710873SJiawen Wu 206460229dcfSJiawen Wu mbx->init_params = ngbe_init_mbx_params_pf; 2065e2a289a7SJiawen Wu mbx->read = ngbe_read_mbx_pf; 2066e2a289a7SJiawen Wu mbx->write = ngbe_write_mbx_pf; 2067e2a289a7SJiawen Wu mbx->check_for_msg = ngbe_check_for_msg_pf; 2068e2a289a7SJiawen Wu mbx->check_for_ack = ngbe_check_for_ack_pf; 2069e2a289a7SJiawen Wu mbx->check_for_rst = ngbe_check_for_rst_pf; 207060229dcfSJiawen Wu 2071f501a195SJiawen Wu /* EEPROM */ 2072f501a195SJiawen Wu rom->init_params = ngbe_init_eeprom_params; 20739459ea29SJiawen Wu rom->readw_buffer = ngbe_ee_readw_buffer; 2074506abd4aSJiawen Wu rom->read32 = ngbe_ee_read32; 20759459ea29SJiawen Wu rom->writew_buffer = ngbe_ee_writew_buffer; 2076f501a195SJiawen Wu rom->validate_checksum = ngbe_validate_eeprom_checksum_em; 2077f501a195SJiawen Wu 2078539d55daSJiawen Wu mac->mcft_size = NGBE_EM_MC_TBL_SIZE; 207959b46438SJiawen Wu mac->vft_size = NGBE_EM_VFT_TBL_SIZE; 2080539d55daSJiawen Wu mac->num_rar_entries = NGBE_EM_RAR_ENTRIES; 2081ccdeca8eSJiawen Wu mac->rx_pb_size = NGBE_EM_RX_PB_SIZE; 208278710873SJiawen Wu mac->max_rx_queues = NGBE_EM_MAX_RX_QUEUES; 208378710873SJiawen Wu mac->max_tx_queues = NGBE_EM_MAX_TX_QUEUES; 208478710873SJiawen Wu 20853518df57SJiawen Wu mac->default_speeds = NGBE_LINK_SPEED_10M_FULL | 20863518df57SJiawen Wu NGBE_LINK_SPEED_100M_FULL | 20873518df57SJiawen Wu NGBE_LINK_SPEED_1GB_FULL; 20883518df57SJiawen Wu 208968eb13a1SJiawen Wu return 0; 209068eb13a1SJiawen Wu } 209168eb13a1SJiawen Wu 209268eb13a1SJiawen Wu /** 209368eb13a1SJiawen Wu * ngbe_init_shared_code - Initialize the shared code 209468eb13a1SJiawen Wu * @hw: pointer to hardware structure 209568eb13a1SJiawen Wu * 209668eb13a1SJiawen Wu * This will assign function pointers and assign the MAC type and PHY code. 209768eb13a1SJiawen Wu * Does not touch the hardware. This function must be called prior to any 209868eb13a1SJiawen Wu * other function in the shared code. The ngbe_hw structure should be 209968eb13a1SJiawen Wu * memset to 0 prior to calling this function. The following fields in 210068eb13a1SJiawen Wu * hw structure should be filled in prior to calling this function: 210168eb13a1SJiawen Wu * hw_addr, back, device_id, vendor_id, subsystem_device_id 210268eb13a1SJiawen Wu **/ 210368eb13a1SJiawen Wu s32 ngbe_init_shared_code(struct ngbe_hw *hw) 210468eb13a1SJiawen Wu { 210568eb13a1SJiawen Wu s32 status = 0; 210668eb13a1SJiawen Wu 210768eb13a1SJiawen Wu /* 210868eb13a1SJiawen Wu * Set the mac type 210968eb13a1SJiawen Wu */ 211068eb13a1SJiawen Wu ngbe_set_mac_type(hw); 211168eb13a1SJiawen Wu 211268eb13a1SJiawen Wu ngbe_init_ops_dummy(hw); 211368eb13a1SJiawen Wu switch (hw->mac.type) { 211468eb13a1SJiawen Wu case ngbe_mac_em: 211568eb13a1SJiawen Wu ngbe_init_ops_pf(hw); 211668eb13a1SJiawen Wu break; 2117*950820f1SZaiyu Wang case ngbe_mac_em_vf: 2118*950820f1SZaiyu Wang ngbe_init_ops_vf(hw); 2119*950820f1SZaiyu Wang break; 212068eb13a1SJiawen Wu default: 212168eb13a1SJiawen Wu status = NGBE_ERR_DEVICE_NOT_SUPPORTED; 212268eb13a1SJiawen Wu break; 212368eb13a1SJiawen Wu } 21243d0af706SJiawen Wu hw->mac.max_link_up_time = NGBE_LINK_UP_TIME; 212568eb13a1SJiawen Wu 212668eb13a1SJiawen Wu hw->bus.set_lan_id(hw); 212768eb13a1SJiawen Wu 212868eb13a1SJiawen Wu return status; 212968eb13a1SJiawen Wu } 213068eb13a1SJiawen Wu 21315f1ab0d5SJiawen Wu void ngbe_set_ncsi_status(struct ngbe_hw *hw) 21325f1ab0d5SJiawen Wu { 21335f1ab0d5SJiawen Wu u16 ncsi_pin = 0; 21345f1ab0d5SJiawen Wu s32 err = 0; 21355f1ab0d5SJiawen Wu 21365f1ab0d5SJiawen Wu /* need to check ncsi pin status for oem ncsi card */ 21375f1ab0d5SJiawen Wu if (hw->ncsi_enabled || hw->wol_enabled) 21385f1ab0d5SJiawen Wu return; 21395f1ab0d5SJiawen Wu 21405f1ab0d5SJiawen Wu err = hw->rom.readw_buffer(hw, FW_READ_SHADOW_RAM_GPIO, 1, &ncsi_pin); 21415f1ab0d5SJiawen Wu if (err) { 21425f1ab0d5SJiawen Wu DEBUGOUT("get ncsi pin status failed"); 21435f1ab0d5SJiawen Wu return; 21445f1ab0d5SJiawen Wu } 21455f1ab0d5SJiawen Wu 21465f1ab0d5SJiawen Wu if (ncsi_pin == 1) { 21475f1ab0d5SJiawen Wu hw->ncsi_enabled = true; 21485f1ab0d5SJiawen Wu hw->wol_enabled = true; 21495f1ab0d5SJiawen Wu } 21505f1ab0d5SJiawen Wu } 2151