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