summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/octeon/dev/cn30xxgmx.c137
-rw-r--r--sys/arch/octeon/dev/cn30xxgmxreg.h9
-rw-r--r--sys/arch/octeon/dev/cn30xxgmxvar.h4
-rw-r--r--sys/arch/octeon/dev/if_cnmac.c11
4 files changed, 47 insertions, 114 deletions
diff --git a/sys/arch/octeon/dev/cn30xxgmx.c b/sys/arch/octeon/dev/cn30xxgmx.c
index f27b180e493..9b601c97abf 100644
--- a/sys/arch/octeon/dev/cn30xxgmx.c
+++ b/sys/arch/octeon/dev/cn30xxgmx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cn30xxgmx.c,v 1.49 2021/02/04 16:16:10 visa Exp $ */
+/* $OpenBSD: cn30xxgmx.c,v 1.50 2021/02/13 17:12:38 visa Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -47,22 +47,7 @@
#include <octeon/dev/cn30xxpipvar.h>
#include <octeon/dev/cn30xxsmivar.h>
-#define dprintf(...)
-#define OCTEON_ETH_KASSERT KASSERT
-
-#define ADDR2UINT64(u, a) \
- do { \
- u = \
- (((uint64_t)a[0] << 40) | ((uint64_t)a[1] << 32) | \
- ((uint64_t)a[2] << 24) | ((uint64_t)a[3] << 16) | \
- ((uint64_t)a[4] << 8) | ((uint64_t)a[5] << 0)); \
- } while (0)
-#define UINT642ADDR(a, u) \
- do { \
- a[0] = (uint8_t)((u) >> 40); a[1] = (uint8_t)((u) >> 32); \
- a[2] = (uint8_t)((u) >> 24); a[3] = (uint8_t)((u) >> 16); \
- a[4] = (uint8_t)((u) >> 8); a[5] = (uint8_t)((u) >> 0); \
- } while (0)
+#define GMX_NCAM 8
#define _GMX_RD8(sc, off) \
bus_space_read_8((sc)->sc_port_gmx->sc_regt, (sc)->sc_port_gmx->sc_regh, (off))
@@ -127,11 +112,6 @@ int cn30xxgmx_rgmii_speed_newlink_log(struct cn30xxgmx_port_softc *,
uint64_t);
#endif
-static const int cn30xxgmx_rx_adr_cam_regs[] = {
- GMX0_RX0_ADR_CAM0, GMX0_RX0_ADR_CAM1, GMX0_RX0_ADR_CAM2,
- GMX0_RX0_ADR_CAM3, GMX0_RX0_ADR_CAM4, GMX0_RX0_ADR_CAM5
-};
-
struct cn30xxgmx_port_ops cn30xxgmx_port_ops_agl = {
.port_ops_enable = cn30xxgmx_agl_enable,
.port_ops_speed = cn30xxgmx_agl_speed,
@@ -643,42 +623,17 @@ cn30xxgmx_tx_thresh(struct cn30xxgmx_port_softc *sc, int cnt)
}
int
-cn30xxgmx_set_mac_addr(struct cn30xxgmx_port_softc *sc, uint8_t *addr)
-{
- uint64_t mac;
- int i;
-
- ADDR2UINT64(mac, addr);
-
- cn30xxgmx_link_enable(sc, 0);
-
- sc->sc_mac = mac;
- _GMX_PORT_WR8(sc, GMX0_SMAC0, mac);
- for (i = 0; i < 6; i++)
- _GMX_PORT_WR8(sc, cn30xxgmx_rx_adr_cam_regs[i], addr[i]);
-
- cn30xxgmx_link_enable(sc, 1);
-
- return 0;
-}
-
-int
cn30xxgmx_set_filter(struct cn30xxgmx_port_softc *sc)
{
struct ifnet *ifp = &sc->sc_port_ac->ac_if;
struct arpcom *ac = sc->sc_port_ac;
struct ether_multi *enm;
struct ether_multistep step;
- uint64_t cam_en = 0x01ULL;
+ uint64_t cam[ETHER_ADDR_LEN];
+ uint64_t cam_en = 0;
uint64_t ctl = 0;
- int multi = 0;
-
- cn30xxgmx_link_enable(sc, 0);
-
- SET(ctl, RXN_ADR_CTL_CAM_MODE);
- CLR(ctl, RXN_ADR_CTL_MCST_ACCEPT | RXN_ADR_CTL_MCST_AFCAM |
- RXN_ADR_CTL_MCST_REJECT);
- CLR(ifp->if_flags, IFF_ALLMULTI);
+ uint64_t mac;
+ int i, cidx;
/*
* Always accept broadcast frames.
@@ -687,63 +642,53 @@ cn30xxgmx_set_filter(struct cn30xxgmx_port_softc *sc)
if (ISSET(ifp->if_flags, IFF_PROMISC)) {
SET(ifp->if_flags, IFF_ALLMULTI);
- CLR(ctl, RXN_ADR_CTL_CAM_MODE);
SET(ctl, RXN_ADR_CTL_MCST_ACCEPT);
- cam_en = 0x00ULL;
- } else if (ac->ac_multirangecnt > 0 || ac->ac_multicnt > 7) {
+ } else if (ac->ac_multirangecnt > 0 || ac->ac_multicnt >= GMX_NCAM) {
SET(ifp->if_flags, IFF_ALLMULTI);
+ SET(ctl, RXN_ADR_CTL_CAM_MODE);
SET(ctl, RXN_ADR_CTL_MCST_ACCEPT);
} else {
- /*
- * Note first entry is self MAC address; other 7 entires are
- * available for multicast addresses.
- */
- ETHER_FIRST_MULTI(step, sc->sc_port_ac, enm);
- while (enm != NULL) {
- int i;
-
- dprintf("%d: %02x:%02x:%02x:%02x:%02x:%02x\n"
- multi + 1,
- enm->enm_addrlo[0], enm->enm_addrlo[1],
- enm->enm_addrlo[2], enm->enm_addrlo[3],
- enm->enm_addrlo[4], enm->enm_addrlo[5]);
- multi++;
-
- SET(cam_en, 1ULL << multi); /* XXX */
-
- for (i = 0; i < 6; i++) {
- uint64_t tmp;
-
- /* XXX */
- tmp = _GMX_PORT_RD8(sc,
- cn30xxgmx_rx_adr_cam_regs[i]);
- CLR(tmp, 0xffULL << (8 * multi));
- SET(tmp, (uint64_t)enm->enm_addrlo[i] <<
- (8 * multi));
- _GMX_PORT_WR8(sc, cn30xxgmx_rx_adr_cam_regs[i],
- tmp);
- }
+ CLR(ifp->if_flags, IFF_ALLMULTI);
+ SET(ctl, RXN_ADR_CTL_CAM_MODE);
+ SET(ctl, RXN_ADR_CTL_MCST_AFCAM);
+ }
- for (i = 0; i < 6; i++)
- dprintf("cam%d = %016llx\n", i,
- _GMX_PORT_RD8(sc,
- cn30xxgmx_rx_adr_cam_regs[i]));
+ mac = 0;
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ mac |= (uint64_t)ac->ac_enaddr[i] <<
+ ((ETHER_ADDR_LEN - 1 - i) * 8);
+ /*
+ * The first CAM entry is used for the local unicast MAC.
+ * The remaining entries are used for multicast MACs.
+ */
+ memset(cam, 0, sizeof(cam));
+ cidx = 0;
+ if (!ISSET(ifp->if_flags, IFF_PROMISC)) {
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ cam[i] |= (uint64_t)ac->ac_enaddr[i] << (cidx * 8);
+ cam_en |= 1U << cidx;
+ cidx++;
+ }
+ if (!ISSET(ifp->if_flags, IFF_ALLMULTI)) {
+ ETHER_FIRST_MULTI(step, ac, enm);
+ while (enm != NULL && cidx < GMX_NCAM) {
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ cam[i] |= (uint64_t)enm->enm_addrlo[i] <<
+ (cidx * 8);
+ cam_en |= 1U << cidx;
+ cidx++;
ETHER_NEXT_MULTI(step, enm);
}
-
- if (multi)
- SET(ctl, RXN_ADR_CTL_MCST_AFCAM);
- else
- SET(ctl, RXN_ADR_CTL_MCST_REJECT);
-
- OCTEON_ETH_KASSERT(enm == NULL);
}
- dprintf("ctl = %llx, cam_en = %llx\n", ctl, cam_en);
+ cn30xxgmx_link_enable(sc, 0);
+ _GMX_PORT_WR8(sc, GMX0_SMAC0, mac);
_GMX_PORT_WR8(sc, GMX0_RX0_ADR_CTL, ctl);
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ _GMX_PORT_WR8(sc, GMX0_RX0_ADR_CAM(i), cam[i]);
_GMX_PORT_WR8(sc, GMX0_RX0_ADR_CAM_EN, cam_en);
-
+ (void)_GMX_PORT_RD8(sc, GMX0_RX0_ADR_CAM_EN);
cn30xxgmx_link_enable(sc, 1);
return 0;
diff --git a/sys/arch/octeon/dev/cn30xxgmxreg.h b/sys/arch/octeon/dev/cn30xxgmxreg.h
index c601a40aba9..55edb362112 100644
--- a/sys/arch/octeon/dev/cn30xxgmxreg.h
+++ b/sys/arch/octeon/dev/cn30xxgmxreg.h
@@ -3,7 +3,7 @@
* DONT EDIT THIS FILE
*/
-/* $OpenBSD: cn30xxgmxreg.h,v 1.7 2020/09/08 13:54:48 visa Exp $ */
+/* $OpenBSD: cn30xxgmxreg.h,v 1.8 2021/02/13 17:12:38 visa Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -64,12 +64,7 @@
#define GMX0_RX0_STATS_PKTS_BAD 0x0c0
#define GMX0_RX0_ADR_CTL 0x100
#define GMX0_RX0_ADR_CAM_EN 0x108
-#define GMX0_RX0_ADR_CAM0 0x180
-#define GMX0_RX0_ADR_CAM1 0x188
-#define GMX0_RX0_ADR_CAM2 0x190
-#define GMX0_RX0_ADR_CAM3 0x198
-#define GMX0_RX0_ADR_CAM4 0x1a0
-#define GMX0_RX0_ADR_CAM5 0x1a8
+#define GMX0_RX0_ADR_CAM(i) (0x180 + (i) * 8)
#define GMX0_TX0_CLK 0x208
#define GMX0_TX0_THRESH 0x210
#define GMX0_TX0_APPEND 0x218
diff --git a/sys/arch/octeon/dev/cn30xxgmxvar.h b/sys/arch/octeon/dev/cn30xxgmxvar.h
index 066ba8b2347..1368b5bf14c 100644
--- a/sys/arch/octeon/dev/cn30xxgmxvar.h
+++ b/sys/arch/octeon/dev/cn30xxgmxvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cn30xxgmxvar.h,v 1.11 2020/09/08 13:54:48 visa Exp $ */
+/* $OpenBSD: cn30xxgmxvar.h,v 1.12 2021/02/13 17:12:38 visa Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -61,7 +61,6 @@ struct cn30xxgmx_port_softc {
bus_space_handle_t sc_port_regh;
int sc_port_no; /* GMX0:0, GMX0:1, ... */
int sc_port_type;
- uint64_t sc_mac;
uint64_t sc_link;
struct mii_data *sc_port_mii;
struct arpcom *sc_port_ac;
@@ -111,7 +110,6 @@ int cn30xxgmx_rx_frm_ctl_enable(struct cn30xxgmx_port_softc *,
int cn30xxgmx_rx_frm_ctl_disable(struct cn30xxgmx_port_softc *,
uint64_t rx_frm_ctl);
int cn30xxgmx_tx_thresh(struct cn30xxgmx_port_softc *, int);
-int cn30xxgmx_set_mac_addr(struct cn30xxgmx_port_softc *, uint8_t *);
int cn30xxgmx_set_filter(struct cn30xxgmx_port_softc *);
int cn30xxgmx_port_enable(struct cn30xxgmx_port_softc *, int);
int cn30xxgmx_reset_speed(struct cn30xxgmx_port_softc *);
diff --git a/sys/arch/octeon/dev/if_cnmac.c b/sys/arch/octeon/dev/if_cnmac.c
index c3f20ff5f09..ebb341f5948 100644
--- a/sys/arch/octeon/dev/if_cnmac.c
+++ b/sys/arch/octeon/dev/if_cnmac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_cnmac.c,v 1.80 2020/12/12 11:48:52 jan Exp $ */
+/* $OpenBSD: if_cnmac.c,v 1.81 2021/02/13 17:12:38 visa Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -247,7 +247,6 @@ cnmac_attach(struct device *parent, struct device *self, void *aux)
struct cnmac_softc *sc = (void *)self;
struct cn30xxgmx_attach_args *ga = aux;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
- uint8_t enaddr[ETHER_ADDR_LEN];
if (cnmac_npowgroups >= OCTEON_POW_GROUP_MAX) {
printf(": out of POW groups\n");
@@ -275,8 +274,8 @@ cnmac_attach(struct device *parent, struct device *self, void *aux)
*/
sc->sc_ip_offset = 0/* XXX */;
- cnmac_board_mac_addr(enaddr);
- printf(", address %s\n", ether_sprintf(enaddr));
+ cnmac_board_mac_addr(sc->sc_arpcom.ac_enaddr);
+ printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
ml_init(&sc->sc_sendq);
sc->sc_soft_req_thresh = 15/* XXX */;
@@ -319,12 +318,9 @@ cnmac_attach(struct device *parent, struct device *self, void *aux)
ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_TCPv4 |
IFCAP_CSUM_UDPv4 | IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6;
- cn30xxgmx_set_mac_addr(sc->sc_gmx_port, enaddr);
cn30xxgmx_set_filter(sc->sc_gmx_port);
if_attach(ifp);
-
- memcpy(sc->sc_arpcom.ac_enaddr, enaddr, ETHER_ADDR_LEN);
ether_ifattach(ifp);
cnmac_buf_init(sc);
@@ -1011,7 +1007,6 @@ cnmac_init(struct ifnet *ifp)
cn30xxpip_stats_init(sc->sc_pip);
cn30xxgmx_stats_init(sc->sc_gmx_port);
- cn30xxgmx_set_mac_addr(sc->sc_gmx_port, sc->sc_arpcom.ac_enaddr);
cn30xxgmx_set_filter(sc->sc_gmx_port);
timeout_add_sec(&sc->sc_tick_misc_ch, 1);