aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c96
1 files changed, 94 insertions, 2 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index acfab86431b1..ecc8602c6799 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -296,7 +296,9 @@ static int __stmmac_test_loopback(struct stmmac_priv *priv,
296 tpriv->pt.dev = priv->dev; 296 tpriv->pt.dev = priv->dev;
297 tpriv->pt.af_packet_priv = tpriv; 297 tpriv->pt.af_packet_priv = tpriv;
298 tpriv->packet = attr; 298 tpriv->packet = attr;
299 dev_add_pack(&tpriv->pt); 299
300 if (!attr->dont_wait)
301 dev_add_pack(&tpriv->pt);
300 302
301 skb = stmmac_test_get_udp_skb(priv, attr); 303 skb = stmmac_test_get_udp_skb(priv, attr);
302 if (!skb) { 304 if (!skb) {
@@ -319,7 +321,8 @@ static int __stmmac_test_loopback(struct stmmac_priv *priv,
319 ret = !tpriv->ok; 321 ret = !tpriv->ok;
320 322
321cleanup: 323cleanup:
322 dev_remove_pack(&tpriv->pt); 324 if (!attr->dont_wait)
325 dev_remove_pack(&tpriv->pt);
323 kfree(tpriv); 326 kfree(tpriv);
324 return ret; 327 return ret;
325} 328}
@@ -731,6 +734,9 @@ static int stmmac_test_vlan_validate(struct sk_buff *skb,
731 struct ethhdr *ehdr; 734 struct ethhdr *ehdr;
732 struct udphdr *uhdr; 735 struct udphdr *uhdr;
733 struct iphdr *ihdr; 736 struct iphdr *ihdr;
737 u16 proto;
738
739 proto = tpriv->double_vlan ? ETH_P_8021AD : ETH_P_8021Q;
734 740
735 skb = skb_unshare(skb, GFP_ATOMIC); 741 skb = skb_unshare(skb, GFP_ATOMIC);
736 if (!skb) 742 if (!skb)
@@ -740,6 +746,12 @@ static int stmmac_test_vlan_validate(struct sk_buff *skb,
740 goto out; 746 goto out;
741 if (skb_headlen(skb) < (STMMAC_TEST_PKT_SIZE - ETH_HLEN)) 747 if (skb_headlen(skb) < (STMMAC_TEST_PKT_SIZE - ETH_HLEN))
742 goto out; 748 goto out;
749 if (tpriv->vlan_id) {
750 if (skb->vlan_proto != htons(proto))
751 goto out;
752 if (skb->vlan_tci != tpriv->vlan_id)
753 goto out;
754 }
743 755
744 ehdr = (struct ethhdr *)skb_mac_header(skb); 756 ehdr = (struct ethhdr *)skb_mac_header(skb);
745 if (!ether_addr_equal(ehdr->h_dest, tpriv->packet->dst)) 757 if (!ether_addr_equal(ehdr->h_dest, tpriv->packet->dst))
@@ -1084,6 +1096,78 @@ static int stmmac_test_reg_sar(struct stmmac_priv *priv)
1084 return ret; 1096 return ret;
1085} 1097}
1086 1098
1099static int stmmac_test_vlanoff_common(struct stmmac_priv *priv, bool svlan)
1100{
1101 struct stmmac_packet_attrs attr = { };
1102 struct stmmac_test_priv *tpriv;
1103 struct sk_buff *skb = NULL;
1104 int ret = 0;
1105 u16 proto;
1106
1107 if (!priv->dma_cap.vlins)
1108 return -EOPNOTSUPP;
1109
1110 tpriv = kzalloc(sizeof(*tpriv), GFP_KERNEL);
1111 if (!tpriv)
1112 return -ENOMEM;
1113
1114 proto = svlan ? ETH_P_8021AD : ETH_P_8021Q;
1115
1116 tpriv->ok = false;
1117 tpriv->double_vlan = svlan;
1118 init_completion(&tpriv->comp);
1119
1120 tpriv->pt.type = svlan ? htons(ETH_P_8021Q) : htons(ETH_P_IP);
1121 tpriv->pt.func = stmmac_test_vlan_validate;
1122 tpriv->pt.dev = priv->dev;
1123 tpriv->pt.af_packet_priv = tpriv;
1124 tpriv->packet = &attr;
1125 tpriv->vlan_id = 0x123;
1126 dev_add_pack(&tpriv->pt);
1127
1128 ret = vlan_vid_add(priv->dev, htons(proto), tpriv->vlan_id);
1129 if (ret)
1130 goto cleanup;
1131
1132 attr.dst = priv->dev->dev_addr;
1133
1134 skb = stmmac_test_get_udp_skb(priv, &attr);
1135 if (!skb) {
1136 ret = -ENOMEM;
1137 goto vlan_del;
1138 }
1139
1140 __vlan_hwaccel_put_tag(skb, htons(proto), tpriv->vlan_id);
1141 skb->protocol = htons(proto);
1142
1143 skb_set_queue_mapping(skb, 0);
1144 ret = dev_queue_xmit(skb);
1145 if (ret)
1146 goto vlan_del;
1147
1148 wait_for_completion_timeout(&tpriv->comp, STMMAC_LB_TIMEOUT);
1149 ret = tpriv->ok ? 0 : -ETIMEDOUT;
1150
1151vlan_del:
1152 vlan_vid_del(priv->dev, htons(proto), tpriv->vlan_id);
1153cleanup:
1154 dev_remove_pack(&tpriv->pt);
1155 kfree(tpriv);
1156 return ret;
1157}
1158
1159static int stmmac_test_vlanoff(struct stmmac_priv *priv)
1160{
1161 return stmmac_test_vlanoff_common(priv, false);
1162}
1163
1164static int stmmac_test_svlanoff(struct stmmac_priv *priv)
1165{
1166 if (!priv->dma_cap.dvlan)
1167 return -EOPNOTSUPP;
1168 return stmmac_test_vlanoff_common(priv, true);
1169}
1170
1087#define STMMAC_LOOPBACK_NONE 0 1171#define STMMAC_LOOPBACK_NONE 0
1088#define STMMAC_LOOPBACK_MAC 1 1172#define STMMAC_LOOPBACK_MAC 1
1089#define STMMAC_LOOPBACK_PHY 2 1173#define STMMAC_LOOPBACK_PHY 2
@@ -1161,6 +1245,14 @@ static const struct stmmac_test {
1161 .name = "SA Replacement (reg)", 1245 .name = "SA Replacement (reg)",
1162 .lb = STMMAC_LOOPBACK_PHY, 1246 .lb = STMMAC_LOOPBACK_PHY,
1163 .fn = stmmac_test_reg_sar, 1247 .fn = stmmac_test_reg_sar,
1248 }, {
1249 .name = "VLAN TX Insertion ",
1250 .lb = STMMAC_LOOPBACK_PHY,
1251 .fn = stmmac_test_vlanoff,
1252 }, {
1253 .name = "SVLAN TX Insertion ",
1254 .lb = STMMAC_LOOPBACK_PHY,
1255 .fn = stmmac_test_svlanoff,
1164 }, 1256 },
1165}; 1257};
1166 1258