Mon Aug 24 18:40:57 2015 UTC ()
Fix logic for setting multicast addresses.

Setting CRC values for hashes is broken so all multicast addresses are
accepted for now.


(rjs)
diff -r1.5 -r1.6 src/sys/dev/cadence/if_cemac.c

cvs diff -r1.5 -r1.6 src/sys/dev/cadence/if_cemac.c (expand / switch to unified diff)

--- src/sys/dev/cadence/if_cemac.c 2015/08/24 18:26:51 1.5
+++ src/sys/dev/cadence/if_cemac.c 2015/08/24 18:40:57 1.6
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_cemac.c,v 1.5 2015/08/24 18:26:51 rjs Exp $ */ 1/* $NetBSD: if_cemac.c,v 1.6 2015/08/24 18:40:57 rjs Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2015 Genetec Corporation. All rights reserved. 4 * Copyright (c) 2015 Genetec Corporation. All rights reserved.
5 * Written by Hashimoto Kenichi for Genetec Corporation. 5 * Written by Hashimoto Kenichi for Genetec Corporation.
6 * 6 *
7 * Based on arch/arm/at91/at91emac.c 7 * Based on arch/arm/at91/at91emac.c
8 * 8 *
9 * Copyright (c) 2007 Embedtronics Oy 9 * Copyright (c) 2007 Embedtronics Oy
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Copyright (c) 2004 Jesse Off 12 * Copyright (c) 2004 Jesse Off
13 * All rights reserved. 13 * All rights reserved.
14 * 14 *
@@ -30,27 +30,27 @@ @@ -30,27 +30,27 @@
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37/* 37/*
38 * Cadence EMAC/GEM ethernet controller IP driver 38 * Cadence EMAC/GEM ethernet controller IP driver
39 * used by arm/at91, arm/zynq SoC 39 * used by arm/at91, arm/zynq SoC
40 */ 40 */
41 41
42#include <sys/cdefs.h> 42#include <sys/cdefs.h>
43__KERNEL_RCSID(0, "$NetBSD: if_cemac.c,v 1.5 2015/08/24 18:26:51 rjs Exp $"); 43__KERNEL_RCSID(0, "$NetBSD: if_cemac.c,v 1.6 2015/08/24 18:40:57 rjs Exp $");
44 44
45#include <sys/types.h> 45#include <sys/types.h>
46#include <sys/param.h> 46#include <sys/param.h>
47#include <sys/systm.h> 47#include <sys/systm.h>
48#include <sys/ioctl.h> 48#include <sys/ioctl.h>
49#include <sys/kernel.h> 49#include <sys/kernel.h>
50#include <sys/proc.h> 50#include <sys/proc.h>
51#include <sys/malloc.h> 51#include <sys/malloc.h>
52#include <sys/time.h> 52#include <sys/time.h>
53#include <sys/device.h> 53#include <sys/device.h>
54#include <uvm/uvm_extern.h> 54#include <uvm/uvm_extern.h>
55 55
56#include <sys/bus.h> 56#include <sys/bus.h>
@@ -939,85 +939,89 @@ cemac_setaddr(struct ifnet *ifp) @@ -939,85 +939,89 @@ cemac_setaddr(struct ifnet *ifp)
939 ifp->if_flags &= ~IFF_ALLMULTI; 939 ifp->if_flags &= ~IFF_ALLMULTI;
940 940
941 ETHER_FIRST_MULTI(step, ac, enm); 941 ETHER_FIRST_MULTI(step, ac, enm);
942 while (enm != NULL) { 942 while (enm != NULL) {
943 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 943 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
944 /* 944 /*
945 * We must listen to a range of multicast addresses. 945 * We must listen to a range of multicast addresses.
946 * For now, just accept all multicasts, rather than 946 * For now, just accept all multicasts, rather than
947 * trying to set only those filter bits needed to match 947 * trying to set only those filter bits needed to match
948 * the range. (At this time, the only use of address 948 * the range. (At this time, the only use of address
949 * ranges is for IP multicast routing, for which the 949 * ranges is for IP multicast routing, for which the
950 * range is big enough to require all bits set.) 950 * range is big enough to require all bits set.)
951 */ 951 */
952 cfg |= ETH_CFG_CAF; 952 cfg |= ETH_CFG_MTI;
953 hashes[0] = 0xffffffffUL; 953 hashes[0] = 0xffffffffUL;
954 hashes[1] = 0xffffffffUL; 954 hashes[1] = 0xffffffffUL;
955 ifp->if_flags |= IFF_ALLMULTI; 955 ifp->if_flags |= IFF_ALLMULTI;
956 nma = 0; 956 nma = 0;
957 break; 957 break;
958 } 958 }
959 959
960 if (nma < 3) { 960 if (nma < 3) {
961 /* We can program 3 perfect address filters for mcast */ 961 /* We can program 3 perfect address filters for mcast */
962 memcpy(ias[nma], enm->enm_addrlo, ETHER_ADDR_LEN); 962 memcpy(ias[nma], enm->enm_addrlo, ETHER_ADDR_LEN);
963 } else { 963 } else {
964 /* 964 /*
965 * XXX: Datasheet is not very clear here, I'm not sure 965 * XXX: Datasheet is not very clear here, I'm not sure
966 * if I'm doing this right. --joff 966 * if I'm doing this right. --joff
967 */ 967 */
968 h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN); 968 h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
969 969
970 /* Just want the 6 most-significant bits. */ 970 /* Just want the 6 most-significant bits. */
971 h = h >> 26; 971 h = h >> 26;
972 972#if 0
973 hashes[h / 32] |= (1 << (h % 32)); 973 hashes[h / 32] |= (1 << (h % 32));
 974#else
 975 hashes[0] = 0xffffffffUL;
 976 hashes[1] = 0xffffffffUL;
 977#endif
974 cfg |= ETH_CFG_MTI; 978 cfg |= ETH_CFG_MTI;
975 } 979 }
976 ETHER_NEXT_MULTI(step, enm); 980 ETHER_NEXT_MULTI(step, enm);
977 nma++; 981 nma++;
978 } 982 }
979 983
980 // program... 984 // program...
981 DPRINTFN(1,("%s: en0 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, 985 DPRINTFN(1,("%s: en0 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
982 sc->sc_enaddr[0], sc->sc_enaddr[1], sc->sc_enaddr[2], 986 sc->sc_enaddr[0], sc->sc_enaddr[1], sc->sc_enaddr[2],
983 sc->sc_enaddr[3], sc->sc_enaddr[4], sc->sc_enaddr[5])); 987 sc->sc_enaddr[3], sc->sc_enaddr[4], sc->sc_enaddr[5]));
984 CEMAC_GEM_WRITE(SA1L, (sc->sc_enaddr[3] << 24) 988 CEMAC_GEM_WRITE(SA1L, (sc->sc_enaddr[3] << 24)
985 | (sc->sc_enaddr[2] << 16) | (sc->sc_enaddr[1] << 8) 989 | (sc->sc_enaddr[2] << 16) | (sc->sc_enaddr[1] << 8)
986 | (sc->sc_enaddr[0])); 990 | (sc->sc_enaddr[0]));
987 CEMAC_GEM_WRITE(SA1H, (sc->sc_enaddr[5] << 8) 991 CEMAC_GEM_WRITE(SA1H, (sc->sc_enaddr[5] << 8)
988 | (sc->sc_enaddr[4])); 992 | (sc->sc_enaddr[4]));
989 if (nma > 1) { 993 if (nma > 0) {
990 DPRINTFN(1,("%s: en1 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, 994 DPRINTFN(1,("%s: en1 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
991 ias[0][0], ias[0][1], ias[0][2], 995 ias[0][0], ias[0][1], ias[0][2],
992 ias[0][3], ias[0][4], ias[0][5])); 996 ias[0][3], ias[0][4], ias[0][5]));
993 CEMAC_WRITE(ETH_SA2L, (ias[0][3] << 24) 997 CEMAC_WRITE(ETH_SA2L, (ias[0][3] << 24)
994 | (ias[0][2] << 16) | (ias[0][1] << 8) 998 | (ias[0][2] << 16) | (ias[0][1] << 8)
995 | (ias[0][0])); 999 | (ias[0][0]));
996 CEMAC_WRITE(ETH_SA2H, (ias[0][4] << 8) 1000 CEMAC_WRITE(ETH_SA2H, (ias[0][4] << 8)
997 | (ias[0][5])); 1001 | (ias[0][5]));
998 } 1002 }
999 if (nma > 2) { 1003 if (nma > 1) {
1000 DPRINTFN(1,("%s: en2 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, 1004 DPRINTFN(1,("%s: en2 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
1001 ias[1][0], ias[1][1], ias[1][2], 1005 ias[1][0], ias[1][1], ias[1][2],
1002 ias[1][3], ias[1][4], ias[1][5])); 1006 ias[1][3], ias[1][4], ias[1][5]));
1003 CEMAC_WRITE(ETH_SA3L, (ias[1][3] << 24) 1007 CEMAC_WRITE(ETH_SA3L, (ias[1][3] << 24)
1004 | (ias[1][2] << 16) | (ias[1][1] << 8) 1008 | (ias[1][2] << 16) | (ias[1][1] << 8)
1005 | (ias[1][0])); 1009 | (ias[1][0]));
1006 CEMAC_WRITE(ETH_SA3H, (ias[1][4] << 8) 1010 CEMAC_WRITE(ETH_SA3H, (ias[1][4] << 8)
1007 | (ias[1][5])); 1011 | (ias[1][5]));
1008 } 1012 }
1009 if (nma > 3) { 1013 if (nma > 2) {
1010 DPRINTFN(1,("%s: en3 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, 1014 DPRINTFN(1,("%s: en3 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
1011 ias[2][0], ias[2][1], ias[2][2], 1015 ias[2][0], ias[2][1], ias[2][2],
1012 ias[2][3], ias[2][4], ias[2][5])); 1016 ias[2][3], ias[2][4], ias[2][5]));
1013 CEMAC_WRITE(ETH_SA3L, (ias[2][3] << 24) 1017 CEMAC_WRITE(ETH_SA4L, (ias[2][3] << 24)
1014 | (ias[2][2] << 16) | (ias[2][1] << 8) 1018 | (ias[2][2] << 16) | (ias[2][1] << 8)
1015 | (ias[2][0])); 1019 | (ias[2][0]));
1016 CEMAC_WRITE(ETH_SA3H, (ias[2][4] << 8) 1020 CEMAC_WRITE(ETH_SA4H, (ias[2][4] << 8)
1017 | (ias[2][5])); 1021 | (ias[2][5]));
1018 } 1022 }
1019 CEMAC_GEM_WRITE(HSH, hashes[0]); 1023 CEMAC_GEM_WRITE(HSH, hashes[0]);
1020 CEMAC_GEM_WRITE(HSL, hashes[1]); 1024 CEMAC_GEM_WRITE(HSL, hashes[1]);
1021 CEMAC_WRITE(ETH_CFG, cfg); 1025 CEMAC_WRITE(ETH_CFG, cfg);
1022 CEMAC_WRITE(ETH_CTL, ctl | ETH_CTL_RE); 1026 CEMAC_WRITE(ETH_CTL, ctl | ETH_CTL_RE);
1023} 1027}