1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c)  2018 Intel Corporation */
3 
4 #include "igc.h"
5 
6 struct igc_reg_info {
7 	u32 ofs;
8 	char *name;
9 };
10 
11 static const struct igc_reg_info igc_reg_info_tbl[] = {
12 	/* General Registers */
13 	{IGC_CTRL, "CTRL"},
14 	{IGC_STATUS, "STATUS"},
15 	{IGC_CTRL_EXT, "CTRL_EXT"},
16 	{IGC_MDIC, "MDIC"},
17 
18 	/* Interrupt Registers */
19 	{IGC_ICR, "ICR"},
20 
21 	/* RX Registers */
22 	{IGC_RCTL, "RCTL"},
23 	{IGC_RDLEN(0), "RDLEN"},
24 	{IGC_RDH(0), "RDH"},
25 	{IGC_RDT(0), "RDT"},
26 	{IGC_RXDCTL(0), "RXDCTL"},
27 	{IGC_RDBAL(0), "RDBAL"},
28 	{IGC_RDBAH(0), "RDBAH"},
29 
30 	/* TX Registers */
31 	{IGC_TCTL, "TCTL"},
32 	{IGC_TDBAL(0), "TDBAL"},
33 	{IGC_TDBAH(0), "TDBAH"},
34 	{IGC_TDLEN(0), "TDLEN"},
35 	{IGC_TDH(0), "TDH"},
36 	{IGC_TDT(0), "TDT"},
37 	{IGC_TXDCTL(0), "TXDCTL"},
38 
39 	/* List Terminator */
40 	{}
41 };
42 
43 /* igc_regdump - register printout routine */
44 static void igc_regdump(struct igc_hw *hw, struct igc_reg_info *reginfo)
45 {
46 	struct net_device *dev = igc_get_hw_dev(hw);
47 	int n = 0;
48 	char rname[16];
49 	u32 regs[8];
50 
51 	switch (reginfo->ofs) {
52 	case IGC_RDLEN(0):
53 		for (n = 0; n < 4; n++)
54 			regs[n] = rd32(IGC_RDLEN(n));
55 		break;
56 	case IGC_RDH(0):
57 		for (n = 0; n < 4; n++)
58 			regs[n] = rd32(IGC_RDH(n));
59 		break;
60 	case IGC_RDT(0):
61 		for (n = 0; n < 4; n++)
62 			regs[n] = rd32(IGC_RDT(n));
63 		break;
64 	case IGC_RXDCTL(0):
65 		for (n = 0; n < 4; n++)
66 			regs[n] = rd32(IGC_RXDCTL(n));
67 		break;
68 	case IGC_RDBAL(0):
69 		for (n = 0; n < 4; n++)
70 			regs[n] = rd32(IGC_RDBAL(n));
71 		break;
72 	case IGC_RDBAH(0):
73 		for (n = 0; n < 4; n++)
74 			regs[n] = rd32(IGC_RDBAH(n));
75 		break;
76 	case IGC_TDBAL(0):
77 		for (n = 0; n < 4; n++)
78 			regs[n] = rd32(IGC_RDBAL(n));
79 		break;
80 	case IGC_TDBAH(0):
81 		for (n = 0; n < 4; n++)
82 			regs[n] = rd32(IGC_TDBAH(n));
83 		break;
84 	case IGC_TDLEN(0):
85 		for (n = 0; n < 4; n++)
86 			regs[n] = rd32(IGC_TDLEN(n));
87 		break;
88 	case IGC_TDH(0):
89 		for (n = 0; n < 4; n++)
90 			regs[n] = rd32(IGC_TDH(n));
91 		break;
92 	case IGC_TDT(0):
93 		for (n = 0; n < 4; n++)
94 			regs[n] = rd32(IGC_TDT(n));
95 		break;
96 	case IGC_TXDCTL(0):
97 		for (n = 0; n < 4; n++)
98 			regs[n] = rd32(IGC_TXDCTL(n));
99 		break;
100 	default:
101 		netdev_info(dev, "%-15s %08x\n", reginfo->name,
102 			    rd32(reginfo->ofs));
103 		return;
104 	}
105 
106 	snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]");
107 	netdev_info(dev, "%-15s %08x %08x %08x %08x\n", rname, regs[0], regs[1],
108 		    regs[2], regs[3]);
109 }
110 
111 /* igc_rings_dump - Tx-rings and Rx-rings */
112 void igc_rings_dump(struct igc_adapter *adapter)
113 {
114 	struct net_device *netdev = adapter->netdev;
115 	struct my_u0 { u64 a; u64 b; } *u0;
116 	union igc_adv_tx_desc *tx_desc;
117 	union igc_adv_rx_desc *rx_desc;
118 	struct igc_ring *tx_ring;
119 	struct igc_ring *rx_ring;
120 	u32 staterr;
121 	u16 i, n;
122 
123 	if (!netif_msg_hw(adapter))
124 		return;
125 
126 	netdev_info(netdev, "Device info: state %016lX trans_start %016lX\n",
127 		    netdev->state, dev_trans_start(netdev));
128 
129 	/* Print TX Ring Summary */
130 	if (!netif_running(netdev))
131 		goto exit;
132 
133 	netdev_info(netdev, "TX Rings Summary\n");
134 	netdev_info(netdev, "Queue [NTU] [NTC] [bi(ntc)->dma  ] leng ntw timestamp\n");
135 	for (n = 0; n < adapter->num_tx_queues; n++) {
136 		struct igc_tx_buffer *buffer_info;
137 
138 		tx_ring = adapter->tx_ring[n];
139 		buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean];
140 
141 		netdev_info(netdev, "%5d %5X %5X %016llX %04X %p %016llX\n",
142 			    n, tx_ring->next_to_use, tx_ring->next_to_clean,
143 			    (u64)dma_unmap_addr(buffer_info, dma),
144 			    dma_unmap_len(buffer_info, len),
145 			    buffer_info->next_to_watch,
146 			    (u64)buffer_info->time_stamp);
147 	}
148 
149 	/* Print TX Rings */
150 	if (!netif_msg_tx_done(adapter))
151 		goto rx_ring_summary;
152 
153 	netdev_info(netdev, "TX Rings Dump\n");
154 
155 	/* Transmit Descriptor Formats
156 	 *
157 	 * Advanced Transmit Descriptor
158 	 *   +--------------------------------------------------------------+
159 	 * 0 |         Buffer Address [63:0]                                |
160 	 *   +--------------------------------------------------------------+
161 	 * 8 | PAYLEN  | PORTS  |CC|IDX | STA | DCMD  |DTYP|MAC|RSV| DTALEN |
162 	 *   +--------------------------------------------------------------+
163 	 *   63      46 45    40 39 38 36 35 32 31   24             15       0
164 	 */
165 
166 	for (n = 0; n < adapter->num_tx_queues; n++) {
167 		tx_ring = adapter->tx_ring[n];
168 		netdev_info(netdev, "------------------------------------\n");
169 		netdev_info(netdev, "TX QUEUE INDEX = %d\n",
170 			    tx_ring->queue_index);
171 		netdev_info(netdev, "------------------------------------\n");
172 		netdev_info(netdev, "T [desc]     [address 63:0  ] [PlPOCIStDDM Ln] [bi->dma       ] leng  ntw timestamp        bi->skb\n");
173 
174 		for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
175 			const char *next_desc;
176 			struct igc_tx_buffer *buffer_info;
177 
178 			tx_desc = IGC_TX_DESC(tx_ring, i);
179 			buffer_info = &tx_ring->tx_buffer_info[i];
180 			u0 = (struct my_u0 *)tx_desc;
181 			if (i == tx_ring->next_to_use &&
182 			    i == tx_ring->next_to_clean)
183 				next_desc = " NTC/U";
184 			else if (i == tx_ring->next_to_use)
185 				next_desc = " NTU";
186 			else if (i == tx_ring->next_to_clean)
187 				next_desc = " NTC";
188 			else
189 				next_desc = "";
190 
191 			netdev_info(netdev, "T [0x%03X]    %016llX %016llX %016llX %04X  %p %016llX %p%s\n",
192 				    i, le64_to_cpu(u0->a),
193 				    le64_to_cpu(u0->b),
194 				    (u64)dma_unmap_addr(buffer_info, dma),
195 				    dma_unmap_len(buffer_info, len),
196 				    buffer_info->next_to_watch,
197 				    (u64)buffer_info->time_stamp,
198 				    buffer_info->skb, next_desc);
199 
200 			if (netif_msg_pktdata(adapter) && buffer_info->skb)
201 				print_hex_dump(KERN_INFO, "",
202 					       DUMP_PREFIX_ADDRESS,
203 					       16, 1, buffer_info->skb->data,
204 					       dma_unmap_len(buffer_info, len),
205 					       true);
206 		}
207 	}
208 
209 	/* Print RX Rings Summary */
210 rx_ring_summary:
211 	netdev_info(netdev, "RX Rings Summary\n");
212 	netdev_info(netdev, "Queue [NTU] [NTC]\n");
213 	for (n = 0; n < adapter->num_rx_queues; n++) {
214 		rx_ring = adapter->rx_ring[n];
215 		netdev_info(netdev, "%5d %5X %5X\n", n, rx_ring->next_to_use,
216 			    rx_ring->next_to_clean);
217 	}
218 
219 	/* Print RX Rings */
220 	if (!netif_msg_rx_status(adapter))
221 		goto exit;
222 
223 	netdev_info(netdev, "RX Rings Dump\n");
224 
225 	/* Advanced Receive Descriptor (Read) Format
226 	 *    63                                           1        0
227 	 *    +-----------------------------------------------------+
228 	 *  0 |       Packet Buffer Address [63:1]           |A0/NSE|
229 	 *    +----------------------------------------------+------+
230 	 *  8 |       Header Buffer Address [63:1]           |  DD  |
231 	 *    +-----------------------------------------------------+
232 	 *
233 	 *
234 	 * Advanced Receive Descriptor (Write-Back) Format
235 	 *
236 	 *   63       48 47    32 31  30      21 20 17 16   4 3     0
237 	 *   +------------------------------------------------------+
238 	 * 0 | Packet     IP     |SPH| HDR_LEN   | RSV|Packet|  RSS |
239 	 *   | Checksum   Ident  |   |           |    | Type | Type |
240 	 *   +------------------------------------------------------+
241 	 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
242 	 *   +------------------------------------------------------+
243 	 *   63       48 47    32 31            20 19               0
244 	 */
245 
246 	for (n = 0; n < adapter->num_rx_queues; n++) {
247 		rx_ring = adapter->rx_ring[n];
248 		netdev_info(netdev, "------------------------------------\n");
249 		netdev_info(netdev, "RX QUEUE INDEX = %d\n",
250 			    rx_ring->queue_index);
251 		netdev_info(netdev, "------------------------------------\n");
252 		netdev_info(netdev, "R  [desc]      [ PktBuf     A0] [  HeadBuf   DD] [bi->dma       ] [bi->skb] <-- Adv Rx Read format\n");
253 		netdev_info(netdev, "RWB[desc]      [PcsmIpSHl PtRs] [vl er S cks ln] ---------------- [bi->skb] <-- Adv Rx Write-Back format\n");
254 
255 		for (i = 0; i < rx_ring->count; i++) {
256 			const char *next_desc;
257 			struct igc_rx_buffer *buffer_info;
258 
259 			buffer_info = &rx_ring->rx_buffer_info[i];
260 			rx_desc = IGC_RX_DESC(rx_ring, i);
261 			u0 = (struct my_u0 *)rx_desc;
262 			staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
263 
264 			if (i == rx_ring->next_to_use)
265 				next_desc = " NTU";
266 			else if (i == rx_ring->next_to_clean)
267 				next_desc = " NTC";
268 			else
269 				next_desc = "";
270 
271 			if (staterr & IGC_RXD_STAT_DD) {
272 				/* Descriptor Done */
273 				netdev_info(netdev, "%s[0x%03X]     %016llX %016llX ---------------- %s\n",
274 					    "RWB", i,
275 					    le64_to_cpu(u0->a),
276 					    le64_to_cpu(u0->b),
277 					    next_desc);
278 			} else {
279 				netdev_info(netdev, "%s[0x%03X]     %016llX %016llX %016llX %s\n",
280 					    "R  ", i,
281 					    le64_to_cpu(u0->a),
282 					    le64_to_cpu(u0->b),
283 					    (u64)buffer_info->dma,
284 					    next_desc);
285 
286 				if (netif_msg_pktdata(adapter) &&
287 				    buffer_info->dma && buffer_info->page) {
288 					print_hex_dump(KERN_INFO, "",
289 						       DUMP_PREFIX_ADDRESS,
290 						       16, 1,
291 						       page_address
292 						       (buffer_info->page) +
293 						       buffer_info->page_offset,
294 						       igc_rx_bufsz(rx_ring),
295 						       true);
296 				}
297 			}
298 		}
299 	}
300 
301 exit:
302 	return;
303 }
304 
305 /* igc_regs_dump - registers dump */
306 void igc_regs_dump(struct igc_adapter *adapter)
307 {
308 	struct igc_hw *hw = &adapter->hw;
309 	struct igc_reg_info *reginfo;
310 
311 	/* Print Registers */
312 	netdev_info(adapter->netdev, "Register Dump\n");
313 	netdev_info(adapter->netdev, "Register Name   Value\n");
314 	for (reginfo = (struct igc_reg_info *)igc_reg_info_tbl;
315 	     reginfo->name; reginfo++) {
316 		igc_regdump(hw, reginfo);
317 	}
318 }
319