188f5b657SHoward Wang /* SPDX-License-Identifier: BSD-3-Clause 288f5b657SHoward Wang * Copyright(c) 2024 Realtek Corporation. All rights reserved 388f5b657SHoward Wang */ 488f5b657SHoward Wang 588f5b657SHoward Wang #include <stdio.h> 688f5b657SHoward Wang #include <errno.h> 788f5b657SHoward Wang #include <stdint.h> 888f5b657SHoward Wang 988f5b657SHoward Wang #include <rte_ether.h> 1088f5b657SHoward Wang #include <ethdev_driver.h> 1188f5b657SHoward Wang 1288f5b657SHoward Wang #include "r8169_hw.h" 1388f5b657SHoward Wang #include "r8169_logs.h" 147d502791SHoward Wang #include "r8169_dash.h" 1588f5b657SHoward Wang 16619f6ebcSHoward Wang static u32 17619f6ebcSHoward Wang rtl_eri_read_with_oob_base_address(struct rtl_hw *hw, int addr, int len, 18619f6ebcSHoward Wang int type, const u32 base_address) 19619f6ebcSHoward Wang { 20619f6ebcSHoward Wang int i, val_shift, shift = 0; 21619f6ebcSHoward Wang u32 value1 = 0; 22619f6ebcSHoward Wang u32 value2 = 0; 23619f6ebcSHoward Wang u32 eri_cmd, tmp, mask; 24619f6ebcSHoward Wang const u32 transformed_base_address = ((base_address & 0x00FFF000) << 6) | 25619f6ebcSHoward Wang (base_address & 0x000FFF); 26619f6ebcSHoward Wang 27619f6ebcSHoward Wang if (len > 4 || len <= 0) 28619f6ebcSHoward Wang return -1; 29619f6ebcSHoward Wang 30619f6ebcSHoward Wang while (len > 0) { 31619f6ebcSHoward Wang val_shift = addr % ERIAR_Addr_Align; 32619f6ebcSHoward Wang addr = addr & ~0x3; 33619f6ebcSHoward Wang 34619f6ebcSHoward Wang eri_cmd = ERIAR_Read | transformed_base_address | 35619f6ebcSHoward Wang type << ERIAR_Type_shift | 36619f6ebcSHoward Wang ERIAR_ByteEn << ERIAR_ByteEn_shift | 37619f6ebcSHoward Wang (addr & 0x0FFF); 38619f6ebcSHoward Wang if (addr & 0xF000) { 39619f6ebcSHoward Wang tmp = addr & 0xF000; 40619f6ebcSHoward Wang tmp >>= 12; 41619f6ebcSHoward Wang eri_cmd |= (tmp << 20) & 0x00F00000; 42619f6ebcSHoward Wang } 43619f6ebcSHoward Wang 44619f6ebcSHoward Wang RTL_W32(hw, ERIAR, eri_cmd); 45619f6ebcSHoward Wang 46619f6ebcSHoward Wang for (i = 0; i < RTL_CHANNEL_WAIT_COUNT; i++) { 47619f6ebcSHoward Wang rte_delay_us(RTL_CHANNEL_WAIT_TIME); 48619f6ebcSHoward Wang 49619f6ebcSHoward Wang /* Check if the NIC has completed ERI read */ 50619f6ebcSHoward Wang if (RTL_R32(hw, ERIAR) & ERIAR_Flag) 51619f6ebcSHoward Wang break; 52619f6ebcSHoward Wang } 53619f6ebcSHoward Wang 54619f6ebcSHoward Wang if (len == 1) 55619f6ebcSHoward Wang mask = (0xFF << (val_shift * 8)) & 0xFFFFFFFF; 56619f6ebcSHoward Wang else if (len == 2) 57619f6ebcSHoward Wang mask = (0xFFFF << (val_shift * 8)) & 0xFFFFFFFF; 58619f6ebcSHoward Wang else if (len == 3) 59619f6ebcSHoward Wang mask = (0xFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; 60619f6ebcSHoward Wang else 61619f6ebcSHoward Wang mask = (0xFFFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; 62619f6ebcSHoward Wang 63619f6ebcSHoward Wang value1 = RTL_R32(hw, ERIDR) & mask; 64619f6ebcSHoward Wang value2 |= (value1 >> val_shift * 8) << shift * 8; 65619f6ebcSHoward Wang 66619f6ebcSHoward Wang if (len <= 4 - val_shift) { 67619f6ebcSHoward Wang len = 0; 68619f6ebcSHoward Wang } else { 69619f6ebcSHoward Wang len -= (4 - val_shift); 70619f6ebcSHoward Wang shift = 4 - val_shift; 71619f6ebcSHoward Wang addr += 4; 72619f6ebcSHoward Wang } 73619f6ebcSHoward Wang } 74619f6ebcSHoward Wang 75619f6ebcSHoward Wang rte_delay_us(RTL_CHANNEL_EXIT_DELAY_TIME); 76619f6ebcSHoward Wang 77619f6ebcSHoward Wang return value2; 78619f6ebcSHoward Wang } 79619f6ebcSHoward Wang 80619f6ebcSHoward Wang static int 81619f6ebcSHoward Wang rtl_eri_write_with_oob_base_address(struct rtl_hw *hw, int addr, 82619f6ebcSHoward Wang int len, u32 value, int type, const u32 base_address) 83619f6ebcSHoward Wang { 84619f6ebcSHoward Wang int i, val_shift, shift = 0; 85619f6ebcSHoward Wang u32 value1 = 0; 86619f6ebcSHoward Wang u32 eri_cmd, mask, tmp; 87619f6ebcSHoward Wang const u32 transformed_base_address = ((base_address & 0x00FFF000) << 6) | 88619f6ebcSHoward Wang (base_address & 0x000FFF); 89619f6ebcSHoward Wang 90619f6ebcSHoward Wang if (len > 4 || len <= 0) 91619f6ebcSHoward Wang return -1; 92619f6ebcSHoward Wang 93619f6ebcSHoward Wang while (len > 0) { 94619f6ebcSHoward Wang val_shift = addr % ERIAR_Addr_Align; 95619f6ebcSHoward Wang addr = addr & ~0x3; 96619f6ebcSHoward Wang 97619f6ebcSHoward Wang if (len == 1) 98619f6ebcSHoward Wang mask = (0xFF << (val_shift * 8)) & 0xFFFFFFFF; 99619f6ebcSHoward Wang else if (len == 2) 100619f6ebcSHoward Wang mask = (0xFFFF << (val_shift * 8)) & 0xFFFFFFFF; 101619f6ebcSHoward Wang else if (len == 3) 102619f6ebcSHoward Wang mask = (0xFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; 103619f6ebcSHoward Wang else 104619f6ebcSHoward Wang mask = (0xFFFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; 105619f6ebcSHoward Wang 106619f6ebcSHoward Wang value1 = rtl_eri_read_with_oob_base_address(hw, addr, 4, type, 107619f6ebcSHoward Wang base_address) & ~mask; 108619f6ebcSHoward Wang value1 |= ((value << val_shift * 8) >> shift * 8); 109619f6ebcSHoward Wang 110619f6ebcSHoward Wang RTL_W32(hw, ERIDR, value1); 111619f6ebcSHoward Wang 112619f6ebcSHoward Wang eri_cmd = ERIAR_Write | transformed_base_address | 113619f6ebcSHoward Wang type << ERIAR_Type_shift | 114619f6ebcSHoward Wang ERIAR_ByteEn << ERIAR_ByteEn_shift | 115619f6ebcSHoward Wang (addr & 0x0FFF); 116619f6ebcSHoward Wang if (addr & 0xF000) { 117619f6ebcSHoward Wang tmp = addr & 0xF000; 118619f6ebcSHoward Wang tmp >>= 12; 119619f6ebcSHoward Wang eri_cmd |= (tmp << 20) & 0x00F00000; 120619f6ebcSHoward Wang } 121619f6ebcSHoward Wang 122619f6ebcSHoward Wang RTL_W32(hw, ERIAR, eri_cmd); 123619f6ebcSHoward Wang 124619f6ebcSHoward Wang for (i = 0; i < RTL_CHANNEL_WAIT_COUNT; i++) { 125619f6ebcSHoward Wang rte_delay_us(RTL_CHANNEL_WAIT_TIME); 126619f6ebcSHoward Wang 127619f6ebcSHoward Wang /* Check if the NIC has completed ERI write */ 128619f6ebcSHoward Wang if (!(RTL_R32(hw, ERIAR) & ERIAR_Flag)) 129619f6ebcSHoward Wang break; 130619f6ebcSHoward Wang } 131619f6ebcSHoward Wang 132619f6ebcSHoward Wang if (len <= 4 - val_shift) { 133619f6ebcSHoward Wang len = 0; 134619f6ebcSHoward Wang } else { 135619f6ebcSHoward Wang len -= (4 - val_shift); 136619f6ebcSHoward Wang shift = 4 - val_shift; 137619f6ebcSHoward Wang addr += 4; 138619f6ebcSHoward Wang } 139619f6ebcSHoward Wang } 140619f6ebcSHoward Wang 141619f6ebcSHoward Wang rte_delay_us(RTL_CHANNEL_EXIT_DELAY_TIME); 142619f6ebcSHoward Wang 143619f6ebcSHoward Wang return 0; 144619f6ebcSHoward Wang } 145619f6ebcSHoward Wang 146619f6ebcSHoward Wang static u32 147619f6ebcSHoward Wang rtl_ocp_read_with_oob_base_address(struct rtl_hw *hw, u16 addr, u8 len, 148619f6ebcSHoward Wang const u32 base_address) 149619f6ebcSHoward Wang { 150619f6ebcSHoward Wang return rtl_eri_read_with_oob_base_address(hw, addr, len, ERIAR_OOB, 151619f6ebcSHoward Wang base_address); 152619f6ebcSHoward Wang } 153619f6ebcSHoward Wang 154619f6ebcSHoward Wang u32 155619f6ebcSHoward Wang rtl_ocp_read(struct rtl_hw *hw, u16 addr, u8 len) 156619f6ebcSHoward Wang { 157619f6ebcSHoward Wang u32 value = 0; 158619f6ebcSHoward Wang 159619f6ebcSHoward Wang if (!hw->AllowAccessDashOcp) 160619f6ebcSHoward Wang return 0xffffffff; 161619f6ebcSHoward Wang 162619f6ebcSHoward Wang if (hw->HwSuppOcpChannelVer == 2) 163619f6ebcSHoward Wang value = rtl_ocp_read_with_oob_base_address(hw, addr, len, NO_BASE_ADDRESS); 164619f6ebcSHoward Wang 165619f6ebcSHoward Wang return value; 166619f6ebcSHoward Wang } 167619f6ebcSHoward Wang 168619f6ebcSHoward Wang static u32 169619f6ebcSHoward Wang rtl_ocp_write_with_oob_base_address(struct rtl_hw *hw, u16 addr, u8 len, 170619f6ebcSHoward Wang u32 value, const u32 base_address) 171619f6ebcSHoward Wang { 172619f6ebcSHoward Wang return rtl_eri_write_with_oob_base_address(hw, addr, len, value, ERIAR_OOB, 173619f6ebcSHoward Wang base_address); 174619f6ebcSHoward Wang } 175619f6ebcSHoward Wang 176619f6ebcSHoward Wang void 177619f6ebcSHoward Wang rtl_ocp_write(struct rtl_hw *hw, u16 addr, u8 len, u32 value) 178619f6ebcSHoward Wang { 179619f6ebcSHoward Wang if (!hw->AllowAccessDashOcp) 180619f6ebcSHoward Wang return; 181619f6ebcSHoward Wang 182619f6ebcSHoward Wang if (hw->HwSuppOcpChannelVer == 2) 183619f6ebcSHoward Wang rtl_ocp_write_with_oob_base_address(hw, addr, len, value, NO_BASE_ADDRESS); 184619f6ebcSHoward Wang } 185619f6ebcSHoward Wang 186619f6ebcSHoward Wang void 187619f6ebcSHoward Wang rtl8125_oob_mutex_lock(struct rtl_hw *hw) 188619f6ebcSHoward Wang { 189619f6ebcSHoward Wang u8 reg_16, reg_a0; 190619f6ebcSHoward Wang u16 ocp_reg_mutex_ib; 191619f6ebcSHoward Wang u16 ocp_reg_mutex_oob; 192619f6ebcSHoward Wang u16 ocp_reg_mutex_prio; 193619f6ebcSHoward Wang u32 wait_cnt_0, wait_cnt_1; 194619f6ebcSHoward Wang 195619f6ebcSHoward Wang if (!hw->DASH) 196619f6ebcSHoward Wang return; 197619f6ebcSHoward Wang 198619f6ebcSHoward Wang switch (hw->mcfg) { 199619f6ebcSHoward Wang case CFG_METHOD_48: 200619f6ebcSHoward Wang case CFG_METHOD_49: 201619f6ebcSHoward Wang case CFG_METHOD_52: 202619f6ebcSHoward Wang case CFG_METHOD_54: 203619f6ebcSHoward Wang case CFG_METHOD_55: 204619f6ebcSHoward Wang ocp_reg_mutex_oob = 0x110; 205619f6ebcSHoward Wang ocp_reg_mutex_ib = 0x114; 206619f6ebcSHoward Wang ocp_reg_mutex_prio = 0x11C; 207619f6ebcSHoward Wang break; 208619f6ebcSHoward Wang default: 209619f6ebcSHoward Wang return; 210619f6ebcSHoward Wang } 211619f6ebcSHoward Wang 212619f6ebcSHoward Wang rtl_ocp_write(hw, ocp_reg_mutex_ib, 1, BIT_0); 213619f6ebcSHoward Wang reg_16 = rtl_ocp_read(hw, ocp_reg_mutex_oob, 1); 214619f6ebcSHoward Wang wait_cnt_0 = 0; 215619f6ebcSHoward Wang while (reg_16) { 216619f6ebcSHoward Wang reg_a0 = rtl_ocp_read(hw, ocp_reg_mutex_prio, 1); 217619f6ebcSHoward Wang if (reg_a0) { 218619f6ebcSHoward Wang rtl_ocp_write(hw, ocp_reg_mutex_ib, 1, 0x00); 219619f6ebcSHoward Wang reg_a0 = rtl_ocp_read(hw, ocp_reg_mutex_prio, 1); 220619f6ebcSHoward Wang wait_cnt_1 = 0; 221619f6ebcSHoward Wang while (reg_a0) { 222619f6ebcSHoward Wang reg_a0 = rtl_ocp_read(hw, ocp_reg_mutex_prio, 1); 223619f6ebcSHoward Wang 224619f6ebcSHoward Wang wait_cnt_1++; 225619f6ebcSHoward Wang 226619f6ebcSHoward Wang if (wait_cnt_1 > 2000) 227619f6ebcSHoward Wang break; 228619f6ebcSHoward Wang }; 229619f6ebcSHoward Wang rtl_ocp_write(hw, ocp_reg_mutex_ib, 1, BIT_0); 230619f6ebcSHoward Wang } 231619f6ebcSHoward Wang reg_16 = rtl_ocp_read(hw, ocp_reg_mutex_oob, 1); 232619f6ebcSHoward Wang 233619f6ebcSHoward Wang wait_cnt_0++; 234619f6ebcSHoward Wang 235619f6ebcSHoward Wang if (wait_cnt_0 > 2000) 236619f6ebcSHoward Wang break; 237619f6ebcSHoward Wang }; 238619f6ebcSHoward Wang } 239619f6ebcSHoward Wang 240619f6ebcSHoward Wang void 241619f6ebcSHoward Wang rtl8125_oob_mutex_unlock(struct rtl_hw *hw) 242619f6ebcSHoward Wang { 243619f6ebcSHoward Wang u16 ocp_reg_mutex_ib; 244619f6ebcSHoward Wang u16 ocp_reg_mutex_prio; 245619f6ebcSHoward Wang 246619f6ebcSHoward Wang if (!hw->DASH) 247619f6ebcSHoward Wang return; 248619f6ebcSHoward Wang 249619f6ebcSHoward Wang switch (hw->mcfg) { 250619f6ebcSHoward Wang case CFG_METHOD_48: 251619f6ebcSHoward Wang case CFG_METHOD_49: 252619f6ebcSHoward Wang case CFG_METHOD_52: 253619f6ebcSHoward Wang case CFG_METHOD_54: 254619f6ebcSHoward Wang case CFG_METHOD_55: 255619f6ebcSHoward Wang ocp_reg_mutex_ib = 0x114; 256619f6ebcSHoward Wang ocp_reg_mutex_prio = 0x11C; 257619f6ebcSHoward Wang break; 258619f6ebcSHoward Wang default: 259619f6ebcSHoward Wang return; 260619f6ebcSHoward Wang } 261619f6ebcSHoward Wang 262619f6ebcSHoward Wang rtl_ocp_write(hw, ocp_reg_mutex_prio, 1, BIT_0); 263619f6ebcSHoward Wang rtl_ocp_write(hw, ocp_reg_mutex_ib, 1, 0x00); 264619f6ebcSHoward Wang } 265619f6ebcSHoward Wang 26688f5b657SHoward Wang void 26788f5b657SHoward Wang rtl_mac_ocp_write(struct rtl_hw *hw, u16 addr, u16 value) 26888f5b657SHoward Wang { 26988f5b657SHoward Wang u32 data32; 27088f5b657SHoward Wang 27188f5b657SHoward Wang data32 = addr / 2; 27288f5b657SHoward Wang data32 <<= OCPR_Addr_Reg_shift; 27388f5b657SHoward Wang data32 += value; 27488f5b657SHoward Wang data32 |= OCPR_Write; 27588f5b657SHoward Wang 27688f5b657SHoward Wang RTL_W32(hw, MACOCP, data32); 27788f5b657SHoward Wang } 27888f5b657SHoward Wang 27988f5b657SHoward Wang u16 28088f5b657SHoward Wang rtl_mac_ocp_read(struct rtl_hw *hw, u16 addr) 28188f5b657SHoward Wang { 28288f5b657SHoward Wang u32 data32; 28388f5b657SHoward Wang u16 data16 = 0; 28488f5b657SHoward Wang 28588f5b657SHoward Wang data32 = addr / 2; 28688f5b657SHoward Wang data32 <<= OCPR_Addr_Reg_shift; 28788f5b657SHoward Wang 28888f5b657SHoward Wang RTL_W32(hw, MACOCP, data32); 28988f5b657SHoward Wang data16 = (u16)RTL_R32(hw, MACOCP); 29088f5b657SHoward Wang 29188f5b657SHoward Wang return data16; 29288f5b657SHoward Wang } 29388f5b657SHoward Wang 29488f5b657SHoward Wang u32 29588f5b657SHoward Wang rtl_csi_read(struct rtl_hw *hw, u32 addr) 29688f5b657SHoward Wang { 29788f5b657SHoward Wang u32 cmd; 29888f5b657SHoward Wang int i; 29988f5b657SHoward Wang u32 value = 0; 30088f5b657SHoward Wang 30188f5b657SHoward Wang cmd = CSIAR_Read | CSIAR_ByteEn << CSIAR_ByteEn_shift | 30288f5b657SHoward Wang (addr & CSIAR_Addr_Mask); 30388f5b657SHoward Wang 30488f5b657SHoward Wang RTL_W32(hw, CSIAR, cmd); 30588f5b657SHoward Wang 30688f5b657SHoward Wang for (i = 0; i < 10; i++) { 30788f5b657SHoward Wang rte_delay_us(100); 30888f5b657SHoward Wang 30988f5b657SHoward Wang /* Check if the NIC has completed CSI read */ 31088f5b657SHoward Wang if (RTL_R32(hw, CSIAR) & CSIAR_Flag) { 31188f5b657SHoward Wang value = RTL_R32(hw, CSIDR); 31288f5b657SHoward Wang break; 31388f5b657SHoward Wang } 31488f5b657SHoward Wang } 31588f5b657SHoward Wang 31688f5b657SHoward Wang rte_delay_us(20); 31788f5b657SHoward Wang 31888f5b657SHoward Wang return value; 31988f5b657SHoward Wang } 32088f5b657SHoward Wang 32188f5b657SHoward Wang void 32288f5b657SHoward Wang rtl_csi_write(struct rtl_hw *hw, u32 addr, u32 value) 32388f5b657SHoward Wang { 32488f5b657SHoward Wang u32 cmd; 32588f5b657SHoward Wang int i; 32688f5b657SHoward Wang 32788f5b657SHoward Wang RTL_W32(hw, CSIDR, value); 32888f5b657SHoward Wang cmd = CSIAR_Write | CSIAR_ByteEn << CSIAR_ByteEn_shift | 32988f5b657SHoward Wang (addr & CSIAR_Addr_Mask); 33088f5b657SHoward Wang 33188f5b657SHoward Wang RTL_W32(hw, CSIAR, cmd); 33288f5b657SHoward Wang 33388f5b657SHoward Wang for (i = 0; i < RTL_CHANNEL_WAIT_COUNT; i++) { 33488f5b657SHoward Wang rte_delay_us(RTL_CHANNEL_WAIT_TIME); 33588f5b657SHoward Wang 33688f5b657SHoward Wang /* Check if the NIC has completed CSI write */ 33788f5b657SHoward Wang if (!(RTL_R32(hw, CSIAR) & CSIAR_Flag)) 33888f5b657SHoward Wang break; 33988f5b657SHoward Wang } 34088f5b657SHoward Wang 34188f5b657SHoward Wang rte_delay_us(RTL_CHANNEL_EXIT_DELAY_TIME); 34288f5b657SHoward Wang } 343619f6ebcSHoward Wang 344619f6ebcSHoward Wang static void 345619f6ebcSHoward Wang rtl_enable_rxdvgate(struct rtl_hw *hw) 346619f6ebcSHoward Wang { 347619f6ebcSHoward Wang switch (hw->mcfg) { 348619f6ebcSHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 349619f6ebcSHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 350619f6ebcSHoward Wang RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) | BIT_3); 351619f6ebcSHoward Wang rte_delay_ms(2); 352619f6ebcSHoward Wang } 353619f6ebcSHoward Wang } 354619f6ebcSHoward Wang 355619f6ebcSHoward Wang void 356619f6ebcSHoward Wang rtl_disable_rxdvgate(struct rtl_hw *hw) 357619f6ebcSHoward Wang { 358619f6ebcSHoward Wang switch (hw->mcfg) { 3598e852260SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 360c4adac96SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 361619f6ebcSHoward Wang RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) & ~BIT_3); 362619f6ebcSHoward Wang rte_delay_ms(2); 363619f6ebcSHoward Wang } 364619f6ebcSHoward Wang } 365619f6ebcSHoward Wang 366619f6ebcSHoward Wang static void 367619f6ebcSHoward Wang rtl_stop_all_request(struct rtl_hw *hw) 368619f6ebcSHoward Wang { 369619f6ebcSHoward Wang int i; 370619f6ebcSHoward Wang 371619f6ebcSHoward Wang RTL_W8(hw, ChipCmd, RTL_R8(hw, ChipCmd) | StopReq); 372619f6ebcSHoward Wang 373619f6ebcSHoward Wang switch (hw->mcfg) { 374619f6ebcSHoward Wang case CFG_METHOD_48: 375619f6ebcSHoward Wang case CFG_METHOD_49: 376619f6ebcSHoward Wang case CFG_METHOD_52: 377619f6ebcSHoward Wang for (i = 0; i < 20; i++) { 378619f6ebcSHoward Wang rte_delay_us(10); 379619f6ebcSHoward Wang if (!(RTL_R8(hw, ChipCmd) & StopReq)) 380619f6ebcSHoward Wang break; 381619f6ebcSHoward Wang } 382619f6ebcSHoward Wang 383619f6ebcSHoward Wang break; 384619f6ebcSHoward Wang default: 385619f6ebcSHoward Wang rte_delay_us(200); 386619f6ebcSHoward Wang break; 387619f6ebcSHoward Wang } 388619f6ebcSHoward Wang 389619f6ebcSHoward Wang RTL_W8(hw, ChipCmd, RTL_R8(hw, ChipCmd) & (CmdTxEnb | CmdRxEnb)); 390619f6ebcSHoward Wang } 391619f6ebcSHoward Wang 392619f6ebcSHoward Wang static void 393619f6ebcSHoward Wang rtl_wait_txrx_fifo_empty(struct rtl_hw *hw) 394619f6ebcSHoward Wang { 395619f6ebcSHoward Wang int i; 396619f6ebcSHoward Wang 397619f6ebcSHoward Wang switch (hw->mcfg) { 398619f6ebcSHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 399619f6ebcSHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 400619f6ebcSHoward Wang for (i = 0; i < 3000; i++) { 401619f6ebcSHoward Wang rte_delay_us(50); 402619f6ebcSHoward Wang if ((RTL_R8(hw, MCUCmd_reg) & (Txfifo_empty | Rxfifo_empty)) == 403619f6ebcSHoward Wang (Txfifo_empty | Rxfifo_empty)) 404619f6ebcSHoward Wang break; 405619f6ebcSHoward Wang } 406619f6ebcSHoward Wang break; 407619f6ebcSHoward Wang } 408619f6ebcSHoward Wang 409619f6ebcSHoward Wang switch (hw->mcfg) { 410619f6ebcSHoward Wang case CFG_METHOD_50: 411619f6ebcSHoward Wang case CFG_METHOD_51: 412619f6ebcSHoward Wang case CFG_METHOD_53 ... CFG_METHOD_57: 413619f6ebcSHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 414619f6ebcSHoward Wang for (i = 0; i < 3000; i++) { 415619f6ebcSHoward Wang rte_delay_us(50); 416619f6ebcSHoward Wang if ((RTL_R16(hw, IntrMitigate) & (BIT_0 | BIT_1 | BIT_8)) == 417619f6ebcSHoward Wang (BIT_0 | BIT_1 | BIT_8)) 418619f6ebcSHoward Wang break; 419619f6ebcSHoward Wang } 420619f6ebcSHoward Wang break; 421619f6ebcSHoward Wang } 422619f6ebcSHoward Wang } 423619f6ebcSHoward Wang 424619f6ebcSHoward Wang static void 425619f6ebcSHoward Wang rtl_disable_rx_packet_filter(struct rtl_hw *hw) 426619f6ebcSHoward Wang { 427619f6ebcSHoward Wang RTL_W32(hw, RxConfig, RTL_R32(hw, RxConfig) & 428619f6ebcSHoward Wang ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast | 429619f6ebcSHoward Wang AcceptMyPhys | AcceptAllPhys)); 430619f6ebcSHoward Wang } 431619f6ebcSHoward Wang 432619f6ebcSHoward Wang void 433619f6ebcSHoward Wang rtl_nic_reset(struct rtl_hw *hw) 434619f6ebcSHoward Wang { 435619f6ebcSHoward Wang int i; 436619f6ebcSHoward Wang 437619f6ebcSHoward Wang rtl_disable_rx_packet_filter(hw); 438619f6ebcSHoward Wang 439619f6ebcSHoward Wang rtl_enable_rxdvgate(hw); 440619f6ebcSHoward Wang 441619f6ebcSHoward Wang rtl_stop_all_request(hw); 442619f6ebcSHoward Wang 443619f6ebcSHoward Wang rtl_wait_txrx_fifo_empty(hw); 444619f6ebcSHoward Wang 445619f6ebcSHoward Wang rte_delay_ms(2); 446619f6ebcSHoward Wang 447619f6ebcSHoward Wang /* Soft reset the chip. */ 448619f6ebcSHoward Wang RTL_W8(hw, ChipCmd, CmdReset); 449619f6ebcSHoward Wang 450619f6ebcSHoward Wang /* Check that the chip has finished the reset. */ 451619f6ebcSHoward Wang for (i = 100; i > 0; i--) { 452619f6ebcSHoward Wang rte_delay_us(100); 453619f6ebcSHoward Wang if ((RTL_R8(hw, ChipCmd) & CmdReset) == 0) 454619f6ebcSHoward Wang break; 455619f6ebcSHoward Wang } 456619f6ebcSHoward Wang } 457619f6ebcSHoward Wang 458619f6ebcSHoward Wang void 459619f6ebcSHoward Wang rtl_enable_cfg9346_write(struct rtl_hw *hw) 460619f6ebcSHoward Wang { 461619f6ebcSHoward Wang RTL_W8(hw, Cfg9346, RTL_R8(hw, Cfg9346) | Cfg9346_Unlock); 462619f6ebcSHoward Wang } 463619f6ebcSHoward Wang 464619f6ebcSHoward Wang void 465619f6ebcSHoward Wang rtl_disable_cfg9346_write(struct rtl_hw *hw) 466619f6ebcSHoward Wang { 467619f6ebcSHoward Wang RTL_W8(hw, Cfg9346, RTL_R8(hw, Cfg9346) & ~Cfg9346_Unlock); 468619f6ebcSHoward Wang } 469619f6ebcSHoward Wang 470619f6ebcSHoward Wang static void 471619f6ebcSHoward Wang rtl_enable_force_clkreq(struct rtl_hw *hw, bool enable) 472619f6ebcSHoward Wang { 473619f6ebcSHoward Wang if (enable) 474619f6ebcSHoward Wang RTL_W8(hw, 0xF1, RTL_R8(hw, 0xF1) | BIT_7); 475619f6ebcSHoward Wang else 476619f6ebcSHoward Wang RTL_W8(hw, 0xF1, RTL_R8(hw, 0xF1) & ~BIT_7); 477619f6ebcSHoward Wang } 478619f6ebcSHoward Wang 479619f6ebcSHoward Wang static void 480619f6ebcSHoward Wang rtl_enable_aspm_clkreq_lock(struct rtl_hw *hw, bool enable) 481619f6ebcSHoward Wang { 482619f6ebcSHoward Wang switch (hw->mcfg) { 483619f6ebcSHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 484619f6ebcSHoward Wang case CFG_METHOD_69: 485619f6ebcSHoward Wang rtl_enable_cfg9346_write(hw); 486619f6ebcSHoward Wang if (enable) { 487619f6ebcSHoward Wang RTL_W8(hw, Config2, RTL_R8(hw, Config2) | BIT_7); 488619f6ebcSHoward Wang RTL_W8(hw, Config5, RTL_R8(hw, Config5) | BIT_0); 489619f6ebcSHoward Wang } else { 490619f6ebcSHoward Wang RTL_W8(hw, Config2, RTL_R8(hw, Config2) & ~BIT_7); 491619f6ebcSHoward Wang RTL_W8(hw, Config5, RTL_R8(hw, Config5) & ~BIT_0); 492619f6ebcSHoward Wang } 493619f6ebcSHoward Wang rtl_disable_cfg9346_write(hw); 494619f6ebcSHoward Wang break; 495619f6ebcSHoward Wang case CFG_METHOD_70: 496619f6ebcSHoward Wang case CFG_METHOD_71: 497619f6ebcSHoward Wang rtl_enable_cfg9346_write(hw); 498619f6ebcSHoward Wang if (enable) { 499619f6ebcSHoward Wang RTL_W8(hw, INT_CFG0_8125, RTL_R8(hw, INT_CFG0_8125) | BIT_3); 500619f6ebcSHoward Wang RTL_W8(hw, Config5, RTL_R8(hw, Config5) | BIT_0); 501619f6ebcSHoward Wang } else { 502619f6ebcSHoward Wang RTL_W8(hw, INT_CFG0_8125, RTL_R8(hw, INT_CFG0_8125) & ~BIT_3); 503619f6ebcSHoward Wang RTL_W8(hw, Config5, RTL_R8(hw, Config5) & ~BIT_0); 504619f6ebcSHoward Wang } 505619f6ebcSHoward Wang rtl_disable_cfg9346_write(hw); 506619f6ebcSHoward Wang break; 507619f6ebcSHoward Wang } 508619f6ebcSHoward Wang } 509619f6ebcSHoward Wang 510619f6ebcSHoward Wang static void 511619f6ebcSHoward Wang rtl_disable_l1_timeout(struct rtl_hw *hw) 512619f6ebcSHoward Wang { 513619f6ebcSHoward Wang rtl_csi_write(hw, 0x890, rtl_csi_read(hw, 0x890) & ~BIT_0); 514619f6ebcSHoward Wang } 515619f6ebcSHoward Wang 516619f6ebcSHoward Wang static void 517619f6ebcSHoward Wang rtl_disable_eee_plus(struct rtl_hw *hw) 518619f6ebcSHoward Wang { 519619f6ebcSHoward Wang switch (hw->mcfg) { 520619f6ebcSHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 521619f6ebcSHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 522619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xE080, rtl_mac_ocp_read(hw, 0xE080) & ~BIT_1); 523619f6ebcSHoward Wang break; 524619f6ebcSHoward Wang 525619f6ebcSHoward Wang default: 526619f6ebcSHoward Wang /* Not support EEEPlus */ 527619f6ebcSHoward Wang break; 528619f6ebcSHoward Wang } 529619f6ebcSHoward Wang } 530619f6ebcSHoward Wang 531619f6ebcSHoward Wang static void 532619f6ebcSHoward Wang rtl_hw_clear_timer_int(struct rtl_hw *hw) 533619f6ebcSHoward Wang { 534619f6ebcSHoward Wang switch (hw->mcfg) { 535619f6ebcSHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 536619f6ebcSHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 537619f6ebcSHoward Wang RTL_W32(hw, TIMER_INT0_8125, 0x0000); 538619f6ebcSHoward Wang RTL_W32(hw, TIMER_INT1_8125, 0x0000); 539619f6ebcSHoward Wang RTL_W32(hw, TIMER_INT2_8125, 0x0000); 540619f6ebcSHoward Wang RTL_W32(hw, TIMER_INT3_8125, 0x0000); 541619f6ebcSHoward Wang break; 542619f6ebcSHoward Wang } 543619f6ebcSHoward Wang } 544619f6ebcSHoward Wang 545619f6ebcSHoward Wang static void 546619f6ebcSHoward Wang rtl_hw_clear_int_miti(struct rtl_hw *hw) 547619f6ebcSHoward Wang { 548619f6ebcSHoward Wang int i; 549619f6ebcSHoward Wang 550619f6ebcSHoward Wang switch (hw->HwSuppIntMitiVer) { 551619f6ebcSHoward Wang case 3: 552619f6ebcSHoward Wang case 6: 553619f6ebcSHoward Wang /* IntMITI_0-IntMITI_31 */ 554619f6ebcSHoward Wang for (i = 0xA00; i < 0xB00; i += 4) 555619f6ebcSHoward Wang RTL_W32(hw, i, 0x0000); 556619f6ebcSHoward Wang break; 557619f6ebcSHoward Wang case 4: 558619f6ebcSHoward Wang case 5: 559619f6ebcSHoward Wang /* IntMITI_0-IntMITI_15 */ 560619f6ebcSHoward Wang for (i = 0xA00; i < 0xA80; i += 4) 561619f6ebcSHoward Wang RTL_W32(hw, i, 0x0000); 562619f6ebcSHoward Wang 563619f6ebcSHoward Wang if (hw->HwSuppIntMitiVer == 5) 564619f6ebcSHoward Wang RTL_W8(hw, INT_CFG0_8125, RTL_R8(hw, INT_CFG0_8125) & 565619f6ebcSHoward Wang ~(INT_CFG0_TIMEOUT0_BYPASS_8125 | 566619f6ebcSHoward Wang INT_CFG0_MITIGATION_BYPASS_8125 | 567619f6ebcSHoward Wang INT_CFG0_RDU_BYPASS_8126)); 568619f6ebcSHoward Wang else 569619f6ebcSHoward Wang RTL_W8(hw, INT_CFG0_8125, RTL_R8(hw, INT_CFG0_8125) & 570619f6ebcSHoward Wang ~(INT_CFG0_TIMEOUT0_BYPASS_8125 | INT_CFG0_MITIGATION_BYPASS_8125)); 571619f6ebcSHoward Wang 572619f6ebcSHoward Wang RTL_W16(hw, INT_CFG1_8125, 0x0000); 573619f6ebcSHoward Wang break; 574619f6ebcSHoward Wang } 575619f6ebcSHoward Wang } 576619f6ebcSHoward Wang 577619f6ebcSHoward Wang void 578619f6ebcSHoward Wang rtl_hw_config(struct rtl_hw *hw) 579619f6ebcSHoward Wang { 580619f6ebcSHoward Wang u32 mac_ocp_data; 581619f6ebcSHoward Wang 582619f6ebcSHoward Wang /* Set RxConfig to default */ 583619f6ebcSHoward Wang RTL_W32(hw, RxConfig, (RX_DMA_BURST_unlimited << RxCfgDMAShift)); 584619f6ebcSHoward Wang 585619f6ebcSHoward Wang rtl_nic_reset(hw); 586619f6ebcSHoward Wang 587619f6ebcSHoward Wang rtl_enable_cfg9346_write(hw); 588619f6ebcSHoward Wang 589619f6ebcSHoward Wang /* Disable aspm clkreq internal */ 590619f6ebcSHoward Wang switch (hw->mcfg) { 591619f6ebcSHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 592619f6ebcSHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 593619f6ebcSHoward Wang rtl_enable_force_clkreq(hw, 0); 594619f6ebcSHoward Wang rtl_enable_aspm_clkreq_lock(hw, 0); 595619f6ebcSHoward Wang break; 596619f6ebcSHoward Wang } 597619f6ebcSHoward Wang 598619f6ebcSHoward Wang /* Disable magic packet */ 599619f6ebcSHoward Wang switch (hw->mcfg) { 600619f6ebcSHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 601619f6ebcSHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 602619f6ebcSHoward Wang mac_ocp_data = 0; 603619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xC0B6, mac_ocp_data); 604619f6ebcSHoward Wang break; 605619f6ebcSHoward Wang } 606619f6ebcSHoward Wang 607619f6ebcSHoward Wang /* Set DMA burst size and interframe gap time */ 608619f6ebcSHoward Wang RTL_W32(hw, TxConfig, (TX_DMA_BURST_unlimited << TxDMAShift) | 609619f6ebcSHoward Wang (InterFrameGap << TxInterFrameGapShift)); 610619f6ebcSHoward Wang 611619f6ebcSHoward Wang if (hw->EnableTxNoClose) 612619f6ebcSHoward Wang RTL_W32(hw, TxConfig, (RTL_R32(hw, TxConfig) | BIT_6)); 613619f6ebcSHoward Wang 614619f6ebcSHoward Wang /* TCAM */ 615619f6ebcSHoward Wang switch (hw->mcfg) { 616619f6ebcSHoward Wang case CFG_METHOD_48 ... CFG_METHOD_53: 617619f6ebcSHoward Wang RTL_W16(hw, 0x382, 0x221B); 618619f6ebcSHoward Wang break; 619619f6ebcSHoward Wang } 620619f6ebcSHoward Wang 621619f6ebcSHoward Wang switch (hw->mcfg) { 622619f6ebcSHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 623619f6ebcSHoward Wang rtl_disable_l1_timeout(hw); 624619f6ebcSHoward Wang break; 625619f6ebcSHoward Wang } 626619f6ebcSHoward Wang 627619f6ebcSHoward Wang switch (hw->mcfg) { 628619f6ebcSHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 629619f6ebcSHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 630619f6ebcSHoward Wang 631619f6ebcSHoward Wang /* RSS_control_0 */ 632619f6ebcSHoward Wang RTL_W32(hw, RSS_CTRL_8125, 0x00); 633619f6ebcSHoward Wang 634619f6ebcSHoward Wang /* VMQ_control */ 635619f6ebcSHoward Wang RTL_W16(hw, Q_NUM_CTRL_8125, 0x0000); 636619f6ebcSHoward Wang 637619f6ebcSHoward Wang /* Disable speed down */ 638619f6ebcSHoward Wang RTL_W8(hw, Config1, RTL_R8(hw, Config1) & ~0x10); 639619f6ebcSHoward Wang 640619f6ebcSHoward Wang /* CRC disable set */ 641619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xC140, 0xFFFF); 642619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xC142, 0xFFFF); 643619f6ebcSHoward Wang 644619f6ebcSHoward Wang /* New TX desc format */ 645619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xEB58); 646619f6ebcSHoward Wang if (hw->mcfg == CFG_METHOD_70 || hw->mcfg == CFG_METHOD_71) 647619f6ebcSHoward Wang mac_ocp_data &= ~(BIT_0 | BIT_1); 648619f6ebcSHoward Wang mac_ocp_data |= BIT_0; 649619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xEB58, mac_ocp_data); 650619f6ebcSHoward Wang 651619f6ebcSHoward Wang if (hw->mcfg == CFG_METHOD_70 || hw->mcfg == CFG_METHOD_71) 652619f6ebcSHoward Wang RTL_W8(hw, 0xD8, RTL_R8(hw, 0xD8) & ~BIT_1); 653619f6ebcSHoward Wang 654619f6ebcSHoward Wang /* 655619f6ebcSHoward Wang * MTPS 656619f6ebcSHoward Wang * 15-8 maximum tx use credit number 657619f6ebcSHoward Wang * 7-0 reserved for pcie product line 658619f6ebcSHoward Wang */ 659619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xE614); 660619f6ebcSHoward Wang mac_ocp_data &= ~(BIT_10 | BIT_9 | BIT_8); 661619f6ebcSHoward Wang if (hw->mcfg == CFG_METHOD_50 || hw->mcfg == CFG_METHOD_51 || 662619f6ebcSHoward Wang hw->mcfg == CFG_METHOD_53) 663619f6ebcSHoward Wang mac_ocp_data |= ((2 & 0x07) << 8); 664619f6ebcSHoward Wang else if (hw->mcfg == CFG_METHOD_69 || hw->mcfg == CFG_METHOD_70 || 665619f6ebcSHoward Wang hw->mcfg == CFG_METHOD_71) 666619f6ebcSHoward Wang mac_ocp_data |= ((4 & 0x07) << 8); 667619f6ebcSHoward Wang else 668619f6ebcSHoward Wang mac_ocp_data |= ((3 & 0x07) << 8); 669619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xE614, mac_ocp_data); 670619f6ebcSHoward Wang 671619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xE63E); 672619f6ebcSHoward Wang mac_ocp_data &= ~(BIT_5 | BIT_4); 673619f6ebcSHoward Wang if (hw->mcfg == CFG_METHOD_48 || hw->mcfg == CFG_METHOD_49 || 674619f6ebcSHoward Wang hw->mcfg == CFG_METHOD_52 || hw->mcfg == CFG_METHOD_69 || 675619f6ebcSHoward Wang hw->mcfg == CFG_METHOD_70 || hw->mcfg == CFG_METHOD_71) 676619f6ebcSHoward Wang mac_ocp_data |= ((0x02 & 0x03) << 4); 677619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xE63E, mac_ocp_data); 678619f6ebcSHoward Wang 679619f6ebcSHoward Wang /* 680619f6ebcSHoward Wang * FTR_MCU_CTRL 681619f6ebcSHoward Wang * 3-2 txpla packet valid start 682619f6ebcSHoward Wang */ 683619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xC0B4); 684619f6ebcSHoward Wang mac_ocp_data &= ~BIT_0; 685619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xC0B4, mac_ocp_data); 686619f6ebcSHoward Wang mac_ocp_data |= BIT_0; 687619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xC0B4, mac_ocp_data); 688619f6ebcSHoward Wang 689619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xC0B4); 690619f6ebcSHoward Wang mac_ocp_data |= (BIT_3 | BIT_2); 691619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xC0B4, mac_ocp_data); 692619f6ebcSHoward Wang 693619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xEB6A); 694619f6ebcSHoward Wang mac_ocp_data &= ~(BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | 695619f6ebcSHoward Wang BIT_0); 696619f6ebcSHoward Wang mac_ocp_data |= (BIT_5 | BIT_4 | BIT_1 | BIT_0); 697619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xEB6A, mac_ocp_data); 698619f6ebcSHoward Wang 699619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xEB50); 700619f6ebcSHoward Wang mac_ocp_data &= ~(BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5); 701619f6ebcSHoward Wang mac_ocp_data |= BIT_6; 702619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xEB50, mac_ocp_data); 703619f6ebcSHoward Wang 704619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xE056); 705619f6ebcSHoward Wang mac_ocp_data &= ~(BIT_7 | BIT_6 | BIT_5 | BIT_4); 706619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xE056, mac_ocp_data); 707619f6ebcSHoward Wang 708619f6ebcSHoward Wang /* EEE_CR */ 709619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xE040); 710619f6ebcSHoward Wang mac_ocp_data &= ~BIT_12; 711619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xE040, mac_ocp_data); 712619f6ebcSHoward Wang 713619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xEA1C); 714619f6ebcSHoward Wang mac_ocp_data &= ~(BIT_1 | BIT_0); 715619f6ebcSHoward Wang mac_ocp_data |= BIT_0; 716619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xEA1C, mac_ocp_data); 717619f6ebcSHoward Wang 718619f6ebcSHoward Wang switch (hw->mcfg) { 719619f6ebcSHoward Wang case CFG_METHOD_48: 720619f6ebcSHoward Wang case CFG_METHOD_49: 721619f6ebcSHoward Wang case CFG_METHOD_52: 722619f6ebcSHoward Wang case CFG_METHOD_54: 723619f6ebcSHoward Wang case CFG_METHOD_55: 724619f6ebcSHoward Wang rtl8125_oob_mutex_lock(hw); 725619f6ebcSHoward Wang break; 726619f6ebcSHoward Wang } 727619f6ebcSHoward Wang 728619f6ebcSHoward Wang /* MAC_PWRDWN_CR0 */ 729619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xE0C0, 0x4000); 730619f6ebcSHoward Wang 731619f6ebcSHoward Wang rtl_set_mac_ocp_bit(hw, 0xE052, (BIT_6 | BIT_5)); 732619f6ebcSHoward Wang rtl_clear_mac_ocp_bit(hw, 0xE052, (BIT_3 | BIT_7)); 733619f6ebcSHoward Wang 734619f6ebcSHoward Wang switch (hw->mcfg) { 735619f6ebcSHoward Wang case CFG_METHOD_48: 736619f6ebcSHoward Wang case CFG_METHOD_49: 737619f6ebcSHoward Wang case CFG_METHOD_52: 738619f6ebcSHoward Wang case CFG_METHOD_54: 739619f6ebcSHoward Wang case CFG_METHOD_55: 740619f6ebcSHoward Wang rtl8125_oob_mutex_unlock(hw); 741619f6ebcSHoward Wang break; 742619f6ebcSHoward Wang } 743619f6ebcSHoward Wang 744619f6ebcSHoward Wang /* 745619f6ebcSHoward Wang * DMY_PWR_REG_0 746619f6ebcSHoward Wang * (1)ERI(0xD4)(OCP 0xC0AC).bit[7:12]=6'b111111, L1 Mask 747619f6ebcSHoward Wang */ 748619f6ebcSHoward Wang rtl_set_mac_ocp_bit(hw, 0xC0AC, 749619f6ebcSHoward Wang (BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12)); 750619f6ebcSHoward Wang 751619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xD430); 752619f6ebcSHoward Wang mac_ocp_data &= ~(BIT_11 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5 | 753619f6ebcSHoward Wang BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0); 754619f6ebcSHoward Wang mac_ocp_data |= 0x45F; 755619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xD430, mac_ocp_data); 756619f6ebcSHoward Wang 757619f6ebcSHoward Wang if (!hw->DASH) 758619f6ebcSHoward Wang RTL_W8(hw, 0xD0, RTL_R8(hw, 0xD0) | BIT_6 | BIT_7); 759619f6ebcSHoward Wang else 760619f6ebcSHoward Wang RTL_W8(hw, 0xD0, RTL_R8(hw, 0xD0) & ~(BIT_6 | BIT_7)); 761619f6ebcSHoward Wang 762619f6ebcSHoward Wang if (hw->mcfg == CFG_METHOD_48 || hw->mcfg == CFG_METHOD_49 || 763619f6ebcSHoward Wang hw->mcfg == CFG_METHOD_52) 764619f6ebcSHoward Wang RTL_W8(hw, MCUCmd_reg, RTL_R8(hw, MCUCmd_reg) | BIT_0); 765619f6ebcSHoward Wang 766619f6ebcSHoward Wang rtl_disable_eee_plus(hw); 767619f6ebcSHoward Wang 768619f6ebcSHoward Wang mac_ocp_data = rtl_mac_ocp_read(hw, 0xEA1C); 769619f6ebcSHoward Wang mac_ocp_data &= ~BIT_2; 770619f6ebcSHoward Wang if (hw->mcfg == CFG_METHOD_70 || hw->mcfg == CFG_METHOD_71) 771619f6ebcSHoward Wang mac_ocp_data &= ~(BIT_9 | BIT_8); 772619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xEA1C, mac_ocp_data); 773619f6ebcSHoward Wang 774619f6ebcSHoward Wang /* Clear TCAM entries */ 775619f6ebcSHoward Wang rtl_set_mac_ocp_bit(hw, 0xEB54, BIT_0); 776619f6ebcSHoward Wang rte_delay_us(1); 777619f6ebcSHoward Wang rtl_clear_mac_ocp_bit(hw, 0xEB54, BIT_0); 778619f6ebcSHoward Wang 779619f6ebcSHoward Wang RTL_W16(hw, 0x1880, RTL_R16(hw, 0x1880) & ~(BIT_4 | BIT_5)); 780619f6ebcSHoward Wang 781619f6ebcSHoward Wang switch (hw->mcfg) { 782619f6ebcSHoward Wang case CFG_METHOD_54 ... CFG_METHOD_57: 783619f6ebcSHoward Wang RTL_W8(hw, 0xd8, RTL_R8(hw, 0xd8) & ~EnableRxDescV4_0); 784619f6ebcSHoward Wang break; 785619f6ebcSHoward Wang } 786619f6ebcSHoward Wang } 787619f6ebcSHoward Wang 788619f6ebcSHoward Wang /* Other hw parameters */ 789619f6ebcSHoward Wang rtl_hw_clear_timer_int(hw); 790619f6ebcSHoward Wang 791619f6ebcSHoward Wang rtl_hw_clear_int_miti(hw); 792619f6ebcSHoward Wang 793619f6ebcSHoward Wang switch (hw->mcfg) { 794619f6ebcSHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 795619f6ebcSHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 796619f6ebcSHoward Wang rtl_mac_ocp_write(hw, 0xE098, 0xC302); 797619f6ebcSHoward Wang break; 798619f6ebcSHoward Wang } 799619f6ebcSHoward Wang 800619f6ebcSHoward Wang rtl_disable_cfg9346_write(hw); 801619f6ebcSHoward Wang 802619f6ebcSHoward Wang rte_delay_us(10); 803619f6ebcSHoward Wang } 8048e852260SHoward Wang 8058e852260SHoward Wang int 8068e852260SHoward Wang rtl_set_hw_ops(struct rtl_hw *hw) 8078e852260SHoward Wang { 8088e852260SHoward Wang switch (hw->mcfg) { 8098e852260SHoward Wang /* 8125A */ 8108e852260SHoward Wang case CFG_METHOD_48: 8118e852260SHoward Wang case CFG_METHOD_49: 8128e852260SHoward Wang hw->hw_ops = rtl8125a_ops; 8138e852260SHoward Wang return 0; 8148e852260SHoward Wang /* 8125B */ 8158e852260SHoward Wang case CFG_METHOD_50: 8168e852260SHoward Wang case CFG_METHOD_51: 8178e852260SHoward Wang hw->hw_ops = rtl8125b_ops; 8188e852260SHoward Wang return 0; 8198e852260SHoward Wang /* 8125BP */ 8208e852260SHoward Wang case CFG_METHOD_54: 8218e852260SHoward Wang case CFG_METHOD_55: 8228e852260SHoward Wang hw->hw_ops = rtl8125bp_ops; 8238e852260SHoward Wang return 0; 8248e852260SHoward Wang /* 8125D */ 8258e852260SHoward Wang case CFG_METHOD_56: 8268e852260SHoward Wang case CFG_METHOD_57: 8278e852260SHoward Wang hw->hw_ops = rtl8125d_ops; 8288e852260SHoward Wang return 0; 8298e852260SHoward Wang /* 8126A */ 8308e852260SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 8318e852260SHoward Wang hw->hw_ops = rtl8126a_ops; 8328e852260SHoward Wang return 0; 8338e852260SHoward Wang default: 8348e852260SHoward Wang return -ENOTSUP; 8358e852260SHoward Wang } 8368e852260SHoward Wang } 8378e852260SHoward Wang 8388e852260SHoward Wang void 8398e852260SHoward Wang rtl_hw_disable_mac_mcu_bps(struct rtl_hw *hw) 8408e852260SHoward Wang { 8418e852260SHoward Wang u16 reg_addr; 8428e852260SHoward Wang 8438e852260SHoward Wang rtl_enable_aspm_clkreq_lock(hw, 0); 8448e852260SHoward Wang 8458e852260SHoward Wang switch (hw->mcfg) { 8468e852260SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 8478e852260SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 8488e852260SHoward Wang rtl_mac_ocp_write(hw, 0xFC48, 0x0000); 8498e852260SHoward Wang break; 8508e852260SHoward Wang } 8518e852260SHoward Wang 8528e852260SHoward Wang switch (hw->mcfg) { 8538e852260SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 8548e852260SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 8558e852260SHoward Wang for (reg_addr = 0xFC28; reg_addr < 0xFC48; reg_addr += 2) 8568e852260SHoward Wang rtl_mac_ocp_write(hw, reg_addr, 0x0000); 8578e852260SHoward Wang 8588e852260SHoward Wang rte_delay_ms(3); 8598e852260SHoward Wang 8608e852260SHoward Wang rtl_mac_ocp_write(hw, 0xFC26, 0x0000); 8618e852260SHoward Wang break; 8628e852260SHoward Wang } 8638e852260SHoward Wang } 8648e852260SHoward Wang 8658e852260SHoward Wang static void 8668e852260SHoward Wang rtl_switch_mac_mcu_ram_code_page(struct rtl_hw *hw, u16 page) 8678e852260SHoward Wang { 8688e852260SHoward Wang u16 tmp_ushort; 8698e852260SHoward Wang 8708e852260SHoward Wang page &= (BIT_1 | BIT_0); 8718e852260SHoward Wang tmp_ushort = rtl_mac_ocp_read(hw, 0xE446); 8728e852260SHoward Wang tmp_ushort &= ~(BIT_1 | BIT_0); 8738e852260SHoward Wang tmp_ushort |= page; 8748e852260SHoward Wang rtl_mac_ocp_write(hw, 0xE446, tmp_ushort); 8758e852260SHoward Wang } 8768e852260SHoward Wang 8778e852260SHoward Wang static void 8788e852260SHoward Wang _rtl_write_mac_mcu_ram_code(struct rtl_hw *hw, const u16 *entry, u16 entry_cnt) 8798e852260SHoward Wang { 8808e852260SHoward Wang u16 i; 8818e852260SHoward Wang 8828e852260SHoward Wang for (i = 0; i < entry_cnt; i++) 8838e852260SHoward Wang rtl_mac_ocp_write(hw, 0xF800 + i * 2, entry[i]); 8848e852260SHoward Wang } 8858e852260SHoward Wang 8868e852260SHoward Wang static void 8878e852260SHoward Wang _rtl_write_mac_mcu_ram_code_with_page(struct rtl_hw *hw, const u16 *entry, 8888e852260SHoward Wang u16 entry_cnt, u16 page_size) 8898e852260SHoward Wang { 8908e852260SHoward Wang u16 i; 8918e852260SHoward Wang u16 offset; 8928e852260SHoward Wang u16 page; 8938e852260SHoward Wang 8948e852260SHoward Wang if (page_size == 0) 8958e852260SHoward Wang return; 8968e852260SHoward Wang 8978e852260SHoward Wang for (i = 0; i < entry_cnt; i++) { 8988e852260SHoward Wang offset = i % page_size; 8998e852260SHoward Wang if (offset == 0) { 9008e852260SHoward Wang page = (i / page_size); 9018e852260SHoward Wang rtl_switch_mac_mcu_ram_code_page(hw, page); 9028e852260SHoward Wang } 9038e852260SHoward Wang rtl_mac_ocp_write(hw, 0xF800 + offset * 2, entry[i]); 9048e852260SHoward Wang } 9058e852260SHoward Wang } 9068e852260SHoward Wang 9078e852260SHoward Wang void 9088e852260SHoward Wang rtl_write_mac_mcu_ram_code(struct rtl_hw *hw, const u16 *entry, u16 entry_cnt) 9098e852260SHoward Wang { 9108e852260SHoward Wang if (HW_SUPPORT_MAC_MCU(hw) == FALSE) 9118e852260SHoward Wang return; 9128e852260SHoward Wang if (entry == NULL || entry_cnt == 0) 9138e852260SHoward Wang return; 9148e852260SHoward Wang 9158e852260SHoward Wang if (hw->MacMcuPageSize > 0) 9168e852260SHoward Wang _rtl_write_mac_mcu_ram_code_with_page(hw, entry, entry_cnt, 9178e852260SHoward Wang hw->MacMcuPageSize); 9188e852260SHoward Wang else 9198e852260SHoward Wang _rtl_write_mac_mcu_ram_code(hw, entry, entry_cnt); 9208e852260SHoward Wang } 9217d502791SHoward Wang 9227d502791SHoward Wang bool 9237d502791SHoward Wang rtl_is_speed_mode_valid(u32 speed) 9247d502791SHoward Wang { 9257d502791SHoward Wang switch (speed) { 9267d502791SHoward Wang case SPEED_5000: 9277d502791SHoward Wang case SPEED_2500: 9287d502791SHoward Wang case SPEED_1000: 9297d502791SHoward Wang case SPEED_100: 9307d502791SHoward Wang case SPEED_10: 9317d502791SHoward Wang return true; 9327d502791SHoward Wang default: 9337d502791SHoward Wang return false; 9347d502791SHoward Wang } 9357d502791SHoward Wang } 9367d502791SHoward Wang 9377d502791SHoward Wang static bool 9387d502791SHoward Wang rtl_is_duplex_mode_valid(u8 duplex) 9397d502791SHoward Wang { 9407d502791SHoward Wang switch (duplex) { 9417d502791SHoward Wang case DUPLEX_FULL: 9427d502791SHoward Wang case DUPLEX_HALF: 9437d502791SHoward Wang return true; 9447d502791SHoward Wang default: 9457d502791SHoward Wang return false; 9467d502791SHoward Wang } 9477d502791SHoward Wang } 9487d502791SHoward Wang 9497d502791SHoward Wang static bool 9507d502791SHoward Wang rtl_is_autoneg_mode_valid(u32 autoneg) 9517d502791SHoward Wang { 9527d502791SHoward Wang switch (autoneg) { 9537d502791SHoward Wang case AUTONEG_ENABLE: 9547d502791SHoward Wang case AUTONEG_DISABLE: 9557d502791SHoward Wang return true; 9567d502791SHoward Wang default: 9577d502791SHoward Wang return false; 9587d502791SHoward Wang } 9597d502791SHoward Wang } 9607d502791SHoward Wang 961f7327670SHoward Wang void 9627d502791SHoward Wang rtl_set_link_option(struct rtl_hw *hw, u8 autoneg, u32 speed, u8 duplex, 9637d502791SHoward Wang enum rtl_fc_mode fc) 9647d502791SHoward Wang { 9657d502791SHoward Wang u64 adv; 9667d502791SHoward Wang 9677d502791SHoward Wang if (!rtl_is_speed_mode_valid(speed)) 9687d502791SHoward Wang speed = SPEED_5000; 9697d502791SHoward Wang 9707d502791SHoward Wang if (!rtl_is_duplex_mode_valid(duplex)) 9717d502791SHoward Wang duplex = DUPLEX_FULL; 9727d502791SHoward Wang 9737d502791SHoward Wang if (!rtl_is_autoneg_mode_valid(autoneg)) 9747d502791SHoward Wang autoneg = AUTONEG_ENABLE; 9757d502791SHoward Wang 9767d502791SHoward Wang speed = RTE_MIN(speed, hw->HwSuppMaxPhyLinkSpeed); 9777d502791SHoward Wang 9787d502791SHoward Wang adv = 0; 9797d502791SHoward Wang switch (speed) { 9807d502791SHoward Wang case SPEED_5000: 9817d502791SHoward Wang adv |= ADVERTISE_5000_FULL; 9827d502791SHoward Wang /* Fall through */ 9837d502791SHoward Wang case SPEED_2500: 9847d502791SHoward Wang adv |= ADVERTISE_2500_FULL; 9857d502791SHoward Wang /* Fall through */ 9867d502791SHoward Wang default: 9877d502791SHoward Wang adv |= (ADVERTISE_10_HALF | ADVERTISE_10_FULL | 9887d502791SHoward Wang ADVERTISE_100_HALF | ADVERTISE_100_FULL | 9897d502791SHoward Wang ADVERTISE_1000_HALF | ADVERTISE_1000_FULL); 9907d502791SHoward Wang break; 9917d502791SHoward Wang } 9927d502791SHoward Wang 9937d502791SHoward Wang hw->autoneg = autoneg; 9947d502791SHoward Wang hw->speed = speed; 9957d502791SHoward Wang hw->duplex = duplex; 9967d502791SHoward Wang hw->advertising = adv; 9977d502791SHoward Wang hw->fcpause = fc; 9987d502791SHoward Wang } 9997d502791SHoward Wang 10007d502791SHoward Wang static void 10017d502791SHoward Wang rtl_init_software_variable(struct rtl_hw *hw) 10027d502791SHoward Wang { 10037d502791SHoward Wang int tx_no_close_enable = 1; 10047d502791SHoward Wang unsigned int speed_mode = SPEED_5000; 10057d502791SHoward Wang unsigned int duplex_mode = DUPLEX_FULL; 10067d502791SHoward Wang unsigned int autoneg_mode = AUTONEG_ENABLE; 10077d502791SHoward Wang u8 tmp; 10087d502791SHoward Wang 10097d502791SHoward Wang switch (hw->mcfg) { 10107d502791SHoward Wang case CFG_METHOD_48: 10117d502791SHoward Wang case CFG_METHOD_49: 10127d502791SHoward Wang tmp = (u8)rtl_mac_ocp_read(hw, 0xD006); 10137d502791SHoward Wang if (tmp == 0x02 || tmp == 0x04) 10147d502791SHoward Wang hw->HwSuppDashVer = 2; 10157d502791SHoward Wang break; 10167d502791SHoward Wang case CFG_METHOD_54: 10177d502791SHoward Wang case CFG_METHOD_55: 10187d502791SHoward Wang hw->HwSuppDashVer = 4; 10197d502791SHoward Wang break; 10207d502791SHoward Wang default: 10217d502791SHoward Wang hw->HwSuppDashVer = 0; 10227d502791SHoward Wang break; 10237d502791SHoward Wang } 10247d502791SHoward Wang 10257d502791SHoward Wang switch (hw->mcfg) { 10267d502791SHoward Wang case CFG_METHOD_48: 10277d502791SHoward Wang case CFG_METHOD_49: 10287d502791SHoward Wang if (HW_DASH_SUPPORT_DASH(hw)) 10297d502791SHoward Wang hw->HwSuppOcpChannelVer = 2; 10307d502791SHoward Wang break; 10317d502791SHoward Wang case CFG_METHOD_54: 10327d502791SHoward Wang case CFG_METHOD_55: 10337d502791SHoward Wang hw->HwSuppOcpChannelVer = 2; 10347d502791SHoward Wang break; 10357d502791SHoward Wang } 10367d502791SHoward Wang 10377d502791SHoward Wang hw->AllowAccessDashOcp = rtl_is_allow_access_dash_ocp(hw); 10387d502791SHoward Wang 10397d502791SHoward Wang if (HW_DASH_SUPPORT_DASH(hw) && rtl_check_dash(hw)) 10407d502791SHoward Wang hw->DASH = 1; 10417d502791SHoward Wang else 10427d502791SHoward Wang hw->DASH = 0; 10437d502791SHoward Wang 10447d502791SHoward Wang if (HW_DASH_SUPPORT_TYPE_2(hw)) 10457d502791SHoward Wang hw->cmac_ioaddr = hw->mmio_addr; 10467d502791SHoward Wang 10477d502791SHoward Wang switch (hw->mcfg) { 10487d502791SHoward Wang case CFG_METHOD_48: 10497d502791SHoward Wang case CFG_METHOD_49: 10507d502791SHoward Wang hw->chipset_name = RTL8125A; 10517d502791SHoward Wang break; 10527d502791SHoward Wang case CFG_METHOD_50: 10537d502791SHoward Wang case CFG_METHOD_51: 10547d502791SHoward Wang hw->chipset_name = RTL8125B; 10557d502791SHoward Wang break; 10567d502791SHoward Wang case CFG_METHOD_52: 10577d502791SHoward Wang case CFG_METHOD_53: 10587d502791SHoward Wang hw->chipset_name = RTL8168KB; 10597d502791SHoward Wang break; 10607d502791SHoward Wang case CFG_METHOD_54: 10617d502791SHoward Wang case CFG_METHOD_55: 10627d502791SHoward Wang hw->chipset_name = RTL8125BP; 10637d502791SHoward Wang break; 10647d502791SHoward Wang case CFG_METHOD_56: 10657d502791SHoward Wang case CFG_METHOD_57: 10667d502791SHoward Wang hw->chipset_name = RTL8125D; 10677d502791SHoward Wang break; 10687d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 10697d502791SHoward Wang hw->chipset_name = RTL8126A; 10707d502791SHoward Wang break; 10717d502791SHoward Wang default: 10727d502791SHoward Wang hw->chipset_name = UNKNOWN; 10737d502791SHoward Wang break; 10747d502791SHoward Wang } 10757d502791SHoward Wang 10767d502791SHoward Wang switch (hw->mcfg) { 10777d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 10787d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 10797d502791SHoward Wang hw->HwSuppNowIsOobVer = 1; 10807d502791SHoward Wang } 10817d502791SHoward Wang 10827d502791SHoward Wang switch (hw->mcfg) { 10837d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 10847d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 10857d502791SHoward Wang hw->HwSuppCheckPhyDisableModeVer = 3; 10867d502791SHoward Wang } 10877d502791SHoward Wang 10887d502791SHoward Wang switch (hw->mcfg) { 10897d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_51: 10907d502791SHoward Wang case CFG_METHOD_54 ... CFG_METHOD_57: 1091f7327670SHoward Wang hw->HwSuppMaxPhyLinkSpeed = SPEED_2500; 10927d502791SHoward Wang break; 10937d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 1094f7327670SHoward Wang hw->HwSuppMaxPhyLinkSpeed = SPEED_5000; 10957d502791SHoward Wang break; 10967d502791SHoward Wang default: 1097f7327670SHoward Wang hw->HwSuppMaxPhyLinkSpeed = SPEED_1000; 10987d502791SHoward Wang break; 10997d502791SHoward Wang } 11007d502791SHoward Wang 11017d502791SHoward Wang switch (hw->mcfg) { 11027d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_53: 11037d502791SHoward Wang hw->HwSuppTxNoCloseVer = 3; 11047d502791SHoward Wang break; 11057d502791SHoward Wang case CFG_METHOD_54 ... CFG_METHOD_57: 11067d502791SHoward Wang hw->HwSuppTxNoCloseVer = 6; 11077d502791SHoward Wang break; 11087d502791SHoward Wang case CFG_METHOD_69: 11097d502791SHoward Wang hw->HwSuppTxNoCloseVer = 4; 11107d502791SHoward Wang break; 11117d502791SHoward Wang case CFG_METHOD_70: 11127d502791SHoward Wang case CFG_METHOD_71: 11137d502791SHoward Wang hw->HwSuppTxNoCloseVer = 5; 11147d502791SHoward Wang break; 11157d502791SHoward Wang } 11167d502791SHoward Wang 11177d502791SHoward Wang switch (hw->HwSuppTxNoCloseVer) { 11187d502791SHoward Wang case 5: 11197d502791SHoward Wang case 6: 11207d502791SHoward Wang hw->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V4; 11217d502791SHoward Wang break; 11227d502791SHoward Wang case 4: 11237d502791SHoward Wang hw->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V3; 11247d502791SHoward Wang break; 11257d502791SHoward Wang case 3: 11267d502791SHoward Wang hw->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V2; 11277d502791SHoward Wang break; 11287d502791SHoward Wang default: 11297d502791SHoward Wang tx_no_close_enable = 0; 11307d502791SHoward Wang break; 11317d502791SHoward Wang } 11327d502791SHoward Wang 11337d502791SHoward Wang if (hw->HwSuppTxNoCloseVer > 0 && tx_no_close_enable == 1) 11347d502791SHoward Wang hw->EnableTxNoClose = TRUE; 11357d502791SHoward Wang 11367d502791SHoward Wang switch (hw->HwSuppTxNoCloseVer) { 11377d502791SHoward Wang case 4: 11387d502791SHoward Wang case 5: 11397d502791SHoward Wang hw->hw_clo_ptr_reg = HW_CLO_PTR0_8126; 11407d502791SHoward Wang hw->sw_tail_ptr_reg = SW_TAIL_PTR0_8126; 11417d502791SHoward Wang break; 11427d502791SHoward Wang case 6: 11437d502791SHoward Wang hw->hw_clo_ptr_reg = HW_CLO_PTR0_8125BP; 11447d502791SHoward Wang hw->sw_tail_ptr_reg = SW_TAIL_PTR0_8125BP; 11457d502791SHoward Wang break; 11467d502791SHoward Wang default: 11477d502791SHoward Wang hw->hw_clo_ptr_reg = HW_CLO_PTR0_8125; 11487d502791SHoward Wang hw->sw_tail_ptr_reg = SW_TAIL_PTR0_8125; 11497d502791SHoward Wang break; 11507d502791SHoward Wang } 11517d502791SHoward Wang 11527d502791SHoward Wang switch (hw->mcfg) { 11537d502791SHoward Wang case CFG_METHOD_48: 11547d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_48; 11557d502791SHoward Wang break; 11567d502791SHoward Wang case CFG_METHOD_49: 11577d502791SHoward Wang case CFG_METHOD_52: 11587d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_49; 11597d502791SHoward Wang break; 11607d502791SHoward Wang case CFG_METHOD_50: 11617d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_50; 11627d502791SHoward Wang break; 11637d502791SHoward Wang case CFG_METHOD_51: 11647d502791SHoward Wang case CFG_METHOD_53: 11657d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_51; 11667d502791SHoward Wang break; 11677d502791SHoward Wang case CFG_METHOD_54: 11687d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_54; 11697d502791SHoward Wang break; 11707d502791SHoward Wang case CFG_METHOD_55: 11717d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_55; 11727d502791SHoward Wang break; 11737d502791SHoward Wang case CFG_METHOD_56: 11747d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_56; 11757d502791SHoward Wang break; 11767d502791SHoward Wang case CFG_METHOD_57: 11777d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_57; 11787d502791SHoward Wang break; 11797d502791SHoward Wang case CFG_METHOD_69: 11807d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_69; 11817d502791SHoward Wang break; 11827d502791SHoward Wang case CFG_METHOD_70: 11837d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_70; 11847d502791SHoward Wang break; 11857d502791SHoward Wang case CFG_METHOD_71: 11867d502791SHoward Wang hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_71; 11877d502791SHoward Wang break; 11887d502791SHoward Wang } 11897d502791SHoward Wang 11907d502791SHoward Wang if (hw->HwIcVerUnknown) { 11917d502791SHoward Wang hw->NotWrRamCodeToMicroP = TRUE; 11927d502791SHoward Wang hw->NotWrMcuPatchCode = TRUE; 11937d502791SHoward Wang } 11947d502791SHoward Wang 11957d502791SHoward Wang switch (hw->mcfg) { 11967d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 11977d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 11987d502791SHoward Wang hw->HwSuppMacMcuVer = 2; 11997d502791SHoward Wang break; 12007d502791SHoward Wang } 12017d502791SHoward Wang 12027d502791SHoward Wang switch (hw->mcfg) { 12037d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 12047d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 12057d502791SHoward Wang hw->MacMcuPageSize = RTL_MAC_MCU_PAGE_SIZE; 12067d502791SHoward Wang break; 12077d502791SHoward Wang } 12087d502791SHoward Wang 12097d502791SHoward Wang switch (hw->mcfg) { 12107d502791SHoward Wang case CFG_METHOD_49: 12117d502791SHoward Wang case CFG_METHOD_52: 12127d502791SHoward Wang if ((rtl_mac_ocp_read(hw, 0xD442) & BIT_5) && 12137d502791SHoward Wang (rtl_mdio_direct_read_phy_ocp(hw, 0xD068) & BIT_1)) 12147d502791SHoward Wang hw->RequirePhyMdiSwapPatch = TRUE; 12157d502791SHoward Wang break; 12167d502791SHoward Wang } 12177d502791SHoward Wang 12187d502791SHoward Wang switch (hw->mcfg) { 12197d502791SHoward Wang case CFG_METHOD_48: 12207d502791SHoward Wang case CFG_METHOD_49: 12217d502791SHoward Wang case CFG_METHOD_52: 12227d502791SHoward Wang hw->HwSuppIntMitiVer = 3; 12237d502791SHoward Wang break; 12247d502791SHoward Wang case CFG_METHOD_50: 12257d502791SHoward Wang case CFG_METHOD_51: 12267d502791SHoward Wang case CFG_METHOD_53: 12277d502791SHoward Wang case CFG_METHOD_69: 12287d502791SHoward Wang hw->HwSuppIntMitiVer = 4; 12297d502791SHoward Wang break; 12307d502791SHoward Wang case CFG_METHOD_54 ... CFG_METHOD_57: 12317d502791SHoward Wang hw->HwSuppIntMitiVer = 6; 12327d502791SHoward Wang break; 12337d502791SHoward Wang case CFG_METHOD_70: 12347d502791SHoward Wang case CFG_METHOD_71: 12357d502791SHoward Wang hw->HwSuppIntMitiVer = 5; 12367d502791SHoward Wang break; 12377d502791SHoward Wang } 12387d502791SHoward Wang 12397d502791SHoward Wang rtl_set_link_option(hw, autoneg_mode, speed_mode, duplex_mode, rtl_fc_full); 12407d502791SHoward Wang 12417d502791SHoward Wang switch (hw->mcfg) { 12427d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 12437d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 12447d502791SHoward Wang hw->mcu_pme_setting = rtl_mac_ocp_read(hw, 0xE00A); 12457d502791SHoward Wang break; 12467d502791SHoward Wang } 12477d502791SHoward Wang 12487d502791SHoward Wang hw->mtu = RTL_DEFAULT_MTU; 12497d502791SHoward Wang } 12507d502791SHoward Wang 12517d502791SHoward Wang static void 12527d502791SHoward Wang rtl_exit_realwow(struct rtl_hw *hw) 12537d502791SHoward Wang { 12547d502791SHoward Wang /* Disable realwow function */ 12557d502791SHoward Wang switch (hw->mcfg) { 12567d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 12577d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 12587d502791SHoward Wang rtl_mac_ocp_write(hw, 0xC0BC, 0x00FF); 12597d502791SHoward Wang break; 12607d502791SHoward Wang } 12617d502791SHoward Wang } 12627d502791SHoward Wang 12637d502791SHoward Wang static void 12647d502791SHoward Wang rtl_disable_now_is_oob(struct rtl_hw *hw) 12657d502791SHoward Wang { 12667d502791SHoward Wang if (hw->HwSuppNowIsOobVer == 1) 12677d502791SHoward Wang RTL_W8(hw, MCUCmd_reg, RTL_R8(hw, MCUCmd_reg) & ~Now_is_oob); 12687d502791SHoward Wang } 12697d502791SHoward Wang 12707d502791SHoward Wang static void 12717d502791SHoward Wang rtl_wait_ll_share_fifo_ready(struct rtl_hw *hw) 12727d502791SHoward Wang { 12737d502791SHoward Wang int i; 12747d502791SHoward Wang 12757d502791SHoward Wang for (i = 0; i < 10; i++) { 12767d502791SHoward Wang rte_delay_us(100); 12777d502791SHoward Wang if (RTL_R16(hw, 0xD2) & BIT_9) 12787d502791SHoward Wang break; 12797d502791SHoward Wang } 12807d502791SHoward Wang } 12817d502791SHoward Wang 12827d502791SHoward Wang static void 12837d502791SHoward Wang rtl_exit_oob(struct rtl_hw *hw) 12847d502791SHoward Wang { 12857d502791SHoward Wang u16 data16; 12867d502791SHoward Wang 12877d502791SHoward Wang rtl_disable_rx_packet_filter(hw); 12887d502791SHoward Wang 1289*b574fb4cSHoward Wang if (HW_DASH_SUPPORT_DASH(hw)) { 1290*b574fb4cSHoward Wang rtl8125_driver_start(hw); 1291*b574fb4cSHoward Wang rtl8125_dash2_disable_txrx(hw); 1292*b574fb4cSHoward Wang } 1293*b574fb4cSHoward Wang 12947d502791SHoward Wang rtl_exit_realwow(hw); 12957d502791SHoward Wang 12967d502791SHoward Wang rtl_nic_reset(hw); 12977d502791SHoward Wang 12987d502791SHoward Wang switch (hw->mcfg) { 12997d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 13007d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 13017d502791SHoward Wang rtl_disable_now_is_oob(hw); 13027d502791SHoward Wang 13037d502791SHoward Wang data16 = rtl_mac_ocp_read(hw, 0xE8DE) & ~BIT_14; 13047d502791SHoward Wang rtl_mac_ocp_write(hw, 0xE8DE, data16); 13057d502791SHoward Wang rtl_wait_ll_share_fifo_ready(hw); 13067d502791SHoward Wang 13077d502791SHoward Wang rtl_mac_ocp_write(hw, 0xC0AA, 0x07D0); 13087d502791SHoward Wang 13097d502791SHoward Wang rtl_mac_ocp_write(hw, 0xC0A6, 0x01B5); 13107d502791SHoward Wang 13117d502791SHoward Wang rtl_mac_ocp_write(hw, 0xC01E, 0x5555); 13127d502791SHoward Wang 13137d502791SHoward Wang rtl_wait_ll_share_fifo_ready(hw); 13147d502791SHoward Wang break; 13157d502791SHoward Wang } 13167d502791SHoward Wang } 13177d502791SHoward Wang 13187d502791SHoward Wang static void 13197d502791SHoward Wang rtl_disable_ups(struct rtl_hw *hw) 13207d502791SHoward Wang { 13217d502791SHoward Wang switch (hw->mcfg) { 13227d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 13237d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 13247d502791SHoward Wang rtl_mac_ocp_write(hw, 0xD40A, rtl_mac_ocp_read(hw, 0xD40A) & ~BIT_4); 13257d502791SHoward Wang break; 13267d502791SHoward Wang } 13277d502791SHoward Wang } 13287d502791SHoward Wang 13297d502791SHoward Wang static void 13307d502791SHoward Wang rtl8125_disable_ocp_phy_power_saving(struct rtl_hw *hw) 13317d502791SHoward Wang { 13327d502791SHoward Wang u16 val; 13337d502791SHoward Wang 13347d502791SHoward Wang if (hw->mcfg == CFG_METHOD_48 || hw->mcfg == CFG_METHOD_49 || 13357d502791SHoward Wang hw->mcfg == CFG_METHOD_52) { 13367d502791SHoward Wang val = rtl_mdio_direct_read_phy_ocp(hw, 0xC416); 13377d502791SHoward Wang if (val != 0x0050) { 13387d502791SHoward Wang rtl_set_phy_mcu_patch_request(hw); 13397d502791SHoward Wang rtl_mdio_direct_write_phy_ocp(hw, 0xC416, 0x0000); 13407d502791SHoward Wang rtl_mdio_direct_write_phy_ocp(hw, 0xC416, 0x0500); 13417d502791SHoward Wang rtl_clear_phy_mcu_patch_request(hw); 13427d502791SHoward Wang } 13437d502791SHoward Wang } 13447d502791SHoward Wang } 13457d502791SHoward Wang 13467d502791SHoward Wang static void 13477d502791SHoward Wang rtl_hw_init(struct rtl_hw *hw) 13487d502791SHoward Wang { 13497d502791SHoward Wang switch (hw->mcfg) { 13507d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 13517d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 13527d502791SHoward Wang rtl_enable_aspm_clkreq_lock(hw, 0); 13537d502791SHoward Wang rtl_enable_force_clkreq(hw, 0); 13547d502791SHoward Wang break; 13557d502791SHoward Wang } 13567d502791SHoward Wang 13577d502791SHoward Wang rtl_disable_ups(hw); 13587d502791SHoward Wang 13597d502791SHoward Wang hw->hw_ops.hw_mac_mcu_config(hw); 13607d502791SHoward Wang 13617d502791SHoward Wang /* Disable ocp phy power saving */ 13627d502791SHoward Wang rtl8125_disable_ocp_phy_power_saving(hw); 13637d502791SHoward Wang } 13647d502791SHoward Wang 13657d502791SHoward Wang void 13667d502791SHoward Wang rtl_hw_initialize(struct rtl_hw *hw) 13677d502791SHoward Wang { 13687d502791SHoward Wang rtl_init_software_variable(hw); 13697d502791SHoward Wang 13707d502791SHoward Wang rtl_exit_oob(hw); 13717d502791SHoward Wang 13727d502791SHoward Wang rtl_hw_init(hw); 13737d502791SHoward Wang 13747d502791SHoward Wang rtl_nic_reset(hw); 13757d502791SHoward Wang } 13767d502791SHoward Wang 13777d502791SHoward Wang void 13787d502791SHoward Wang rtl_get_mac_version(struct rtl_hw *hw, struct rte_pci_device *pci_dev) 13797d502791SHoward Wang { 13807d502791SHoward Wang u32 reg, val32; 13817d502791SHoward Wang u32 ic_version_id; 13827d502791SHoward Wang 13837d502791SHoward Wang val32 = RTL_R32(hw, TxConfig); 13847d502791SHoward Wang reg = val32 & 0x7c800000; 13857d502791SHoward Wang ic_version_id = val32 & 0x00700000; 13867d502791SHoward Wang 13877d502791SHoward Wang switch (reg) { 13887d502791SHoward Wang case 0x60800000: 13897d502791SHoward Wang if (ic_version_id == 0x00000000) { 13907d502791SHoward Wang hw->mcfg = CFG_METHOD_48; 13917d502791SHoward Wang 13927d502791SHoward Wang } else if (ic_version_id == 0x100000) { 13937d502791SHoward Wang hw->mcfg = CFG_METHOD_49; 13947d502791SHoward Wang 13957d502791SHoward Wang } else { 13967d502791SHoward Wang hw->mcfg = CFG_METHOD_49; 13977d502791SHoward Wang hw->HwIcVerUnknown = TRUE; 13987d502791SHoward Wang } 13997d502791SHoward Wang 14007d502791SHoward Wang hw->efuse_ver = EFUSE_SUPPORT_V4; 14017d502791SHoward Wang break; 14027d502791SHoward Wang case 0x64000000: 14037d502791SHoward Wang if (ic_version_id == 0x00000000) { 14047d502791SHoward Wang hw->mcfg = CFG_METHOD_50; 14057d502791SHoward Wang 14067d502791SHoward Wang } else if (ic_version_id == 0x100000) { 14077d502791SHoward Wang hw->mcfg = CFG_METHOD_51; 14087d502791SHoward Wang 14097d502791SHoward Wang } else { 14107d502791SHoward Wang hw->mcfg = CFG_METHOD_51; 14117d502791SHoward Wang hw->HwIcVerUnknown = TRUE; 14127d502791SHoward Wang } 14137d502791SHoward Wang 14147d502791SHoward Wang hw->efuse_ver = EFUSE_SUPPORT_V4; 14157d502791SHoward Wang break; 14167d502791SHoward Wang case 0x68000000: 14177d502791SHoward Wang if (ic_version_id == 0x00000000) { 14187d502791SHoward Wang hw->mcfg = CFG_METHOD_54; 14197d502791SHoward Wang } else if (ic_version_id == 0x100000) { 14207d502791SHoward Wang hw->mcfg = CFG_METHOD_55; 14217d502791SHoward Wang } else { 14227d502791SHoward Wang hw->mcfg = CFG_METHOD_55; 14237d502791SHoward Wang hw->HwIcVerUnknown = TRUE; 14247d502791SHoward Wang } 14257d502791SHoward Wang 14267d502791SHoward Wang hw->efuse_ver = EFUSE_SUPPORT_V4; 14277d502791SHoward Wang break; 14287d502791SHoward Wang case 0x68800000: 14297d502791SHoward Wang if (ic_version_id == 0x00000000) { 14307d502791SHoward Wang hw->mcfg = CFG_METHOD_56; 14317d502791SHoward Wang } else if (ic_version_id == 0x100000) { 14327d502791SHoward Wang hw->mcfg = CFG_METHOD_57; 14337d502791SHoward Wang } else { 14347d502791SHoward Wang hw->mcfg = CFG_METHOD_57; 14357d502791SHoward Wang hw->HwIcVerUnknown = TRUE; 14367d502791SHoward Wang } 14377d502791SHoward Wang 14387d502791SHoward Wang hw->efuse_ver = EFUSE_SUPPORT_V4; 14397d502791SHoward Wang break; 14407d502791SHoward Wang case 0x64800000: 14417d502791SHoward Wang if (ic_version_id == 0x00000000) { 14427d502791SHoward Wang hw->mcfg = CFG_METHOD_69; 14437d502791SHoward Wang } else if (ic_version_id == 0x100000) { 14447d502791SHoward Wang hw->mcfg = CFG_METHOD_70; 14457d502791SHoward Wang } else if (ic_version_id == 0x200000) { 14467d502791SHoward Wang hw->mcfg = CFG_METHOD_71; 14477d502791SHoward Wang } else { 14487d502791SHoward Wang hw->mcfg = CFG_METHOD_71; 14497d502791SHoward Wang hw->HwIcVerUnknown = TRUE; 14507d502791SHoward Wang } 14517d502791SHoward Wang 14527d502791SHoward Wang hw->efuse_ver = EFUSE_SUPPORT_V4; 14537d502791SHoward Wang break; 14547d502791SHoward Wang default: 14557d502791SHoward Wang PMD_INIT_LOG(NOTICE, "unknown chip version (%x)", reg); 14567d502791SHoward Wang hw->mcfg = CFG_METHOD_DEFAULT; 14577d502791SHoward Wang hw->HwIcVerUnknown = TRUE; 14587d502791SHoward Wang hw->efuse_ver = EFUSE_NOT_SUPPORT; 14597d502791SHoward Wang break; 14607d502791SHoward Wang } 14617d502791SHoward Wang 14627d502791SHoward Wang if (pci_dev->id.device_id == 0x8162) { 14637d502791SHoward Wang if (hw->mcfg == CFG_METHOD_49) 14647d502791SHoward Wang hw->mcfg = CFG_METHOD_52; 14657d502791SHoward Wang else if (hw->mcfg == CFG_METHOD_51) 14667d502791SHoward Wang hw->mcfg = CFG_METHOD_53; 14677d502791SHoward Wang } 14687d502791SHoward Wang } 14697d502791SHoward Wang 14707d502791SHoward Wang int 14717d502791SHoward Wang rtl_get_mac_address(struct rtl_hw *hw, struct rte_ether_addr *ea) 14727d502791SHoward Wang { 14737d502791SHoward Wang u8 mac_addr[MAC_ADDR_LEN]; 14747d502791SHoward Wang 14757d502791SHoward Wang switch (hw->mcfg) { 14767d502791SHoward Wang case CFG_METHOD_48 ... CFG_METHOD_57: 14777d502791SHoward Wang case CFG_METHOD_69 ... CFG_METHOD_71: 14787d502791SHoward Wang *(u32 *)&mac_addr[0] = RTL_R32(hw, BACKUP_ADDR0_8125); 14797d502791SHoward Wang *(u16 *)&mac_addr[4] = RTL_R16(hw, BACKUP_ADDR1_8125); 14807d502791SHoward Wang break; 14817d502791SHoward Wang default: 14827d502791SHoward Wang break; 14837d502791SHoward Wang } 14847d502791SHoward Wang 14857d502791SHoward Wang rte_ether_addr_copy((struct rte_ether_addr *)mac_addr, ea); 14867d502791SHoward Wang 14877d502791SHoward Wang return 0; 14887d502791SHoward Wang } 14897d502791SHoward Wang 14907d502791SHoward Wang void 14917d502791SHoward Wang rtl_rar_set(struct rtl_hw *hw, uint8_t *addr) 14927d502791SHoward Wang { 14937d502791SHoward Wang uint32_t rar_low = 0; 14947d502791SHoward Wang uint32_t rar_high = 0; 14957d502791SHoward Wang 14967d502791SHoward Wang rar_low = ((uint32_t)addr[0] | ((uint32_t)addr[1] << 8) | 14977d502791SHoward Wang ((uint32_t)addr[2] << 16) | ((uint32_t)addr[3] << 24)); 14987d502791SHoward Wang 14997d502791SHoward Wang rar_high = ((uint32_t)addr[4] | ((uint32_t)addr[5] << 8)); 15007d502791SHoward Wang 15017d502791SHoward Wang rtl_enable_cfg9346_write(hw); 15027d502791SHoward Wang 15037d502791SHoward Wang RTL_W32(hw, MAC0, rar_low); 15047d502791SHoward Wang RTL_W32(hw, MAC4, rar_high); 15057d502791SHoward Wang 15067d502791SHoward Wang rtl_disable_cfg9346_write(hw); 15077d502791SHoward Wang } 1508fa0b0ad6SHoward Wang 1509fa0b0ad6SHoward Wang void 1510fa0b0ad6SHoward Wang rtl_get_tally_stats(struct rtl_hw *hw, struct rte_eth_stats *rte_stats) 1511fa0b0ad6SHoward Wang { 1512fa0b0ad6SHoward Wang struct rtl_counters *counters; 1513fa0b0ad6SHoward Wang uint64_t paddr; 1514fa0b0ad6SHoward Wang u32 cmd; 1515fa0b0ad6SHoward Wang u32 wait_cnt; 1516fa0b0ad6SHoward Wang 1517fa0b0ad6SHoward Wang counters = hw->tally_vaddr; 1518fa0b0ad6SHoward Wang paddr = hw->tally_paddr; 1519fa0b0ad6SHoward Wang if (!counters) 1520fa0b0ad6SHoward Wang return; 1521fa0b0ad6SHoward Wang 1522fa0b0ad6SHoward Wang RTL_W32(hw, CounterAddrHigh, (u64)paddr >> 32); 1523fa0b0ad6SHoward Wang cmd = (u64)paddr & DMA_BIT_MASK(32); 1524fa0b0ad6SHoward Wang RTL_W32(hw, CounterAddrLow, cmd); 1525fa0b0ad6SHoward Wang RTL_W32(hw, CounterAddrLow, cmd | CounterDump); 1526fa0b0ad6SHoward Wang 1527fa0b0ad6SHoward Wang wait_cnt = 0; 1528fa0b0ad6SHoward Wang while (RTL_R32(hw, CounterAddrLow) & CounterDump) { 1529fa0b0ad6SHoward Wang rte_delay_us(10); 1530fa0b0ad6SHoward Wang 1531fa0b0ad6SHoward Wang wait_cnt++; 1532fa0b0ad6SHoward Wang if (wait_cnt > 20) 1533fa0b0ad6SHoward Wang break; 1534fa0b0ad6SHoward Wang } 1535fa0b0ad6SHoward Wang 1536fa0b0ad6SHoward Wang /* RX errors */ 1537fa0b0ad6SHoward Wang rte_stats->imissed = rte_le_to_cpu_64(counters->rx_missed); 1538fa0b0ad6SHoward Wang rte_stats->ierrors = rte_le_to_cpu_64(counters->rx_errors); 1539fa0b0ad6SHoward Wang 1540fa0b0ad6SHoward Wang /* TX errors */ 1541fa0b0ad6SHoward Wang rte_stats->oerrors = rte_le_to_cpu_64(counters->tx_errors); 1542fa0b0ad6SHoward Wang 1543fa0b0ad6SHoward Wang rte_stats->ipackets = rte_le_to_cpu_64(counters->rx_packets); 1544fa0b0ad6SHoward Wang rte_stats->opackets = rte_le_to_cpu_64(counters->tx_packets); 1545fa0b0ad6SHoward Wang } 1546fa0b0ad6SHoward Wang 1547fa0b0ad6SHoward Wang void 1548fa0b0ad6SHoward Wang rtl_clear_tally_stats(struct rtl_hw *hw) 1549fa0b0ad6SHoward Wang { 1550fa0b0ad6SHoward Wang if (!hw->tally_paddr) 1551fa0b0ad6SHoward Wang return; 1552fa0b0ad6SHoward Wang 1553fa0b0ad6SHoward Wang RTL_W32(hw, CounterAddrHigh, (u64)hw->tally_paddr >> 32); 1554fa0b0ad6SHoward Wang RTL_W32(hw, CounterAddrLow, 1555fa0b0ad6SHoward Wang ((u64)hw->tally_paddr & (DMA_BIT_MASK(32))) | CounterReset); 1556fa0b0ad6SHoward Wang } 1557fa0b0ad6SHoward Wang 1558fa0b0ad6SHoward Wang int 1559fa0b0ad6SHoward Wang rtl_tally_init(struct rte_eth_dev *dev) 1560fa0b0ad6SHoward Wang { 1561fa0b0ad6SHoward Wang struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev); 1562fa0b0ad6SHoward Wang struct rtl_hw *hw = &adapter->hw; 1563fa0b0ad6SHoward Wang const struct rte_memzone *mz; 1564fa0b0ad6SHoward Wang 1565fa0b0ad6SHoward Wang mz = rte_eth_dma_zone_reserve(dev, "tally_counters", 0, 1566fa0b0ad6SHoward Wang sizeof(struct rtl_counters), 64, rte_socket_id()); 1567fa0b0ad6SHoward Wang if (mz == NULL) 1568fa0b0ad6SHoward Wang return -ENOMEM; 1569fa0b0ad6SHoward Wang 1570fa0b0ad6SHoward Wang hw->tally_vaddr = mz->addr; 1571fa0b0ad6SHoward Wang hw->tally_paddr = mz->iova; 1572fa0b0ad6SHoward Wang 1573fa0b0ad6SHoward Wang /* Fill tally addrs */ 1574fa0b0ad6SHoward Wang RTL_W32(hw, CounterAddrHigh, (u64)hw->tally_paddr >> 32); 1575fa0b0ad6SHoward Wang RTL_W32(hw, CounterAddrLow, (u64)hw->tally_paddr & (DMA_BIT_MASK(32))); 1576fa0b0ad6SHoward Wang 1577fa0b0ad6SHoward Wang /* Reset the hw statistics */ 1578fa0b0ad6SHoward Wang rtl_clear_tally_stats(hw); 1579fa0b0ad6SHoward Wang 1580fa0b0ad6SHoward Wang return 0; 1581fa0b0ad6SHoward Wang } 1582fa0b0ad6SHoward Wang 1583fa0b0ad6SHoward Wang void 1584fa0b0ad6SHoward Wang rtl_tally_free(struct rte_eth_dev *dev) 1585fa0b0ad6SHoward Wang { 1586fa0b0ad6SHoward Wang rte_eth_dma_zone_free(dev, "tally_counters", 0); 1587fa0b0ad6SHoward Wang } 1588