Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/cxgbe/t4_main.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 4,778 Lines • ▼ Show 20 Lines | if (rc != 0) { | ||||
*/ | */ | ||||
if (lc->link_ok && !(lc->requested_fc & PAUSE_AUTONEG)) | if (lc->link_ok && !(lc->requested_fc & PAUSE_AUTONEG)) | ||||
lc->fc = lc->requested_fc & (PAUSE_TX | PAUSE_RX); | lc->fc = lc->requested_fc & (PAUSE_TX | PAUSE_RX); | ||||
} | } | ||||
return (rc); | return (rc); | ||||
} | } | ||||
#define FW_MAC_EXACT_CHUNK 7 | #define FW_MAC_EXACT_CHUNK 7 | ||||
struct mcaddr_ctx { | |||||
struct ifnet *ifp; | |||||
const uint8_t *mcaddr[FW_MAC_EXACT_CHUNK]; | |||||
uint64_t hash; | |||||
int i; | |||||
int del; | |||||
int rc; | |||||
}; | |||||
static u_int | |||||
add_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) | |||||
{ | |||||
struct mcaddr_ctx *ctx = arg; | |||||
struct vi_info *vi = ctx->ifp->if_softc; | |||||
struct port_info *pi = vi->pi; | |||||
struct adapter *sc = pi->adapter; | |||||
if (ctx->rc < 0) | |||||
return (0); | |||||
ctx->mcaddr[ctx->i] = LLADDR(sdl); | |||||
MPASS(ETHER_IS_MULTICAST(ctx->mcaddr[ctx->i])); | |||||
ctx->i++; | |||||
if (ctx->i == FW_MAC_EXACT_CHUNK) { | |||||
ctx->rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, ctx->del, | |||||
ctx->i, ctx->mcaddr, NULL, &ctx->hash, 0); | |||||
if (ctx->rc < 0) { | |||||
int j; | |||||
for (j = 0; j < ctx->i; j++) { | |||||
if_printf(ctx->ifp, | |||||
"failed to add mc address" | |||||
" %02x:%02x:%02x:" | |||||
"%02x:%02x:%02x rc=%d\n", | |||||
ctx->mcaddr[j][0], ctx->mcaddr[j][1], | |||||
ctx->mcaddr[j][2], ctx->mcaddr[j][3], | |||||
ctx->mcaddr[j][4], ctx->mcaddr[j][5], | |||||
-ctx->rc); | |||||
} | |||||
return (0); | |||||
} | |||||
ctx->del = 0; | |||||
ctx->i = 0; | |||||
} | |||||
return (1); | |||||
} | |||||
/* | /* | ||||
* Program the port's XGMAC based on parameters in ifnet. The caller also | * Program the port's XGMAC based on parameters in ifnet. The caller also | ||||
* indicates which parameters should be programmed (the rest are left alone). | * indicates which parameters should be programmed (the rest are left alone). | ||||
*/ | */ | ||||
int | int | ||||
update_mac_settings(struct ifnet *ifp, int flags) | update_mac_settings(struct ifnet *ifp, int flags) | ||||
{ | { | ||||
int rc = 0; | int rc = 0; | ||||
Show All 39 Lines | if (rc < 0) { | ||||
return (rc); | return (rc); | ||||
} else { | } else { | ||||
vi->xact_addr_filt = rc; | vi->xact_addr_filt = rc; | ||||
rc = 0; | rc = 0; | ||||
} | } | ||||
} | } | ||||
if (flags & XGMAC_MCADDRS) { | if (flags & XGMAC_MCADDRS) { | ||||
const uint8_t *mcaddr[FW_MAC_EXACT_CHUNK]; | struct epoch_tracker et; | ||||
int del = 1; | struct mcaddr_ctx ctx; | ||||
uint64_t hash = 0; | int j; | ||||
struct ifmultiaddr *ifma; | |||||
int i = 0, j; | |||||
if_maddr_rlock(ifp); | ctx.ifp = ifp; | ||||
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { | ctx.hash = 0; | ||||
if (ifma->ifma_addr->sa_family != AF_LINK) | ctx.i = 0; | ||||
continue; | ctx.del = 1; | ||||
mcaddr[i] = | /* | ||||
LLADDR((struct sockaddr_dl *)ifma->ifma_addr); | * Unlike other drivers, we accumulate list of pointers into | ||||
MPASS(ETHER_IS_MULTICAST(mcaddr[i])); | * interface address lists and we need to keep it safe even | ||||
i++; | * after if_foreach_llmaddr() returns, thus we must enter the | ||||
* network epoch. | |||||
if (i == FW_MAC_EXACT_CHUNK) { | */ | ||||
NET_EPOCH_ENTER(et); | |||||
if_foreach_llmaddr(ifp, add_maddr, &ctx); | |||||
if (ctx.rc < 0) { | |||||
NET_EPOCH_EXIT(et); | |||||
rc = -ctx.rc; | |||||
return (rc); | |||||
} | |||||
if (ctx.i > 0) { | |||||
rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, | rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, | ||||
del, i, mcaddr, NULL, &hash, 0); | ctx.del, ctx.i, ctx.mcaddr, NULL, &ctx.hash, 0); | ||||
NET_EPOCH_EXIT(et); | |||||
if (rc < 0) { | if (rc < 0) { | ||||
rc = -rc; | rc = -rc; | ||||
for (j = 0; j < i; j++) { | for (j = 0; j < ctx.i; j++) { | ||||
if_printf(ifp, | if_printf(ifp, | ||||
"failed to add mc address" | "failed to add mc address" | ||||
" %02x:%02x:%02x:" | " %02x:%02x:%02x:" | ||||
"%02x:%02x:%02x rc=%d\n", | "%02x:%02x:%02x rc=%d\n", | ||||
mcaddr[j][0], mcaddr[j][1], | ctx.mcaddr[j][0], ctx.mcaddr[j][1], | ||||
mcaddr[j][2], mcaddr[j][3], | ctx.mcaddr[j][2], ctx.mcaddr[j][3], | ||||
mcaddr[j][4], mcaddr[j][5], | ctx.mcaddr[j][4], ctx.mcaddr[j][5], | ||||
rc); | rc); | ||||
} | } | ||||
goto mcfail; | return (rc); | ||||
} | } | ||||
del = 0; | } else | ||||
i = 0; | NET_EPOCH_EXIT(et); | ||||
} | |||||
} | |||||
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); | rc = -t4_set_addr_hash(sc, sc->mbox, vi->viid, 0, ctx.hash, 0); | ||||
if (rc != 0) | if (rc != 0) | ||||
if_printf(ifp, "failed to set mc address hash: %d", rc); | if_printf(ifp, "failed to set mc address hash: %d", rc); | ||||
mcfail: | |||||
if_maddr_runlock(ifp); | |||||
} | } | ||||
return (rc); | return (rc); | ||||
} | } | ||||
/* | /* | ||||
* {begin|end}_synchronized_op must be called from the same thread. | * {begin|end}_synchronized_op must be called from the same thread. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 5,961 Lines • Show Last 20 Lines |