aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2014-03-17 09:34:09 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-03-17 13:44:16 -0400
commit2232abd59ae5801b20c1e8269a63515bac50d28d (patch)
tree1682447eaed196d980edb21ebb4d4d22d3fb4eff /drivers/net/wireless/ath
parentc236658f1434a1e00ec1fec9054964bcaf3ddde7 (diff)
wil6210: generalize tx desc mapping
Introduce enum to describe mapping type; allow 'none' in addition to 'single' and 'page'; this is preparation for GSO Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c52
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h8
2 files changed, 33 insertions, 27 deletions
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 2eb545e3981f..41f88ee49bca 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -104,6 +104,23 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
104 return 0; 104 return 0;
105} 105}
106 106
107static void wil_txdesc_unmap(struct device *dev, struct vring_tx_desc *d,
108 struct wil_ctx *ctx)
109{
110 dma_addr_t pa = wil_desc_addr(&d->dma.addr);
111 u16 dmalen = le16_to_cpu(d->dma.length);
112 switch (ctx->mapped_as) {
113 case wil_mapped_as_single:
114 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
115 break;
116 case wil_mapped_as_page:
117 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
118 break;
119 default:
120 break;
121 }
122}
123
107static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring, 124static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring,
108 int tx) 125 int tx)
109{ 126{
@@ -122,15 +139,7 @@ static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring,
122 139
123 ctx = &vring->ctx[vring->swtail]; 140 ctx = &vring->ctx[vring->swtail];
124 *d = *_d; 141 *d = *_d;
125 pa = wil_desc_addr(&d->dma.addr); 142 wil_txdesc_unmap(dev, d, ctx);
126 dmalen = le16_to_cpu(d->dma.length);
127 if (vring->ctx[vring->swtail].mapped_as_page) {
128 dma_unmap_page(dev, pa, dmalen,
129 DMA_TO_DEVICE);
130 } else {
131 dma_unmap_single(dev, pa, dmalen,
132 DMA_TO_DEVICE);
133 }
134 if (ctx->skb) 143 if (ctx->skb)
135 dev_kfree_skb_any(ctx->skb); 144 dev_kfree_skb_any(ctx->skb);
136 vring->swtail = wil_vring_next_tail(vring); 145 vring->swtail = wil_vring_next_tail(vring);
@@ -845,8 +854,6 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
845 854
846 wil_dbg_txrx(wil, "%s()\n", __func__); 855 wil_dbg_txrx(wil, "%s()\n", __func__);
847 856
848 if (avail < vring->size/8)
849 netif_tx_stop_all_queues(wil_to_ndev(wil));
850 if (avail < 1 + nr_frags) { 857 if (avail < 1 + nr_frags) {
851 wil_err(wil, "Tx ring full. No space for %d fragments\n", 858 wil_err(wil, "Tx ring full. No space for %d fragments\n",
852 1 + nr_frags); 859 1 + nr_frags);
@@ -864,6 +871,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
864 871
865 if (unlikely(dma_mapping_error(dev, pa))) 872 if (unlikely(dma_mapping_error(dev, pa)))
866 return -EINVAL; 873 return -EINVAL;
874 vring->ctx[i].mapped_as = wil_mapped_as_single;
867 /* 1-st segment */ 875 /* 1-st segment */
868 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); 876 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index);
869 /* Process TCP/UDP checksum offloading */ 877 /* Process TCP/UDP checksum offloading */
@@ -889,13 +897,13 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
889 DMA_TO_DEVICE); 897 DMA_TO_DEVICE);
890 if (unlikely(dma_mapping_error(dev, pa))) 898 if (unlikely(dma_mapping_error(dev, pa)))
891 goto dma_error; 899 goto dma_error;
900 vring->ctx[i].mapped_as = wil_mapped_as_page;
892 wil_tx_desc_map(d, pa, len, vring_index); 901 wil_tx_desc_map(d, pa, len, vring_index);
893 /* no need to check return code - 902 /* no need to check return code -
894 * if it succeeded for 1-st descriptor, 903 * if it succeeded for 1-st descriptor,
895 * it will succeed here too 904 * it will succeed here too
896 */ 905 */
897 wil_tx_desc_offload_cksum_set(wil, d, skb); 906 wil_tx_desc_offload_cksum_set(wil, d, skb);
898 vring->ctx[i].mapped_as_page = 1;
899 *_d = *d; 907 *_d = *d;
900 } 908 }
901 /* for the last seg only */ 909 /* for the last seg only */
@@ -924,7 +932,6 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
924 /* unmap what we have mapped */ 932 /* unmap what we have mapped */
925 nr_frags = f + 1; /* frags mapped + one for skb head */ 933 nr_frags = f + 1; /* frags mapped + one for skb head */
926 for (f = 0; f < nr_frags; f++) { 934 for (f = 0; f < nr_frags; f++) {
927 u16 dmalen;
928 struct wil_ctx *ctx; 935 struct wil_ctx *ctx;
929 936
930 i = (swhead + f) % vring->size; 937 i = (swhead + f) % vring->size;
@@ -932,12 +939,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
932 _d = &(vring->va[i].tx); 939 _d = &(vring->va[i].tx);
933 *d = *_d; 940 *d = *_d;
934 _d->dma.status = TX_DMA_STATUS_DU; 941 _d->dma.status = TX_DMA_STATUS_DU;
935 pa = wil_desc_addr(&d->dma.addr); 942 wil_txdesc_unmap(dev, d, ctx);
936 dmalen = le16_to_cpu(d->dma.length);
937 if (ctx->mapped_as_page)
938 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
939 else
940 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
941 943
942 if (ctx->skb) 944 if (ctx->skb)
943 dev_kfree_skb_any(ctx->skb); 945 dev_kfree_skb_any(ctx->skb);
@@ -983,6 +985,10 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
983 /* set up vring entry */ 985 /* set up vring entry */
984 rc = wil_tx_vring(wil, vring, skb); 986 rc = wil_tx_vring(wil, vring, skb);
985 987
988 /* do we still have enough room in the vring? */
989 if (wil_vring_avail_tx(vring) < vring->size/8)
990 netif_tx_stop_all_queues(wil_to_ndev(wil));
991
986 switch (rc) { 992 switch (rc) {
987 case 0: 993 case 0:
988 /* statistics will be updated on the tx_complete */ 994 /* statistics will be updated on the tx_complete */
@@ -1041,7 +1047,6 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1041 new_swtail = (lf + 1) % vring->size; 1047 new_swtail = (lf + 1) % vring->size;
1042 while (vring->swtail != new_swtail) { 1048 while (vring->swtail != new_swtail) {
1043 struct vring_tx_desc dd, *d = &dd; 1049 struct vring_tx_desc dd, *d = &dd;
1044 dma_addr_t pa;
1045 u16 dmalen; 1050 u16 dmalen;
1046 struct wil_ctx *ctx = &vring->ctx[vring->swtail]; 1051 struct wil_ctx *ctx = &vring->ctx[vring->swtail];
1047 struct sk_buff *skb = ctx->skb; 1052 struct sk_buff *skb = ctx->skb;
@@ -1059,12 +1064,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1059 wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4, 1064 wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4,
1060 (const void *)d, sizeof(*d), false); 1065 (const void *)d, sizeof(*d), false);
1061 1066
1062 pa = wil_desc_addr(&d->dma.addr); 1067 wil_txdesc_unmap(dev, d, ctx);
1063 if (ctx->mapped_as_page)
1064 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
1065 else
1066 dma_unmap_single(dev, pa, dmalen,
1067 DMA_TO_DEVICE);
1068 1068
1069 if (skb) { 1069 if (skb) {
1070 if (d->dma.error == 0) { 1070 if (d->dma.error == 0) {
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 574f4d9af18b..11e0898bcffd 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -209,13 +209,19 @@ struct pending_wmi_event {
209 } __packed event; 209 } __packed event;
210}; 210};
211 211
212enum { /* for wil_ctx.mapped_as */
213 wil_mapped_as_none = 0,
214 wil_mapped_as_single = 1,
215 wil_mapped_as_page = 2,
216};
217
212/** 218/**
213 * struct wil_ctx - software context for Vring descriptor 219 * struct wil_ctx - software context for Vring descriptor
214 */ 220 */
215struct wil_ctx { 221struct wil_ctx {
216 struct sk_buff *skb; 222 struct sk_buff *skb;
217 u8 nr_frags; 223 u8 nr_frags;
218 u8 mapped_as_page:1; 224 u8 mapped_as;
219}; 225};
220 226
221union vring_desc; 227union vring_desc;