static int bgmac_poll(struct napi_struct *napi, int weight) { struct bgmac *bgmac = container_of(napi, struct bgmac, napi); struct bgmac_dma_ring *ring; int handled = 0; if (bgmac->int_status & BGMAC_IS_TX0) { ring = &bgmac->tx_ring[0]; bgmac_dma_tx_free(bgmac, ring); bgmac->int_status &= ~BGMAC_IS_TX0; } if (bgmac->int_status & BGMAC_IS_RX) { ring = &bgmac->rx_ring[0]; handled += bgmac_dma_rx_read(bgmac, ring, weight); bgmac->int_status &= ~BGMAC_IS_RX; } if (bgmac->int_status) { bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status); bgmac->int_status = 0; } if (handled < weight) napi_complete(napi); bgmac_chip_intrs_on(bgmac); return handled; }
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ static void bgmac_chip_init(struct bgmac *bgmac) { /* Clear any erroneously pending interrupts */ bgmac_write(bgmac, BGMAC_INT_STATUS, ~0); /* 1 interrupt per received frame */ bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); /* Enable 802.3x tx flow control (honor received PAUSE frames) */ bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true); bgmac_set_rx_mode(bgmac->net_dev); bgmac_write_mac_address(bgmac, bgmac->net_dev->dev_addr); if (bgmac->loopback) bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false); else bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_ML, 0, false); bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN); bgmac_chip_intrs_on(bgmac); bgmac_enable(bgmac); }
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ static void bgmac_chip_init(struct bgmac *bgmac, bool full_init) { struct bgmac_dma_ring *ring; int i; /* 1 interrupt per received frame */ bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); /* Enable 802.3x tx flow control (honor received PAUSE frames) */ bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true); bgmac_set_rx_mode(bgmac->net_dev); bgmac_write_mac_address(bgmac, bgmac->net_dev->dev_addr); if (bgmac->loopback) bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false); else bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_ML, 0, false); bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN); if (full_init) { bgmac_dma_init(bgmac); if (1) /* FIXME: is there any case we don't want IRQs? */ bgmac_chip_intrs_on(bgmac); } else { for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) { ring = &bgmac->rx_ring[i]; bgmac_dma_rx_enable(bgmac, ring); } } bgmac_enable(bgmac); }
static int bgmac_poll(struct napi_struct *napi, int weight) { struct bgmac *bgmac = container_of(napi, struct bgmac, napi); int handled = 0; /* Ack */ bgmac_write(bgmac, BGMAC_INT_STATUS, ~0); bgmac_dma_tx_free(bgmac, &bgmac->tx_ring[0]); handled += bgmac_dma_rx_read(bgmac, &bgmac->rx_ring[0], weight); /* Poll again if more events arrived in the meantime */ if (bgmac_read(bgmac, BGMAC_INT_STATUS) & (BGMAC_IS_TX0 | BGMAC_IS_RX)) return weight; if (handled < weight) { napi_complete(napi); bgmac_chip_intrs_on(bgmac); } return handled; }