diff options
author | Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> | 2014-03-17 09:34:09 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-03-17 13:44:16 -0400 |
commit | 2232abd59ae5801b20c1e8269a63515bac50d28d (patch) | |
tree | 1682447eaed196d980edb21ebb4d4d22d3fb4eff /drivers/net/wireless/ath | |
parent | c236658f1434a1e00ec1fec9054964bcaf3ddde7 (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.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wil6210.h | 8 |
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 | ||
107 | static 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 | |||
107 | static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring, | 124 | static 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 = ⅆ | 1049 | struct vring_tx_desc dd, *d = ⅆ |
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 | ||
212 | enum { /* 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 | */ |
215 | struct wil_ctx { | 221 | struct 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 | ||
221 | union vring_desc; | 227 | union vring_desc; |