Commit 28a45957 authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller

tg3: Restructure tg3_test_loopback

The tg3_test_loopback() function is starting to get more complicated as
more loopback tests are added.  This patch cleans up the code.
Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Reviewed-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5e5a7f37
...@@ -390,12 +390,13 @@ static const struct { ...@@ -390,12 +390,13 @@ static const struct {
static const struct { static const struct {
const char string[ETH_GSTRING_LEN]; const char string[ETH_GSTRING_LEN];
} ethtool_test_keys[] = { } ethtool_test_keys[] = {
{ "nvram test (online) " }, { "nvram test (online) " },
{ "link test (online) " }, { "link test (online) " },
{ "register test (offline)" }, { "register test (offline)" },
{ "memory test (offline)" }, { "memory test (offline)" },
{ "loopback test (offline)" }, { "mac loopback test (offline)" },
{ "interrupt test (offline)" }, { "phy loopback test (offline)" },
{ "interrupt test (offline)" },
}; };
#define TG3_NUM_TEST ARRAY_SIZE(ethtool_test_keys) #define TG3_NUM_TEST ARRAY_SIZE(ethtool_test_keys)
...@@ -11310,10 +11311,6 @@ static int tg3_test_memory(struct tg3 *tp) ...@@ -11310,10 +11311,6 @@ static int tg3_test_memory(struct tg3 *tp)
return err; return err;
} }
#define TG3_MAC_LOOPBACK 0
#define TG3_PHY_LOOPBACK 1
#define TG3_TSO_LOOPBACK 2
#define TG3_TSO_MSS 500 #define TG3_TSO_MSS 500
#define TG3_TSO_IP_HDR_LEN 20 #define TG3_TSO_IP_HDR_LEN 20
...@@ -11337,7 +11334,7 @@ static const u8 tg3_tso_header[] = { ...@@ -11337,7 +11334,7 @@ static const u8 tg3_tso_header[] = {
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
}; };
static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode) static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback)
{ {
u32 rx_start_idx, rx_idx, tx_idx, opaque_key; u32 rx_start_idx, rx_idx, tx_idx, opaque_key;
u32 base_flags = 0, mss = 0, desc_idx, coal_now, data_off, val; u32 base_flags = 0, mss = 0, desc_idx, coal_now, data_off, val;
...@@ -11373,7 +11370,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode) ...@@ -11373,7 +11370,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)
tw32(MAC_RX_MTU_SIZE, tx_len + ETH_FCS_LEN); tw32(MAC_RX_MTU_SIZE, tx_len + ETH_FCS_LEN);
if (loopback_mode == TG3_TSO_LOOPBACK) { if (tso_loopback) {
struct iphdr *iph = (struct iphdr *)&tx_data[ETH_HLEN]; struct iphdr *iph = (struct iphdr *)&tx_data[ETH_HLEN];
u32 hdr_len = TG3_TSO_IP_HDR_LEN + TG3_TSO_TCP_HDR_LEN + u32 hdr_len = TG3_TSO_IP_HDR_LEN + TG3_TSO_TCP_HDR_LEN +
...@@ -11493,7 +11490,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode) ...@@ -11493,7 +11490,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)
rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT)
- ETH_FCS_LEN; - ETH_FCS_LEN;
if (loopback_mode != TG3_TSO_LOOPBACK) { if (!tso_loopback) {
if (rx_len != tx_len) if (rx_len != tx_len)
goto out; goto out;
...@@ -11540,25 +11537,29 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode) ...@@ -11540,25 +11537,29 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)
#define TG3_STD_LOOPBACK_FAILED 1 #define TG3_STD_LOOPBACK_FAILED 1
#define TG3_JMB_LOOPBACK_FAILED 2 #define TG3_JMB_LOOPBACK_FAILED 2
#define TG3_TSO_LOOPBACK_FAILED 4 #define TG3_TSO_LOOPBACK_FAILED 4
#define TG3_LOOPBACK_FAILED \
(TG3_STD_LOOPBACK_FAILED | \
TG3_JMB_LOOPBACK_FAILED | \
TG3_TSO_LOOPBACK_FAILED)
#define TG3_MAC_LOOPBACK_SHIFT 0 static int tg3_test_loopback(struct tg3 *tp, u64 *data)
#define TG3_PHY_LOOPBACK_SHIFT 4
#define TG3_LOOPBACK_FAILED 0x00000077
static int tg3_test_loopback(struct tg3 *tp)
{ {
int err = 0; int err = -EIO;
u32 eee_cap; u32 eee_cap;
if (!netif_running(tp->dev))
return TG3_LOOPBACK_FAILED;
eee_cap = tp->phy_flags & TG3_PHYFLG_EEE_CAP; eee_cap = tp->phy_flags & TG3_PHYFLG_EEE_CAP;
tp->phy_flags &= ~TG3_PHYFLG_EEE_CAP; tp->phy_flags &= ~TG3_PHYFLG_EEE_CAP;
if (!netif_running(tp->dev)) {
data[0] = TG3_LOOPBACK_FAILED;
data[1] = TG3_LOOPBACK_FAILED;
goto done;
}
err = tg3_reset_hw(tp, 1); err = tg3_reset_hw(tp, 1);
if (err) { if (err) {
err = TG3_LOOPBACK_FAILED; data[0] = TG3_LOOPBACK_FAILED;
data[1] = TG3_LOOPBACK_FAILED;
goto done; goto done;
} }
...@@ -11580,14 +11581,12 @@ static int tg3_test_loopback(struct tg3 *tp) ...@@ -11580,14 +11581,12 @@ static int tg3_test_loopback(struct tg3 *tp)
!tg3_flag(tp, CPMU_PRESENT)) { !tg3_flag(tp, CPMU_PRESENT)) {
tg3_mac_loopback(tp, true); tg3_mac_loopback(tp, true);
if (tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_MAC_LOOPBACK)) if (tg3_run_loopback(tp, ETH_FRAME_LEN, false))
err |= TG3_STD_LOOPBACK_FAILED << data[0] |= TG3_STD_LOOPBACK_FAILED;
TG3_MAC_LOOPBACK_SHIFT;
if (tg3_flag(tp, JUMBO_RING_ENABLE) && if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
tg3_run_loopback(tp, 9000 + ETH_HLEN, TG3_MAC_LOOPBACK)) tg3_run_loopback(tp, 9000 + ETH_HLEN, false))
err |= TG3_JMB_LOOPBACK_FAILED << data[0] |= TG3_JMB_LOOPBACK_FAILED;
TG3_MAC_LOOPBACK_SHIFT;
tg3_mac_loopback(tp, false); tg3_mac_loopback(tp, false);
} }
...@@ -11605,23 +11604,22 @@ static int tg3_test_loopback(struct tg3 *tp) ...@@ -11605,23 +11604,22 @@ static int tg3_test_loopback(struct tg3 *tp)
mdelay(1); mdelay(1);
} }
if (tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_PHY_LOOPBACK)) if (tg3_run_loopback(tp, ETH_FRAME_LEN, false))
err |= TG3_STD_LOOPBACK_FAILED << data[1] |= TG3_STD_LOOPBACK_FAILED;
TG3_PHY_LOOPBACK_SHIFT;
if (tg3_flag(tp, TSO_CAPABLE) && if (tg3_flag(tp, TSO_CAPABLE) &&
tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_TSO_LOOPBACK)) tg3_run_loopback(tp, ETH_FRAME_LEN, true))
err |= TG3_TSO_LOOPBACK_FAILED << data[1] |= TG3_TSO_LOOPBACK_FAILED;
TG3_PHY_LOOPBACK_SHIFT;
if (tg3_flag(tp, JUMBO_RING_ENABLE) && if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
tg3_run_loopback(tp, 9000 + ETH_HLEN, TG3_PHY_LOOPBACK)) tg3_run_loopback(tp, 9000 + ETH_HLEN, false))
err |= TG3_JMB_LOOPBACK_FAILED << data[1] |= TG3_JMB_LOOPBACK_FAILED;
TG3_PHY_LOOPBACK_SHIFT;
/* Re-enable gphy autopowerdown. */ /* Re-enable gphy autopowerdown. */
if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD) if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD)
tg3_phy_toggle_apd(tp, true); tg3_phy_toggle_apd(tp, true);
} }
err = (data[0] | data[1]) ? -EIO : 0;
done: done:
tp->phy_flags |= eee_cap; tp->phy_flags |= eee_cap;
...@@ -11676,18 +11674,20 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, ...@@ -11676,18 +11674,20 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
etest->flags |= ETH_TEST_FL_FAILED; etest->flags |= ETH_TEST_FL_FAILED;
data[2] = 1; data[2] = 1;
} }
if (tg3_test_memory(tp) != 0) { if (tg3_test_memory(tp) != 0) {
etest->flags |= ETH_TEST_FL_FAILED; etest->flags |= ETH_TEST_FL_FAILED;
data[3] = 1; data[3] = 1;
} }
if ((data[4] = tg3_test_loopback(tp)) != 0)
if (tg3_test_loopback(tp, &data[4]))
etest->flags |= ETH_TEST_FL_FAILED; etest->flags |= ETH_TEST_FL_FAILED;
tg3_full_unlock(tp); tg3_full_unlock(tp);
if (tg3_test_interrupt(tp) != 0) { if (tg3_test_interrupt(tp) != 0) {
etest->flags |= ETH_TEST_FL_FAILED; etest->flags |= ETH_TEST_FL_FAILED;
data[5] = 1; data[6] = 1;
} }
tg3_full_lock(tp, 0); tg3_full_lock(tp, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment