FreeBSD/sys/dev/cxgbe/t4_main.c
/*
 * Program the port's XGMAC based on parameters in ifnet.  The caller also
 * indicates which parameters should be programmed (the rest are left alone).
 */
Program the port's XGMAC based on parameters in ifnet.  The caller also
indicates which parameters should be programmed (the rest are left alone).
Program the port ' s XGMAC based on parameters in ifnet . The caller also indicates which parameters should be programmed ( the rest are left alone ) .
int
update_mac_settings(struct ifnet *ifp, int flags)
{
	int rc = 0;
	struct vi_info *vi = ifp->if_softc;
	struct port_info *pi = vi->pi;
	struct adapter *sc = pi->adapter;
	int mtu = -1, promisc = -1, allmulti = -1, vlanex = -1;
	ASSERT_SYNCHRONIZED_OP(sc);
	KASSERT(flags, ("%s: not told what to update.", __func__));
	if (flags & XGMAC_MTU)
		mtu = ifp->if_mtu;
	if (flags & XGMAC_PROMISC)
		promisc = ifp->if_flags & IFF_PROMISC ? 1 : 0;
	if (flags & XGMAC_ALLMULTI)
		allmulti = ifp->if_flags & IFF_ALLMULTI ? 1 : 0;
	if (flags & XGMAC_VLANEX)
		vlanex = ifp->if_capenable & IFCAP_VLAN_HWTAGGING ? 1 : 0;
	if (flags & (XGMAC_MTU|XGMAC_PROMISC|XGMAC_ALLMULTI|XGMAC_VLANEX)) {
		rc = -t4_set_rxmode(sc, sc->mbox, vi->viid, mtu, promisc,
		    allmulti, 1, vlanex, false);
		if (rc) {
			if_printf(ifp, "set_rxmode (%x) failed: %d\n", flags,
			    rc);
			return (rc);
		}
	}
	if (flags & XGMAC_UCADDR) {
		uint8_t ucaddr[ETHER_ADDR_LEN];
		bcopy(IF_LLADDR(ifp), ucaddr, sizeof(ucaddr));
		rc = t4_change_mac(sc, sc->mbox, vi->viid, vi->xact_addr_filt,
		    ucaddr, true, true);
		if (rc < 0) {
			rc = -rc;
			if_printf(ifp, "change_mac failed: %d\n", rc);
			return (rc);
		} else {
			vi->xact_addr_filt = rc;
			rc = 0;
		}
	}
	if (flags & XGMAC_MCADDRS) {
		const uint8_t *mcaddr[FW_MAC_EXACT_CHUNK];
		int del = 1;
		uint64_t hash = 0;
		struct ifmultiaddr *ifma;
		int i = 0, j;
		if_maddr_rlock(ifp);
		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
			if (ifma->ifma_addr->sa_family != AF_LINK)
				continue;
			mcaddr[i] =
			    LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
			MPASS(ETHER_IS_MULTICAST(mcaddr[i]));
			i++;
			if (i == FW_MAC_EXACT_CHUNK) {
				rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid,
				    del, i, mcaddr, NULL, &hash, 0);
				if (rc < 0) {
					rc = -rc;
					for (j = 0; j < i; j++) {
						if_printf(ifp,
						    "failed to add mc address"
						    " %02x:%02x:%02x:"
						    "%02x:%02x:%02x rc=%d\n",
						    mcaddr[j][0], mcaddr[j][1],
						    mcaddr[j][2], mcaddr[j][3],
						    mcaddr[j][4], mcaddr[j][5],
						    rc);
					}
					goto mcfail;
				}
				del = 0;
				i = 0;
			}
		}
		if (i > 0) {
			rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, del, i,
			    mcaddr, NULL, &hash, 0);
			if (rc < 0) {
				rc = -rc;
				for (j = 0; j < i; j++) {
					if_printf(ifp,
					    "failed to add mc address"
					    " %02x:%02x:%02x:"
					    "%02x:%02x:%02x rc=%d\n",
					    mcaddr[j][0], mcaddr[j][1],
					    mcaddr[j][2], mcaddr[j][3],
					    mcaddr[j][4], mcaddr[j][5],
					    rc);
				}
				goto mcfail;
			}
		}
		rc = -t4_set_addr_hash(sc, sc->mbox, vi->viid, 0, hash, 0);
		if (rc != 0)
			if_printf(ifp, "failed to set mc address hash: %d", rc);
