aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-01-27 03:15:06 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-27 03:15:06 -0500
commitd2fa7cc4e3bd759f5c8e093d1e08b718c722f319 (patch)
tree942f6246951b450195861964c2b7bdfe4a71db8d
parentb8665c6c16fee59540b14ef145363971dc6cb6c8 (diff)
parentb58b667687b71e1f07190ba5faa66e80013eaac6 (diff)
Merge branch 'cxgb4-next'
Hariprasad Shenai says: ==================== Add support to dump cim ibq, obq and qinfo, etc This patch series adds support to dump cim_ibq, cim_obq, sge_qinfo, pm_stats and clk debugfs entries. The patches series is created against 'net-next' tree. And includes patches on cxgb4 driver. We have included all the maintainers of respective drivers. Kindly review the change and let us know in case of any review comments. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h8
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c439
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c139
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.h3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_regs.h68
6 files changed, 659 insertions, 2 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 24fc162ee57a..d98a44637896 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -1029,6 +1029,8 @@ int cxgb4_t4_bar2_sge_qregs(struct adapter *adapter,
1029 u64 *pbar2_qoffset, 1029 u64 *pbar2_qoffset,
1030 unsigned int *pbar2_qid); 1030 unsigned int *pbar2_qid);
1031 1031
1032unsigned int qtimer_val(const struct adapter *adap,
1033 const struct sge_rspq *q);
1032int t4_init_sge_params(struct adapter *adapter); 1034int t4_init_sge_params(struct adapter *adapter);
1033int t4_init_tp_params(struct adapter *adap); 1035int t4_init_tp_params(struct adapter *adap);
1034int t4_filter_field_shift(const struct adapter *adap, int filter_sel); 1036int t4_filter_field_shift(const struct adapter *adap, int filter_sel);
@@ -1052,6 +1054,12 @@ int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data,
1052 u64 *parity); 1054 u64 *parity);
1053int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, 1055int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data,
1054 u64 *parity); 1056 u64 *parity);
1057void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]);
1058void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]);
1059int t4_read_cim_ibq(struct adapter *adap, unsigned int qid, u32 *data,
1060 size_t n);
1061int t4_read_cim_obq(struct adapter *adap, unsigned int qid, u32 *data,
1062 size_t n);
1055int t4_cim_read(struct adapter *adap, unsigned int addr, unsigned int n, 1063int t4_cim_read(struct adapter *adap, unsigned int addr, unsigned int n,
1056 unsigned int *valp); 1064 unsigned int *valp);
1057int t4_cim_write(struct adapter *adap, unsigned int addr, unsigned int n, 1065int t4_cim_write(struct adapter *adap, unsigned int addr, unsigned int n,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 714cc70b97cc..47c0869f34ca 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -104,6 +104,17 @@ struct seq_tab *seq_open_tab(struct file *f, unsigned int rows,
104 return p; 104 return p;
105} 105}
106 106
107/* Trim the size of a seq_tab to the supplied number of rows. The operation is
108 * irreversible.
109 */
110static int seq_tab_trim(struct seq_tab *p, unsigned int new_rows)
111{
112 if (new_rows > p->rows)
113 return -EINVAL;
114 p->rows = new_rows;
115 return 0;
116}
117
107static int cim_la_show(struct seq_file *seq, void *v, int idx) 118static int cim_la_show(struct seq_file *seq, void *v, int idx)
108{ 119{
109 if (v == SEQ_START_TOKEN) 120 if (v == SEQ_START_TOKEN)
@@ -239,6 +250,198 @@ static const struct file_operations cim_qcfg_fops = {
239 .release = single_release, 250 .release = single_release,
240}; 251};
241 252
253static int cimq_show(struct seq_file *seq, void *v, int idx)
254{
255 const u32 *p = v;
256
257 seq_printf(seq, "%#06x: %08x %08x %08x %08x\n", idx * 16, p[0], p[1],
258 p[2], p[3]);
259 return 0;
260}
261
262static int cim_ibq_open(struct inode *inode, struct file *file)
263{
264 int ret;
265 struct seq_tab *p;
266 unsigned int qid = (uintptr_t)inode->i_private & 7;
267 struct adapter *adap = inode->i_private - qid;
268
269 p = seq_open_tab(file, CIM_IBQ_SIZE, 4 * sizeof(u32), 0, cimq_show);
270 if (!p)
271 return -ENOMEM;
272
273 ret = t4_read_cim_ibq(adap, qid, (u32 *)p->data, CIM_IBQ_SIZE * 4);
274 if (ret < 0)
275 seq_release_private(inode, file);
276 else
277 ret = 0;
278 return ret;
279}
280
281static const struct file_operations cim_ibq_fops = {
282 .owner = THIS_MODULE,
283 .open = cim_ibq_open,
284 .read = seq_read,
285 .llseek = seq_lseek,
286 .release = seq_release_private
287};
288
289static int cim_obq_open(struct inode *inode, struct file *file)
290{
291 int ret;
292 struct seq_tab *p;
293 unsigned int qid = (uintptr_t)inode->i_private & 7;
294 struct adapter *adap = inode->i_private - qid;
295
296 p = seq_open_tab(file, 6 * CIM_OBQ_SIZE, 4 * sizeof(u32), 0, cimq_show);
297 if (!p)
298 return -ENOMEM;
299
300 ret = t4_read_cim_obq(adap, qid, (u32 *)p->data, 6 * CIM_OBQ_SIZE * 4);
301 if (ret < 0) {
302 seq_release_private(inode, file);
303 } else {
304 seq_tab_trim(p, ret / 4);
305 ret = 0;
306 }
307 return ret;
308}
309
310static const struct file_operations cim_obq_fops = {
311 .owner = THIS_MODULE,
312 .open = cim_obq_open,
313 .read = seq_read,
314 .llseek = seq_lseek,
315 .release = seq_release_private
316};
317
318/* Show the PM memory stats. These stats include:
319 *
320 * TX:
321 * Read: memory read operation
322 * Write Bypass: cut-through
323 * Bypass + mem: cut-through and save copy
324 *
325 * RX:
326 * Read: memory read
327 * Write Bypass: cut-through
328 * Flush: payload trim or drop
329 */
330static int pm_stats_show(struct seq_file *seq, void *v)
331{
332 static const char * const tx_pm_stats[] = {
333 "Read:", "Write bypass:", "Write mem:", "Bypass + mem:"
334 };
335 static const char * const rx_pm_stats[] = {
336 "Read:", "Write bypass:", "Write mem:", "Flush:"
337 };
338
339 int i;
340 u32 tx_cnt[PM_NSTATS], rx_cnt[PM_NSTATS];
341 u64 tx_cyc[PM_NSTATS], rx_cyc[PM_NSTATS];
342 struct adapter *adap = seq->private;
343
344 t4_pmtx_get_stats(adap, tx_cnt, tx_cyc);
345 t4_pmrx_get_stats(adap, rx_cnt, rx_cyc);
346
347 seq_printf(seq, "%13s %10s %20s\n", " ", "Tx pcmds", "Tx bytes");
348 for (i = 0; i < PM_NSTATS - 1; i++)
349 seq_printf(seq, "%-13s %10u %20llu\n",
350 tx_pm_stats[i], tx_cnt[i], tx_cyc[i]);
351
352 seq_printf(seq, "%13s %10s %20s\n", " ", "Rx pcmds", "Rx bytes");
353 for (i = 0; i < PM_NSTATS - 1; i++)
354 seq_printf(seq, "%-13s %10u %20llu\n",
355 rx_pm_stats[i], rx_cnt[i], rx_cyc[i]);
356 return 0;
357}
358
359static int pm_stats_open(struct inode *inode, struct file *file)
360{
361 return single_open(file, pm_stats_show, inode->i_private);
362}
363
364static ssize_t pm_stats_clear(struct file *file, const char __user *buf,
365 size_t count, loff_t *pos)
366{
367 struct adapter *adap = FILE_DATA(file)->i_private;
368
369 t4_write_reg(adap, PM_RX_STAT_CONFIG_A, 0);
370 t4_write_reg(adap, PM_TX_STAT_CONFIG_A, 0);
371 return count;
372}
373
374static const struct file_operations pm_stats_debugfs_fops = {
375 .owner = THIS_MODULE,
376 .open = pm_stats_open,
377 .read = seq_read,
378 .llseek = seq_lseek,
379 .release = single_release,
380 .write = pm_stats_clear
381};
382
383/* Format a value in a unit that differs from the value's native unit by the
384 * given factor.
385 */
386static char *unit_conv(char *buf, size_t len, unsigned int val,
387 unsigned int factor)
388{
389 unsigned int rem = val % factor;
390
391 if (rem == 0) {
392 snprintf(buf, len, "%u", val / factor);
393 } else {
394 while (rem % 10 == 0)
395 rem /= 10;
396 snprintf(buf, len, "%u.%u", val / factor, rem);
397 }
398 return buf;
399}
400
401static int clk_show(struct seq_file *seq, void *v)
402{
403 char buf[32];
404 struct adapter *adap = seq->private;
405 unsigned int cclk_ps = 1000000000 / adap->params.vpd.cclk; /* in ps */
406 u32 res = t4_read_reg(adap, TP_TIMER_RESOLUTION_A);
407 unsigned int tre = TIMERRESOLUTION_G(res);
408 unsigned int dack_re = DELAYEDACKRESOLUTION_G(res);
409 unsigned long long tp_tick_us = (cclk_ps << tre) / 1000000; /* in us */
410
411 seq_printf(seq, "Core clock period: %s ns\n",
412 unit_conv(buf, sizeof(buf), cclk_ps, 1000));
413 seq_printf(seq, "TP timer tick: %s us\n",
414 unit_conv(buf, sizeof(buf), (cclk_ps << tre), 1000000));
415 seq_printf(seq, "TCP timestamp tick: %s us\n",
416 unit_conv(buf, sizeof(buf),
417 (cclk_ps << TIMESTAMPRESOLUTION_G(res)), 1000000));
418 seq_printf(seq, "DACK tick: %s us\n",
419 unit_conv(buf, sizeof(buf), (cclk_ps << dack_re), 1000000));
420 seq_printf(seq, "DACK timer: %u us\n",
421 ((cclk_ps << dack_re) / 1000000) *
422 t4_read_reg(adap, TP_DACK_TIMER_A));
423 seq_printf(seq, "Retransmit min: %llu us\n",
424 tp_tick_us * t4_read_reg(adap, TP_RXT_MIN_A));
425 seq_printf(seq, "Retransmit max: %llu us\n",
426 tp_tick_us * t4_read_reg(adap, TP_RXT_MAX_A));
427 seq_printf(seq, "Persist timer min: %llu us\n",
428 tp_tick_us * t4_read_reg(adap, TP_PERS_MIN_A));
429 seq_printf(seq, "Persist timer max: %llu us\n",
430 tp_tick_us * t4_read_reg(adap, TP_PERS_MAX_A));
431 seq_printf(seq, "Keepalive idle timer: %llu us\n",
432 tp_tick_us * t4_read_reg(adap, TP_KEEP_IDLE_A));
433 seq_printf(seq, "Keepalive interval: %llu us\n",
434 tp_tick_us * t4_read_reg(adap, TP_KEEP_INTVL_A));
435 seq_printf(seq, "Initial SRTT: %llu us\n",
436 tp_tick_us * INITSRTT_G(t4_read_reg(adap, TP_INIT_SRTT_A)));
437 seq_printf(seq, "FINWAIT2 timer: %llu us\n",
438 tp_tick_us * t4_read_reg(adap, TP_FINWAIT2_TIMER_A));
439
440 return 0;
441}
442
443DEFINE_SIMPLE_DEBUGFS_FILE(clk);
444
242/* Firmware Device Log dump. */ 445/* Firmware Device Log dump. */
243static const char * const devlog_level_strings[] = { 446static const char * const devlog_level_strings[] = {
244 [FW_DEVLOG_LEVEL_EMERG] = "EMERG", 447 [FW_DEVLOG_LEVEL_EMERG] = "EMERG",
@@ -1026,6 +1229,216 @@ static const struct file_operations rss_vf_config_debugfs_fops = {
1026 .release = seq_release_private 1229 .release = seq_release_private
1027}; 1230};
1028 1231
1232static int sge_qinfo_show(struct seq_file *seq, void *v)
1233{
1234 struct adapter *adap = seq->private;
1235 int eth_entries = DIV_ROUND_UP(adap->sge.ethqsets, 4);
1236 int toe_entries = DIV_ROUND_UP(adap->sge.ofldqsets, 4);
1237 int rdma_entries = DIV_ROUND_UP(adap->sge.rdmaqs, 4);
1238 int ciq_entries = DIV_ROUND_UP(adap->sge.rdmaciqs, 4);
1239 int ctrl_entries = DIV_ROUND_UP(MAX_CTRL_QUEUES, 4);
1240 int i, r = (uintptr_t)v - 1;
1241 int toe_idx = r - eth_entries;
1242 int rdma_idx = toe_idx - toe_entries;
1243 int ciq_idx = rdma_idx - rdma_entries;
1244 int ctrl_idx = ciq_idx - ciq_entries;
1245 int fq_idx = ctrl_idx - ctrl_entries;
1246
1247 if (r)
1248 seq_putc(seq, '\n');
1249
1250#define S3(fmt_spec, s, v) \
1251do { \
1252 seq_printf(seq, "%-12s", s); \
1253 for (i = 0; i < n; ++i) \
1254 seq_printf(seq, " %16" fmt_spec, v); \
1255 seq_putc(seq, '\n'); \
1256} while (0)
1257#define S(s, v) S3("s", s, v)
1258#define T(s, v) S3("u", s, tx[i].v)
1259#define R(s, v) S3("u", s, rx[i].v)
1260
1261 if (r < eth_entries) {
1262 int base_qset = r * 4;
1263 const struct sge_eth_rxq *rx = &adap->sge.ethrxq[base_qset];
1264 const struct sge_eth_txq *tx = &adap->sge.ethtxq[base_qset];
1265 int n = min(4, adap->sge.ethqsets - 4 * r);
1266
1267 S("QType:", "Ethernet");
1268 S("Interface:",
1269 rx[i].rspq.netdev ? rx[i].rspq.netdev->name : "N/A");
1270 T("TxQ ID:", q.cntxt_id);
1271 T("TxQ size:", q.size);
1272 T("TxQ inuse:", q.in_use);
1273 T("TxQ CIDX:", q.cidx);
1274 T("TxQ PIDX:", q.pidx);
1275#ifdef CONFIG_CXGB4_DCB
1276 T("DCB Prio:", dcb_prio);
1277 S3("u", "DCB PGID:",
1278 (ethqset2pinfo(adap, base_qset + i)->dcb.pgid >>
1279 4*(7-tx[i].dcb_prio)) & 0xf);
1280 S3("u", "DCB PFC:",
1281 (ethqset2pinfo(adap, base_qset + i)->dcb.pfcen >>
1282 1*(7-tx[i].dcb_prio)) & 0x1);
1283#endif
1284 R("RspQ ID:", rspq.abs_id);
1285 R("RspQ size:", rspq.size);
1286 R("RspQE size:", rspq.iqe_len);
1287 R("RspQ CIDX:", rspq.cidx);
1288 R("RspQ Gen:", rspq.gen);
1289 S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
1290 S3("u", "Intr pktcnt:",
1291 adap->sge.counter_val[rx[i].rspq.pktcnt_idx]);
1292 R("FL ID:", fl.cntxt_id);
1293 R("FL size:", fl.size - 8);
1294 R("FL pend:", fl.pend_cred);
1295 R("FL avail:", fl.avail);
1296 R("FL PIDX:", fl.pidx);
1297 R("FL CIDX:", fl.cidx);
1298 } else if (toe_idx < toe_entries) {
1299 const struct sge_ofld_rxq *rx = &adap->sge.ofldrxq[toe_idx * 4];
1300 const struct sge_ofld_txq *tx = &adap->sge.ofldtxq[toe_idx * 4];
1301 int n = min(4, adap->sge.ofldqsets - 4 * toe_idx);
1302
1303 S("QType:", "TOE");
1304 T("TxQ ID:", q.cntxt_id);
1305 T("TxQ size:", q.size);
1306 T("TxQ inuse:", q.in_use);
1307 T("TxQ CIDX:", q.cidx);
1308 T("TxQ PIDX:", q.pidx);
1309 R("RspQ ID:", rspq.abs_id);
1310 R("RspQ size:", rspq.size);
1311 R("RspQE size:", rspq.iqe_len);
1312 R("RspQ CIDX:", rspq.cidx);
1313 R("RspQ Gen:", rspq.gen);
1314 S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
1315 S3("u", "Intr pktcnt:",
1316 adap->sge.counter_val[rx[i].rspq.pktcnt_idx]);
1317 R("FL ID:", fl.cntxt_id);
1318 R("FL size:", fl.size - 8);
1319 R("FL pend:", fl.pend_cred);
1320 R("FL avail:", fl.avail);
1321 R("FL PIDX:", fl.pidx);
1322 R("FL CIDX:", fl.cidx);
1323 } else if (rdma_idx < rdma_entries) {
1324 const struct sge_ofld_rxq *rx =
1325 &adap->sge.rdmarxq[rdma_idx * 4];
1326 int n = min(4, adap->sge.rdmaqs - 4 * rdma_idx);
1327
1328 S("QType:", "RDMA-CPL");
1329 R("RspQ ID:", rspq.abs_id);
1330 R("RspQ size:", rspq.size);
1331 R("RspQE size:", rspq.iqe_len);
1332 R("RspQ CIDX:", rspq.cidx);
1333 R("RspQ Gen:", rspq.gen);
1334 S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
1335 S3("u", "Intr pktcnt:",
1336 adap->sge.counter_val[rx[i].rspq.pktcnt_idx]);
1337 R("FL ID:", fl.cntxt_id);
1338 R("FL size:", fl.size - 8);
1339 R("FL pend:", fl.pend_cred);
1340 R("FL avail:", fl.avail);
1341 R("FL PIDX:", fl.pidx);
1342 R("FL CIDX:", fl.cidx);
1343 } else if (ciq_idx < ciq_entries) {
1344 const struct sge_ofld_rxq *rx = &adap->sge.rdmaciq[ciq_idx * 4];
1345 int n = min(4, adap->sge.rdmaciqs - 4 * ciq_idx);
1346
1347 S("QType:", "RDMA-CIQ");
1348 R("RspQ ID:", rspq.abs_id);
1349 R("RspQ size:", rspq.size);
1350 R("RspQE size:", rspq.iqe_len);
1351 R("RspQ CIDX:", rspq.cidx);
1352 R("RspQ Gen:", rspq.gen);
1353 S3("u", "Intr delay:", qtimer_val(adap, &rx[i].rspq));
1354 S3("u", "Intr pktcnt:",
1355 adap->sge.counter_val[rx[i].rspq.pktcnt_idx]);
1356 } else if (ctrl_idx < ctrl_entries) {
1357 const struct sge_ctrl_txq *tx = &adap->sge.ctrlq[ctrl_idx * 4];
1358 int n = min(4, adap->params.nports - 4 * ctrl_idx);
1359
1360 S("QType:", "Control");
1361 T("TxQ ID:", q.cntxt_id);
1362 T("TxQ size:", q.size);
1363 T("TxQ inuse:", q.in_use);
1364 T("TxQ CIDX:", q.cidx);
1365 T("TxQ PIDX:", q.pidx);
1366 } else if (fq_idx == 0) {
1367 const struct sge_rspq *evtq = &adap->sge.fw_evtq;
1368
1369 seq_printf(seq, "%-12s %16s\n", "QType:", "FW event queue");
1370 seq_printf(seq, "%-12s %16u\n", "RspQ ID:", evtq->abs_id);
1371 seq_printf(seq, "%-12s %16u\n", "RspQ size:", evtq->size);
1372 seq_printf(seq, "%-12s %16u\n", "RspQE size:", evtq->iqe_len);
1373 seq_printf(seq, "%-12s %16u\n", "RspQ CIDX:", evtq->cidx);
1374 seq_printf(seq, "%-12s %16u\n", "RspQ Gen:", evtq->gen);
1375 seq_printf(seq, "%-12s %16u\n", "Intr delay:",
1376 qtimer_val(adap, evtq));
1377 seq_printf(seq, "%-12s %16u\n", "Intr pktcnt:",
1378 adap->sge.counter_val[evtq->pktcnt_idx]);
1379 }
1380#undef R
1381#undef T
1382#undef S
1383#undef S3
1384return 0;
1385}
1386
1387static int sge_queue_entries(const struct adapter *adap)
1388{
1389 return DIV_ROUND_UP(adap->sge.ethqsets, 4) +
1390 DIV_ROUND_UP(adap->sge.ofldqsets, 4) +
1391 DIV_ROUND_UP(adap->sge.rdmaqs, 4) +
1392 DIV_ROUND_UP(adap->sge.rdmaciqs, 4) +
1393 DIV_ROUND_UP(MAX_CTRL_QUEUES, 4) + 1;
1394}
1395
1396static void *sge_queue_start(struct seq_file *seq, loff_t *pos)
1397{
1398 int entries = sge_queue_entries(seq->private);
1399
1400 return *pos < entries ? (void *)((uintptr_t)*pos + 1) : NULL;
1401}
1402
1403static void sge_queue_stop(struct seq_file *seq, void *v)
1404{
1405}
1406
1407static void *sge_queue_next(struct seq_file *seq, void *v, loff_t *pos)
1408{
1409 int entries = sge_queue_entries(seq->private);
1410
1411 ++*pos;
1412 return *pos < entries ? (void *)((uintptr_t)*pos + 1) : NULL;
1413}
1414
1415static const struct seq_operations sge_qinfo_seq_ops = {
1416 .start = sge_queue_start,
1417 .next = sge_queue_next,
1418 .stop = sge_queue_stop,
1419 .show = sge_qinfo_show
1420};
1421
1422static int sge_qinfo_open(struct inode *inode, struct file *file)
1423{
1424 int res = seq_open(file, &sge_qinfo_seq_ops);
1425
1426 if (!res) {
1427 struct seq_file *seq = file->private_data;
1428
1429 seq->private = inode->i_private;
1430 }
1431 return res;
1432}
1433
1434static const struct file_operations sge_qinfo_debugfs_fops = {
1435 .owner = THIS_MODULE,
1436 .open = sge_qinfo_open,
1437 .read = seq_read,
1438 .llseek = seq_lseek,
1439 .release = seq_release,
1440};
1441
1029int mem_open(struct inode *inode, struct file *file) 1442int mem_open(struct inode *inode, struct file *file)
1030{ 1443{
1031 unsigned int mem; 1444 unsigned int mem;
@@ -1127,6 +1540,7 @@ int t4_setup_debugfs(struct adapter *adap)
1127 static struct t4_debugfs_entry t4_debugfs_files[] = { 1540 static struct t4_debugfs_entry t4_debugfs_files[] = {
1128 { "cim_la", &cim_la_fops, S_IRUSR, 0 }, 1541 { "cim_la", &cim_la_fops, S_IRUSR, 0 },
1129 { "cim_qcfg", &cim_qcfg_fops, S_IRUSR, 0 }, 1542 { "cim_qcfg", &cim_qcfg_fops, S_IRUSR, 0 },
1543 { "clk", &clk_debugfs_fops, S_IRUSR, 0 },
1130 { "devlog", &devlog_fops, S_IRUSR, 0 }, 1544 { "devlog", &devlog_fops, S_IRUSR, 0 },
1131 { "l2t", &t4_l2t_fops, S_IRUSR, 0}, 1545 { "l2t", &t4_l2t_fops, S_IRUSR, 0},
1132 { "mps_tcam", &mps_tcam_debugfs_fops, S_IRUSR, 0 }, 1546 { "mps_tcam", &mps_tcam_debugfs_fops, S_IRUSR, 0 },
@@ -1135,14 +1549,39 @@ int t4_setup_debugfs(struct adapter *adap)
1135 { "rss_key", &rss_key_debugfs_fops, S_IRUSR, 0 }, 1549 { "rss_key", &rss_key_debugfs_fops, S_IRUSR, 0 },
1136 { "rss_pf_config", &rss_pf_config_debugfs_fops, S_IRUSR, 0 }, 1550 { "rss_pf_config", &rss_pf_config_debugfs_fops, S_IRUSR, 0 },
1137 { "rss_vf_config", &rss_vf_config_debugfs_fops, S_IRUSR, 0 }, 1551 { "rss_vf_config", &rss_vf_config_debugfs_fops, S_IRUSR, 0 },
1552 { "sge_qinfo", &sge_qinfo_debugfs_fops, S_IRUSR, 0 },
1553 { "ibq_tp0", &cim_ibq_fops, S_IRUSR, 0 },
1554 { "ibq_tp1", &cim_ibq_fops, S_IRUSR, 1 },
1555 { "ibq_ulp", &cim_ibq_fops, S_IRUSR, 2 },
1556 { "ibq_sge0", &cim_ibq_fops, S_IRUSR, 3 },
1557 { "ibq_sge1", &cim_ibq_fops, S_IRUSR, 4 },
1558 { "ibq_ncsi", &cim_ibq_fops, S_IRUSR, 5 },
1559 { "obq_ulp0", &cim_obq_fops, S_IRUSR, 0 },
1560 { "obq_ulp1", &cim_obq_fops, S_IRUSR, 1 },
1561 { "obq_ulp2", &cim_obq_fops, S_IRUSR, 2 },
1562 { "obq_ulp3", &cim_obq_fops, S_IRUSR, 3 },
1563 { "obq_sge", &cim_obq_fops, S_IRUSR, 4 },
1564 { "obq_ncsi", &cim_obq_fops, S_IRUSR, 5 },
1565 { "pm_stats", &pm_stats_debugfs_fops, S_IRUSR, 0 },
1138#if IS_ENABLED(CONFIG_IPV6) 1566#if IS_ENABLED(CONFIG_IPV6)
1139 { "clip_tbl", &clip_tbl_debugfs_fops, S_IRUSR, 0 }, 1567 { "clip_tbl", &clip_tbl_debugfs_fops, S_IRUSR, 0 },
1140#endif 1568#endif
1141 }; 1569 };
1142 1570
1571 /* Debug FS nodes common to all T5 and later adapters.
1572 */
1573 static struct t4_debugfs_entry t5_debugfs_files[] = {
1574 { "obq_sge_rx_q0", &cim_obq_fops, S_IRUSR, 6 },
1575 { "obq_sge_rx_q1", &cim_obq_fops, S_IRUSR, 7 },
1576 };
1577
1143 add_debugfs_files(adap, 1578 add_debugfs_files(adap,
1144 t4_debugfs_files, 1579 t4_debugfs_files,
1145 ARRAY_SIZE(t4_debugfs_files)); 1580 ARRAY_SIZE(t4_debugfs_files));
1581 if (!is_t4(adap->params.chip))
1582 add_debugfs_files(adap,
1583 t5_debugfs_files,
1584 ARRAY_SIZE(t5_debugfs_files));
1146 1585
1147 i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A); 1586 i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A);
1148 if (i & EDRAM0_ENABLE_F) { 1587 if (i & EDRAM0_ENABLE_F) {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 12c1a3fbf296..c27dcd98ea33 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2500,8 +2500,8 @@ static int closest_thres(const struct sge *s, int thres)
2500/* 2500/*
2501 * Return a queue's interrupt hold-off time in us. 0 means no timer. 2501 * Return a queue's interrupt hold-off time in us. 0 means no timer.
2502 */ 2502 */
2503static unsigned int qtimer_val(const struct adapter *adap, 2503unsigned int qtimer_val(const struct adapter *adap,
2504 const struct sge_rspq *q) 2504 const struct sge_rspq *q)
2505{ 2505{
2506 unsigned int idx = q->intr_params >> 1; 2506 unsigned int idx = q->intr_params >> 1;
2507 2507
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 8f99878a4913..ea16c623e8b2 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -2512,6 +2512,60 @@ void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
2512} 2512}
2513 2513
2514/** 2514/**
2515 * t4_pmtx_get_stats - returns the HW stats from PMTX
2516 * @adap: the adapter
2517 * @cnt: where to store the count statistics
2518 * @cycles: where to store the cycle statistics
2519 *
2520 * Returns performance statistics from PMTX.
2521 */
2522void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
2523{
2524 int i;
2525 u32 data[2];
2526
2527 for (i = 0; i < PM_NSTATS; i++) {
2528 t4_write_reg(adap, PM_TX_STAT_CONFIG_A, i + 1);
2529 cnt[i] = t4_read_reg(adap, PM_TX_STAT_COUNT_A);
2530 if (is_t4(adap->params.chip)) {
2531 cycles[i] = t4_read_reg64(adap, PM_TX_STAT_LSB_A);
2532 } else {
2533 t4_read_indirect(adap, PM_TX_DBG_CTRL_A,
2534 PM_TX_DBG_DATA_A, data, 2,
2535 PM_TX_DBG_STAT_MSB_A);
2536 cycles[i] = (((u64)data[0] << 32) | data[1]);
2537 }
2538 }
2539}
2540
2541/**
2542 * t4_pmrx_get_stats - returns the HW stats from PMRX
2543 * @adap: the adapter
2544 * @cnt: where to store the count statistics
2545 * @cycles: where to store the cycle statistics
2546 *
2547 * Returns performance statistics from PMRX.
2548 */
2549void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
2550{
2551 int i;
2552 u32 data[2];
2553
2554 for (i = 0; i < PM_NSTATS; i++) {
2555 t4_write_reg(adap, PM_RX_STAT_CONFIG_A, i + 1);
2556 cnt[i] = t4_read_reg(adap, PM_RX_STAT_COUNT_A);
2557 if (is_t4(adap->params.chip)) {
2558 cycles[i] = t4_read_reg64(adap, PM_RX_STAT_LSB_A);
2559 } else {
2560 t4_read_indirect(adap, PM_RX_DBG_CTRL_A,
2561 PM_RX_DBG_DATA_A, data, 2,
2562 PM_RX_DBG_STAT_MSB_A);
2563 cycles[i] = (((u64)data[0] << 32) | data[1]);
2564 }
2565 }
2566}
2567
2568/**
2515 * get_mps_bg_map - return the buffer groups associated with a port 2569 * get_mps_bg_map - return the buffer groups associated with a port
2516 * @adap: the adapter 2570 * @adap: the adapter
2517 * @idx: the port index 2571 * @idx: the port index
@@ -4526,6 +4580,91 @@ void t4_read_cimq_cfg(struct adapter *adap, u16 *base, u16 *size, u16 *thres)
4526} 4580}
4527 4581
4528/** 4582/**
4583 * t4_read_cim_ibq - read the contents of a CIM inbound queue
4584 * @adap: the adapter
4585 * @qid: the queue index
4586 * @data: where to store the queue contents
4587 * @n: capacity of @data in 32-bit words
4588 *
4589 * Reads the contents of the selected CIM queue starting at address 0 up
4590 * to the capacity of @data. @n must be a multiple of 4. Returns < 0 on
4591 * error and the number of 32-bit words actually read on success.
4592 */
4593int t4_read_cim_ibq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
4594{
4595 int i, err, attempts;
4596 unsigned int addr;
4597 const unsigned int nwords = CIM_IBQ_SIZE * 4;
4598
4599 if (qid > 5 || (n & 3))
4600 return -EINVAL;
4601
4602 addr = qid * nwords;
4603 if (n > nwords)
4604 n = nwords;
4605
4606 /* It might take 3-10ms before the IBQ debug read access is allowed.
4607 * Wait for 1 Sec with a delay of 1 usec.
4608 */
4609 attempts = 1000000;
4610
4611 for (i = 0; i < n; i++, addr++) {
4612 t4_write_reg(adap, CIM_IBQ_DBG_CFG_A, IBQDBGADDR_V(addr) |
4613 IBQDBGEN_F);
4614 err = t4_wait_op_done(adap, CIM_IBQ_DBG_CFG_A, IBQDBGBUSY_F, 0,
4615 attempts, 1);
4616 if (err)
4617 return err;
4618 *data++ = t4_read_reg(adap, CIM_IBQ_DBG_DATA_A);
4619 }
4620 t4_write_reg(adap, CIM_IBQ_DBG_CFG_A, 0);
4621 return i;
4622}
4623
4624/**
4625 * t4_read_cim_obq - read the contents of a CIM outbound queue
4626 * @adap: the adapter
4627 * @qid: the queue index
4628 * @data: where to store the queue contents
4629 * @n: capacity of @data in 32-bit words
4630 *
4631 * Reads the contents of the selected CIM queue starting at address 0 up
4632 * to the capacity of @data. @n must be a multiple of 4. Returns < 0 on
4633 * error and the number of 32-bit words actually read on success.
4634 */
4635int t4_read_cim_obq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
4636{
4637 int i, err;
4638 unsigned int addr, v, nwords;
4639 int cim_num_obq = is_t4(adap->params.chip) ?
4640 CIM_NUM_OBQ : CIM_NUM_OBQ_T5;
4641
4642 if ((qid > (cim_num_obq - 1)) || (n & 3))
4643 return -EINVAL;
4644
4645 t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |
4646 QUENUMSELECT_V(qid));
4647 v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
4648
4649 addr = CIMQBASE_G(v) * 64; /* muliple of 256 -> muliple of 4 */
4650 nwords = CIMQSIZE_G(v) * 64; /* same */
4651 if (n > nwords)
4652 n = nwords;
4653
4654 for (i = 0; i < n; i++, addr++) {
4655 t4_write_reg(adap, CIM_OBQ_DBG_CFG_A, OBQDBGADDR_V(addr) |
4656 OBQDBGEN_F);
4657 err = t4_wait_op_done(adap, CIM_OBQ_DBG_CFG_A, OBQDBGBUSY_F, 0,
4658 2, 1);
4659 if (err)
4660 return err;
4661 *data++ = t4_read_reg(adap, CIM_OBQ_DBG_DATA_A);
4662 }
4663 t4_write_reg(adap, CIM_OBQ_DBG_CFG_A, 0);
4664 return i;
4665}
4666
4667/**
4529 * t4_cim_read - read a block from CIM internal address space 4668 * t4_cim_read - read a block from CIM internal address space
4530 * @adap: the adapter 4669 * @adap: the adapter
4531 * @addr: the start address within the CIM address space 4670 * @addr: the start address within the CIM address space
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
index f6b82da350e2..664375f290ee 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
@@ -48,6 +48,7 @@ enum {
48 NMTUS = 16, /* size of MTU table */ 48 NMTUS = 16, /* size of MTU table */
49 NCCTRL_WIN = 32, /* # of congestion control windows */ 49 NCCTRL_WIN = 32, /* # of congestion control windows */
50 L2T_SIZE = 4096, /* # of L2T entries */ 50 L2T_SIZE = 4096, /* # of L2T entries */
51 PM_NSTATS = 5, /* # of PM stats */
51 MBOX_LEN = 64, /* mailbox size in bytes */ 52 MBOX_LEN = 64, /* mailbox size in bytes */
52 TRACE_LEN = 112, /* length of trace data and mask */ 53 TRACE_LEN = 112, /* length of trace data and mask */
53 FILTER_OPT_LEN = 36, /* filter tuple width for optional components */ 54 FILTER_OPT_LEN = 36, /* filter tuple width for optional components */
@@ -60,6 +61,8 @@ enum {
60 CIM_NUM_OBQ = 6, /* # of CIM OBQs */ 61 CIM_NUM_OBQ = 6, /* # of CIM OBQs */
61 CIM_NUM_OBQ_T5 = 8, /* # of CIM OBQs for T5 adapter */ 62 CIM_NUM_OBQ_T5 = 8, /* # of CIM OBQs for T5 adapter */
62 CIMLA_SIZE = 2048, /* # of 32-bit words in CIM LA */ 63 CIMLA_SIZE = 2048, /* # of 32-bit words in CIM LA */
64 CIM_IBQ_SIZE = 128, /* # of 128-bit words in a CIM IBQ */
65 CIM_OBQ_SIZE = 128, /* # of 128-bit words in a CIM OBQ */
63}; 66};
64 67
65enum { 68enum {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index e036b563bf3c..940b56cd5caa 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -1203,12 +1203,35 @@
1203#define TIMERRESOLUTION_M 0xffU 1203#define TIMERRESOLUTION_M 0xffU
1204#define TIMERRESOLUTION_G(x) (((x) >> TIMERRESOLUTION_S) & TIMERRESOLUTION_M) 1204#define TIMERRESOLUTION_G(x) (((x) >> TIMERRESOLUTION_S) & TIMERRESOLUTION_M)
1205 1205
1206#define TIMESTAMPRESOLUTION_S 8
1207#define TIMESTAMPRESOLUTION_M 0xffU
1208#define TIMESTAMPRESOLUTION_G(x) \
1209 (((x) >> TIMESTAMPRESOLUTION_S) & TIMESTAMPRESOLUTION_M)
1210
1206#define DELAYEDACKRESOLUTION_S 0 1211#define DELAYEDACKRESOLUTION_S 0
1207#define DELAYEDACKRESOLUTION_M 0xffU 1212#define DELAYEDACKRESOLUTION_M 0xffU
1208#define DELAYEDACKRESOLUTION_G(x) \ 1213#define DELAYEDACKRESOLUTION_G(x) \
1209 (((x) >> DELAYEDACKRESOLUTION_S) & DELAYEDACKRESOLUTION_M) 1214 (((x) >> DELAYEDACKRESOLUTION_S) & DELAYEDACKRESOLUTION_M)
1210 1215
1211#define TP_SHIFT_CNT_A 0x7dc0 1216#define TP_SHIFT_CNT_A 0x7dc0
1217#define TP_RXT_MIN_A 0x7d98
1218#define TP_RXT_MAX_A 0x7d9c
1219#define TP_PERS_MIN_A 0x7da0
1220#define TP_PERS_MAX_A 0x7da4
1221#define TP_KEEP_IDLE_A 0x7da8
1222#define TP_KEEP_INTVL_A 0x7dac
1223#define TP_INIT_SRTT_A 0x7db0
1224#define TP_DACK_TIMER_A 0x7db4
1225#define TP_FINWAIT2_TIMER_A 0x7db8
1226
1227#define INITSRTT_S 0
1228#define INITSRTT_M 0xffffU
1229#define INITSRTT_G(x) (((x) >> INITSRTT_S) & INITSRTT_M)
1230
1231#define PERSMAX_S 0
1232#define PERSMAX_M 0x3fffffffU
1233#define PERSMAX_V(x) ((x) << PERSMAX_S)
1234#define PERSMAX_G(x) (((x) >> PERSMAX_S) & PERSMAX_M)
1212 1235
1213#define SYNSHIFTMAX_S 24 1236#define SYNSHIFTMAX_S 24
1214#define SYNSHIFTMAX_M 0xffU 1237#define SYNSHIFTMAX_M 0xffU
@@ -1380,6 +1403,12 @@
1380#define PBL_BOUND_ERR_CH0_F PBL_BOUND_ERR_CH0_V(1U) 1403#define PBL_BOUND_ERR_CH0_F PBL_BOUND_ERR_CH0_V(1U)
1381 1404
1382#define PM_RX_INT_CAUSE_A 0x8fdc 1405#define PM_RX_INT_CAUSE_A 0x8fdc
1406#define PM_RX_STAT_CONFIG_A 0x8fc8
1407#define PM_RX_STAT_COUNT_A 0x8fcc
1408#define PM_RX_STAT_LSB_A 0x8fd0
1409#define PM_RX_DBG_CTRL_A 0x8fd0
1410#define PM_RX_DBG_DATA_A 0x8fd4
1411#define PM_RX_DBG_STAT_MSB_A 0x10013
1383 1412
1384#define PMRX_FRAMING_ERROR_F 0x003ffff0U 1413#define PMRX_FRAMING_ERROR_F 0x003ffff0U
1385 1414
@@ -1404,6 +1433,12 @@
1404#define PMRX_E_PCMD_PAR_ERROR_F PMRX_E_PCMD_PAR_ERROR_V(1U) 1433#define PMRX_E_PCMD_PAR_ERROR_F PMRX_E_PCMD_PAR_ERROR_V(1U)
1405 1434
1406#define PM_TX_INT_CAUSE_A 0x8ffc 1435#define PM_TX_INT_CAUSE_A 0x8ffc
1436#define PM_TX_STAT_CONFIG_A 0x8fe8
1437#define PM_TX_STAT_COUNT_A 0x8fec
1438#define PM_TX_STAT_LSB_A 0x8ff0
1439#define PM_TX_DBG_CTRL_A 0x8ff0
1440#define PM_TX_DBG_DATA_A 0x8ff4
1441#define PM_TX_DBG_STAT_MSB_A 0x1001a
1407 1442
1408#define PCMD_LEN_OVFL0_S 31 1443#define PCMD_LEN_OVFL0_S 31
1409#define PCMD_LEN_OVFL0_V(x) ((x) << PCMD_LEN_OVFL0_S) 1444#define PCMD_LEN_OVFL0_V(x) ((x) << PCMD_LEN_OVFL0_S)
@@ -2538,6 +2573,39 @@
2538#define HOSTWRITE_V(x) ((x) << HOSTWRITE_S) 2573#define HOSTWRITE_V(x) ((x) << HOSTWRITE_S)
2539#define HOSTWRITE_F HOSTWRITE_V(1U) 2574#define HOSTWRITE_F HOSTWRITE_V(1U)
2540 2575
2576#define CIM_IBQ_DBG_CFG_A 0x7b60
2577
2578#define IBQDBGADDR_S 16
2579#define IBQDBGADDR_M 0xfffU
2580#define IBQDBGADDR_V(x) ((x) << IBQDBGADDR_S)
2581#define IBQDBGADDR_G(x) (((x) >> IBQDBGADDR_S) & IBQDBGADDR_M)
2582
2583#define IBQDBGBUSY_S 1
2584#define IBQDBGBUSY_V(x) ((x) << IBQDBGBUSY_S)
2585#define IBQDBGBUSY_F IBQDBGBUSY_V(1U)
2586
2587#define IBQDBGEN_S 0
2588#define IBQDBGEN_V(x) ((x) << IBQDBGEN_S)
2589#define IBQDBGEN_F IBQDBGEN_V(1U)
2590
2591#define CIM_OBQ_DBG_CFG_A 0x7b64
2592
2593#define OBQDBGADDR_S 16
2594#define OBQDBGADDR_M 0xfffU
2595#define OBQDBGADDR_V(x) ((x) << OBQDBGADDR_S)
2596#define OBQDBGADDR_G(x) (((x) >> OBQDBGADDR_S) & OBQDBGADDR_M)
2597
2598#define OBQDBGBUSY_S 1
2599#define OBQDBGBUSY_V(x) ((x) << OBQDBGBUSY_S)
2600#define OBQDBGBUSY_F OBQDBGBUSY_V(1U)
2601
2602#define OBQDBGEN_S 0
2603#define OBQDBGEN_V(x) ((x) << OBQDBGEN_S)
2604#define OBQDBGEN_F OBQDBGEN_V(1U)
2605
2606#define CIM_IBQ_DBG_DATA_A 0x7b68
2607#define CIM_OBQ_DBG_DATA_A 0x7b6c
2608
2541#define UPDBGLARDEN_S 1 2609#define UPDBGLARDEN_S 1
2542#define UPDBGLARDEN_V(x) ((x) << UPDBGLARDEN_S) 2610#define UPDBGLARDEN_V(x) ((x) << UPDBGLARDEN_S)
2543#define UPDBGLARDEN_F UPDBGLARDEN_V(1U) 2611#define UPDBGLARDEN_F UPDBGLARDEN_V(1U)