Loading arch/arm/configs/vendor/sdxprairie-perf_defconfig +0 −2 Original line number Original line Diff line number Diff line Loading @@ -352,8 +352,6 @@ CONFIG_MSM_MHI_DEV=y CONFIG_IPA3=y CONFIG_IPA3=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_ETH=y CONFIG_IPA_ETH=y CONFIG_AQC_IPA=y CONFIG_AQC_IPA_PROXY_UC=y CONFIG_RMNET_IPA3=y CONFIG_RMNET_IPA3=y CONFIG_ECM_IPA=y CONFIG_ECM_IPA=y CONFIG_RNDIS_IPA=y CONFIG_RNDIS_IPA=y Loading arch/arm/configs/vendor/sdxprairie_defconfig +0 −3 Original line number Original line Diff line number Diff line Loading @@ -356,9 +356,6 @@ CONFIG_IPA_DEBUG=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_ETH=y CONFIG_IPA_ETH=y CONFIG_IPA_ETH_DEBUG=y CONFIG_IPA_ETH_DEBUG=y CONFIG_AQC_IPA=y CONFIG_AQC_IPA_PROXY_UC=y CONFIG_AQC_IPA_DEBUG=y CONFIG_RMNET_IPA3=y CONFIG_RMNET_IPA3=y CONFIG_ECM_IPA=y CONFIG_ECM_IPA=y CONFIG_RNDIS_IPA=y CONFIG_RNDIS_IPA=y Loading drivers/net/ethernet/aquantia/atlantic-fwd/atl_qcom_ipa.c +174 −47 Original line number Original line Diff line number Diff line Loading @@ -14,28 +14,99 @@ #include <linux/gfp.h> #include <linux/gfp.h> #include <linux/slab.h> #include <linux/slab.h> #define IPA_ETH_NET_DRIVER #include <linux/ipa_eth.h> #include <linux/ipa_eth.h> #include "atl_fwd.h" #include "atl_fwd.h" #include "atl_qcom_ipa.h" #include "atl_qcom_ipa.h" #define ATL_IPA_DEFAULT_RING_SZ 128 #define ATL_IPA_DEFAULT_BUFF_SZ 2048 static inline struct atl_fwd_ring *CH_RING(struct ipa_eth_channel *ch) static inline struct atl_fwd_ring *CH_RING(struct ipa_eth_channel *ch) { { return (struct atl_fwd_ring *)(ch->nd_priv); return (struct atl_fwd_ring *)(ch->nd_priv); } } static void *atl_ipa_dma_alloc(struct device *dev, size_t size, dma_addr_t *daddr, gfp_t gfp, struct ipa_eth_dma_allocator *dma_allocator) { struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(dev); struct ipa_eth_device *eth_dev = nic->fwd.private; struct ipa_eth_resource mem; if (dma_allocator->alloc(eth_dev, size, gfp, &mem)) return NULL; if (daddr) *daddr = mem.daddr; return mem.vaddr; } static void atl_ipa_dma_free(void *buf, struct device *dev, size_t size, dma_addr_t daddr, struct ipa_eth_dma_allocator *dma_allocator) { struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(dev); struct ipa_eth_device *eth_dev = nic->fwd.private; struct ipa_eth_resource mem = { .size = size, .vaddr = buf, .daddr = daddr, }; return dma_allocator->free(eth_dev, &mem); } static void *atl_ipa_alloc_descs(struct device *dev, size_t size, dma_addr_t *daddr, gfp_t gfp, struct atl_fwd_mem_ops *ops) { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_alloc(dev, size, daddr, gfp, ch->mem_params.desc.allocator); } static void *atl_ipa_alloc_buf(struct device *dev, size_t size, dma_addr_t *daddr, gfp_t gfp, struct atl_fwd_mem_ops *ops) { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_alloc(dev, size, daddr, gfp, ch->mem_params.buff.allocator); } static void atl_ipa_free_descs(void *buf, struct device *dev, size_t size, dma_addr_t daddr, struct atl_fwd_mem_ops *ops) { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_free(buf, dev, size, daddr, ch->mem_params.desc.allocator); } static void atl_ipa_free_buf(void *buf, struct device *dev, size_t size, dma_addr_t daddr, struct atl_fwd_mem_ops *ops) { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_free(buf, dev, size, daddr, ch->mem_params.desc.allocator); } static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) { { struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(eth_dev->dev); struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(eth_dev->dev); if (!nic || !nic->ndev) { if (!nic || !nic->ndev) { dev_err(eth_dev->dev, "Invalid atl_nic"); dev_err(eth_dev->dev, "Invalid atl_nic\n"); return -ENODEV; return -ENODEV; } } nic->fwd.private = eth_dev; /* atl specific init, ref counting go here */ /* atl specific init, ref counting go here */ eth_dev->nd_priv = nic; eth_dev->nd_priv = nic; Loading @@ -46,17 +117,48 @@ static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) static void atl_ipa_close_device(struct ipa_eth_device *eth_dev) static void atl_ipa_close_device(struct ipa_eth_device *eth_dev) { { struct atl_nic *nic = eth_dev->nd_priv; nic->fwd.private = NULL; eth_dev->nd_priv = NULL; eth_dev->nd_priv = NULL; eth_dev->net_dev = NULL; eth_dev->net_dev = NULL; } } static struct ipa_eth_channel *atl_ipa_request_channel( static struct ipa_eth_channel *atl_ipa_request_channel( struct ipa_eth_device *eth_dev, enum ipa_eth_channel_dir dir, struct ipa_eth_device *eth_dev, enum ipa_eth_channel_dir dir, unsigned long features, unsigned long events) unsigned long events, unsigned long features, const struct ipa_eth_channel_mem_params *mem_params) { { struct atl_fwd_ring *ring = NULL; struct atl_fwd_ring *ring = NULL; enum atl_fwd_ring_flags ring_flags = 0; enum atl_fwd_ring_flags ring_flags = 0; struct ipa_eth_channel *channel = NULL; struct ipa_eth_channel *channel = NULL; struct atl_fwd_mem_ops *mem_ops = NULL; struct ipa_eth_channel_mem *desc_mem = NULL; struct ipa_eth_channel_mem *buff_mem = NULL; size_t desc_count; size_t buff_size; channel = ipa_eth_net_alloc_channel(eth_dev, dir, events, features, mem_params); if (!channel) { dev_err(eth_dev->dev, "Failed to alloc ipa eth channel\n"); goto err_channel; } desc_count = channel->mem_params.desc.count; buff_size = channel->mem_params.buff.size; mem_ops = kzalloc(sizeof(*mem_ops), GFP_KERNEL); if (!mem_ops) goto err_mem_ops; mem_ops->alloc_descs = atl_ipa_alloc_descs; mem_ops->alloc_buf = atl_ipa_alloc_buf; mem_ops->free_descs = atl_ipa_free_descs; mem_ops->free_buf = atl_ipa_free_buf; mem_ops->private = channel; switch (dir) { switch (dir) { case IPA_ETH_DIR_RX: case IPA_ETH_DIR_RX: Loading @@ -65,67 +167,92 @@ static struct ipa_eth_channel *atl_ipa_request_channel( ring_flags |= ATL_FWR_TX; ring_flags |= ATL_FWR_TX; break; break; default: default: dev_err(eth_dev->dev, "Unsupported direction %d", dir); dev_err(eth_dev->dev, "Unsupported direction %d\n", dir); return NULL; goto err_dir; } } ring_flags |= ATL_FWR_ALLOC_BUFS; ring_flags |= ATL_FWR_ALLOC_BUFS; ring_flags |= ATL_FWR_CONTIG_BUFS; ring_flags |= ATL_FWR_CONTIG_BUFS; ring = atl_fwd_request_ring(eth_dev->net_dev, ring_flags, ring = atl_fwd_request_ring(eth_dev->net_dev, ring_flags, ATL_IPA_DEFAULT_RING_SZ, desc_count, buff_size, 1, mem_ops); ATL_IPA_DEFAULT_BUFF_SZ, 1, NULL); if (IS_ERR_OR_NULL(ring)) { if (IS_ERR_OR_NULL(ring)) { dev_err(eth_dev->dev, "Request ring failed"); dev_err(eth_dev->dev, "Request ring failed\n"); goto err_exit; goto err_ring; } } channel = kzalloc(sizeof(*channel), GFP_KERNEL); channel->nd_priv = ring; if (!channel) goto err_exit; channel->events = 0; channel->features = 0; channel->direction = dir; channel->queue = ring->idx; channel->queue = ring->idx; channel->desc_size = 16; desc_mem = kzalloc(sizeof(*desc_mem), GFP_KERNEL); channel->desc_count = ring->hw.size; if (!desc_mem) channel->desc_mem.size = channel->desc_size * channel->desc_count; goto err_desc_mem; channel->desc_mem.vaddr = ring->hw.descs; channel->mem_params.desc.size = 16; channel->desc_mem.daddr = ring->hw.daddr; channel->mem_params.desc.count = ring->hw.size; channel->desc_mem.paddr = page_to_phys(vmalloc_to_page(channel->desc_mem.vaddr)); channel->buff_size = ATL_IPA_DEFAULT_BUFF_SZ; desc_mem->mem.size = channel->buff_count = channel->desc_count; channel->mem_params.desc.size * channel->mem_params.desc.count; channel->buff_mem.size = channel->buff_size * channel->buff_count; desc_mem->mem.vaddr = ring->hw.descs; desc_mem->mem.daddr = ring->hw.daddr; desc_mem->mem.paddr = channel->mem_params.desc.allocator->paddr( eth_dev, desc_mem->mem.vaddr); channel->buff_mem.vaddr = (void *)ring->bufs->vaddr_vec; buff_mem = kzalloc(sizeof(*buff_mem), GFP_KERNEL); channel->buff_mem.daddr = ring->bufs->daddr_vec_base; if (!buff_mem) channel->buff_mem.paddr = virt_to_phys((void *)ring->bufs->vaddr_vec); goto err_buff_mem; channel->eth_dev = eth_dev; channel->mem_params.buff.size = buff_size; channel->nd_priv = ring; channel->mem_params.buff.count = channel->mem_params.desc.count; return channel; buff_mem->mem.size = channel->mem_params.buff.size * channel->mem_params.buff.count; buff_mem->mem.vaddr = (void *)ring->bufs->vaddr_vec; buff_mem->mem.daddr = ring->bufs->daddr_vec_base; buff_mem->mem.paddr = channel->mem_params.buff.allocator->paddr( eth_dev, buff_mem->mem.vaddr); err_exit: list_add(&desc_mem->mem_list_entry, &channel->desc_mem); kzfree(channel); list_add(&buff_mem->mem_list_entry, &channel->buff_mem); if (!IS_ERR_OR_NULL(ring)) { return channel; atl_fwd_release_ring(ring); ring = NULL; } err_buff_mem: kzfree(desc_mem); err_desc_mem: atl_fwd_release_ring(ring); err_ring: err_dir: if (mem_ops) kzfree(mem_ops); err_mem_ops: ipa_eth_net_free_channel(channel); err_channel: return NULL; return NULL; } } static void atl_ipa_release_channel(struct ipa_eth_channel *ch) static void atl_ipa_release_channel(struct ipa_eth_channel *ch) { { atl_fwd_release_ring(CH_RING(ch)); struct ipa_eth_channel_mem *mem, *tmp; kzfree(ch); struct atl_fwd_ring *ring = CH_RING(ch); struct atl_fwd_mem_ops *mem_ops = ring->mem_ops; atl_fwd_release_ring(ring); if (mem_ops) kzfree(mem_ops); list_for_each_entry_safe(mem, tmp, &ch->desc_mem, mem_list_entry) { list_del(&mem->mem_list_entry); kzfree(mem); } list_for_each_entry_safe(mem, tmp, &ch->buff_mem, mem_list_entry) { list_del(&mem->mem_list_entry); kzfree(mem); } ipa_eth_net_free_channel(ch); } } static int atl_ipa_enable_channel(struct ipa_eth_channel *ch) static int atl_ipa_enable_channel(struct ipa_eth_channel *ch) Loading Loading @@ -153,7 +280,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, case IPA_ETH_DEV_EV_RX_INT: case IPA_ETH_DEV_EV_RX_INT: if (ch->direction != IPA_ETH_DIR_RX) { if (ch->direction != IPA_ETH_DIR_RX) { dev_err(eth_dev->dev, dev_err(eth_dev->dev, "Rx interrupt requested on incorrect channel"); "Rx interrupt requested on tx channel\n"); return -EFAULT; return -EFAULT; } } Loading @@ -166,7 +293,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, case IPA_ETH_DEV_EV_TX_INT: case IPA_ETH_DEV_EV_TX_INT: if (ch->direction != IPA_ETH_DIR_TX) { if (ch->direction != IPA_ETH_DIR_TX) { dev_err(eth_dev->dev, dev_err(eth_dev->dev, "Tx interrupt requested on incorrect channel"); "Tx interrupt requested on rx channel\n"); return -EFAULT; return -EFAULT; } } Loading @@ -179,7 +306,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, case IPA_ETH_DEV_EV_TX_PTR: case IPA_ETH_DEV_EV_TX_PTR: if (ch->direction != IPA_ETH_DIR_TX) { if (ch->direction != IPA_ETH_DIR_TX) { dev_err(eth_dev->dev, dev_err(eth_dev->dev, "Tx ptr wrb requested on incorrect channel"); "Tx ptr wrb requested on rx channel\n"); return -EFAULT; return -EFAULT; } } Loading @@ -190,7 +317,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, break; break; default: default: dev_err(eth_dev->dev, "Unsupported event requested"); dev_err(eth_dev->dev, "Unsupported event requested\n"); return -ENODEV; return -ENODEV; } } Loading Loading @@ -226,7 +353,7 @@ static void atl_ipa_release_event(struct ipa_eth_channel *ch, break; break; default: default: dev_err(eth_dev->dev, "Unsupported event for release"); dev_err(eth_dev->dev, "Unsupported event for release\n"); return; return; } } Loading drivers/platform/msm/ipa/ipa_v3/ethernet/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -6,6 +6,7 @@ ipa-eth-y := \ ipa_eth.o \ ipa_eth.o \ ipa_eth_ep.o \ ipa_eth_ep.o \ ipa_eth_gsi.o \ ipa_eth_gsi.o \ ipa_eth_net.o \ ipa_eth_offload.o \ ipa_eth_offload.o \ ipa_eth_pci.o \ ipa_eth_pci.o \ ipa_eth_pm.o \ ipa_eth_pm.o \ Loading drivers/platform/msm/ipa/ipa_v3/ethernet/aquantia/Kconfig +1 −0 Original line number Original line Diff line number Diff line Loading @@ -11,6 +11,7 @@ config AQC_IPA choice choice prompt "Default Rx Interrupt Proxy Method" prompt "Default Rx Interrupt Proxy Method" depends on AQC_IPA default AQC_IPA_PROXY_HOST default AQC_IPA_PROXY_HOST config AQC_IPA_PROXY_UC config AQC_IPA_PROXY_UC Loading Loading
arch/arm/configs/vendor/sdxprairie-perf_defconfig +0 −2 Original line number Original line Diff line number Diff line Loading @@ -352,8 +352,6 @@ CONFIG_MSM_MHI_DEV=y CONFIG_IPA3=y CONFIG_IPA3=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_ETH=y CONFIG_IPA_ETH=y CONFIG_AQC_IPA=y CONFIG_AQC_IPA_PROXY_UC=y CONFIG_RMNET_IPA3=y CONFIG_RMNET_IPA3=y CONFIG_ECM_IPA=y CONFIG_ECM_IPA=y CONFIG_RNDIS_IPA=y CONFIG_RNDIS_IPA=y Loading
arch/arm/configs/vendor/sdxprairie_defconfig +0 −3 Original line number Original line Diff line number Diff line Loading @@ -356,9 +356,6 @@ CONFIG_IPA_DEBUG=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_WDI_UNIFIED_API=y CONFIG_IPA_ETH=y CONFIG_IPA_ETH=y CONFIG_IPA_ETH_DEBUG=y CONFIG_IPA_ETH_DEBUG=y CONFIG_AQC_IPA=y CONFIG_AQC_IPA_PROXY_UC=y CONFIG_AQC_IPA_DEBUG=y CONFIG_RMNET_IPA3=y CONFIG_RMNET_IPA3=y CONFIG_ECM_IPA=y CONFIG_ECM_IPA=y CONFIG_RNDIS_IPA=y CONFIG_RNDIS_IPA=y Loading
drivers/net/ethernet/aquantia/atlantic-fwd/atl_qcom_ipa.c +174 −47 Original line number Original line Diff line number Diff line Loading @@ -14,28 +14,99 @@ #include <linux/gfp.h> #include <linux/gfp.h> #include <linux/slab.h> #include <linux/slab.h> #define IPA_ETH_NET_DRIVER #include <linux/ipa_eth.h> #include <linux/ipa_eth.h> #include "atl_fwd.h" #include "atl_fwd.h" #include "atl_qcom_ipa.h" #include "atl_qcom_ipa.h" #define ATL_IPA_DEFAULT_RING_SZ 128 #define ATL_IPA_DEFAULT_BUFF_SZ 2048 static inline struct atl_fwd_ring *CH_RING(struct ipa_eth_channel *ch) static inline struct atl_fwd_ring *CH_RING(struct ipa_eth_channel *ch) { { return (struct atl_fwd_ring *)(ch->nd_priv); return (struct atl_fwd_ring *)(ch->nd_priv); } } static void *atl_ipa_dma_alloc(struct device *dev, size_t size, dma_addr_t *daddr, gfp_t gfp, struct ipa_eth_dma_allocator *dma_allocator) { struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(dev); struct ipa_eth_device *eth_dev = nic->fwd.private; struct ipa_eth_resource mem; if (dma_allocator->alloc(eth_dev, size, gfp, &mem)) return NULL; if (daddr) *daddr = mem.daddr; return mem.vaddr; } static void atl_ipa_dma_free(void *buf, struct device *dev, size_t size, dma_addr_t daddr, struct ipa_eth_dma_allocator *dma_allocator) { struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(dev); struct ipa_eth_device *eth_dev = nic->fwd.private; struct ipa_eth_resource mem = { .size = size, .vaddr = buf, .daddr = daddr, }; return dma_allocator->free(eth_dev, &mem); } static void *atl_ipa_alloc_descs(struct device *dev, size_t size, dma_addr_t *daddr, gfp_t gfp, struct atl_fwd_mem_ops *ops) { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_alloc(dev, size, daddr, gfp, ch->mem_params.desc.allocator); } static void *atl_ipa_alloc_buf(struct device *dev, size_t size, dma_addr_t *daddr, gfp_t gfp, struct atl_fwd_mem_ops *ops) { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_alloc(dev, size, daddr, gfp, ch->mem_params.buff.allocator); } static void atl_ipa_free_descs(void *buf, struct device *dev, size_t size, dma_addr_t daddr, struct atl_fwd_mem_ops *ops) { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_free(buf, dev, size, daddr, ch->mem_params.desc.allocator); } static void atl_ipa_free_buf(void *buf, struct device *dev, size_t size, dma_addr_t daddr, struct atl_fwd_mem_ops *ops) { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_free(buf, dev, size, daddr, ch->mem_params.desc.allocator); } static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) { { struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(eth_dev->dev); struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(eth_dev->dev); if (!nic || !nic->ndev) { if (!nic || !nic->ndev) { dev_err(eth_dev->dev, "Invalid atl_nic"); dev_err(eth_dev->dev, "Invalid atl_nic\n"); return -ENODEV; return -ENODEV; } } nic->fwd.private = eth_dev; /* atl specific init, ref counting go here */ /* atl specific init, ref counting go here */ eth_dev->nd_priv = nic; eth_dev->nd_priv = nic; Loading @@ -46,17 +117,48 @@ static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) static void atl_ipa_close_device(struct ipa_eth_device *eth_dev) static void atl_ipa_close_device(struct ipa_eth_device *eth_dev) { { struct atl_nic *nic = eth_dev->nd_priv; nic->fwd.private = NULL; eth_dev->nd_priv = NULL; eth_dev->nd_priv = NULL; eth_dev->net_dev = NULL; eth_dev->net_dev = NULL; } } static struct ipa_eth_channel *atl_ipa_request_channel( static struct ipa_eth_channel *atl_ipa_request_channel( struct ipa_eth_device *eth_dev, enum ipa_eth_channel_dir dir, struct ipa_eth_device *eth_dev, enum ipa_eth_channel_dir dir, unsigned long features, unsigned long events) unsigned long events, unsigned long features, const struct ipa_eth_channel_mem_params *mem_params) { { struct atl_fwd_ring *ring = NULL; struct atl_fwd_ring *ring = NULL; enum atl_fwd_ring_flags ring_flags = 0; enum atl_fwd_ring_flags ring_flags = 0; struct ipa_eth_channel *channel = NULL; struct ipa_eth_channel *channel = NULL; struct atl_fwd_mem_ops *mem_ops = NULL; struct ipa_eth_channel_mem *desc_mem = NULL; struct ipa_eth_channel_mem *buff_mem = NULL; size_t desc_count; size_t buff_size; channel = ipa_eth_net_alloc_channel(eth_dev, dir, events, features, mem_params); if (!channel) { dev_err(eth_dev->dev, "Failed to alloc ipa eth channel\n"); goto err_channel; } desc_count = channel->mem_params.desc.count; buff_size = channel->mem_params.buff.size; mem_ops = kzalloc(sizeof(*mem_ops), GFP_KERNEL); if (!mem_ops) goto err_mem_ops; mem_ops->alloc_descs = atl_ipa_alloc_descs; mem_ops->alloc_buf = atl_ipa_alloc_buf; mem_ops->free_descs = atl_ipa_free_descs; mem_ops->free_buf = atl_ipa_free_buf; mem_ops->private = channel; switch (dir) { switch (dir) { case IPA_ETH_DIR_RX: case IPA_ETH_DIR_RX: Loading @@ -65,67 +167,92 @@ static struct ipa_eth_channel *atl_ipa_request_channel( ring_flags |= ATL_FWR_TX; ring_flags |= ATL_FWR_TX; break; break; default: default: dev_err(eth_dev->dev, "Unsupported direction %d", dir); dev_err(eth_dev->dev, "Unsupported direction %d\n", dir); return NULL; goto err_dir; } } ring_flags |= ATL_FWR_ALLOC_BUFS; ring_flags |= ATL_FWR_ALLOC_BUFS; ring_flags |= ATL_FWR_CONTIG_BUFS; ring_flags |= ATL_FWR_CONTIG_BUFS; ring = atl_fwd_request_ring(eth_dev->net_dev, ring_flags, ring = atl_fwd_request_ring(eth_dev->net_dev, ring_flags, ATL_IPA_DEFAULT_RING_SZ, desc_count, buff_size, 1, mem_ops); ATL_IPA_DEFAULT_BUFF_SZ, 1, NULL); if (IS_ERR_OR_NULL(ring)) { if (IS_ERR_OR_NULL(ring)) { dev_err(eth_dev->dev, "Request ring failed"); dev_err(eth_dev->dev, "Request ring failed\n"); goto err_exit; goto err_ring; } } channel = kzalloc(sizeof(*channel), GFP_KERNEL); channel->nd_priv = ring; if (!channel) goto err_exit; channel->events = 0; channel->features = 0; channel->direction = dir; channel->queue = ring->idx; channel->queue = ring->idx; channel->desc_size = 16; desc_mem = kzalloc(sizeof(*desc_mem), GFP_KERNEL); channel->desc_count = ring->hw.size; if (!desc_mem) channel->desc_mem.size = channel->desc_size * channel->desc_count; goto err_desc_mem; channel->desc_mem.vaddr = ring->hw.descs; channel->mem_params.desc.size = 16; channel->desc_mem.daddr = ring->hw.daddr; channel->mem_params.desc.count = ring->hw.size; channel->desc_mem.paddr = page_to_phys(vmalloc_to_page(channel->desc_mem.vaddr)); channel->buff_size = ATL_IPA_DEFAULT_BUFF_SZ; desc_mem->mem.size = channel->buff_count = channel->desc_count; channel->mem_params.desc.size * channel->mem_params.desc.count; channel->buff_mem.size = channel->buff_size * channel->buff_count; desc_mem->mem.vaddr = ring->hw.descs; desc_mem->mem.daddr = ring->hw.daddr; desc_mem->mem.paddr = channel->mem_params.desc.allocator->paddr( eth_dev, desc_mem->mem.vaddr); channel->buff_mem.vaddr = (void *)ring->bufs->vaddr_vec; buff_mem = kzalloc(sizeof(*buff_mem), GFP_KERNEL); channel->buff_mem.daddr = ring->bufs->daddr_vec_base; if (!buff_mem) channel->buff_mem.paddr = virt_to_phys((void *)ring->bufs->vaddr_vec); goto err_buff_mem; channel->eth_dev = eth_dev; channel->mem_params.buff.size = buff_size; channel->nd_priv = ring; channel->mem_params.buff.count = channel->mem_params.desc.count; return channel; buff_mem->mem.size = channel->mem_params.buff.size * channel->mem_params.buff.count; buff_mem->mem.vaddr = (void *)ring->bufs->vaddr_vec; buff_mem->mem.daddr = ring->bufs->daddr_vec_base; buff_mem->mem.paddr = channel->mem_params.buff.allocator->paddr( eth_dev, buff_mem->mem.vaddr); err_exit: list_add(&desc_mem->mem_list_entry, &channel->desc_mem); kzfree(channel); list_add(&buff_mem->mem_list_entry, &channel->buff_mem); if (!IS_ERR_OR_NULL(ring)) { return channel; atl_fwd_release_ring(ring); ring = NULL; } err_buff_mem: kzfree(desc_mem); err_desc_mem: atl_fwd_release_ring(ring); err_ring: err_dir: if (mem_ops) kzfree(mem_ops); err_mem_ops: ipa_eth_net_free_channel(channel); err_channel: return NULL; return NULL; } } static void atl_ipa_release_channel(struct ipa_eth_channel *ch) static void atl_ipa_release_channel(struct ipa_eth_channel *ch) { { atl_fwd_release_ring(CH_RING(ch)); struct ipa_eth_channel_mem *mem, *tmp; kzfree(ch); struct atl_fwd_ring *ring = CH_RING(ch); struct atl_fwd_mem_ops *mem_ops = ring->mem_ops; atl_fwd_release_ring(ring); if (mem_ops) kzfree(mem_ops); list_for_each_entry_safe(mem, tmp, &ch->desc_mem, mem_list_entry) { list_del(&mem->mem_list_entry); kzfree(mem); } list_for_each_entry_safe(mem, tmp, &ch->buff_mem, mem_list_entry) { list_del(&mem->mem_list_entry); kzfree(mem); } ipa_eth_net_free_channel(ch); } } static int atl_ipa_enable_channel(struct ipa_eth_channel *ch) static int atl_ipa_enable_channel(struct ipa_eth_channel *ch) Loading Loading @@ -153,7 +280,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, case IPA_ETH_DEV_EV_RX_INT: case IPA_ETH_DEV_EV_RX_INT: if (ch->direction != IPA_ETH_DIR_RX) { if (ch->direction != IPA_ETH_DIR_RX) { dev_err(eth_dev->dev, dev_err(eth_dev->dev, "Rx interrupt requested on incorrect channel"); "Rx interrupt requested on tx channel\n"); return -EFAULT; return -EFAULT; } } Loading @@ -166,7 +293,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, case IPA_ETH_DEV_EV_TX_INT: case IPA_ETH_DEV_EV_TX_INT: if (ch->direction != IPA_ETH_DIR_TX) { if (ch->direction != IPA_ETH_DIR_TX) { dev_err(eth_dev->dev, dev_err(eth_dev->dev, "Tx interrupt requested on incorrect channel"); "Tx interrupt requested on rx channel\n"); return -EFAULT; return -EFAULT; } } Loading @@ -179,7 +306,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, case IPA_ETH_DEV_EV_TX_PTR: case IPA_ETH_DEV_EV_TX_PTR: if (ch->direction != IPA_ETH_DIR_TX) { if (ch->direction != IPA_ETH_DIR_TX) { dev_err(eth_dev->dev, dev_err(eth_dev->dev, "Tx ptr wrb requested on incorrect channel"); "Tx ptr wrb requested on rx channel\n"); return -EFAULT; return -EFAULT; } } Loading @@ -190,7 +317,7 @@ static int atl_ipa_request_event(struct ipa_eth_channel *ch, break; break; default: default: dev_err(eth_dev->dev, "Unsupported event requested"); dev_err(eth_dev->dev, "Unsupported event requested\n"); return -ENODEV; return -ENODEV; } } Loading Loading @@ -226,7 +353,7 @@ static void atl_ipa_release_event(struct ipa_eth_channel *ch, break; break; default: default: dev_err(eth_dev->dev, "Unsupported event for release"); dev_err(eth_dev->dev, "Unsupported event for release\n"); return; return; } } Loading
drivers/platform/msm/ipa/ipa_v3/ethernet/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -6,6 +6,7 @@ ipa-eth-y := \ ipa_eth.o \ ipa_eth.o \ ipa_eth_ep.o \ ipa_eth_ep.o \ ipa_eth_gsi.o \ ipa_eth_gsi.o \ ipa_eth_net.o \ ipa_eth_offload.o \ ipa_eth_offload.o \ ipa_eth_pci.o \ ipa_eth_pci.o \ ipa_eth_pm.o \ ipa_eth_pm.o \ Loading
drivers/platform/msm/ipa/ipa_v3/ethernet/aquantia/Kconfig +1 −0 Original line number Original line Diff line number Diff line Loading @@ -11,6 +11,7 @@ config AQC_IPA choice choice prompt "Default Rx Interrupt Proxy Method" prompt "Default Rx Interrupt Proxy Method" depends on AQC_IPA default AQC_IPA_PROXY_HOST default AQC_IPA_PROXY_HOST config AQC_IPA_PROXY_UC config AQC_IPA_PROXY_UC Loading