diff options
author | Taku Izumi <izumi.taku@jp.fujitsu.com> | 2010-04-27 10:39:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-27 20:46:56 -0400 |
commit | 84f4ee902ad3ee964b7b3a13d5b7cf9c086e9916 (patch) | |
tree | 31b1b420e3ca1da32824840fc6d31d71c2efabdf | |
parent | 675ad47375c76a7c3be4ace9554d92cd55518ced (diff) |
e1000e: add registers etc. printout code just before resetting adapters
This patch adds registers (,tx/rx rings' status and so on) printout
code just before resetting adapters. This will be helpful for detecting
the root cause of adapters reset.
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/e1000e/netdev.c | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3a712157b6a1..904bd6bf3199 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -69,6 +69,361 @@ static const struct e1000_info *e1000_info_tbl[] = { | |||
69 | [board_pchlan] = &e1000_pch_info, | 69 | [board_pchlan] = &e1000_pch_info, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct e1000_reg_info { | ||
73 | u32 ofs; | ||
74 | char *name; | ||
75 | }; | ||
76 | |||
77 | #define E1000_RDFH 0x02410 /* Rx Data FIFO Head - RW */ | ||
78 | #define E1000_RDFT 0x02418 /* Rx Data FIFO Tail - RW */ | ||
79 | #define E1000_RDFHS 0x02420 /* Rx Data FIFO Head Saved - RW */ | ||
80 | #define E1000_RDFTS 0x02428 /* Rx Data FIFO Tail Saved - RW */ | ||
81 | #define E1000_RDFPC 0x02430 /* Rx Data FIFO Packet Count - RW */ | ||
82 | |||
83 | #define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */ | ||
84 | #define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */ | ||
85 | #define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */ | ||
86 | #define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */ | ||
87 | #define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */ | ||
88 | |||
89 | static const struct e1000_reg_info e1000_reg_info_tbl[] = { | ||
90 | |||
91 | /* General Registers */ | ||
92 | {E1000_CTRL, "CTRL"}, | ||
93 | {E1000_STATUS, "STATUS"}, | ||
94 | {E1000_CTRL_EXT, "CTRL_EXT"}, | ||
95 | |||
96 | /* Interrupt Registers */ | ||
97 | {E1000_ICR, "ICR"}, | ||
98 | |||
99 | /* RX Registers */ | ||
100 | {E1000_RCTL, "RCTL"}, | ||
101 | {E1000_RDLEN, "RDLEN"}, | ||
102 | {E1000_RDH, "RDH"}, | ||
103 | {E1000_RDT, "RDT"}, | ||
104 | {E1000_RDTR, "RDTR"}, | ||
105 | {E1000_RXDCTL(0), "RXDCTL"}, | ||
106 | {E1000_ERT, "ERT"}, | ||
107 | {E1000_RDBAL, "RDBAL"}, | ||
108 | {E1000_RDBAH, "RDBAH"}, | ||
109 | {E1000_RDFH, "RDFH"}, | ||
110 | {E1000_RDFT, "RDFT"}, | ||
111 | {E1000_RDFHS, "RDFHS"}, | ||
112 | {E1000_RDFTS, "RDFTS"}, | ||
113 | {E1000_RDFPC, "RDFPC"}, | ||
114 | |||
115 | /* TX Registers */ | ||
116 | {E1000_TCTL, "TCTL"}, | ||
117 | {E1000_TDBAL, "TDBAL"}, | ||
118 | {E1000_TDBAH, "TDBAH"}, | ||
119 | {E1000_TDLEN, "TDLEN"}, | ||
120 | {E1000_TDH, "TDH"}, | ||
121 | {E1000_TDT, "TDT"}, | ||
122 | {E1000_TIDV, "TIDV"}, | ||
123 | {E1000_TXDCTL(0), "TXDCTL"}, | ||
124 | {E1000_TADV, "TADV"}, | ||
125 | {E1000_TARC(0), "TARC"}, | ||
126 | {E1000_TDFH, "TDFH"}, | ||
127 | {E1000_TDFT, "TDFT"}, | ||
128 | {E1000_TDFHS, "TDFHS"}, | ||
129 | {E1000_TDFTS, "TDFTS"}, | ||
130 | {E1000_TDFPC, "TDFPC"}, | ||
131 | |||
132 | /* List Terminator */ | ||
133 | {} | ||
134 | }; | ||
135 | |||
136 | /* | ||
137 | * e1000_regdump - register printout routine | ||
138 | */ | ||
139 | static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo) | ||
140 | { | ||
141 | int n = 0; | ||
142 | char rname[16]; | ||
143 | u32 regs[8]; | ||
144 | |||
145 | switch (reginfo->ofs) { | ||
146 | case E1000_RXDCTL(0): | ||
147 | for (n = 0; n < 2; n++) | ||
148 | regs[n] = __er32(hw, E1000_RXDCTL(n)); | ||
149 | break; | ||
150 | case E1000_TXDCTL(0): | ||
151 | for (n = 0; n < 2; n++) | ||
152 | regs[n] = __er32(hw, E1000_TXDCTL(n)); | ||
153 | break; | ||
154 | case E1000_TARC(0): | ||
155 | for (n = 0; n < 2; n++) | ||
156 | regs[n] = __er32(hw, E1000_TARC(n)); | ||
157 | break; | ||
158 | default: | ||
159 | printk(KERN_INFO "%-15s %08x\n", | ||
160 | reginfo->name, __er32(hw, reginfo->ofs)); | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]"); | ||
165 | printk(KERN_INFO "%-15s ", rname); | ||
166 | for (n = 0; n < 2; n++) | ||
167 | printk(KERN_CONT "%08x ", regs[n]); | ||
168 | printk(KERN_CONT "\n"); | ||
169 | } | ||
170 | |||
171 | |||
172 | /* | ||
173 | * e1000e_dump - Print registers, tx-ring and rx-ring | ||
174 | */ | ||
175 | static void e1000e_dump(struct e1000_adapter *adapter) | ||
176 | { | ||
177 | struct net_device *netdev = adapter->netdev; | ||
178 | struct e1000_hw *hw = &adapter->hw; | ||
179 | struct e1000_reg_info *reginfo; | ||
180 | struct e1000_ring *tx_ring = adapter->tx_ring; | ||
181 | struct e1000_tx_desc *tx_desc; | ||
182 | struct my_u0 { u64 a; u64 b; } *u0; | ||
183 | struct e1000_buffer *buffer_info; | ||
184 | struct e1000_ring *rx_ring = adapter->rx_ring; | ||
185 | union e1000_rx_desc_packet_split *rx_desc_ps; | ||
186 | struct e1000_rx_desc *rx_desc; | ||
187 | struct my_u1 { u64 a; u64 b; u64 c; u64 d; } *u1; | ||
188 | u32 staterr; | ||
189 | int i = 0; | ||
190 | |||
191 | if (!netif_msg_hw(adapter)) | ||
192 | return; | ||
193 | |||
194 | /* Print netdevice Info */ | ||
195 | if (netdev) { | ||
196 | dev_info(&adapter->pdev->dev, "Net device Info\n"); | ||
197 | printk(KERN_INFO "Device Name state " | ||
198 | "trans_start last_rx\n"); | ||
199 | printk(KERN_INFO "%-15s %016lX %016lX %016lX\n", | ||
200 | netdev->name, | ||
201 | netdev->state, | ||
202 | netdev->trans_start, | ||
203 | netdev->last_rx); | ||
204 | } | ||
205 | |||
206 | /* Print Registers */ | ||
207 | dev_info(&adapter->pdev->dev, "Register Dump\n"); | ||
208 | printk(KERN_INFO " Register Name Value\n"); | ||
209 | for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl; | ||
210 | reginfo->name; reginfo++) { | ||
211 | e1000_regdump(hw, reginfo); | ||
212 | } | ||
213 | |||
214 | /* Print TX Ring Summary */ | ||
215 | if (!netdev || !netif_running(netdev)) | ||
216 | goto exit; | ||
217 | |||
218 | dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); | ||
219 | printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ]" | ||
220 | " leng ntw timestamp\n"); | ||
221 | buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean]; | ||
222 | printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n", | ||
223 | 0, tx_ring->next_to_use, tx_ring->next_to_clean, | ||
224 | (u64)buffer_info->dma, | ||
225 | buffer_info->length, | ||
226 | buffer_info->next_to_watch, | ||
227 | (u64)buffer_info->time_stamp); | ||
228 | |||
229 | /* Print TX Rings */ | ||
230 | if (!netif_msg_tx_done(adapter)) | ||
231 | goto rx_ring_summary; | ||
232 | |||
233 | dev_info(&adapter->pdev->dev, "TX Rings Dump\n"); | ||
234 | |||
235 | /* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended) | ||
236 | * | ||
237 | * Legacy Transmit Descriptor | ||
238 | * +--------------------------------------------------------------+ | ||
239 | * 0 | Buffer Address [63:0] (Reserved on Write Back) | | ||
240 | * +--------------------------------------------------------------+ | ||
241 | * 8 | Special | CSS | Status | CMD | CSO | Length | | ||
242 | * +--------------------------------------------------------------+ | ||
243 | * 63 48 47 36 35 32 31 24 23 16 15 0 | ||
244 | * | ||
245 | * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload | ||
246 | * 63 48 47 40 39 32 31 16 15 8 7 0 | ||
247 | * +----------------------------------------------------------------+ | ||
248 | * 0 | TUCSE | TUCS0 | TUCSS | IPCSE | IPCS0 | IPCSS | | ||
249 | * +----------------------------------------------------------------+ | ||
250 | * 8 | MSS | HDRLEN | RSV | STA | TUCMD | DTYP | PAYLEN | | ||
251 | * +----------------------------------------------------------------+ | ||
252 | * 63 48 47 40 39 36 35 32 31 24 23 20 19 0 | ||
253 | * | ||
254 | * Extended Data Descriptor (DTYP=0x1) | ||
255 | * +----------------------------------------------------------------+ | ||
256 | * 0 | Buffer Address [63:0] | | ||
257 | * +----------------------------------------------------------------+ | ||
258 | * 8 | VLAN tag | POPTS | Rsvd | Status | Command | DTYP | DTALEN | | ||
259 | * +----------------------------------------------------------------+ | ||
260 | * 63 48 47 40 39 36 35 32 31 24 23 20 19 0 | ||
261 | */ | ||
262 | printk(KERN_INFO "Tl[desc] [address 63:0 ] [SpeCssSCmCsLen]" | ||
263 | " [bi->dma ] leng ntw timestamp bi->skb " | ||
264 | "<-- Legacy format\n"); | ||
265 | printk(KERN_INFO "Tc[desc] [Ce CoCsIpceCoS] [MssHlRSCm0Plen]" | ||
266 | " [bi->dma ] leng ntw timestamp bi->skb " | ||
267 | "<-- Ext Context format\n"); | ||
268 | printk(KERN_INFO "Td[desc] [address 63:0 ] [VlaPoRSCm1Dlen]" | ||
269 | " [bi->dma ] leng ntw timestamp bi->skb " | ||
270 | "<-- Ext Data format\n"); | ||
271 | for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { | ||
272 | tx_desc = E1000_TX_DESC(*tx_ring, i); | ||
273 | buffer_info = &tx_ring->buffer_info[i]; | ||
274 | u0 = (struct my_u0 *)tx_desc; | ||
275 | printk(KERN_INFO "T%c[0x%03X] %016llX %016llX %016llX " | ||
276 | "%04X %3X %016llX %p", | ||
277 | (!(le64_to_cpu(u0->b) & (1<<29)) ? 'l' : | ||
278 | ((le64_to_cpu(u0->b) & (1<<20)) ? 'd' : 'c')), i, | ||
279 | le64_to_cpu(u0->a), le64_to_cpu(u0->b), | ||
280 | (u64)buffer_info->dma, buffer_info->length, | ||
281 | buffer_info->next_to_watch, (u64)buffer_info->time_stamp, | ||
282 | buffer_info->skb); | ||
283 | if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean) | ||
284 | printk(KERN_CONT " NTC/U\n"); | ||
285 | else if (i == tx_ring->next_to_use) | ||
286 | printk(KERN_CONT " NTU\n"); | ||
287 | else if (i == tx_ring->next_to_clean) | ||
288 | printk(KERN_CONT " NTC\n"); | ||
289 | else | ||
290 | printk(KERN_CONT "\n"); | ||
291 | |||
292 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) | ||
293 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, | ||
294 | 16, 1, phys_to_virt(buffer_info->dma), | ||
295 | buffer_info->length, true); | ||
296 | } | ||
297 | |||
298 | /* Print RX Rings Summary */ | ||
299 | rx_ring_summary: | ||
300 | dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); | ||
301 | printk(KERN_INFO "Queue [NTU] [NTC]\n"); | ||
302 | printk(KERN_INFO " %5d %5X %5X\n", 0, | ||
303 | rx_ring->next_to_use, rx_ring->next_to_clean); | ||
304 | |||
305 | /* Print RX Rings */ | ||
306 | if (!netif_msg_rx_status(adapter)) | ||
307 | goto exit; | ||
308 | |||
309 | dev_info(&adapter->pdev->dev, "RX Rings Dump\n"); | ||
310 | switch (adapter->rx_ps_pages) { | ||
311 | case 1: | ||
312 | case 2: | ||
313 | case 3: | ||
314 | /* [Extended] Packet Split Receive Descriptor Format | ||
315 | * | ||
316 | * +-----------------------------------------------------+ | ||
317 | * 0 | Buffer Address 0 [63:0] | | ||
318 | * +-----------------------------------------------------+ | ||
319 | * 8 | Buffer Address 1 [63:0] | | ||
320 | * +-----------------------------------------------------+ | ||
321 | * 16 | Buffer Address 2 [63:0] | | ||
322 | * +-----------------------------------------------------+ | ||
323 | * 24 | Buffer Address 3 [63:0] | | ||
324 | * +-----------------------------------------------------+ | ||
325 | */ | ||
326 | printk(KERN_INFO "R [desc] [buffer 0 63:0 ] " | ||
327 | "[buffer 1 63:0 ] " | ||
328 | "[buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma ] " | ||
329 | "[bi->skb] <-- Ext Pkt Split format\n"); | ||
330 | /* [Extended] Receive Descriptor (Write-Back) Format | ||
331 | * | ||
332 | * 63 48 47 32 31 13 12 8 7 4 3 0 | ||
333 | * +------------------------------------------------------+ | ||
334 | * 0 | Packet | IP | Rsvd | MRQ | Rsvd | MRQ RSS | | ||
335 | * | Checksum | Ident | | Queue | | Type | | ||
336 | * +------------------------------------------------------+ | ||
337 | * 8 | VLAN Tag | Length | Extended Error | Extended Status | | ||
338 | * +------------------------------------------------------+ | ||
339 | * 63 48 47 32 31 20 19 0 | ||
340 | */ | ||
341 | printk(KERN_INFO "RWB[desc] [ck ipid mrqhsh] " | ||
342 | "[vl l0 ee es] " | ||
343 | "[ l3 l2 l1 hs] [reserved ] ---------------- " | ||
344 | "[bi->skb] <-- Ext Rx Write-Back format\n"); | ||
345 | for (i = 0; i < rx_ring->count; i++) { | ||
346 | buffer_info = &rx_ring->buffer_info[i]; | ||
347 | rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i); | ||
348 | u1 = (struct my_u1 *)rx_desc_ps; | ||
349 | staterr = | ||
350 | le32_to_cpu(rx_desc_ps->wb.middle.status_error); | ||
351 | if (staterr & E1000_RXD_STAT_DD) { | ||
352 | /* Descriptor Done */ | ||
353 | printk(KERN_INFO "RWB[0x%03X] %016llX " | ||
354 | "%016llX %016llX %016llX " | ||
355 | "---------------- %p", i, | ||
356 | le64_to_cpu(u1->a), | ||
357 | le64_to_cpu(u1->b), | ||
358 | le64_to_cpu(u1->c), | ||
359 | le64_to_cpu(u1->d), | ||
360 | buffer_info->skb); | ||
361 | } else { | ||
362 | printk(KERN_INFO "R [0x%03X] %016llX " | ||
363 | "%016llX %016llX %016llX %016llX %p", i, | ||
364 | le64_to_cpu(u1->a), | ||
365 | le64_to_cpu(u1->b), | ||
366 | le64_to_cpu(u1->c), | ||
367 | le64_to_cpu(u1->d), | ||
368 | (u64)buffer_info->dma, | ||
369 | buffer_info->skb); | ||
370 | |||
371 | if (netif_msg_pktdata(adapter)) | ||
372 | print_hex_dump(KERN_INFO, "", | ||
373 | DUMP_PREFIX_ADDRESS, 16, 1, | ||
374 | phys_to_virt(buffer_info->dma), | ||
375 | adapter->rx_ps_bsize0, true); | ||
376 | } | ||
377 | |||
378 | if (i == rx_ring->next_to_use) | ||
379 | printk(KERN_CONT " NTU\n"); | ||
380 | else if (i == rx_ring->next_to_clean) | ||
381 | printk(KERN_CONT " NTC\n"); | ||
382 | else | ||
383 | printk(KERN_CONT "\n"); | ||
384 | } | ||
385 | break; | ||
386 | default: | ||
387 | case 0: | ||
388 | /* Legacy Receive Descriptor Format | ||
389 | * | ||
390 | * +-----------------------------------------------------+ | ||
391 | * | Buffer Address [63:0] | | ||
392 | * +-----------------------------------------------------+ | ||
393 | * | VLAN Tag | Errors | Status 0 | Packet csum | Length | | ||
394 | * +-----------------------------------------------------+ | ||
395 | * 63 48 47 40 39 32 31 16 15 0 | ||
396 | */ | ||
397 | printk(KERN_INFO "Rl[desc] [address 63:0 ] " | ||
398 | "[vl er S cks ln] [bi->dma ] [bi->skb] " | ||
399 | "<-- Legacy format\n"); | ||
400 | for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) { | ||
401 | rx_desc = E1000_RX_DESC(*rx_ring, i); | ||
402 | buffer_info = &rx_ring->buffer_info[i]; | ||
403 | u0 = (struct my_u0 *)rx_desc; | ||
404 | printk(KERN_INFO "Rl[0x%03X] %016llX %016llX " | ||
405 | "%016llX %p", | ||
406 | i, le64_to_cpu(u0->a), le64_to_cpu(u0->b), | ||
407 | (u64)buffer_info->dma, buffer_info->skb); | ||
408 | if (i == rx_ring->next_to_use) | ||
409 | printk(KERN_CONT " NTU\n"); | ||
410 | else if (i == rx_ring->next_to_clean) | ||
411 | printk(KERN_CONT " NTC\n"); | ||
412 | else | ||
413 | printk(KERN_CONT "\n"); | ||
414 | |||
415 | if (netif_msg_pktdata(adapter)) | ||
416 | print_hex_dump(KERN_INFO, "", | ||
417 | DUMP_PREFIX_ADDRESS, | ||
418 | 16, 1, phys_to_virt(buffer_info->dma), | ||
419 | adapter->rx_buffer_len, true); | ||
420 | } | ||
421 | } | ||
422 | |||
423 | exit: | ||
424 | return; | ||
425 | } | ||
426 | |||
72 | /** | 427 | /** |
73 | * e1000_desc_unused - calculate if we have unused descriptors | 428 | * e1000_desc_unused - calculate if we have unused descriptors |
74 | **/ | 429 | **/ |
@@ -4269,6 +4624,8 @@ static void e1000_reset_task(struct work_struct *work) | |||
4269 | struct e1000_adapter *adapter; | 4624 | struct e1000_adapter *adapter; |
4270 | adapter = container_of(work, struct e1000_adapter, reset_task); | 4625 | adapter = container_of(work, struct e1000_adapter, reset_task); |
4271 | 4626 | ||
4627 | e1000e_dump(adapter); | ||
4628 | e_err("Reset adapter\n"); | ||
4272 | e1000e_reinit_locked(adapter); | 4629 | e1000e_reinit_locked(adapter); |
4273 | } | 4630 | } |
4274 | 4631 | ||