Loading drivers/net/ethernet/aquantia/atlantic-fwd/atl_common.h +5 −0 Original line number Diff line number Diff line Loading @@ -384,6 +384,11 @@ int atl_update_eth_stats(struct atl_nic *nic); void atl_adjust_eth_stats(struct atl_ether_stats *stats, struct atl_ether_stats *base, bool add); void atl_fwd_release_rings(struct atl_nic *nic); #ifdef CONFIG_ATLFWD_FWD int atl_fwd_resume_rings(struct atl_nic *nic); #else static inline int atl_fwd_resume_rings(struct atl_nic *nic) { return 0; } #endif int atl_get_lpi_timer(struct atl_nic *nic, uint32_t *lpi_delay); int atl_mdio_hwsem_get(struct atl_hw *hw); void atl_mdio_hwsem_put(struct atl_hw *hw); Loading drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.c +80 −17 Original line number Diff line number Diff line Loading @@ -593,12 +593,47 @@ void atl_fwd_release_event(struct atl_fwd_event *evt) } EXPORT_SYMBOL(atl_fwd_release_event); int atl_fwd_request_event(struct atl_fwd_event *evt) static int atl_fwd_init_event(struct atl_fwd_event *evt) { struct atl_fwd_ring *ring = evt->ring; int dir_tx = atl_fwd_ring_tx(ring); struct atl_nic *nic = ring->nic; struct atl_hw *hw = &nic->hw; bool tx_wb = !!(evt->flags & ATL_FWD_EVT_TXWB); int idx; int ret; if (tx_wb) { struct atl_hw_ring *hwring = &ring->hw; atl_write(hw, ATL_TX_RING_HEAD_WB_LSW(hwring), evt->tx_head_wrb); atl_write(hw, ATL_TX_RING_HEAD_WB_MSW(hwring), upper_32_bits(evt->tx_head_wrb)); return 0; } idx = evt->idx; ret = atl_fwd_set_msix_vec(nic, evt); if (ret) return ret; atl_set_intr_bits(&nic->hw, ring->idx, dir_tx ? -1 : idx, dir_tx ? idx : -1); atl_write_bit(hw, ATL_INTR_AUTO_CLEAR, idx, 1); atl_write_bit(hw, ATL_INTR_AUTO_MASK, idx, !!(evt->flags & ATL_FWD_EVT_AUTOMASK)); return 0; } int atl_fwd_request_event(struct atl_fwd_event *evt) { struct atl_fwd_ring *ring = evt->ring; struct atl_nic *nic = ring->nic; unsigned long *map = &nic->fwd.msi_map; bool tx_wb = !!(evt->flags & ATL_FWD_EVT_TXWB); int idx; Loading Loading @@ -631,13 +666,9 @@ int atl_fwd_request_event(struct atl_fwd_event *evt) ring->evt = evt; if (tx_wb) { struct atl_hw_ring *hwring = &ring->hw; atl_write(hw, ATL_TX_RING_HEAD_WB_LSW(hwring), evt->tx_head_wrb); atl_write(hw, ATL_TX_RING_HEAD_WB_MSW(hwring), upper_32_bits(evt->tx_head_wrb)); return 0; ret = atl_fwd_init_event(evt); if (ret) goto fail; } idx = find_next_zero_bit(map, ATL_NUM_MSI_VECS, ATL_FWD_MSI_BASE); Loading @@ -649,20 +680,12 @@ int atl_fwd_request_event(struct atl_fwd_event *evt) evt->idx = idx; ret = atl_fwd_set_msix_vec(nic, evt); ret = atl_fwd_init_event(evt); if (ret) goto fail; __set_bit(idx, map); atl_set_intr_bits(&nic->hw, ring->idx, dir_tx ? -1 : idx, dir_tx ? idx : -1); atl_write_bit(hw, ATL_INTR_AUTO_CLEAR, idx, 1); atl_write_bit(hw, ATL_INTR_AUTO_MASK, idx, !!(evt->flags & ATL_FWD_EVT_AUTOMASK)); return 0; fail: Loading @@ -681,10 +704,12 @@ int atl_fwd_enable_event(struct atl_fwd_event *evt) return -EINVAL; atl_write_bit(hw, ATL_TX_RING_CTL(&ring->hw), 28, 1); ring->state |= ATL_FWR_ST_EVT_ENABLED; return 0; } atl_intr_enable(hw, BIT(evt->idx)); ring->state |= ATL_FWR_ST_EVT_ENABLED; return 0; } EXPORT_SYMBOL(atl_fwd_enable_event); Loading @@ -699,10 +724,12 @@ int atl_fwd_disable_event(struct atl_fwd_event *evt) return -EINVAL; atl_write_bit(hw, ATL_TX_RING_CTL(&ring->hw), 28, 0); ring->state &= ~ATL_FWR_ST_EVT_ENABLED; return 0; } atl_intr_disable(hw, BIT(evt->idx)); ring->state &= ~ATL_FWR_ST_EVT_ENABLED; return 0; } EXPORT_SYMBOL(atl_fwd_disable_event); Loading @@ -721,3 +748,39 @@ int atl_fwd_transmit_skb(struct net_device *ndev, struct sk_buff *skb) } EXPORT_SYMBOL(atl_fwd_transmit_skb); int atl_fwd_resume_rings(struct atl_nic *nic) { struct atl_fwd_ring **rings = nic->fwd.rings[0]; int i; int ret; for (i = 0; i < ATL_NUM_FWD_RINGS * 2; i++) { struct atl_fwd_ring *ring = rings[i]; if (!ring) continue; atl_fwd_init_ring(ring); if (ring->evt) { ret = atl_fwd_init_event(ring->evt); if (ret) return ret; if (ring->state & ATL_FWR_ST_EVT_ENABLED) { ret = atl_fwd_enable_event(ring->evt); if (ret) return ret; } } if (ring->state & ATL_FWR_ST_ENABLED) { ret = atl_fwd_enable_ring(ring); if (ret) return ret; } } return 0; } drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.h +1 −0 Original line number Diff line number Diff line Loading @@ -364,6 +364,7 @@ int atl_fwd_transmit_skb(struct net_device *ndev, struct sk_buff *skb); enum atl_fwd_ring_state { ATL_FWR_ST_ENABLED = BIT(0), ATL_FWR_ST_EVT_ENABLED = BIT(1), }; #endif drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c +10 −0 Original line number Diff line number Diff line Loading @@ -490,7 +490,10 @@ static int atl_suspend_common(struct device *dev, bool deep) atl_dev_err("Enable WoL failed: %d\n", -ret); } pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); __clear_bit(ATL_ST_ENABLED, &nic->state); rtnl_unlock(); Loading @@ -516,6 +519,9 @@ static int atl_resume_common(struct device *dev, bool deep) rtnl_lock(); pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); ret = pci_enable_device_mem(pdev); if (ret) goto exit; Loading @@ -540,6 +546,10 @@ static int atl_resume_common(struct device *dev, bool deep) if (ret) goto exit; ret = atl_fwd_resume_rings(nic); if (ret) goto exit; netif_device_attach(nic->ndev); exit: Loading drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_gsi.c +8 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,14 @@ int ipa_eth_gsi_dealloc(struct ipa_eth_channel *ch) } if (ep_ctx->gsi_chan_hdl != ~0) { gsi_rc = gsi_reset_channel(ep_ctx->gsi_chan_hdl); if (gsi_rc != GSI_STATUS_SUCCESS) { ipa_eth_dev_err(ch->eth_dev, "Failed to reset channel %u", ep_ctx->gsi_chan_hdl); return gsi_rc; } gsi_rc = gsi_dealloc_channel(ep_ctx->gsi_chan_hdl); if (gsi_rc != GSI_STATUS_SUCCESS) { ipa_eth_dev_err(ch->eth_dev, Loading Loading
drivers/net/ethernet/aquantia/atlantic-fwd/atl_common.h +5 −0 Original line number Diff line number Diff line Loading @@ -384,6 +384,11 @@ int atl_update_eth_stats(struct atl_nic *nic); void atl_adjust_eth_stats(struct atl_ether_stats *stats, struct atl_ether_stats *base, bool add); void atl_fwd_release_rings(struct atl_nic *nic); #ifdef CONFIG_ATLFWD_FWD int atl_fwd_resume_rings(struct atl_nic *nic); #else static inline int atl_fwd_resume_rings(struct atl_nic *nic) { return 0; } #endif int atl_get_lpi_timer(struct atl_nic *nic, uint32_t *lpi_delay); int atl_mdio_hwsem_get(struct atl_hw *hw); void atl_mdio_hwsem_put(struct atl_hw *hw); Loading
drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.c +80 −17 Original line number Diff line number Diff line Loading @@ -593,12 +593,47 @@ void atl_fwd_release_event(struct atl_fwd_event *evt) } EXPORT_SYMBOL(atl_fwd_release_event); int atl_fwd_request_event(struct atl_fwd_event *evt) static int atl_fwd_init_event(struct atl_fwd_event *evt) { struct atl_fwd_ring *ring = evt->ring; int dir_tx = atl_fwd_ring_tx(ring); struct atl_nic *nic = ring->nic; struct atl_hw *hw = &nic->hw; bool tx_wb = !!(evt->flags & ATL_FWD_EVT_TXWB); int idx; int ret; if (tx_wb) { struct atl_hw_ring *hwring = &ring->hw; atl_write(hw, ATL_TX_RING_HEAD_WB_LSW(hwring), evt->tx_head_wrb); atl_write(hw, ATL_TX_RING_HEAD_WB_MSW(hwring), upper_32_bits(evt->tx_head_wrb)); return 0; } idx = evt->idx; ret = atl_fwd_set_msix_vec(nic, evt); if (ret) return ret; atl_set_intr_bits(&nic->hw, ring->idx, dir_tx ? -1 : idx, dir_tx ? idx : -1); atl_write_bit(hw, ATL_INTR_AUTO_CLEAR, idx, 1); atl_write_bit(hw, ATL_INTR_AUTO_MASK, idx, !!(evt->flags & ATL_FWD_EVT_AUTOMASK)); return 0; } int atl_fwd_request_event(struct atl_fwd_event *evt) { struct atl_fwd_ring *ring = evt->ring; struct atl_nic *nic = ring->nic; unsigned long *map = &nic->fwd.msi_map; bool tx_wb = !!(evt->flags & ATL_FWD_EVT_TXWB); int idx; Loading Loading @@ -631,13 +666,9 @@ int atl_fwd_request_event(struct atl_fwd_event *evt) ring->evt = evt; if (tx_wb) { struct atl_hw_ring *hwring = &ring->hw; atl_write(hw, ATL_TX_RING_HEAD_WB_LSW(hwring), evt->tx_head_wrb); atl_write(hw, ATL_TX_RING_HEAD_WB_MSW(hwring), upper_32_bits(evt->tx_head_wrb)); return 0; ret = atl_fwd_init_event(evt); if (ret) goto fail; } idx = find_next_zero_bit(map, ATL_NUM_MSI_VECS, ATL_FWD_MSI_BASE); Loading @@ -649,20 +680,12 @@ int atl_fwd_request_event(struct atl_fwd_event *evt) evt->idx = idx; ret = atl_fwd_set_msix_vec(nic, evt); ret = atl_fwd_init_event(evt); if (ret) goto fail; __set_bit(idx, map); atl_set_intr_bits(&nic->hw, ring->idx, dir_tx ? -1 : idx, dir_tx ? idx : -1); atl_write_bit(hw, ATL_INTR_AUTO_CLEAR, idx, 1); atl_write_bit(hw, ATL_INTR_AUTO_MASK, idx, !!(evt->flags & ATL_FWD_EVT_AUTOMASK)); return 0; fail: Loading @@ -681,10 +704,12 @@ int atl_fwd_enable_event(struct atl_fwd_event *evt) return -EINVAL; atl_write_bit(hw, ATL_TX_RING_CTL(&ring->hw), 28, 1); ring->state |= ATL_FWR_ST_EVT_ENABLED; return 0; } atl_intr_enable(hw, BIT(evt->idx)); ring->state |= ATL_FWR_ST_EVT_ENABLED; return 0; } EXPORT_SYMBOL(atl_fwd_enable_event); Loading @@ -699,10 +724,12 @@ int atl_fwd_disable_event(struct atl_fwd_event *evt) return -EINVAL; atl_write_bit(hw, ATL_TX_RING_CTL(&ring->hw), 28, 0); ring->state &= ~ATL_FWR_ST_EVT_ENABLED; return 0; } atl_intr_disable(hw, BIT(evt->idx)); ring->state &= ~ATL_FWR_ST_EVT_ENABLED; return 0; } EXPORT_SYMBOL(atl_fwd_disable_event); Loading @@ -721,3 +748,39 @@ int atl_fwd_transmit_skb(struct net_device *ndev, struct sk_buff *skb) } EXPORT_SYMBOL(atl_fwd_transmit_skb); int atl_fwd_resume_rings(struct atl_nic *nic) { struct atl_fwd_ring **rings = nic->fwd.rings[0]; int i; int ret; for (i = 0; i < ATL_NUM_FWD_RINGS * 2; i++) { struct atl_fwd_ring *ring = rings[i]; if (!ring) continue; atl_fwd_init_ring(ring); if (ring->evt) { ret = atl_fwd_init_event(ring->evt); if (ret) return ret; if (ring->state & ATL_FWR_ST_EVT_ENABLED) { ret = atl_fwd_enable_event(ring->evt); if (ret) return ret; } } if (ring->state & ATL_FWR_ST_ENABLED) { ret = atl_fwd_enable_ring(ring); if (ret) return ret; } } return 0; }
drivers/net/ethernet/aquantia/atlantic-fwd/atl_fwd.h +1 −0 Original line number Diff line number Diff line Loading @@ -364,6 +364,7 @@ int atl_fwd_transmit_skb(struct net_device *ndev, struct sk_buff *skb); enum atl_fwd_ring_state { ATL_FWR_ST_ENABLED = BIT(0), ATL_FWR_ST_EVT_ENABLED = BIT(1), }; #endif
drivers/net/ethernet/aquantia/atlantic-fwd/atl_main.c +10 −0 Original line number Diff line number Diff line Loading @@ -490,7 +490,10 @@ static int atl_suspend_common(struct device *dev, bool deep) atl_dev_err("Enable WoL failed: %d\n", -ret); } pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); __clear_bit(ATL_ST_ENABLED, &nic->state); rtnl_unlock(); Loading @@ -516,6 +519,9 @@ static int atl_resume_common(struct device *dev, bool deep) rtnl_lock(); pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); ret = pci_enable_device_mem(pdev); if (ret) goto exit; Loading @@ -540,6 +546,10 @@ static int atl_resume_common(struct device *dev, bool deep) if (ret) goto exit; ret = atl_fwd_resume_rings(nic); if (ret) goto exit; netif_device_attach(nic->ndev); exit: Loading
drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_gsi.c +8 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,14 @@ int ipa_eth_gsi_dealloc(struct ipa_eth_channel *ch) } if (ep_ctx->gsi_chan_hdl != ~0) { gsi_rc = gsi_reset_channel(ep_ctx->gsi_chan_hdl); if (gsi_rc != GSI_STATUS_SUCCESS) { ipa_eth_dev_err(ch->eth_dev, "Failed to reset channel %u", ep_ctx->gsi_chan_hdl); return gsi_rc; } gsi_rc = gsi_dealloc_channel(ep_ctx->gsi_chan_hdl); if (gsi_rc != GSI_STATUS_SUCCESS) { ipa_eth_dev_err(ch->eth_dev, Loading