Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/oce/oce_hw.c
Show First 20 Lines • Show All 538 Lines • ▼ Show 20 Lines | oce_hw_intr_disable(POCE_SOFTC sc) | ||||
uint32_t reg; | uint32_t reg; | ||||
reg = OCE_READ_REG32(sc, devcfg, PCICFG_INTR_CTRL); | reg = OCE_READ_REG32(sc, devcfg, PCICFG_INTR_CTRL); | ||||
reg &= ~HOSTINTR_MASK; | reg &= ~HOSTINTR_MASK; | ||||
OCE_WRITE_REG32(sc, devcfg, PCICFG_INTR_CTRL, reg); | OCE_WRITE_REG32(sc, devcfg, PCICFG_INTR_CTRL, reg); | ||||
} | } | ||||
static u_int | |||||
oce_copy_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) | |||||
{ | |||||
struct mbx_set_common_iface_multicast *req = arg; | |||||
if (req->params.req.num_mac == OCE_MAX_MC_FILTER_SIZE) | |||||
return (0); | |||||
bcopy(LLADDR(sdl), &req->params.req.mac[req->params.req.num_mac++], | |||||
ETH_ADDR_LEN); | |||||
return (1); | |||||
} | |||||
/** | /** | ||||
* @brief Function for hardware update multicast filter | * @brief Function for hardware update multicast filter | ||||
* @param sc software handle to the device | * @param sc software handle to the device | ||||
*/ | */ | ||||
int | int | ||||
oce_hw_update_multicast(POCE_SOFTC sc) | oce_hw_update_multicast(POCE_SOFTC sc) | ||||
{ | { | ||||
struct ifnet *ifp = sc->ifp; | struct ifnet *ifp = sc->ifp; | ||||
struct ifmultiaddr *ifma; | |||||
struct mbx_set_common_iface_multicast *req = NULL; | struct mbx_set_common_iface_multicast *req = NULL; | ||||
OCE_DMA_MEM dma; | OCE_DMA_MEM dma; | ||||
int rc = 0; | int rc = 0; | ||||
/* Allocate DMA mem*/ | /* Allocate DMA mem*/ | ||||
if (oce_dma_alloc(sc, sizeof(struct mbx_set_common_iface_multicast), | if (oce_dma_alloc(sc, sizeof(struct mbx_set_common_iface_multicast), | ||||
&dma, 0)) | &dma, 0)) | ||||
return ENOMEM; | return ENOMEM; | ||||
req = OCE_DMAPTR(&dma, struct mbx_set_common_iface_multicast); | req = OCE_DMAPTR(&dma, struct mbx_set_common_iface_multicast); | ||||
bzero(req, sizeof(struct mbx_set_common_iface_multicast)); | bzero(req, sizeof(struct mbx_set_common_iface_multicast)); | ||||
#if __FreeBSD_version > 800000 | if_foreach_llmaddr(ifp, oce_copy_maddr, req); | ||||
if_maddr_rlock(ifp); | |||||
#endif | |||||
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { | |||||
if (ifma->ifma_addr->sa_family != AF_LINK) | |||||
continue; | |||||
if (req->params.req.num_mac == OCE_MAX_MC_FILTER_SIZE) { | if (req->params.req.num_mac == OCE_MAX_MC_FILTER_SIZE) { | ||||
/*More multicast addresses than our hardware table | /*More multicast addresses than our hardware table | ||||
So Enable multicast promiscus in our hardware to | So Enable multicast promiscus in our hardware to | ||||
accept all multicat packets | accept all multicat packets | ||||
*/ | */ | ||||
req->params.req.promiscuous = 1; | req->params.req.promiscuous = 1; | ||||
break; | |||||
} | } | ||||
bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), | |||||
&req->params.req.mac[req->params.req.num_mac], | |||||
ETH_ADDR_LEN); | |||||
req->params.req.num_mac = req->params.req.num_mac + 1; | |||||
} | |||||
#if __FreeBSD_version > 800000 | |||||
if_maddr_runlock(ifp); | |||||
#endif | |||||
req->params.req.if_id = sc->if_id; | req->params.req.if_id = sc->if_id; | ||||
rc = oce_update_multicast(sc, &dma); | rc = oce_update_multicast(sc, &dma); | ||||
oce_dma_free(sc, &dma); | oce_dma_free(sc, &dma); | ||||
return rc; | return rc; | ||||
} | } | ||||