aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/benet
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/benet')
-rw-r--r--drivers/net/benet/be.h1
-rw-r--r--drivers/net/benet/be_cmds.c36
-rw-r--r--drivers/net/benet/be_cmds.h17
-rw-r--r--drivers/net/benet/be_ethtool.c77
4 files changed, 108 insertions, 23 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 9e56014d27ed..9fd8e5ecd5d7 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -275,6 +275,7 @@ struct be_adapter {
275 u32 tx_fc; /* Tx flow control */ 275 u32 tx_fc; /* Tx flow control */
276 int link_speed; 276 int link_speed;
277 u8 port_type; 277 u8 port_type;
278 u8 transceiver;
278}; 279};
279 280
280extern const struct ethtool_ops be_ethtool_ops; 281extern const struct ethtool_ops be_ethtool_ops;
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index b748c197408f..7f64d562ccaa 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1479,6 +1479,41 @@ err:
1479 return status; 1479 return status;
1480} 1480}
1481 1481
1482int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
1483 u8 loopback_type, u8 enable)
1484{
1485 struct be_mcc_wrb *wrb;
1486 struct be_cmd_req_set_lmode *req;
1487 int status;
1488
1489 spin_lock_bh(&adapter->mcc_lock);
1490
1491 wrb = wrb_from_mccq(adapter);
1492 if (!wrb) {
1493 status = -EBUSY;
1494 goto err;
1495 }
1496
1497 req = embedded_payload(wrb);
1498
1499 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
1500 OPCODE_LOWLEVEL_SET_LOOPBACK_MODE);
1501
1502 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
1503 OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
1504 sizeof(*req));
1505
1506 req->src_port = port_num;
1507 req->dest_port = port_num;
1508 req->loopback_type = loopback_type;
1509 req->loopback_state = enable;
1510
1511 status = be_mcc_notify_wait(adapter);
1512err:
1513 spin_unlock_bh(&adapter->mcc_lock);
1514 return status;
1515}
1516
1482int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, 1517int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
1483 u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern) 1518 u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern)
1484{ 1519{
@@ -1501,6 +1536,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
1501 1536
1502 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, 1537 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
1503 OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req)); 1538 OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req));
1539 req->hdr.timeout = 4;
1504 1540
1505 req->pattern = cpu_to_le64(pattern); 1541 req->pattern = cpu_to_le64(pattern);
1506 req->src_port = cpu_to_le32(port_num); 1542 req->src_port = cpu_to_le32(port_num);
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 6eed512bb6d4..cb3188f8708d 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -156,6 +156,7 @@ struct be_mcc_mailbox {
156 156
157#define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 157#define OPCODE_LOWLEVEL_HOST_DDR_DMA 17
158#define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 158#define OPCODE_LOWLEVEL_LOOPBACK_TEST 18
159#define OPCODE_LOWLEVEL_SET_LOOPBACK_MODE 19
159 160
160struct be_cmd_req_hdr { 161struct be_cmd_req_hdr {
161 u8 opcode; /* dword 0 */ 162 u8 opcode; /* dword 0 */
@@ -822,6 +823,19 @@ struct be_cmd_resp_loopback_test {
822 u32 ticks_compl; 823 u32 ticks_compl;
823}; 824};
824 825
826struct be_cmd_req_set_lmode {
827 struct be_cmd_req_hdr hdr;
828 u8 src_port;
829 u8 dest_port;
830 u8 loopback_type;
831 u8 loopback_state;
832};
833
834struct be_cmd_resp_set_lmode {
835 struct be_cmd_resp_hdr resp_hdr;
836 u8 rsvd0[4];
837};
838
825/********************** DDR DMA test *********************/ 839/********************** DDR DMA test *********************/
826struct be_cmd_req_ddrdma_test { 840struct be_cmd_req_ddrdma_test {
827 struct be_cmd_req_hdr hdr; 841 struct be_cmd_req_hdr hdr;
@@ -928,3 +942,6 @@ extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
928 u32 byte_cnt, struct be_dma_mem *cmd); 942 u32 byte_cnt, struct be_dma_mem *cmd);
929extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, 943extern int be_cmd_get_seeprom_data(struct be_adapter *adapter,
930 struct be_dma_mem *nonemb_cmd); 944 struct be_dma_mem *nonemb_cmd);
945extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
946 u8 loopback_type, u8 enable);
947
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index c5afc0286d4d..f18c02f3a5e4 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -118,6 +118,7 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = {
118#define BE_MAC_LOOPBACK 0x0 118#define BE_MAC_LOOPBACK 0x0
119#define BE_PHY_LOOPBACK 0x1 119#define BE_PHY_LOOPBACK 0x1
120#define BE_ONE_PORT_EXT_LOOPBACK 0x2 120#define BE_ONE_PORT_EXT_LOOPBACK 0x2
121#define BE_NO_LOOPBACK 0xff
121 122
122static void 123static void
123be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) 124be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
@@ -339,28 +340,50 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
339 340
340 status = be_cmd_read_port_type(adapter, adapter->port_num, 341 status = be_cmd_read_port_type(adapter, adapter->port_num,
341 &connector); 342 &connector);
342 switch (connector) { 343 if (!status) {
343 case 7: 344 switch (connector) {
344 ecmd->port = PORT_FIBRE; 345 case 7:
345 break; 346 ecmd->port = PORT_FIBRE;
346 default: 347 ecmd->transceiver = XCVR_EXTERNAL;
347 ecmd->port = PORT_TP; 348 break;
348 break; 349 case 0:
350 ecmd->port = PORT_TP;
351 ecmd->transceiver = XCVR_EXTERNAL;
352 break;
353 default:
354 ecmd->port = PORT_TP;
355 ecmd->transceiver = XCVR_INTERNAL;
356 break;
357 }
358 } else {
359 ecmd->port = PORT_AUI;
360 ecmd->transceiver = XCVR_INTERNAL;
349 } 361 }
350 362
351 /* Save for future use */ 363 /* Save for future use */
352 adapter->link_speed = ecmd->speed; 364 adapter->link_speed = ecmd->speed;
353 adapter->port_type = ecmd->port; 365 adapter->port_type = ecmd->port;
366 adapter->transceiver = ecmd->transceiver;
354 } else { 367 } else {
355 ecmd->speed = adapter->link_speed; 368 ecmd->speed = adapter->link_speed;
356 ecmd->port = adapter->port_type; 369 ecmd->port = adapter->port_type;
370 ecmd->transceiver = adapter->transceiver;
357 } 371 }
358 372
359 ecmd->duplex = DUPLEX_FULL; 373 ecmd->duplex = DUPLEX_FULL;
360 ecmd->autoneg = AUTONEG_DISABLE; 374 ecmd->autoneg = AUTONEG_DISABLE;
361 ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP);
362 ecmd->phy_address = adapter->port_num; 375 ecmd->phy_address = adapter->port_num;
363 ecmd->transceiver = XCVR_INTERNAL; 376 switch (ecmd->port) {
377 case PORT_FIBRE:
378 ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
379 break;
380 case PORT_TP:
381 ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP);
382 break;
383 case PORT_AUI:
384 ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI);
385 break;
386 }
364 387
365 return 0; 388 return 0;
366} 389}
@@ -489,6 +512,19 @@ err:
489 return ret; 512 return ret;
490} 513}
491 514
515static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type,
516 u64 *status)
517{
518 be_cmd_set_loopback(adapter, adapter->port_num,
519 loopback_type, 1);
520 *status = be_cmd_loopback_test(adapter, adapter->port_num,
521 loopback_type, 1500,
522 2, 0xabc);
523 be_cmd_set_loopback(adapter, adapter->port_num,
524 BE_NO_LOOPBACK, 1);
525 return *status;
526}
527
492static void 528static void
493be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) 529be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
494{ 530{
@@ -497,23 +533,18 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
497 memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); 533 memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
498 534
499 if (test->flags & ETH_TEST_FL_OFFLINE) { 535 if (test->flags & ETH_TEST_FL_OFFLINE) {
500 data[0] = be_cmd_loopback_test(adapter, adapter->port_num, 536 if (be_loopback_test(adapter, BE_MAC_LOOPBACK,
501 BE_MAC_LOOPBACK, 1500, 537 &data[0]) != 0) {
502 2, 0xabc);
503 if (data[0] != 0)
504 test->flags |= ETH_TEST_FL_FAILED; 538 test->flags |= ETH_TEST_FL_FAILED;
505 539 }
506 data[1] = be_cmd_loopback_test(adapter, adapter->port_num, 540 if (be_loopback_test(adapter, BE_PHY_LOOPBACK,
507 BE_PHY_LOOPBACK, 1500, 541 &data[1]) != 0) {
508 2, 0xabc);
509 if (data[1] != 0)
510 test->flags |= ETH_TEST_FL_FAILED; 542 test->flags |= ETH_TEST_FL_FAILED;
511 543 }
512 data[2] = be_cmd_loopback_test(adapter, adapter->port_num, 544 if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK,
513 BE_ONE_PORT_EXT_LOOPBACK, 545 &data[2]) != 0) {
514 1500, 2, 0xabc);
515 if (data[2] != 0)
516 test->flags |= ETH_TEST_FL_FAILED; 546 test->flags |= ETH_TEST_FL_FAILED;
547 }
517 548
518 data[3] = be_test_ddr_dma(adapter); 549 data[3] = be_test_ddr_dma(adapter);
519 if (data[3] != 0) 550 if (data[3] != 0)