mcfail:
		if_maddr_runlock(ifp);
	}
	return (rc);
}
int update_mac_settings ( struct ifnet * ifp , int flags ) { int rc = 0 ; struct vi_info * vi = ifp -> if_softc ; struct port_info * pi = vi -> pi ; struct adapter * sc = pi -> adapter ; int mtu = -1 , promisc = -1 , allmulti = -1 , vlanex = -1 ; ASSERT_SYNCHRONIZED_OP ( sc ) ; KASSERT ( flags , ( " " , __func__ ) ) ; if ( flags & XGMAC_MTU ) mtu = ifp -> if_mtu ; if ( flags & XGMAC_PROMISC ) promisc = ifp -> if_flags & IFF_PROMISC ? 1 : 0 ; if ( flags & XGMAC_ALLMULTI ) allmulti = ifp -> if_flags & IFF_ALLMULTI ? 1 : 0 ; if ( flags & XGMAC_VLANEX ) vlanex = ifp -> if_capenable & IFCAP_VLAN_HWTAGGING ? 1 : 0 ; if ( flags & ( XGMAC_MTU | XGMAC_PROMISC | XGMAC_ALLMULTI | XGMAC_VLANEX ) ) { rc = - t4_set_rxmode ( sc , sc -> mbox , vi -> viid , mtu , promisc , allmulti , 1 , vlanex , false ) ; if ( rc ) { if_printf ( ifp , " \n " , flags , rc ) ; return ( rc ) ; } } if ( flags & XGMAC_UCADDR ) { uint8_t ucaddr [ ETHER_ADDR_LEN ] ; bcopy ( IF_LLADDR ( ifp ) , ucaddr , sizeof ( ucaddr ) ) ; rc = t4_change_mac ( sc , sc -> mbox , vi -> viid , vi -> xact_addr_filt , ucaddr , true , true ) ; if ( rc < 0 ) { rc = - rc ; if_printf ( ifp , " \n " , rc ) ; return ( rc ) ; } else { vi -> xact_addr_filt = rc ; rc = 0 ; } } if ( flags & XGMAC_MCADDRS ) { const uint8_t * mcaddr [ FW_MAC_EXACT_CHUNK ] ; int del = 1 ; uint64_t hash = 0 ; struct ifmultiaddr * ifma ; int i = 0 , j ; if_maddr_rlock ( ifp ) ; TAILQ_FOREACH ( ifma , & ifp -> if_multiaddrs , ifma_link ) { if ( ifma -> ifma_addr -> sa_family != AF_LINK ) continue ; mcaddr [ i ] = LLADDR ( ( struct sockaddr_dl * ) ifma -> ifma_addr ) ; MPASS ( ETHER_IS_MULTICAST ( mcaddr [ i ] ) ) ; i ++ ; if ( i == FW_MAC_EXACT_CHUNK ) { rc = t4_alloc_mac_filt ( sc , sc -> mbox , vi -> viid , del , i , mcaddr , NULL , & hash , 0 ) ; if ( rc < 0 ) { rc = - rc ; for ( j = 0 ; j < i ; j ++ ) { if_printf ( ifp , " " " " " \n " , mcaddr [ j ] [ 0 ] , mcaddr [ j ] [ 1 ] , mcaddr [ j ] [ 2 ] , mcaddr [ j ] [ 3 ] , mcaddr [ j ] [ 4 ] , mcaddr [ j ] [ 5 ] , rc ) ; } goto mcfail ; } del = 0 ; i = 0 ; } } if ( i > 0 ) { rc = t4_alloc_mac_filt ( sc , sc -> mbox , vi -> viid , del , i , mcaddr , NULL , & hash , 0 ) ; if ( rc < 0 ) { rc = - rc ; for ( j = 0 ; j < i ; j ++ ) { if_printf ( ifp , " " " " " \n " , mcaddr [ j ] [ 0 ] , mcaddr [ j ] [ 1 ] , mcaddr [ j ] [ 2 ] , mcaddr [ j ] [ 3 ] , mcaddr [ j ] [ 4 ] , mcaddr [ j ] [ 5 ] , rc ) ; } goto mcfail ; } } rc = - t4_set_addr_hash ( sc , sc -> mbox , vi -> viid , 0 , hash , 0 ) ; if ( rc != 0 ) if_printf ( ifp , " " , rc ) ; mcfail : if_maddr_runlock ( ifp ) ; } return ( rc ) ; }
Program the port's XGMAC based on parameters in ifnet.
Program the port ' s XGMAC based on parameters in ifnet .