2020-01-14 09:55:54 +02:00
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2018 Intel Corporation */
# include "igc.h"
struct igc_reg_info {
u32 ofs ;
char * name ;
} ;
static const struct igc_reg_info igc_reg_info_tbl [ ] = {
/* General Registers */
{ IGC_CTRL , " CTRL " } ,
{ IGC_STATUS , " STATUS " } ,
{ IGC_CTRL_EXT , " CTRL_EXT " } ,
{ IGC_MDIC , " MDIC " } ,
/* Interrupt Registers */
{ IGC_ICR , " ICR " } ,
/* RX Registers */
{ IGC_RCTL , " RCTL " } ,
{ IGC_RDLEN ( 0 ) , " RDLEN " } ,
{ IGC_RDH ( 0 ) , " RDH " } ,
{ IGC_RDT ( 0 ) , " RDT " } ,
{ IGC_RXDCTL ( 0 ) , " RXDCTL " } ,
{ IGC_RDBAL ( 0 ) , " RDBAL " } ,
{ IGC_RDBAH ( 0 ) , " RDBAH " } ,
/* TX Registers */
{ IGC_TCTL , " TCTL " } ,
{ IGC_TDBAL ( 0 ) , " TDBAL " } ,
{ IGC_TDBAH ( 0 ) , " TDBAH " } ,
{ IGC_TDLEN ( 0 ) , " TDLEN " } ,
{ IGC_TDH ( 0 ) , " TDH " } ,
{ IGC_TDT ( 0 ) , " TDT " } ,
{ IGC_TXDCTL ( 0 ) , " TXDCTL " } ,
/* List Terminator */
{ }
} ;
/* igc_regdump - register printout routine */
static void igc_regdump ( struct igc_hw * hw , struct igc_reg_info * reginfo )
{
2020-03-24 17:38:18 -07:00
struct net_device * dev = igc_get_hw_dev ( hw ) ;
2020-01-14 09:55:54 +02:00
int n = 0 ;
char rname [ 16 ] ;
u32 regs [ 8 ] ;
switch ( reginfo - > ofs ) {
case IGC_RDLEN ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_RDLEN ( n ) ) ;
break ;
case IGC_RDH ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_RDH ( n ) ) ;
break ;
case IGC_RDT ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_RDT ( n ) ) ;
break ;
case IGC_RXDCTL ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_RXDCTL ( n ) ) ;
break ;
case IGC_RDBAL ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_RDBAL ( n ) ) ;
break ;
case IGC_RDBAH ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_RDBAH ( n ) ) ;
break ;
case IGC_TDBAL ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_RDBAL ( n ) ) ;
break ;
case IGC_TDBAH ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_TDBAH ( n ) ) ;
break ;
case IGC_TDLEN ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_TDLEN ( n ) ) ;
break ;
case IGC_TDH ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_TDH ( n ) ) ;
break ;
case IGC_TDT ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_TDT ( n ) ) ;
break ;
case IGC_TXDCTL ( 0 ) :
for ( n = 0 ; n < 4 ; n + + )
regs [ n ] = rd32 ( IGC_TXDCTL ( n ) ) ;
break ;
default :
2020-03-24 17:38:18 -07:00
netdev_info ( dev , " %-15s %08x \n " , reginfo - > name ,
rd32 ( reginfo - > ofs ) ) ;
2020-01-14 09:55:54 +02:00
return ;
}
snprintf ( rname , 16 , " %s%s " , reginfo - > name , " [0-3] " ) ;
2020-03-24 17:38:18 -07:00
netdev_info ( dev , " %-15s %08x %08x %08x %08x \n " , rname , regs [ 0 ] , regs [ 1 ] ,
regs [ 2 ] , regs [ 3 ] ) ;
2020-01-14 09:55:54 +02:00
}
/* igc_rings_dump - Tx-rings and Rx-rings */
void igc_rings_dump ( struct igc_adapter * adapter )
{
struct net_device * netdev = adapter - > netdev ;
struct my_u0 { u64 a ; u64 b ; } * u0 ;
union igc_adv_tx_desc * tx_desc ;
union igc_adv_rx_desc * rx_desc ;
struct igc_ring * tx_ring ;
struct igc_ring * rx_ring ;
u32 staterr ;
u16 i , n ;
if ( ! netif_msg_hw ( adapter ) )
return ;
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " Device info: state %016lX trans_start %016lX \n " ,
netdev - > state , dev_trans_start ( netdev ) ) ;
2020-01-14 09:55:54 +02:00
/* Print TX Ring Summary */
2020-03-24 17:38:18 -07:00
if ( ! netif_running ( netdev ) )
2020-01-14 09:55:54 +02:00
goto exit ;
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " TX Rings Summary \n " ) ;
netdev_info ( netdev , " Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp \n " ) ;
2020-01-14 09:55:54 +02:00
for ( n = 0 ; n < adapter - > num_tx_queues ; n + + ) {
struct igc_tx_buffer * buffer_info ;
tx_ring = adapter - > tx_ring [ n ] ;
buffer_info = & tx_ring - > tx_buffer_info [ tx_ring - > next_to_clean ] ;
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " %5d %5X %5X %016llX %04X %p %016llX \n " ,
n , tx_ring - > next_to_use , tx_ring - > next_to_clean ,
( u64 ) dma_unmap_addr ( buffer_info , dma ) ,
dma_unmap_len ( buffer_info , len ) ,
buffer_info - > next_to_watch ,
( u64 ) buffer_info - > time_stamp ) ;
2020-01-14 09:55:54 +02:00
}
/* Print TX Rings */
if ( ! netif_msg_tx_done ( adapter ) )
goto rx_ring_summary ;
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " TX Rings Dump \n " ) ;
2020-01-14 09:55:54 +02:00
/* Transmit Descriptor Formats
*
* Advanced Transmit Descriptor
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* 0 | Buffer Address [ 63 : 0 ] |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* 8 | PAYLEN | PORTS | CC | IDX | STA | DCMD | DTYP | MAC | RSV | DTALEN |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* 63 46 45 40 39 38 36 35 32 31 24 15 0
*/
for ( n = 0 ; n < adapter - > num_tx_queues ; n + + ) {
tx_ring = adapter - > tx_ring [ n ] ;
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " ------------------------------------ \n " ) ;
netdev_info ( netdev , " TX QUEUE INDEX = %d \n " ,
tx_ring - > queue_index ) ;
netdev_info ( netdev , " ------------------------------------ \n " ) ;
netdev_info ( netdev , " T [desc] [address 63:0 ] [PlPOCIStDDM Ln] [bi->dma ] leng ntw timestamp bi->skb \n " ) ;
2020-01-14 09:55:54 +02:00
for ( i = 0 ; tx_ring - > desc & & ( i < tx_ring - > count ) ; i + + ) {
const char * next_desc ;
struct igc_tx_buffer * buffer_info ;
tx_desc = IGC_TX_DESC ( tx_ring , i ) ;
buffer_info = & tx_ring - > tx_buffer_info [ i ] ;
u0 = ( struct my_u0 * ) tx_desc ;
if ( i = = tx_ring - > next_to_use & &
i = = tx_ring - > next_to_clean )
next_desc = " NTC/U " ;
else if ( i = = tx_ring - > next_to_use )
next_desc = " NTU " ;
else if ( i = = tx_ring - > next_to_clean )
next_desc = " NTC " ;
else
next_desc = " " ;
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " T [0x%03X] %016llX %016llX %016llX %04X %p %016llX %p%s \n " ,
i , le64_to_cpu ( u0 - > a ) ,
le64_to_cpu ( u0 - > b ) ,
( u64 ) dma_unmap_addr ( buffer_info , dma ) ,
dma_unmap_len ( buffer_info , len ) ,
buffer_info - > next_to_watch ,
( u64 ) buffer_info - > time_stamp ,
buffer_info - > skb , next_desc ) ;
2020-01-14 09:55:54 +02:00
if ( netif_msg_pktdata ( adapter ) & & buffer_info - > skb )
print_hex_dump ( KERN_INFO , " " ,
DUMP_PREFIX_ADDRESS ,
16 , 1 , buffer_info - > skb - > data ,
dma_unmap_len ( buffer_info , len ) ,
true ) ;
}
}
/* Print RX Rings Summary */
rx_ring_summary :
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " RX Rings Summary \n " ) ;
netdev_info ( netdev , " Queue [NTU] [NTC] \n " ) ;
2020-01-14 09:55:54 +02:00
for ( n = 0 ; n < adapter - > num_rx_queues ; n + + ) {
rx_ring = adapter - > rx_ring [ n ] ;
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " %5d %5X %5X \n " , n , rx_ring - > next_to_use ,
rx_ring - > next_to_clean ) ;
2020-01-14 09:55:54 +02:00
}
/* Print RX Rings */
if ( ! netif_msg_rx_status ( adapter ) )
goto exit ;
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " RX Rings Dump \n " ) ;
2020-01-14 09:55:54 +02:00
/* Advanced Receive Descriptor (Read) Format
* 63 1 0
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* 0 | Packet Buffer Address [ 63 : 1 ] | A0 / NSE |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - +
* 8 | Header Buffer Address [ 63 : 1 ] | DD |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*
*
* Advanced Receive Descriptor ( Write - Back ) Format
*
* 63 48 47 32 31 30 21 20 17 16 4 3 0
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* 0 | Packet IP | SPH | HDR_LEN | RSV | Packet | RSS |
* | Checksum Ident | | | | Type | Type |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* 8 | VLAN Tag | Length | Extended Error | Extended Status |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* 63 48 47 32 31 20 19 0
*/
for ( n = 0 ; n < adapter - > num_rx_queues ; n + + ) {
rx_ring = adapter - > rx_ring [ n ] ;
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " ------------------------------------ \n " ) ;
netdev_info ( netdev , " RX QUEUE INDEX = %d \n " ,
rx_ring - > queue_index ) ;
netdev_info ( netdev , " ------------------------------------ \n " ) ;
netdev_info ( netdev , " R [desc] [ PktBuf A0] [ HeadBuf DD] [bi->dma ] [bi->skb] <-- Adv Rx Read format \n " ) ;
netdev_info ( netdev , " RWB[desc] [PcsmIpSHl PtRs] [vl er S cks ln] ---------------- [bi->skb] <-- Adv Rx Write-Back format \n " ) ;
2020-01-14 09:55:54 +02:00
for ( i = 0 ; i < rx_ring - > count ; i + + ) {
const char * next_desc ;
struct igc_rx_buffer * buffer_info ;
buffer_info = & rx_ring - > rx_buffer_info [ i ] ;
rx_desc = IGC_RX_DESC ( rx_ring , i ) ;
u0 = ( struct my_u0 * ) rx_desc ;
staterr = le32_to_cpu ( rx_desc - > wb . upper . status_error ) ;
if ( i = = rx_ring - > next_to_use )
next_desc = " NTU " ;
else if ( i = = rx_ring - > next_to_clean )
next_desc = " NTC " ;
else
next_desc = " " ;
if ( staterr & IGC_RXD_STAT_DD ) {
/* Descriptor Done */
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " %s[0x%03X] %016llX %016llX ---------------- %s \n " ,
" RWB " , i ,
le64_to_cpu ( u0 - > a ) ,
le64_to_cpu ( u0 - > b ) ,
next_desc ) ;
2020-01-14 09:55:54 +02:00
} else {
2020-03-24 17:38:18 -07:00
netdev_info ( netdev , " %s[0x%03X] %016llX %016llX %016llX %s \n " ,
" R " , i ,
le64_to_cpu ( u0 - > a ) ,
le64_to_cpu ( u0 - > b ) ,
( u64 ) buffer_info - > dma ,
next_desc ) ;
2020-01-14 09:55:54 +02:00
if ( netif_msg_pktdata ( adapter ) & &
buffer_info - > dma & & buffer_info - > page ) {
print_hex_dump ( KERN_INFO , " " ,
DUMP_PREFIX_ADDRESS ,
16 , 1 ,
page_address
( buffer_info - > page ) +
buffer_info - > page_offset ,
igc_rx_bufsz ( rx_ring ) ,
true ) ;
}
}
}
}
exit :
return ;
}
/* igc_regs_dump - registers dump */
void igc_regs_dump ( struct igc_adapter * adapter )
{
struct igc_hw * hw = & adapter - > hw ;
struct igc_reg_info * reginfo ;
/* Print Registers */
2020-03-24 17:38:18 -07:00
netdev_info ( adapter - > netdev , " Register Dump \n " ) ;
netdev_info ( adapter - > netdev , " Register Name Value \n " ) ;
2020-01-14 09:55:54 +02:00
for ( reginfo = ( struct igc_reg_info * ) igc_reg_info_tbl ;
reginfo - > name ; reginfo + + ) {
igc_regdump ( hw , reginfo ) ;
}
}