From b12ece3d4a94df26042db929a84544b5503c549e Mon Sep 17 00:00:00 2001 From: jmatthew Date: Fri, 24 Aug 2018 12:35:10 +0000 Subject: [PATCH] Include the list of multicast groups in the rx filter configuration. The adapter reads this from host memory, so we allocate a new page for it. The rx filter code ends up looking a lot more like other drivers as a result. --- sys/dev/pci/if_bnxt.c | 126 ++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 72 deletions(-) diff --git a/sys/dev/pci/if_bnxt.c b/sys/dev/pci/if_bnxt.c index 89699978956..6f3fe0fdcf0 100644 --- a/sys/dev/pci/if_bnxt.c +++ b/sys/dev/pci/if_bnxt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bnxt.c,v 1.8 2018/08/24 02:26:31 jmatthew Exp $ */ +/* $OpenBSD: if_bnxt.c,v 1.9 2018/08/24 12:35:10 jmatthew Exp $ */ /*- * Broadcom NetXtreme-C/E network driver. * @@ -151,9 +151,6 @@ struct bnxt_vnic_info { uint16_t lb_rule; uint16_t mru; - uint32_t rx_mask; - /* multicast things */ - uint32_t flags; #define BNXT_VNIC_FLAG_DEFAULT 0x01 #define BNXT_VNIC_FLAG_BD_STALL 0x02 @@ -164,8 +161,6 @@ struct bnxt_vnic_info { uint16_t rss_id; /* rss things */ - - /* vlan things */ }; struct bnxt_slot { @@ -222,6 +217,7 @@ struct bnxt_softc { /* rx */ struct bnxt_dmamem *sc_rx_ring_mem; /* rx and ag */ + struct bnxt_dmamem *sc_rx_mcast; struct bnxt_ring sc_rx_ring; /* struct bnxt_ring sc_rx_ag_ring; */ struct bnxt_grp_info sc_ring_group; @@ -326,7 +322,7 @@ int bnxt_hwrm_vnic_alloc(struct bnxt_softc *, int bnxt_hwrm_vnic_free(struct bnxt_softc *, struct bnxt_vnic_info *); int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt_softc *, - struct bnxt_vnic_info *vnic); + uint32_t, uint32_t, uint64_t, uint32_t); int bnxt_hwrm_set_filter(struct bnxt_softc *, struct bnxt_vnic_info *); int bnxt_hwrm_free_filter(struct bnxt_softc *, @@ -655,10 +651,17 @@ bnxt_up(struct bnxt_softc *sc) goto free_tx; } + sc->sc_rx_mcast = bnxt_dmamem_alloc(sc, PAGE_SIZE); + if (sc->sc_rx_mcast == NULL) { + printf("%s: failed to allocate multicast address table\n", + DEVNAME(sc)); + goto free_rx; + } + if (bnxt_hwrm_stat_ctx_alloc(sc, &sc->sc_cp_ring, BNXT_DMA_DVA(sc->sc_stats_ctx_mem)) != 0) { printf("%s: failed to set up stats context\n", DEVNAME(sc)); - goto free_rx; + goto free_mc; } sc->sc_tx_ring.phys_id = HWRM_NA_SIGNATURE; @@ -730,9 +733,6 @@ bnxt_up(struct bnxt_softc *sc) sc->sc_vnic.mru = MCLBYTES; sc->sc_vnic.cos_rule = (uint16_t)HWRM_NA_SIGNATURE; sc->sc_vnic.lb_rule = (uint16_t)HWRM_NA_SIGNATURE; - sc->sc_vnic.rx_mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST - | HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN; - /* sc->sc_vnic.mc_list_count = 0; */ sc->sc_vnic.flags = BNXT_VNIC_FLAG_DEFAULT; if (bnxt_hwrm_vnic_alloc(sc, &sc->sc_vnic) != 0) { printf("%s: failed to allocate vnic\n", DEVNAME(sc)); @@ -837,6 +837,9 @@ dealloc_rx: &sc->sc_rx_ring); dealloc_stats: bnxt_hwrm_stat_ctx_free(sc, &sc->sc_cp_ring); +free_mc: + bnxt_dmamem_free(sc, sc->sc_rx_mcast); + sc->sc_rx_mcast = NULL; free_rx: bnxt_dmamem_free(sc, sc->sc_rx_ring_mem); sc->sc_rx_ring_mem = NULL; @@ -883,6 +886,9 @@ bnxt_down(struct bnxt_softc *sc) bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_RX, &sc->sc_rx_ring); + bnxt_dmamem_free(sc, sc->sc_rx_mcast); + sc->sc_rx_mcast = NULL; + bnxt_dmamem_free(sc, sc->sc_rx_ring_mem); sc->sc_rx_ring_mem = NULL; @@ -897,22 +903,39 @@ void bnxt_iff(struct bnxt_softc *sc) { struct ifnet *ifp = &sc->sc_ac.ac_if; + struct ether_multi *enm; + struct ether_multistep step; + char *mc_list; + uint32_t rx_mask, mc_count; + + rx_mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST + | HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST + | HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN; + + mc_list = BNXT_DMA_KVA(sc->sc_rx_mcast); + mc_count = 0; + + if (ifp->if_flags & IFF_PROMISC) { + SET(ifp->if_flags, IFF_ALLMULTI); + rx_mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS; + } else if ((sc->sc_ac.ac_multirangecnt > 0) || + (sc->sc_ac.ac_multicnt > (PAGE_SIZE / ETHER_ADDR_LEN))) { + SET(ifp->if_flags, IFF_ALLMULTI); + rx_mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST; + } else { + CLR(ifp->if_flags, IFF_ALLMULTI); + ETHER_FIRST_MULTI(step, &sc->sc_ac, enm); + while (enm != NULL) { + memcpy(mc_list, enm->enm_addrlo, ETHER_ADDR_LEN); + mc_list += ETHER_ADDR_LEN; + mc_count++; + + ETHER_NEXT_MULTI(step, enm); + } + } - if (ifp->if_flags & IFF_ALLMULTI) - sc->sc_vnic.rx_mask |= - HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST; - else - sc->sc_vnic.rx_mask &= - ~HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST; - - if (ifp->if_flags & IFF_PROMISC) - sc->sc_vnic.rx_mask |= - HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS; - else - sc->sc_vnic.rx_mask &= - (~HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS); - - bnxt_hwrm_cfa_l2_set_rx_mask(sc, &sc->sc_vnic); + bnxt_hwrm_cfa_l2_set_rx_mask(sc, sc->sc_vnic.id, rx_mask, + BNXT_DMA_DVA(sc->sc_rx_mcast), mc_count); } int @@ -2570,57 +2593,16 @@ bnxt_hwrm_port_qstats(struct bnxt_softc *softc) int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt_softc *softc, - struct bnxt_vnic_info *vnic) + uint32_t vnic_id, uint32_t rx_mask, uint64_t mc_addr, uint32_t mc_count) { struct hwrm_cfa_l2_set_rx_mask_input req = {0}; - uint32_t mask = vnic->rx_mask; -#if 0 - struct bnxt_vlan_tag *tag; - uint32_t *tags; - uint32_t num_vlan_tags = 0;; - uint32_t i; - int rc; - - SLIST_FOREACH(tag, &vnic->vlan_tags, next) - num_vlan_tags++; - - if (num_vlan_tags) { - if (!(mask & - HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN)) { - if (!vnic->vlan_only) - mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN; - else - mask |= - HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY; - } - if (vnic->vlan_tag_list.idi_vaddr) { - iflib_dma_free(&vnic->vlan_tag_list); - vnic->vlan_tag_list.idi_vaddr = NULL; - } - rc = iflib_dma_alloc(softc->ctx, 4 * num_vlan_tags, - &vnic->vlan_tag_list, BUS_DMA_NOWAIT); - if (rc) - return rc; - tags = (uint32_t *)vnic->vlan_tag_list.idi_vaddr; - - i = 0; - SLIST_FOREACH(tag, &vnic->vlan_tags, next) { - tags[i] = htole32((tag->tpid << 16) | tag->tag); - i++; - } - } -#endif bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_CFA_L2_SET_RX_MASK); - req.vnic_id = htole32(vnic->id); - req.mask = htole32(mask); -#if 0 - req.mc_tbl_addr = htole64(vnic->mc_list.idi_paddr); - req.num_mc_entries = htole32(vnic->mc_list_count); - req.vlan_tag_tbl_addr = htole64(vnic->vlan_tag_list.idi_paddr); - req.num_vlan_tags = htole32(num_vlan_tags); -#endif + req.vnic_id = htole32(vnic_id); + req.mask = htole32(rx_mask); + req.mc_tbl_addr = htole64(mc_addr); + req.num_mc_entries = htole32(mc_count); return hwrm_send_message(softc, &req, sizeof(req)); } -- 2.20.1