162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright (c) 2018 Intel Corporation */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "igc.h" 562306a36Sopenharmony_ci 662306a36Sopenharmony_cistruct igc_reg_info { 762306a36Sopenharmony_ci u32 ofs; 862306a36Sopenharmony_ci char *name; 962306a36Sopenharmony_ci}; 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cistatic const struct igc_reg_info igc_reg_info_tbl[] = { 1262306a36Sopenharmony_ci /* General Registers */ 1362306a36Sopenharmony_ci {IGC_CTRL, "CTRL"}, 1462306a36Sopenharmony_ci {IGC_STATUS, "STATUS"}, 1562306a36Sopenharmony_ci {IGC_CTRL_EXT, "CTRL_EXT"}, 1662306a36Sopenharmony_ci {IGC_MDIC, "MDIC"}, 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci /* Interrupt Registers */ 1962306a36Sopenharmony_ci {IGC_ICR, "ICR"}, 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci /* RX Registers */ 2262306a36Sopenharmony_ci {IGC_RCTL, "RCTL"}, 2362306a36Sopenharmony_ci {IGC_RDLEN(0), "RDLEN"}, 2462306a36Sopenharmony_ci {IGC_RDH(0), "RDH"}, 2562306a36Sopenharmony_ci {IGC_RDT(0), "RDT"}, 2662306a36Sopenharmony_ci {IGC_RXDCTL(0), "RXDCTL"}, 2762306a36Sopenharmony_ci {IGC_RDBAL(0), "RDBAL"}, 2862306a36Sopenharmony_ci {IGC_RDBAH(0), "RDBAH"}, 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci /* TX Registers */ 3162306a36Sopenharmony_ci {IGC_TCTL, "TCTL"}, 3262306a36Sopenharmony_ci {IGC_TDBAL(0), "TDBAL"}, 3362306a36Sopenharmony_ci {IGC_TDBAH(0), "TDBAH"}, 3462306a36Sopenharmony_ci {IGC_TDLEN(0), "TDLEN"}, 3562306a36Sopenharmony_ci {IGC_TDH(0), "TDH"}, 3662306a36Sopenharmony_ci {IGC_TDT(0), "TDT"}, 3762306a36Sopenharmony_ci {IGC_TXDCTL(0), "TXDCTL"}, 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci /* List Terminator */ 4062306a36Sopenharmony_ci {} 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* igc_regdump - register printout routine */ 4462306a36Sopenharmony_cistatic void igc_regdump(struct igc_hw *hw, struct igc_reg_info *reginfo) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci struct net_device *dev = igc_get_hw_dev(hw); 4762306a36Sopenharmony_ci int n = 0; 4862306a36Sopenharmony_ci char rname[16]; 4962306a36Sopenharmony_ci u32 regs[8]; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci switch (reginfo->ofs) { 5262306a36Sopenharmony_ci case IGC_RDLEN(0): 5362306a36Sopenharmony_ci for (n = 0; n < 4; n++) 5462306a36Sopenharmony_ci regs[n] = rd32(IGC_RDLEN(n)); 5562306a36Sopenharmony_ci break; 5662306a36Sopenharmony_ci case IGC_RDH(0): 5762306a36Sopenharmony_ci for (n = 0; n < 4; n++) 5862306a36Sopenharmony_ci regs[n] = rd32(IGC_RDH(n)); 5962306a36Sopenharmony_ci break; 6062306a36Sopenharmony_ci case IGC_RDT(0): 6162306a36Sopenharmony_ci for (n = 0; n < 4; n++) 6262306a36Sopenharmony_ci regs[n] = rd32(IGC_RDT(n)); 6362306a36Sopenharmony_ci break; 6462306a36Sopenharmony_ci case IGC_RXDCTL(0): 6562306a36Sopenharmony_ci for (n = 0; n < 4; n++) 6662306a36Sopenharmony_ci regs[n] = rd32(IGC_RXDCTL(n)); 6762306a36Sopenharmony_ci break; 6862306a36Sopenharmony_ci case IGC_RDBAL(0): 6962306a36Sopenharmony_ci for (n = 0; n < 4; n++) 7062306a36Sopenharmony_ci regs[n] = rd32(IGC_RDBAL(n)); 7162306a36Sopenharmony_ci break; 7262306a36Sopenharmony_ci case IGC_RDBAH(0): 7362306a36Sopenharmony_ci for (n = 0; n < 4; n++) 7462306a36Sopenharmony_ci regs[n] = rd32(IGC_RDBAH(n)); 7562306a36Sopenharmony_ci break; 7662306a36Sopenharmony_ci case IGC_TDBAL(0): 7762306a36Sopenharmony_ci for (n = 0; n < 4; n++) 7862306a36Sopenharmony_ci regs[n] = rd32(IGC_TDBAL(n)); 7962306a36Sopenharmony_ci break; 8062306a36Sopenharmony_ci case IGC_TDBAH(0): 8162306a36Sopenharmony_ci for (n = 0; n < 4; n++) 8262306a36Sopenharmony_ci regs[n] = rd32(IGC_TDBAH(n)); 8362306a36Sopenharmony_ci break; 8462306a36Sopenharmony_ci case IGC_TDLEN(0): 8562306a36Sopenharmony_ci for (n = 0; n < 4; n++) 8662306a36Sopenharmony_ci regs[n] = rd32(IGC_TDLEN(n)); 8762306a36Sopenharmony_ci break; 8862306a36Sopenharmony_ci case IGC_TDH(0): 8962306a36Sopenharmony_ci for (n = 0; n < 4; n++) 9062306a36Sopenharmony_ci regs[n] = rd32(IGC_TDH(n)); 9162306a36Sopenharmony_ci break; 9262306a36Sopenharmony_ci case IGC_TDT(0): 9362306a36Sopenharmony_ci for (n = 0; n < 4; n++) 9462306a36Sopenharmony_ci regs[n] = rd32(IGC_TDT(n)); 9562306a36Sopenharmony_ci break; 9662306a36Sopenharmony_ci case IGC_TXDCTL(0): 9762306a36Sopenharmony_ci for (n = 0; n < 4; n++) 9862306a36Sopenharmony_ci regs[n] = rd32(IGC_TXDCTL(n)); 9962306a36Sopenharmony_ci break; 10062306a36Sopenharmony_ci default: 10162306a36Sopenharmony_ci netdev_info(dev, "%-15s %08x\n", reginfo->name, 10262306a36Sopenharmony_ci rd32(reginfo->ofs)); 10362306a36Sopenharmony_ci return; 10462306a36Sopenharmony_ci } 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]"); 10762306a36Sopenharmony_ci netdev_info(dev, "%-15s %08x %08x %08x %08x\n", rname, regs[0], regs[1], 10862306a36Sopenharmony_ci regs[2], regs[3]); 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci/* igc_rings_dump - Tx-rings and Rx-rings */ 11262306a36Sopenharmony_civoid igc_rings_dump(struct igc_adapter *adapter) 11362306a36Sopenharmony_ci{ 11462306a36Sopenharmony_ci struct net_device *netdev = adapter->netdev; 11562306a36Sopenharmony_ci struct my_u0 { __le64 a; __le64 b; } *u0; 11662306a36Sopenharmony_ci union igc_adv_tx_desc *tx_desc; 11762306a36Sopenharmony_ci union igc_adv_rx_desc *rx_desc; 11862306a36Sopenharmony_ci struct igc_ring *tx_ring; 11962306a36Sopenharmony_ci struct igc_ring *rx_ring; 12062306a36Sopenharmony_ci u32 staterr; 12162306a36Sopenharmony_ci u16 i, n; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci if (!netif_msg_hw(adapter)) 12462306a36Sopenharmony_ci return; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci netdev_info(netdev, "Device info: state %016lX trans_start %016lX\n", 12762306a36Sopenharmony_ci netdev->state, dev_trans_start(netdev)); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci /* Print TX Ring Summary */ 13062306a36Sopenharmony_ci if (!netif_running(netdev)) 13162306a36Sopenharmony_ci goto exit; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci netdev_info(netdev, "TX Rings Summary\n"); 13462306a36Sopenharmony_ci netdev_info(netdev, "Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n"); 13562306a36Sopenharmony_ci for (n = 0; n < adapter->num_tx_queues; n++) { 13662306a36Sopenharmony_ci struct igc_tx_buffer *buffer_info; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci tx_ring = adapter->tx_ring[n]; 13962306a36Sopenharmony_ci buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean]; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci netdev_info(netdev, "%5d %5X %5X %016llX %04X %p %016llX\n", 14262306a36Sopenharmony_ci n, tx_ring->next_to_use, tx_ring->next_to_clean, 14362306a36Sopenharmony_ci (u64)dma_unmap_addr(buffer_info, dma), 14462306a36Sopenharmony_ci dma_unmap_len(buffer_info, len), 14562306a36Sopenharmony_ci buffer_info->next_to_watch, 14662306a36Sopenharmony_ci (u64)buffer_info->time_stamp); 14762306a36Sopenharmony_ci } 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci /* Print TX Rings */ 15062306a36Sopenharmony_ci if (!netif_msg_tx_done(adapter)) 15162306a36Sopenharmony_ci goto rx_ring_summary; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci netdev_info(netdev, "TX Rings Dump\n"); 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci /* Transmit Descriptor Formats 15662306a36Sopenharmony_ci * 15762306a36Sopenharmony_ci * Advanced Transmit Descriptor 15862306a36Sopenharmony_ci * +--------------------------------------------------------------+ 15962306a36Sopenharmony_ci * 0 | Buffer Address [63:0] | 16062306a36Sopenharmony_ci * +--------------------------------------------------------------+ 16162306a36Sopenharmony_ci * 8 | PAYLEN | PORTS |CC|IDX | STA | DCMD |DTYP|MAC|RSV| DTALEN | 16262306a36Sopenharmony_ci * +--------------------------------------------------------------+ 16362306a36Sopenharmony_ci * 63 46 45 40 39 38 36 35 32 31 24 15 0 16462306a36Sopenharmony_ci */ 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci for (n = 0; n < adapter->num_tx_queues; n++) { 16762306a36Sopenharmony_ci tx_ring = adapter->tx_ring[n]; 16862306a36Sopenharmony_ci netdev_info(netdev, "------------------------------------\n"); 16962306a36Sopenharmony_ci netdev_info(netdev, "TX QUEUE INDEX = %d\n", 17062306a36Sopenharmony_ci tx_ring->queue_index); 17162306a36Sopenharmony_ci netdev_info(netdev, "------------------------------------\n"); 17262306a36Sopenharmony_ci netdev_info(netdev, "T [desc] [address 63:0 ] [PlPOCIStDDM Ln] [bi->dma ] leng ntw timestamp bi->skb\n"); 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { 17562306a36Sopenharmony_ci const char *next_desc; 17662306a36Sopenharmony_ci struct igc_tx_buffer *buffer_info; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci tx_desc = IGC_TX_DESC(tx_ring, i); 17962306a36Sopenharmony_ci buffer_info = &tx_ring->tx_buffer_info[i]; 18062306a36Sopenharmony_ci u0 = (struct my_u0 *)tx_desc; 18162306a36Sopenharmony_ci if (i == tx_ring->next_to_use && 18262306a36Sopenharmony_ci i == tx_ring->next_to_clean) 18362306a36Sopenharmony_ci next_desc = " NTC/U"; 18462306a36Sopenharmony_ci else if (i == tx_ring->next_to_use) 18562306a36Sopenharmony_ci next_desc = " NTU"; 18662306a36Sopenharmony_ci else if (i == tx_ring->next_to_clean) 18762306a36Sopenharmony_ci next_desc = " NTC"; 18862306a36Sopenharmony_ci else 18962306a36Sopenharmony_ci next_desc = ""; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci netdev_info(netdev, "T [0x%03X] %016llX %016llX %016llX %04X %p %016llX %p%s\n", 19262306a36Sopenharmony_ci i, le64_to_cpu(u0->a), 19362306a36Sopenharmony_ci le64_to_cpu(u0->b), 19462306a36Sopenharmony_ci (u64)dma_unmap_addr(buffer_info, dma), 19562306a36Sopenharmony_ci dma_unmap_len(buffer_info, len), 19662306a36Sopenharmony_ci buffer_info->next_to_watch, 19762306a36Sopenharmony_ci (u64)buffer_info->time_stamp, 19862306a36Sopenharmony_ci buffer_info->skb, next_desc); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci if (netif_msg_pktdata(adapter) && buffer_info->skb) 20162306a36Sopenharmony_ci print_hex_dump(KERN_INFO, "", 20262306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 20362306a36Sopenharmony_ci 16, 1, buffer_info->skb->data, 20462306a36Sopenharmony_ci dma_unmap_len(buffer_info, len), 20562306a36Sopenharmony_ci true); 20662306a36Sopenharmony_ci } 20762306a36Sopenharmony_ci } 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci /* Print RX Rings Summary */ 21062306a36Sopenharmony_cirx_ring_summary: 21162306a36Sopenharmony_ci netdev_info(netdev, "RX Rings Summary\n"); 21262306a36Sopenharmony_ci netdev_info(netdev, "Queue [NTU] [NTC]\n"); 21362306a36Sopenharmony_ci for (n = 0; n < adapter->num_rx_queues; n++) { 21462306a36Sopenharmony_ci rx_ring = adapter->rx_ring[n]; 21562306a36Sopenharmony_ci netdev_info(netdev, "%5d %5X %5X\n", n, rx_ring->next_to_use, 21662306a36Sopenharmony_ci rx_ring->next_to_clean); 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci /* Print RX Rings */ 22062306a36Sopenharmony_ci if (!netif_msg_rx_status(adapter)) 22162306a36Sopenharmony_ci goto exit; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci netdev_info(netdev, "RX Rings Dump\n"); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci /* Advanced Receive Descriptor (Read) Format 22662306a36Sopenharmony_ci * 63 1 0 22762306a36Sopenharmony_ci * +-----------------------------------------------------+ 22862306a36Sopenharmony_ci * 0 | Packet Buffer Address [63:1] |A0/NSE| 22962306a36Sopenharmony_ci * +----------------------------------------------+------+ 23062306a36Sopenharmony_ci * 8 | Header Buffer Address [63:1] | DD | 23162306a36Sopenharmony_ci * +-----------------------------------------------------+ 23262306a36Sopenharmony_ci * 23362306a36Sopenharmony_ci * 23462306a36Sopenharmony_ci * Advanced Receive Descriptor (Write-Back) Format 23562306a36Sopenharmony_ci * 23662306a36Sopenharmony_ci * 63 48 47 32 31 30 21 20 17 16 4 3 0 23762306a36Sopenharmony_ci * +------------------------------------------------------+ 23862306a36Sopenharmony_ci * 0 | Packet IP |SPH| HDR_LEN | RSV|Packet| RSS | 23962306a36Sopenharmony_ci * | Checksum Ident | | | | Type | Type | 24062306a36Sopenharmony_ci * +------------------------------------------------------+ 24162306a36Sopenharmony_ci * 8 | VLAN Tag | Length | Extended Error | Extended Status | 24262306a36Sopenharmony_ci * +------------------------------------------------------+ 24362306a36Sopenharmony_ci * 63 48 47 32 31 20 19 0 24462306a36Sopenharmony_ci */ 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci for (n = 0; n < adapter->num_rx_queues; n++) { 24762306a36Sopenharmony_ci rx_ring = adapter->rx_ring[n]; 24862306a36Sopenharmony_ci netdev_info(netdev, "------------------------------------\n"); 24962306a36Sopenharmony_ci netdev_info(netdev, "RX QUEUE INDEX = %d\n", 25062306a36Sopenharmony_ci rx_ring->queue_index); 25162306a36Sopenharmony_ci netdev_info(netdev, "------------------------------------\n"); 25262306a36Sopenharmony_ci netdev_info(netdev, "R [desc] [ PktBuf A0] [ HeadBuf DD] [bi->dma ] [bi->skb] <-- Adv Rx Read format\n"); 25362306a36Sopenharmony_ci netdev_info(netdev, "RWB[desc] [PcsmIpSHl PtRs] [vl er S cks ln] ---------------- [bi->skb] <-- Adv Rx Write-Back format\n"); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci for (i = 0; i < rx_ring->count; i++) { 25662306a36Sopenharmony_ci const char *next_desc; 25762306a36Sopenharmony_ci struct igc_rx_buffer *buffer_info; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci buffer_info = &rx_ring->rx_buffer_info[i]; 26062306a36Sopenharmony_ci rx_desc = IGC_RX_DESC(rx_ring, i); 26162306a36Sopenharmony_ci u0 = (struct my_u0 *)rx_desc; 26262306a36Sopenharmony_ci staterr = le32_to_cpu(rx_desc->wb.upper.status_error); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci if (i == rx_ring->next_to_use) 26562306a36Sopenharmony_ci next_desc = " NTU"; 26662306a36Sopenharmony_ci else if (i == rx_ring->next_to_clean) 26762306a36Sopenharmony_ci next_desc = " NTC"; 26862306a36Sopenharmony_ci else 26962306a36Sopenharmony_ci next_desc = ""; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci if (staterr & IGC_RXD_STAT_DD) { 27262306a36Sopenharmony_ci /* Descriptor Done */ 27362306a36Sopenharmony_ci netdev_info(netdev, "%s[0x%03X] %016llX %016llX ---------------- %s\n", 27462306a36Sopenharmony_ci "RWB", i, 27562306a36Sopenharmony_ci le64_to_cpu(u0->a), 27662306a36Sopenharmony_ci le64_to_cpu(u0->b), 27762306a36Sopenharmony_ci next_desc); 27862306a36Sopenharmony_ci } else { 27962306a36Sopenharmony_ci netdev_info(netdev, "%s[0x%03X] %016llX %016llX %016llX %s\n", 28062306a36Sopenharmony_ci "R ", i, 28162306a36Sopenharmony_ci le64_to_cpu(u0->a), 28262306a36Sopenharmony_ci le64_to_cpu(u0->b), 28362306a36Sopenharmony_ci (u64)buffer_info->dma, 28462306a36Sopenharmony_ci next_desc); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci if (netif_msg_pktdata(adapter) && 28762306a36Sopenharmony_ci buffer_info->dma && buffer_info->page) { 28862306a36Sopenharmony_ci print_hex_dump(KERN_INFO, "", 28962306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 29062306a36Sopenharmony_ci 16, 1, 29162306a36Sopenharmony_ci page_address 29262306a36Sopenharmony_ci (buffer_info->page) + 29362306a36Sopenharmony_ci buffer_info->page_offset, 29462306a36Sopenharmony_ci igc_rx_bufsz(rx_ring), 29562306a36Sopenharmony_ci true); 29662306a36Sopenharmony_ci } 29762306a36Sopenharmony_ci } 29862306a36Sopenharmony_ci } 29962306a36Sopenharmony_ci } 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ciexit: 30262306a36Sopenharmony_ci return; 30362306a36Sopenharmony_ci} 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci/* igc_regs_dump - registers dump */ 30662306a36Sopenharmony_civoid igc_regs_dump(struct igc_adapter *adapter) 30762306a36Sopenharmony_ci{ 30862306a36Sopenharmony_ci struct igc_hw *hw = &adapter->hw; 30962306a36Sopenharmony_ci struct igc_reg_info *reginfo; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci /* Print Registers */ 31262306a36Sopenharmony_ci netdev_info(adapter->netdev, "Register Dump\n"); 31362306a36Sopenharmony_ci netdev_info(adapter->netdev, "Register Name Value\n"); 31462306a36Sopenharmony_ci for (reginfo = (struct igc_reg_info *)igc_reg_info_tbl; 31562306a36Sopenharmony_ci reginfo->name; reginfo++) { 31662306a36Sopenharmony_ci igc_regdump(hw, reginfo); 31762306a36Sopenharmony_ci } 31862306a36Sopenharmony_ci} 319