diff options
Diffstat (limited to 'drivers/net/benet')
-rw-r--r-- | drivers/net/benet/be.h | 1 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.c | 36 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 17 | ||||
-rw-r--r-- | drivers/net/benet/be_ethtool.c | 77 |
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 | ||
280 | extern const struct ethtool_ops be_ethtool_ops; | 281 | extern 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 | ||
1482 | int 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); | ||
1512 | err: | ||
1513 | spin_unlock_bh(&adapter->mcc_lock); | ||
1514 | return status; | ||
1515 | } | ||
1516 | |||
1482 | int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, | 1517 | int 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 | ||
160 | struct be_cmd_req_hdr { | 161 | struct 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 | ||
826 | struct 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 | |||
834 | struct 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 *********************/ |
826 | struct be_cmd_req_ddrdma_test { | 840 | struct 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); |
929 | extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, | 943 | extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, |
930 | struct be_dma_mem *nonemb_cmd); | 944 | struct be_dma_mem *nonemb_cmd); |
945 | extern 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 | ||
122 | static void | 123 | static void |
123 | be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | 124 | be_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 | ||
515 | static 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 | |||
492 | static void | 528 | static void |
493 | be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) | 529 | be_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) |