| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_scx.c,v 1.16 2020/03/26 08:28:50 nisimura Exp $ */ | | 1 | /* $NetBSD: if_scx.c,v 1.17 2020/03/26 10:38:16 nisimura Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Tohru Nishimura. | | 8 | * by Tohru Nishimura. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -30,44 +30,44 @@ | | | @@ -30,44 +30,44 @@ |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #define NOT_MP_SAFE 0 | | 32 | #define NOT_MP_SAFE 0 |
33 | | | 33 | |
34 | /* | | 34 | /* |
35 | * Socionext SC2A11 SynQuacer NetSec GbE driver | | 35 | * Socionext SC2A11 SynQuacer NetSec GbE driver |
36 | * | | 36 | * |
37 | * (possibly incorrect notes to be removed eventually) | | 37 | * (possibly incorrect notes to be removed eventually) |
38 | * - 32 byte descriptor for 64 bit paddr design. | | 38 | * - 32 byte descriptor for 64 bit paddr design. |
39 | * - multiple rings seems available. There are special descriptor fields | | 39 | * - multiple rings seems available. There are special descriptor fields |
40 | * to designify ring number from which to arrive or to which go. | | 40 | * to designify ring number from which to arrive or to which go. |
41 | * - memory mapped EEPROM to hold MAC address. The rest of the area is | | 41 | * - memory mapped EEPROM to hold MAC address. The rest of the area is |
42 | * occupied by a set of ucode for two DMA engines and one packet engine. | | 42 | * occupied by a set of ucode for two DMA engines and one packet engine. |
43 | * - The size of frame address filter is unknown. Might be 16 or even 128. | | 43 | * - The size of frame address filter is 16 plus 32. |
44 | * - The first slot is my own station address. Always enabled to perform | | 44 | * - The first slot is my own station address. Always enabled to perform |
45 | * to identify oneself. | | 45 | * to identify oneself. |
46 | * - 1~16 are for supplimental MAC addresses. Independently enabled for | | 46 | * - 1~16 are for supplimental MAC addresses. Independently enabled for |
47 | * use. Good to catch multicast. Byte-wise selective match available. | | 47 | * use. Good to catch multicast. Byte-wise selective match available. |
48 | * Use the mask to catch { 0x01, 0x00, 0x00 } and/or { 0x33, 0x33 }. | | 48 | * Use the mask to catch { 0x01, 0x00, 0x00 } and/or { 0x33, 0x33 }. |
49 | * - 16~128 might be exact match without byte-mask. | | 49 | * - 16~32 might be exact match without byte-mask. |
50 | * - The size of multicast hash filter store is unknown. Might be 256 bit. | | 50 | * - The size of multicast hash filter store is 64 bit. |
51 | * - Socionext/Linaro "NetSec" code makes many cut shorts. Some constants | | 51 | * - Socionext/Linaro "NetSec" code makes many cut shorts. Some constants |
52 | * are left unexplained. The values should be handled via external | | 52 | * are left unexplained. The values should be handled via external |
53 | * controls like FDT descriptions. Fortunately, Intel/Altera CycloneV PDFs | | 53 | * controls like FDT descriptions. Fortunately, Intel/Altera CycloneV PDFs |
54 | * describe every detail of "such the instance of" DW EMAC IP and | | 54 | * describe every detail of "such the instance of" DW EMAC IP and |
55 | * most of them are likely applicable to SC2A11 GbE. | | 55 | * most of them are likely applicable to SC2A11 GbE. |
56 | * - DW EMAC implmentation (0x20) is 0x10.0x36 | | 56 | * - DW EMAC implmentation (0x20) is 0x10.0x36 |
57 | */ | | 57 | */ |
58 | | | 58 | |
59 | #include <sys/cdefs.h> | | 59 | #include <sys/cdefs.h> |
60 | __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.16 2020/03/26 08:28:50 nisimura Exp $"); | | 60 | __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.17 2020/03/26 10:38:16 nisimura Exp $"); |
61 | | | 61 | |
62 | #include <sys/param.h> | | 62 | #include <sys/param.h> |
63 | #include <sys/bus.h> | | 63 | #include <sys/bus.h> |
64 | #include <sys/intr.h> | | 64 | #include <sys/intr.h> |
65 | #include <sys/device.h> | | 65 | #include <sys/device.h> |
66 | #include <sys/callout.h> | | 66 | #include <sys/callout.h> |
67 | #include <sys/mbuf.h> | | 67 | #include <sys/mbuf.h> |
68 | #include <sys/malloc.h> | | 68 | #include <sys/malloc.h> |
69 | #include <sys/errno.h> | | 69 | #include <sys/errno.h> |
70 | #include <sys/rndsource.h> | | 70 | #include <sys/rndsource.h> |
71 | #include <sys/kernel.h> | | 71 | #include <sys/kernel.h> |
72 | #include <sys/systm.h> | | 72 | #include <sys/systm.h> |
73 | | | 73 | |
| @@ -76,26 +76,28 @@ __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1 | | | @@ -76,26 +76,28 @@ __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1 |
76 | #include <net/if_dl.h> | | 76 | #include <net/if_dl.h> |
77 | #include <net/if_ether.h> | | 77 | #include <net/if_ether.h> |
78 | #include <dev/mii/mii.h> | | 78 | #include <dev/mii/mii.h> |
79 | #include <dev/mii/miivar.h> | | 79 | #include <dev/mii/miivar.h> |
80 | #include <net/bpf.h> | | 80 | #include <net/bpf.h> |
81 | | | 81 | |
82 | #include <dev/fdt/fdtvar.h> | | 82 | #include <dev/fdt/fdtvar.h> |
83 | #include <dev/acpi/acpireg.h> | | 83 | #include <dev/acpi/acpireg.h> |
84 | #include <dev/acpi/acpivar.h> | | 84 | #include <dev/acpi/acpivar.h> |
85 | #include <dev/acpi/acpi_intr.h> | | 85 | #include <dev/acpi/acpi_intr.h> |
86 | | | 86 | |
87 | /* SC2A11 register block */ | | 87 | /* SC2A11 register block */ |
88 | #define SWRESET 0x104 | | 88 | #define SWRESET 0x104 |
| | | 89 | #define MACADRH 0x10c |
| | | 90 | #define MACADRL 0x110 |
89 | #define COMINIT 0x120 | | 91 | #define COMINIT 0x120 |
90 | #define INTRST 0x200 | | 92 | #define INTRST 0x200 |
91 | #define IRQ_RX (1U<<1) | | 93 | #define IRQ_RX (1U<<1) |
92 | #define IRQ_TX (1U<<0) | | 94 | #define IRQ_TX (1U<<0) |
93 | #define INTREN 0x204 | | 95 | #define INTREN 0x204 |
94 | #define INTR_SET 0x234 | | 96 | #define INTR_SET 0x234 |
95 | #define INTR_CLR 0x238 | | 97 | #define INTR_CLR 0x238 |
96 | #define TXINTST 0x400 | | 98 | #define TXINTST 0x400 |
97 | #define TXINTEN 0x404 | | 99 | #define TXINTEN 0x404 |
98 | #define TXINT_SET 0x428 | | 100 | #define TXINT_SET 0x428 |
99 | #define TXINT_CLR 0x42c | | 101 | #define TXINT_CLR 0x42c |
100 | #define TXI_NTOWNR (1U<<17) | | 102 | #define TXI_NTOWNR (1U<<17) |
101 | #define TXI_TR_ERR (1U<<16) | | 103 | #define TXI_TR_ERR (1U<<16) |
| @@ -105,28 +107,28 @@ __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1 | | | @@ -105,28 +107,28 @@ __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1 |
105 | #define RXINTEN 0x444 | | 107 | #define RXINTEN 0x444 |
106 | #define RXINT_SET 0x468 | | 108 | #define RXINT_SET 0x468 |
107 | #define RXINT_CLR 0x46c | | 109 | #define RXINT_CLR 0x46c |
108 | #define RXI_RC_ERR (1U<<16) | | 110 | #define RXI_RC_ERR (1U<<16) |
109 | #define RXI_PKTCNT (1U<<15) | | 111 | #define RXI_PKTCNT (1U<<15) |
110 | #define RXI_TMREXP (1U<<14) | | 112 | #define RXI_TMREXP (1U<<14) |
111 | #define TXTIMER 0x41c | | 113 | #define TXTIMER 0x41c |
112 | #define RXTIMER 0x45c | | 114 | #define RXTIMER 0x45c |
113 | #define TXCOUNT 0x410 | | 115 | #define TXCOUNT 0x410 |
114 | #define RXCOUNT 0x454 | | 116 | #define RXCOUNT 0x454 |
115 | #define H2MENG 0x210 /* DMAC host2media ucode port */ | | 117 | #define H2MENG 0x210 /* DMAC host2media ucode port */ |
116 | #define M2HENG 0x21c /* DMAC media2host ucode port */ | | 118 | #define M2HENG 0x21c /* DMAC media2host ucode port */ |
117 | #define PKTENG 0x0d0 /* packet engine ucode port */ | | 119 | #define PKTENG 0x0d0 /* packet engine ucode port */ |
118 | #define HWVER0 0x22c | | 120 | #define MCVER 0x22c /* micro controller version */ |
119 | #define HWVER1 0x230 | | 121 | #define HWVER 0x230 /* hardware version */ |
120 | | | 122 | |
121 | #define MACSTAT 0x1024 /* gmac status */ | | 123 | #define MACSTAT 0x1024 /* gmac status */ |
122 | #define MACDATA 0x11c0 /* gmac rd/wr data */ | | 124 | #define MACDATA 0x11c0 /* gmac rd/wr data */ |
123 | #define MACCMD 0x11c4 /* gmac operation */ | | 125 | #define MACCMD 0x11c4 /* gmac operation */ |
124 | #define CMD_IOWR (1U<<28) /* write op */ | | 126 | #define CMD_IOWR (1U<<28) /* write op */ |
125 | #define CMD_BUSY (1U<<31) /* busy bit */ | | 127 | #define CMD_BUSY (1U<<31) /* busy bit */ |
126 | #define DESCENG_INIT 0x11fc | | 128 | #define DESCENG_INIT 0x11fc |
127 | #define DESCENG_SRST 0x1204 | | 129 | #define DESCENG_SRST 0x1204 |
128 | | | 130 | |
129 | /* GMAC register block. use mac_write()/mac_read() to handle */ | | 131 | /* GMAC register block. use mac_write()/mac_read() to handle */ |
130 | #define GMACMCR 0x0000 /* MAC configuration */ | | 132 | #define GMACMCR 0x0000 /* MAC configuration */ |
131 | #define MCR_IBN (1U<<30) /* */ | | 133 | #define MCR_IBN (1U<<30) /* */ |
132 | #define MCR_CST (1U<<25) /* strip CRC */ | | 134 | #define MCR_CST (1U<<25) /* strip CRC */ |
| @@ -144,59 +146,59 @@ __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1 | | | @@ -144,59 +146,59 @@ __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1 |
144 | #define GMACAFR 0x0004 /* frame DA/SA address filter */ | | 146 | #define GMACAFR 0x0004 /* frame DA/SA address filter */ |
145 | #define AFR_RA (1U<<31) /* receive block all on */ | | 147 | #define AFR_RA (1U<<31) /* receive block all on */ |
146 | #define AFR_HPF (1U<<10) /* activate hash or perfect filter */ | | 148 | #define AFR_HPF (1U<<10) /* activate hash or perfect filter */ |
147 | #define AFR_SAF (1U<<9) /* source address filter */ | | 149 | #define AFR_SAF (1U<<9) /* source address filter */ |
148 | #define AFR_SAIF (1U<<8) /* SA inverse filtering */ | | 150 | #define AFR_SAIF (1U<<8) /* SA inverse filtering */ |
149 | #define AFR_PCF (3U<<6) /* */ | | 151 | #define AFR_PCF (3U<<6) /* */ |
150 | #define AFR_RB (1U<<5) /* reject broadcast frame */ | | 152 | #define AFR_RB (1U<<5) /* reject broadcast frame */ |
151 | #define AFR_AM (1U<<4) /* accept all multicast frame */ | | 153 | #define AFR_AM (1U<<4) /* accept all multicast frame */ |
152 | #define AFR_DAIF (1U<<3) /* DA inverse filtering */ | | 154 | #define AFR_DAIF (1U<<3) /* DA inverse filtering */ |
153 | #define AFR_MHTE (1U<<2) /* use multicast hash table */ | | 155 | #define AFR_MHTE (1U<<2) /* use multicast hash table */ |
154 | #define AFR_UHTE (1U<<1) /* use additional MAC addresses */ | | 156 | #define AFR_UHTE (1U<<1) /* use additional MAC addresses */ |
155 | #define AFR_PM (1U<<0) /* run promisc mode */ | | 157 | #define AFR_PM (1U<<0) /* run promisc mode */ |
156 | #define _AFR 0x80000001 /* XXX TBD */ | | 158 | #define _AFR 0x80000001 /* XXX TBD */ |
157 | #define GMACMHTH 0x0008 /* XXX multicast hash table 63:32 */ | | 159 | #define GMACMHTH 0x0008 /* multicast hash table 63:32 */ |
158 | #define GMACMHTL 0x000c /* XXX multicast hash table 31:0 */ | | 160 | #define GMACMHTL 0x000c /* multicast hash table 31:0 */ |
159 | #define GMACGAR 0x0010 /* MDIO operation */ | | 161 | #define GMACGAR 0x0010 /* MDIO operation */ |
160 | #define GAR_PHY (11) /* mii phy 15:11 */ | | 162 | #define GAR_PHY (11) /* mii phy 15:11 */ |
161 | #define GAR_REG (6) /* mii reg 10:6 */ | | 163 | #define GAR_REG (6) /* mii reg 10:6 */ |
162 | #define GAR_CTL (2) /* control 5:2 */ | | 164 | #define GAR_CTL (2) /* control 5:2 */ |
163 | #define GAR_IOWR (1U<<1) /* MDIO write op */ | | 165 | #define GAR_IOWR (1U<<1) /* MDIO write op */ |
164 | #define GAR_BUSY (1U) /* busy bit */ | | 166 | #define GAR_BUSY (1U) /* busy bit */ |
165 | #define GMACGDR 0x0014 /* MDIO rd/wr data */ | | 167 | #define GMACGDR 0x0014 /* MDIO rd/wr data */ |
166 | #define GMACFCR 0x0018 /* 802.3x flowcontrol */ | | 168 | #define GMACFCR 0x0018 /* 802.3x flowcontrol */ |
167 | #define FCR_RFE (1U<<2) /* accept PAUSE to throttle Tx */ | | 169 | #define FCR_RFE (1U<<2) /* accept PAUSE to throttle Tx */ |
168 | #define FCR_TFE (1U<<1) /* generate PAUSE to moderate Rx lvl */ | | 170 | #define FCR_TFE (1U<<1) /* generate PAUSE to moderate Rx lvl */ |
169 | #define GMACVTAG 0x001c /* VLAN tag control */ | | 171 | #define GMACVTAG 0x001c /* VLAN tag control */ |
170 | #define GMACIMPL 0x0020 /* implementation number XX.YY */ | | 172 | #define GMACIMPL 0x0020 /* implementation number XX.YY */ |
171 | #define GMACMAH0 0x0040 /* MAC address 0 47:32 */ | | 173 | #define GMACMAH0 0x0040 /* MAC address 0 47:32 */ |
172 | #define GMACMAL0 0x0044 /* MAC address 0 31:0 */ | | 174 | #define GMACMAL0 0x0044 /* MAC address 0 31:0 */ |
173 | #define GMACMAH(i) ((i)*8+0x40) /* supplimental MAC addr 1 - 15 */ | | 175 | #define GMACMAH(i) ((i)*8+0x40) /* supplimental MAC addr 1 - 15 */ |
174 | #define GMACMAL(i) ((i)*8+0x44) | | 176 | #define GMACMAL(i) ((i)*8+0x44) |
175 | #define GMACMIISR 0x00d8 /* resolved xMII link status */ | | 177 | #define GMACMIISR 0x00d8 /* resolved xMII link status */ |
176 | /* 3 link up detected | | 178 | /* 3 link up detected |
177 | * 2:1 resovled speed | | 179 | * 2:1 resovled speed |
178 | * 0 2.5Mhz (10Mbps) | | 180 | * 0 2.5Mhz (10Mbps) |
179 | * 1 25Mhz (100Mbps) | | 181 | * 1 25Mhz (100Mbps) |
180 | * 2 125Mhz (1000Mbps) | | 182 | * 2 125Mhz (1000Mbps) |
181 | * 1 full duplex detected */ | | 183 | * 1 full duplex detected */ |
182 | | | 184 | |
183 | #define GMACMHT0 0x0500 /* multicast hash table 0 - 7 */ | | 185 | #define GMACMHT0 0x0500 /* XXX multicast hash table 0 - 7 */ |
184 | #define GMACMHT(i) ((i)*4+0x500) | | 186 | #define GMACMHT(i) ((i)*4+0x500) |
185 | #define GMACVHT 0x0588 /* VLAN tag hash */ | | 187 | #define GMACVHT 0x0588 /* VLAN tag hash */ |
186 | #define GMACAMAH(i) ((i)*8+0x800) /* supplimental MAC addr 16-127 */ | | 188 | #define GMACAMAH(i) ((i)*8+0x800) /* supplimental MAC addr 16-31 */ |
187 | #define GMACAMAL(i) ((i)*8+0x804) | | 189 | #define GMACAMAL(i) ((i)*8+0x804) |
| | | 190 | #define GMACEVCTL 0x0100 /* event counter control */ |
188 | #define GMACEVCNT(i) ((i)*4+0x114) /* event counter 0x114~284 */ | | 191 | #define GMACEVCNT(i) ((i)*4+0x114) /* event counter 0x114~284 */ |
189 | #define GMACEVCTL 0x0100 /* clear event counter registers */ | | | |
190 | | | 192 | |
191 | #define GMACBMR 0x1000 /* DMA bus mode control | | 193 | #define GMACBMR 0x1000 /* DMA bus mode control |
192 | * 24 4PBL | | 194 | * 24 4PBL |
193 | * 22:17 RPBL | | 195 | * 22:17 RPBL |
194 | * 16 fix burst | | 196 | * 16 fix burst |
195 | * 15:14 priority between Rx and Tx | | 197 | * 15:14 priority between Rx and Tx |
196 | * 3 rxtx ratio 41 | | 198 | * 3 rxtx ratio 41 |
197 | * 2 rxtx ratio 31 | | 199 | * 2 rxtx ratio 31 |
198 | * 1 rxtx ratio 21 | | 200 | * 1 rxtx ratio 21 |
199 | * 0 rxtx ratio 11 | | 201 | * 0 rxtx ratio 11 |
200 | * 13:8 PBL possible DMA burst len | | 202 | * 13:8 PBL possible DMA burst len |
201 | * 0 reset op. self clear | | 203 | * 0 reset op. self clear |
202 | */ | | 204 | */ |
| @@ -603,27 +605,27 @@ aprint_normal_dev(self, | | | @@ -603,27 +605,27 @@ aprint_normal_dev(self, |
603 | | | 605 | |
604 | static void | | 606 | static void |
605 | scx_attach_i(struct scx_softc *sc) | | 607 | scx_attach_i(struct scx_softc *sc) |
606 | { | | 608 | { |
607 | struct ifnet * const ifp = &sc->sc_ethercom.ec_if; | | 609 | struct ifnet * const ifp = &sc->sc_ethercom.ec_if; |
608 | struct mii_data * const mii = &sc->sc_mii; | | 610 | struct mii_data * const mii = &sc->sc_mii; |
609 | struct ifmedia * const ifm = &mii->mii_media; | | 611 | struct ifmedia * const ifm = &mii->mii_media; |
610 | uint32_t hwver, dwimp; | | 612 | uint32_t hwver, dwimp; |
611 | uint8_t enaddr[ETHER_ADDR_LEN]; | | 613 | uint8_t enaddr[ETHER_ADDR_LEN]; |
612 | bus_dma_segment_t seg; | | 614 | bus_dma_segment_t seg; |
613 | uint32_t csr; | | 615 | uint32_t csr; |
614 | int i, nseg, error = 0; | | 616 | int i, nseg, error = 0; |
615 | | | 617 | |
616 | hwver = CSR_READ(sc, HWVER1); /* Socionext HW */ | | 618 | hwver = CSR_READ(sc, HWVER); /* Socionext HW */ |
617 | /* stored in big endian order */ | | 619 | /* stored in big endian order */ |
618 | csr = bus_space_read_4(sc->sc_st, sc->sc_eesh, 0); | | 620 | csr = bus_space_read_4(sc->sc_st, sc->sc_eesh, 0); |
619 | enaddr[0] = csr >> 24; | | 621 | enaddr[0] = csr >> 24; |
620 | enaddr[1] = csr >> 16; | | 622 | enaddr[1] = csr >> 16; |
621 | enaddr[2] = csr >> 8; | | 623 | enaddr[2] = csr >> 8; |
622 | enaddr[3] = csr; | | 624 | enaddr[3] = csr; |
623 | csr = bus_space_read_4(sc->sc_st, sc->sc_eesh, 4); | | 625 | csr = bus_space_read_4(sc->sc_st, sc->sc_eesh, 4); |
624 | enaddr[4] = csr >> 24; | | 626 | enaddr[4] = csr >> 24; |
625 | enaddr[5] = csr >> 16; | | 627 | enaddr[5] = csr >> 16; |
626 | dwimp = mac_read(sc, GMACIMPL); /* DW EMAC XX.YY */ | | 628 | dwimp = mac_read(sc, GMACIMPL); /* DW EMAC XX.YY */ |
627 | | | 629 | |
628 | aprint_normal_dev(sc->sc_dev, | | 630 | aprint_normal_dev(sc->sc_dev, |
629 | "Socionext NetSec GbE hw %d.%d impl 0x%x\n", | | 631 | "Socionext NetSec GbE hw %d.%d impl 0x%x\n", |
| @@ -943,48 +945,47 @@ scx_ioctl(struct ifnet *ifp, u_long cmd, | | | @@ -943,48 +945,47 @@ scx_ioctl(struct ifnet *ifp, u_long cmd, |
943 | } | | 945 | } |
944 | | | 946 | |
945 | splx(s); | | 947 | splx(s); |
946 | return error; | | 948 | return error; |
947 | } | | 949 | } |
948 | | | 950 | |
949 | static void | | 951 | static void |
950 | scx_set_rcvfilt(struct scx_softc *sc) | | 952 | scx_set_rcvfilt(struct scx_softc *sc) |
951 | { | | 953 | { |
952 | struct ethercom * const ec = &sc->sc_ethercom; | | 954 | struct ethercom * const ec = &sc->sc_ethercom; |
953 | struct ifnet * const ifp = &ec->ec_if; | | 955 | struct ifnet * const ifp = &ec->ec_if; |
954 | struct ether_multistep step; | | 956 | struct ether_multistep step; |
955 | struct ether_multi *enm; | | 957 | struct ether_multi *enm; |
956 | uint32_t mchash[8]; /* 8x 32 = 256 bit */ | | 958 | uint32_t mchash[2]; /* 2x 32 = 64 bit */ |
957 | uint32_t csr, crc; | | 959 | uint32_t csr, crc; |
958 | int i; | | 960 | int i; |
959 | | | 961 | |
960 | csr = mac_read(sc, GMACAFR); | | 962 | csr = mac_read(sc, GMACAFR); |
961 | csr &= ~(AFR_PM | AFR_AM | AFR_MHTE); | | 963 | csr &= ~(AFR_PM | AFR_AM | AFR_MHTE); |
962 | mac_write(sc, GMACAFR, csr); | | 964 | mac_write(sc, GMACAFR, csr); |
963 | | | 965 | |
964 | ETHER_LOCK(ec); | | 966 | ETHER_LOCK(ec); |
965 | if (ifp->if_flags & IFF_PROMISC) { | | 967 | if (ifp->if_flags & IFF_PROMISC) { |
966 | ec->ec_flags |= ETHER_F_ALLMULTI; | | 968 | ec->ec_flags |= ETHER_F_ALLMULTI; |
967 | ETHER_UNLOCK(ec); | | 969 | ETHER_UNLOCK(ec); |
968 | goto update; | | 970 | goto update; |
969 | } | | 971 | } |
970 | ec->ec_flags &= ~ETHER_F_ALLMULTI; | | 972 | ec->ec_flags &= ~ETHER_F_ALLMULTI; |
971 | | | 973 | |
972 | /* clear 15 entry supplimental perfect match filter */ | | 974 | /* clear 15 entry supplimental perfect match filter */ |
973 | for (i = 1; i < 16; i++) | | 975 | for (i = 1; i < 16; i++) |
974 | mac_write(sc, GMACMAH(i), 0); | | 976 | mac_write(sc, GMACMAH(i), 0); |
975 | /* build 256 bit multicast hash filter */ | | 977 | /* build 64 bit multicast hash filter */ |
976 | memset(mchash, 0, sizeof(mchash)); | | 978 | crc = mchash[1] = mchash[0] = 0; |
977 | crc = 0; | | | |
978 | | | 979 | |
979 | ETHER_FIRST_MULTI(step, ec, enm); | | 980 | ETHER_FIRST_MULTI(step, ec, enm); |
980 | i = 1; /* slot 0 is occupied */ | | 981 | i = 1; /* slot 0 is occupied */ |
981 | while (enm != NULL) { | | 982 | while (enm != NULL) { |
982 | if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { | | 983 | if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { |
983 | /* | | 984 | /* |
984 | * We must listen to a range of multicast addresses. | | 985 | * We must listen to a range of multicast addresses. |
985 | * For now, just accept all multicasts, rather than | | 986 | * For now, just accept all multicasts, rather than |
986 | * trying to set only those filter bits needed to match | | 987 | * trying to set only those filter bits needed to match |
987 | * the range. (At this time, the only use of address | | 988 | * the range. (At this time, the only use of address |
988 | * ranges is for IP multicast routing, for which the | | 989 | * ranges is for IP multicast routing, for which the |
989 | * range is big enough to require all bits set.) | | 990 | * range is big enough to require all bits set.) |
990 | */ | | 991 | */ |
| @@ -996,38 +997,38 @@ printf("[%d] %s\n", i, ether_sprintf(enm | | | @@ -996,38 +997,38 @@ printf("[%d] %s\n", i, ether_sprintf(enm |
996 | if (i < 16) { | | 997 | if (i < 16) { |
997 | /* use 15 entry perfect match filter */ | | 998 | /* use 15 entry perfect match filter */ |
998 | uint32_t addr; | | 999 | uint32_t addr; |
999 | uint8_t *ep = enm->enm_addrlo; | | 1000 | uint8_t *ep = enm->enm_addrlo; |
1000 | addr = (ep[3] << 24) | (ep[2] << 16) | | 1001 | addr = (ep[3] << 24) | (ep[2] << 16) |
1001 | | (ep[1] << 8) | ep[0]; | | 1002 | | (ep[1] << 8) | ep[0]; |
1002 | mac_write(sc, GMACMAL(i), addr); | | 1003 | mac_write(sc, GMACMAL(i), addr); |
1003 | addr = (ep[5] << 8) | ep[4]; | | 1004 | addr = (ep[5] << 8) | ep[4]; |
1004 | mac_write(sc, GMACMAH(i), addr | 1U<<31); | | 1005 | mac_write(sc, GMACMAH(i), addr | 1U<<31); |
1005 | } else { | | 1006 | } else { |
1006 | /* use hash table when too many */ | | 1007 | /* use hash table when too many */ |
1007 | /* bit_reserve_32(~crc) !? */ | | 1008 | /* bit_reserve_32(~crc) !? */ |
1008 | crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN); | | 1009 | crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN); |
1009 | /* 3(31:29) 5(28:24) bit sampling */ | | 1010 | /* 1(31) 5(30:26) bit sampling */ |
1010 | mchash[crc >> 29] |= 1 << ((crc >> 24) & 0x1f); | | 1011 | mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); |
1011 | } | | 1012 | } |
1012 | ETHER_NEXT_MULTI(step, enm); | | 1013 | ETHER_NEXT_MULTI(step, enm); |
1013 | i++; | | 1014 | i++; |
1014 | } | | 1015 | } |
1015 | ETHER_UNLOCK(ec); | | 1016 | ETHER_UNLOCK(ec); |
1016 | | | 1017 | |
1017 | if (crc) | | 1018 | if (crc) |
1018 | csr |= AFR_MHTE; | | 1019 | csr |= AFR_MHTE; |
1019 | for (i = 0; i < __arraycount(mchash); i++) | | 1020 | mac_write(sc, GMACMHTH, mchash[1]); |
1020 | mac_write(sc, GMACMHT(i), mchash[i]); | | 1021 | mac_write(sc, GMACMHTL, mchash[0]); |
1021 | mac_write(sc, GMACAFR, csr); | | 1022 | mac_write(sc, GMACAFR, csr); |
1022 | return; | | 1023 | return; |
1023 | | | 1024 | |
1024 | update: | | 1025 | update: |
1025 | /* With PM or AM, MHTE/MHT0-7 are never consulted. really? */ | | 1026 | /* With PM or AM, MHTE/MHT0-7 are never consulted. really? */ |
1026 | if (ifp->if_flags & IFF_PROMISC) | | 1027 | if (ifp->if_flags & IFF_PROMISC) |
1027 | csr |= AFR_PM; /* run promisc. mode */ | | 1028 | csr |= AFR_PM; /* run promisc. mode */ |
1028 | else | | 1029 | else |
1029 | csr |= AFR_AM; /* accept all multicast */ | | 1030 | csr |= AFR_AM; /* accept all multicast */ |
1030 | mac_write(sc, GMACAFR, csr); | | 1031 | mac_write(sc, GMACAFR, csr); |
1031 | return; | | 1032 | return; |
1032 | } | | 1033 | } |
1033 | | | 1034 | |