Loading drivers/net/ethernet/aquantia/atlantic-fwd/atl_qcom_ipa.c +73 −16 Original line number Diff line number Diff line Loading @@ -21,17 +21,25 @@ #include "atl_fwd.h" #include "atl_qcom_ipa.h" #if ATL_FWD_API_VERSION >= 2 && IPA_ETH_API_VER >= 4 #define ATL_IPA_SUPPORT_NOTIFY #endif struct atl_ipa_device { struct atl_nic *atl_nic; struct ipa_eth_device *eth_dev; struct notifier_block fwd_notify_nb; }; static inline struct atl_fwd_ring *CH_RING(struct ipa_eth_channel *ch) { 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, static void *atl_ipa_dma_alloc(struct ipa_eth_device *eth_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)) Loading @@ -43,12 +51,10 @@ static void *atl_ipa_dma_alloc(struct device *dev, size_t size, return mem.vaddr; } static void atl_ipa_dma_free(void *buf, struct device *dev, size_t size, dma_addr_t daddr, static void atl_ipa_dma_free(void *buf, struct ipa_eth_device *eth_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, Loading @@ -64,7 +70,7 @@ static void *atl_ipa_alloc_descs(struct device *dev, size_t size, { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_alloc(dev, size, daddr, gfp, return atl_ipa_dma_alloc(ch->eth_dev, size, daddr, gfp, ch->mem_params.desc.allocator); } Loading @@ -74,7 +80,7 @@ static void *atl_ipa_alloc_buf(struct device *dev, size_t size, { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_alloc(dev, size, daddr, gfp, return atl_ipa_dma_alloc(ch->eth_dev, size, daddr, gfp, ch->mem_params.buff.allocator); } Loading @@ -83,7 +89,7 @@ static void atl_ipa_free_descs(void *buf, struct device *dev, size_t size, { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_free(buf, dev, size, daddr, return atl_ipa_dma_free(buf, ch->eth_dev, size, daddr, ch->mem_params.desc.allocator); } Loading @@ -92,12 +98,38 @@ static void atl_ipa_free_buf(void *buf, struct device *dev, size_t size, { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_free(buf, dev, size, daddr, return atl_ipa_dma_free(buf, ch->eth_dev, size, daddr, ch->mem_params.desc.allocator); } #ifdef ATL_IPA_SUPPORT_NOTIFY static int atl_ipa_fwd_notification(struct notifier_block *nb, unsigned long action, void *data) { enum atl_fwd_notify notif = action; struct atl_ipa_device *ai_dev = container_of( nb, struct atl_ipa_device, fwd_notify_nb); switch (notif) { case ATL_FWD_NOTIFY_RESET_PREPARE: ipa_eth_device_notify(ai_dev->eth_dev, IPA_ETH_DEV_RESET_PREPARE, NULL); break; case ATL_FWD_NOTIFY_RESET_COMPLETE: ipa_eth_device_notify(ai_dev->eth_dev, IPA_ETH_DEV_RESET_COMPLETE, NULL); break; default: return NOTIFY_DONE; } return NOTIFY_OK; } #endif static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) { struct atl_ipa_device *ai_dev; struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(eth_dev->dev); if (!nic || !nic->ndev) { Loading @@ -105,24 +137,49 @@ static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) return -ENODEV; } nic->fwd.private = eth_dev; ai_dev = kzalloc(sizeof(*ai_dev), GFP_KERNEL); if (!ai_dev) return -ENOMEM; /* atl specific init, ref counting go here */ eth_dev->nd_priv = nic; ai_dev->atl_nic = nic; ai_dev->eth_dev = eth_dev; eth_dev->nd_priv = ai_dev; eth_dev->net_dev = nic->ndev; #ifdef ATL_IPA_SUPPORT_NOTIFY ai_dev->fwd_notify_nb.notifier_call = atl_ipa_fwd_notification; if (atl_fwd_register_notifier(nic->ndev, &ai_dev->fwd_notify_nb)) { dev_err(eth_dev->dev, "Failed to register notifier\n"); eth_dev->nd_priv = NULL; eth_dev->net_dev = NULL; kfree(ai_dev); return -EFAULT; } #endif return 0; } static void atl_ipa_close_device(struct ipa_eth_device *eth_dev) { struct atl_nic *nic = eth_dev->nd_priv; struct atl_ipa_device *ai_dev = eth_dev->nd_priv; nic->fwd.private = NULL; #ifdef ATL_IPA_SUPPORT_NOTIFY atl_fwd_unregister_notifier(ai_dev->atl_nic->ndev, &ai_dev->fwd_notify_nb); #endif eth_dev->nd_priv = NULL; eth_dev->net_dev = NULL; memset(ai_dev, 0, sizeof(ai_dev)); kfree(ai_dev); } static struct ipa_eth_channel *atl_ipa_request_channel( Loading Loading
drivers/net/ethernet/aquantia/atlantic-fwd/atl_qcom_ipa.c +73 −16 Original line number Diff line number Diff line Loading @@ -21,17 +21,25 @@ #include "atl_fwd.h" #include "atl_qcom_ipa.h" #if ATL_FWD_API_VERSION >= 2 && IPA_ETH_API_VER >= 4 #define ATL_IPA_SUPPORT_NOTIFY #endif struct atl_ipa_device { struct atl_nic *atl_nic; struct ipa_eth_device *eth_dev; struct notifier_block fwd_notify_nb; }; static inline struct atl_fwd_ring *CH_RING(struct ipa_eth_channel *ch) { 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, static void *atl_ipa_dma_alloc(struct ipa_eth_device *eth_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)) Loading @@ -43,12 +51,10 @@ static void *atl_ipa_dma_alloc(struct device *dev, size_t size, return mem.vaddr; } static void atl_ipa_dma_free(void *buf, struct device *dev, size_t size, dma_addr_t daddr, static void atl_ipa_dma_free(void *buf, struct ipa_eth_device *eth_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, Loading @@ -64,7 +70,7 @@ static void *atl_ipa_alloc_descs(struct device *dev, size_t size, { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_alloc(dev, size, daddr, gfp, return atl_ipa_dma_alloc(ch->eth_dev, size, daddr, gfp, ch->mem_params.desc.allocator); } Loading @@ -74,7 +80,7 @@ static void *atl_ipa_alloc_buf(struct device *dev, size_t size, { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_alloc(dev, size, daddr, gfp, return atl_ipa_dma_alloc(ch->eth_dev, size, daddr, gfp, ch->mem_params.buff.allocator); } Loading @@ -83,7 +89,7 @@ static void atl_ipa_free_descs(void *buf, struct device *dev, size_t size, { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_free(buf, dev, size, daddr, return atl_ipa_dma_free(buf, ch->eth_dev, size, daddr, ch->mem_params.desc.allocator); } Loading @@ -92,12 +98,38 @@ static void atl_ipa_free_buf(void *buf, struct device *dev, size_t size, { struct ipa_eth_channel *ch = ops->private; return atl_ipa_dma_free(buf, dev, size, daddr, return atl_ipa_dma_free(buf, ch->eth_dev, size, daddr, ch->mem_params.desc.allocator); } #ifdef ATL_IPA_SUPPORT_NOTIFY static int atl_ipa_fwd_notification(struct notifier_block *nb, unsigned long action, void *data) { enum atl_fwd_notify notif = action; struct atl_ipa_device *ai_dev = container_of( nb, struct atl_ipa_device, fwd_notify_nb); switch (notif) { case ATL_FWD_NOTIFY_RESET_PREPARE: ipa_eth_device_notify(ai_dev->eth_dev, IPA_ETH_DEV_RESET_PREPARE, NULL); break; case ATL_FWD_NOTIFY_RESET_COMPLETE: ipa_eth_device_notify(ai_dev->eth_dev, IPA_ETH_DEV_RESET_COMPLETE, NULL); break; default: return NOTIFY_DONE; } return NOTIFY_OK; } #endif static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) { struct atl_ipa_device *ai_dev; struct atl_nic *nic = (struct atl_nic *)dev_get_drvdata(eth_dev->dev); if (!nic || !nic->ndev) { Loading @@ -105,24 +137,49 @@ static int atl_ipa_open_device(struct ipa_eth_device *eth_dev) return -ENODEV; } nic->fwd.private = eth_dev; ai_dev = kzalloc(sizeof(*ai_dev), GFP_KERNEL); if (!ai_dev) return -ENOMEM; /* atl specific init, ref counting go here */ eth_dev->nd_priv = nic; ai_dev->atl_nic = nic; ai_dev->eth_dev = eth_dev; eth_dev->nd_priv = ai_dev; eth_dev->net_dev = nic->ndev; #ifdef ATL_IPA_SUPPORT_NOTIFY ai_dev->fwd_notify_nb.notifier_call = atl_ipa_fwd_notification; if (atl_fwd_register_notifier(nic->ndev, &ai_dev->fwd_notify_nb)) { dev_err(eth_dev->dev, "Failed to register notifier\n"); eth_dev->nd_priv = NULL; eth_dev->net_dev = NULL; kfree(ai_dev); return -EFAULT; } #endif return 0; } static void atl_ipa_close_device(struct ipa_eth_device *eth_dev) { struct atl_nic *nic = eth_dev->nd_priv; struct atl_ipa_device *ai_dev = eth_dev->nd_priv; nic->fwd.private = NULL; #ifdef ATL_IPA_SUPPORT_NOTIFY atl_fwd_unregister_notifier(ai_dev->atl_nic->ndev, &ai_dev->fwd_notify_nb); #endif eth_dev->nd_priv = NULL; eth_dev->net_dev = NULL; memset(ai_dev, 0, sizeof(ai_dev)); kfree(ai_dev); } static struct ipa_eth_channel *atl_ipa_request_channel( Loading