aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/wil6210/txrx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/txrx.c')
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c81
1 files changed, 57 insertions, 24 deletions
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index b58ee52e1860..8439f65db259 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -671,6 +671,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
671 } 671 }
672 672
673 memset(txdata, 0, sizeof(*txdata)); 673 memset(txdata, 0, sizeof(*txdata));
674 spin_lock_init(&txdata->lock);
674 vring->size = size; 675 vring->size = size;
675 rc = wil_vring_alloc(wil, vring); 676 rc = wil_vring_alloc(wil, vring);
676 if (rc) 677 if (rc)
@@ -718,8 +719,10 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
718 719
719 wil_dbg_misc(wil, "%s() id=%d\n", __func__, id); 720 wil_dbg_misc(wil, "%s() id=%d\n", __func__, id);
720 721
722 spin_lock_bh(&txdata->lock);
723 txdata->enabled = 0; /* no Tx can be in progress or start anew */
724 spin_unlock_bh(&txdata->lock);
721 /* make sure NAPI won't touch this vring */ 725 /* make sure NAPI won't touch this vring */
722 wil->vring_tx_data[id].enabled = 0;
723 if (test_bit(wil_status_napi_en, wil->status)) 726 if (test_bit(wil_status_napi_en, wil->status))
724 napi_synchronize(&wil->napi_tx); 727 napi_synchronize(&wil->napi_tx);
725 728
@@ -873,9 +876,6 @@ static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len,
873 d->mac.d[1] = 0; 876 d->mac.d[1] = 0;
874 d->mac.d[2] = 0; 877 d->mac.d[2] = 0;
875 d->mac.ucode_cmd = 0; 878 d->mac.ucode_cmd = 0;
876 /* use dst index 0 */
877 d->mac.d[1] |= BIT(MAC_CFG_DESC_TX_1_DST_INDEX_EN_POS) |
878 (0 << MAC_CFG_DESC_TX_1_DST_INDEX_POS);
879 /* translation type: 0 - bypass; 1 - 802.3; 2 - native wifi */ 879 /* translation type: 0 - bypass; 1 - 802.3; 2 - native wifi */
880 d->mac.d[2] = BIT(MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_POS) | 880 d->mac.d[2] = BIT(MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_POS) |
881 (1 << MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_POS); 881 (1 << MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_POS);
@@ -938,8 +938,8 @@ static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil,
938 return 0; 938 return 0;
939} 939}
940 940
941static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 941static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
942 struct sk_buff *skb) 942 struct sk_buff *skb)
943{ 943{
944 struct device *dev = wil_to_dev(wil); 944 struct device *dev = wil_to_dev(wil);
945 struct vring_tx_desc dd, *d = &dd; 945 struct vring_tx_desc dd, *d = &dd;
@@ -955,18 +955,21 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
955 955
956 wil_dbg_txrx(wil, "%s()\n", __func__); 956 wil_dbg_txrx(wil, "%s()\n", __func__);
957 957
958 if (unlikely(!txdata->enabled))
959 return -EINVAL;
960
958 if (avail < 1 + nr_frags) { 961 if (avail < 1 + nr_frags) {
959 wil_err_ratelimited(wil, 962 wil_err_ratelimited(wil,
960 "Tx ring full. No space for %d fragments\n", 963 "Tx ring[%2d] full. No space for %d fragments\n",
961 1 + nr_frags); 964 vring_index, 1 + nr_frags);
962 return -ENOMEM; 965 return -ENOMEM;
963 } 966 }
964 _d = &vring->va[i].tx; 967 _d = &vring->va[i].tx;
965 968
966 pa = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); 969 pa = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
967 970
968 wil_dbg_txrx(wil, "Tx skb %d bytes 0x%p -> %pad\n", skb_headlen(skb), 971 wil_dbg_txrx(wil, "Tx[%2d] skb %d bytes 0x%p -> %pad\n", vring_index,
969 skb->data, &pa); 972 skb_headlen(skb), skb->data, &pa);
970 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_OFFSET, 16, 1, 973 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_OFFSET, 16, 1,
971 skb->data, skb_headlen(skb), false); 974 skb->data, skb_headlen(skb), false);
972 975
@@ -977,15 +980,13 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
977 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); 980 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index);
978 /* Process TCP/UDP checksum offloading */ 981 /* Process TCP/UDP checksum offloading */
979 if (wil_tx_desc_offload_cksum_set(wil, d, skb)) { 982 if (wil_tx_desc_offload_cksum_set(wil, d, skb)) {
980 wil_err(wil, "VRING #%d Failed to set cksum, drop packet\n", 983 wil_err(wil, "Tx[%2d] Failed to set cksum, drop packet\n",
981 vring_index); 984 vring_index);
982 goto dma_error; 985 goto dma_error;
983 } 986 }
984 987
985 vring->ctx[i].nr_frags = nr_frags; 988 vring->ctx[i].nr_frags = nr_frags;
986 wil_tx_desc_set_nr_frags(d, nr_frags); 989 wil_tx_desc_set_nr_frags(d, nr_frags);
987 if (nr_frags)
988 *_d = *d;
989 990
990 /* middle segments */ 991 /* middle segments */
991 for (; f < nr_frags; f++) { 992 for (; f < nr_frags; f++) {
@@ -993,6 +994,10 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
993 &skb_shinfo(skb)->frags[f]; 994 &skb_shinfo(skb)->frags[f];
994 int len = skb_frag_size(frag); 995 int len = skb_frag_size(frag);
995 996
997 *_d = *d;
998 wil_dbg_txrx(wil, "Tx[%2d] desc[%4d]\n", vring_index, i);
999 wil_hex_dump_txrx("TxD ", DUMP_PREFIX_NONE, 32, 4,
1000 (const void *)d, sizeof(*d), false);
996 i = (swhead + f + 1) % vring->size; 1001 i = (swhead + f + 1) % vring->size;
997 _d = &vring->va[i].tx; 1002 _d = &vring->va[i].tx;
998 pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag), 1003 pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag),
@@ -1006,13 +1011,15 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1006 * it will succeed here too 1011 * it will succeed here too
1007 */ 1012 */
1008 wil_tx_desc_offload_cksum_set(wil, d, skb); 1013 wil_tx_desc_offload_cksum_set(wil, d, skb);
1009 *_d = *d;
1010 } 1014 }
1011 /* for the last seg only */ 1015 /* for the last seg only */
1012 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS); 1016 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS);
1013 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS); 1017 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS);
1014 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); 1018 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
1015 *_d = *d; 1019 *_d = *d;
1020 wil_dbg_txrx(wil, "Tx[%2d] desc[%4d]\n", vring_index, i);
1021 wil_hex_dump_txrx("TxD ", DUMP_PREFIX_NONE, 32, 4,
1022 (const void *)d, sizeof(*d), false);
1016 1023
1017 /* hold reference to skb 1024 /* hold reference to skb
1018 * to prevent skb release before accounting 1025 * to prevent skb release before accounting
@@ -1020,15 +1027,13 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1020 */ 1027 */
1021 vring->ctx[i].skb = skb_get(skb); 1028 vring->ctx[i].skb = skb_get(skb);
1022 1029
1023 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
1024 (const void *)d, sizeof(*d), false);
1025
1026 if (wil_vring_is_empty(vring)) /* performance monitoring */ 1030 if (wil_vring_is_empty(vring)) /* performance monitoring */
1027 txdata->idle += get_cycles() - txdata->last_idle; 1031 txdata->idle += get_cycles() - txdata->last_idle;
1028 1032
1029 /* advance swhead */ 1033 /* advance swhead */
1030 wil_vring_advance_head(vring, nr_frags + 1); 1034 wil_vring_advance_head(vring, nr_frags + 1);
1031 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead); 1035 wil_dbg_txrx(wil, "Tx[%2d] swhead %d -> %d\n", vring_index, swhead,
1036 vring->swhead);
1032 trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags); 1037 trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags);
1033 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail)); 1038 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
1034 1039
@@ -1055,6 +1060,19 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1055 return -EINVAL; 1060 return -EINVAL;
1056} 1061}
1057 1062
1063static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1064 struct sk_buff *skb)
1065{
1066 int vring_index = vring - wil->vring_tx;
1067 struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index];
1068 int rc;
1069
1070 spin_lock(&txdata->lock);
1071 rc = __wil_tx_vring(wil, vring, skb);
1072 spin_unlock(&txdata->lock);
1073 return rc;
1074}
1075
1058netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) 1076netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1059{ 1077{
1060 struct wil6210_priv *wil = ndev_to_wil(ndev); 1078 struct wil6210_priv *wil = ndev_to_wil(ndev);
@@ -1121,6 +1139,22 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1121 return NET_XMIT_DROP; 1139 return NET_XMIT_DROP;
1122} 1140}
1123 1141
1142static inline bool wil_need_txstat(struct sk_buff *skb)
1143{
1144 struct ethhdr *eth = (void *)skb->data;
1145
1146 return is_unicast_ether_addr(eth->h_dest) && skb->sk &&
1147 (skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS);
1148}
1149
1150static inline void wil_consume_skb(struct sk_buff *skb, bool acked)
1151{
1152 if (unlikely(wil_need_txstat(skb)))
1153 skb_complete_wifi_ack(skb, acked);
1154 else
1155 acked ? dev_consume_skb_any(skb) : dev_kfree_skb_any(skb);
1156}
1157
1124/** 1158/**
1125 * Clean up transmitted skb's from the Tx VRING 1159 * Clean up transmitted skb's from the Tx VRING
1126 * 1160 *
@@ -1181,10 +1215,10 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1181 trace_wil6210_tx_done(ringid, vring->swtail, dmalen, 1215 trace_wil6210_tx_done(ringid, vring->swtail, dmalen,
1182 d->dma.error); 1216 d->dma.error);
1183 wil_dbg_txrx(wil, 1217 wil_dbg_txrx(wil,
1184 "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n", 1218 "TxC[%2d][%3d] : %d bytes, status 0x%02x err 0x%02x\n",
1185 vring->swtail, dmalen, d->dma.status, 1219 ringid, vring->swtail, dmalen,
1186 d->dma.error); 1220 d->dma.status, d->dma.error);
1187 wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4, 1221 wil_hex_dump_txrx("TxCD ", DUMP_PREFIX_NONE, 32, 4,
1188 (const void *)d, sizeof(*d), false); 1222 (const void *)d, sizeof(*d), false);
1189 1223
1190 wil_txdesc_unmap(dev, d, ctx); 1224 wil_txdesc_unmap(dev, d, ctx);
@@ -1199,8 +1233,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1199 ndev->stats.tx_errors++; 1233 ndev->stats.tx_errors++;
1200 stats->tx_errors++; 1234 stats->tx_errors++;
1201 } 1235 }
1202 1236 wil_consume_skb(skb, d->dma.error == 0);
1203 dev_kfree_skb_any(skb);
1204 } 1237 }
1205 memset(ctx, 0, sizeof(*ctx)); 1238 memset(ctx, 0, sizeof(*ctx));
1206 /* There is no need to touch HW descriptor: 1239 /* There is no need to touch HW descriptor: