forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/net/wireless/ath/ath10k/htt_tx.c
....@@ -1,18 +1,7 @@
1
+// SPDX-License-Identifier: ISC
12 /*
23 * Copyright (c) 2005-2011 Atheros Communications Inc.
34 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4
- *
5
- * Permission to use, copy, modify, and/or distribute this software for any
6
- * purpose with or without fee is hereby granted, provided that the above
7
- * copyright notice and this permission notice appear in all copies.
8
- *
9
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
165 */
176
187 #include <linux/etherdevice.h>
....@@ -498,6 +487,9 @@
498487 if (htt->tx_mem_allocated)
499488 return 0;
500489
490
+ if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
491
+ return 0;
492
+
501493 ret = ath10k_htt_tx_alloc_buf(htt);
502494 if (ret)
503495 goto free_idr_pending_tx;
....@@ -540,9 +532,15 @@
540532 htt->tx_mem_allocated = false;
541533 }
542534
535
+static void ath10k_htt_flush_tx_queue(struct ath10k_htt *htt)
536
+{
537
+ ath10k_htc_stop_hl(htt->ar);
538
+ idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
539
+}
540
+
543541 void ath10k_htt_tx_stop(struct ath10k_htt *htt)
544542 {
545
- idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
543
+ ath10k_htt_flush_tx_queue(htt);
546544 idr_destroy(&htt->pending_tx);
547545 }
548546
....@@ -552,9 +550,46 @@
552550 ath10k_htt_tx_destroy(htt);
553551 }
554552
553
+void ath10k_htt_op_ep_tx_credits(struct ath10k *ar)
554
+{
555
+ queue_work(ar->workqueue, &ar->bundle_tx_work);
556
+}
557
+
555558 void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
556559 {
560
+ struct ath10k_htt *htt = &ar->htt;
561
+ struct htt_tx_done tx_done = {0};
562
+ struct htt_cmd_hdr *htt_hdr;
563
+ struct htt_data_tx_desc *desc_hdr = NULL;
564
+ u16 flags1 = 0;
565
+ u8 msg_type = 0;
566
+
567
+ if (htt->disable_tx_comp) {
568
+ htt_hdr = (struct htt_cmd_hdr *)skb->data;
569
+ msg_type = htt_hdr->msg_type;
570
+
571
+ if (msg_type == HTT_H2T_MSG_TYPE_TX_FRM) {
572
+ desc_hdr = (struct htt_data_tx_desc *)
573
+ (skb->data + sizeof(*htt_hdr));
574
+ flags1 = __le16_to_cpu(desc_hdr->flags1);
575
+ }
576
+ }
577
+
557578 dev_kfree_skb_any(skb);
579
+
580
+ if ((!htt->disable_tx_comp) || (msg_type != HTT_H2T_MSG_TYPE_TX_FRM))
581
+ return;
582
+
583
+ ath10k_dbg(ar, ATH10K_DBG_HTT,
584
+ "htt tx complete msdu id:%u ,flags1:%x\n",
585
+ __le16_to_cpu(desc_hdr->id), flags1);
586
+
587
+ if (flags1 & HTT_DATA_TX_DESC_FLAGS1_TX_COMPLETE)
588
+ return;
589
+
590
+ tx_done.status = HTT_TX_COMPL_STATE_ACK;
591
+ tx_done.msdu_id = __le16_to_cpu(desc_hdr->id);
592
+ ath10k_txrx_tx_unref(&ar->htt, &tx_done);
558593 }
559594
560595 void ath10k_htt_hif_tx_complete(struct ath10k *ar, struct sk_buff *skb)
....@@ -591,7 +626,8 @@
591626 return 0;
592627 }
593628
594
-int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie)
629
+int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u32 mask, u32 reset_mask,
630
+ u64 cookie)
595631 {
596632 struct ath10k *ar = htt->ar;
597633 struct htt_stats_req *req;
....@@ -614,11 +650,11 @@
614650
615651 memset(req, 0, sizeof(*req));
616652
617
- /* currently we support only max 8 bit masks so no need to worry
653
+ /* currently we support only max 24 bit masks so no need to worry
618654 * about endian support
619655 */
620
- req->upload_types[0] = mask;
621
- req->reset_types[0] = mask;
656
+ memcpy(req->upload_types, &mask, 3);
657
+ memcpy(req->reset_types, &reset_mask, 3);
622658 req->stat_type = HTT_STATS_REQ_CFG_STAT_TYPE_INVALID;
623659 req->cookie_lsb = cpu_to_le32(cookie & 0xffffffff);
624660 req->cookie_msb = cpu_to_le32((cookie & 0xffffffff00000000ULL) >> 32);
....@@ -937,9 +973,60 @@
937973 return 0;
938974 }
939975
940
-int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
941
- u8 max_subfrms_ampdu,
942
- u8 max_subfrms_amsdu)
976
+static int ath10k_htt_send_rx_ring_cfg_hl(struct ath10k_htt *htt)
977
+{
978
+ struct ath10k *ar = htt->ar;
979
+ struct sk_buff *skb;
980
+ struct htt_cmd *cmd;
981
+ struct htt_rx_ring_setup_ring32 *ring;
982
+ const int num_rx_ring = 1;
983
+ u16 flags;
984
+ int len;
985
+ int ret;
986
+
987
+ /*
988
+ * the HW expects the buffer to be an integral number of 4-byte
989
+ * "words"
990
+ */
991
+ BUILD_BUG_ON(!IS_ALIGNED(HTT_RX_BUF_SIZE, 4));
992
+ BUILD_BUG_ON((HTT_RX_BUF_SIZE & HTT_MAX_CACHE_LINE_SIZE_MASK) != 0);
993
+
994
+ len = sizeof(cmd->hdr) + sizeof(cmd->rx_setup_32.hdr)
995
+ + (sizeof(*ring) * num_rx_ring);
996
+ skb = ath10k_htc_alloc_skb(ar, len);
997
+ if (!skb)
998
+ return -ENOMEM;
999
+
1000
+ skb_put(skb, len);
1001
+
1002
+ cmd = (struct htt_cmd *)skb->data;
1003
+ ring = &cmd->rx_setup_32.rings[0];
1004
+
1005
+ cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_RX_RING_CFG;
1006
+ cmd->rx_setup_32.hdr.num_rings = 1;
1007
+
1008
+ flags = 0;
1009
+ flags |= HTT_RX_RING_FLAGS_MSDU_PAYLOAD;
1010
+ flags |= HTT_RX_RING_FLAGS_UNICAST_RX;
1011
+ flags |= HTT_RX_RING_FLAGS_MULTICAST_RX;
1012
+
1013
+ memset(ring, 0, sizeof(*ring));
1014
+ ring->rx_ring_len = __cpu_to_le16(HTT_RX_RING_SIZE_MIN);
1015
+ ring->rx_ring_bufsize = __cpu_to_le16(HTT_RX_BUF_SIZE);
1016
+ ring->flags = __cpu_to_le16(flags);
1017
+
1018
+ ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
1019
+ if (ret) {
1020
+ dev_kfree_skb_any(skb);
1021
+ return ret;
1022
+ }
1023
+
1024
+ return 0;
1025
+}
1026
+
1027
+static int ath10k_htt_h2t_aggr_cfg_msg_32(struct ath10k_htt *htt,
1028
+ u8 max_subfrms_ampdu,
1029
+ u8 max_subfrms_amsdu)
9431030 {
9441031 struct ath10k *ar = htt->ar;
9451032 struct htt_aggr_conf *aggr_conf;
....@@ -968,6 +1055,53 @@
9681055 cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_AGGR_CFG;
9691056
9701057 aggr_conf = &cmd->aggr_conf;
1058
+ aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu;
1059
+ aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu;
1060
+
1061
+ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d",
1062
+ aggr_conf->max_num_amsdu_subframes,
1063
+ aggr_conf->max_num_ampdu_subframes);
1064
+
1065
+ ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
1066
+ if (ret) {
1067
+ dev_kfree_skb_any(skb);
1068
+ return ret;
1069
+ }
1070
+
1071
+ return 0;
1072
+}
1073
+
1074
+static int ath10k_htt_h2t_aggr_cfg_msg_v2(struct ath10k_htt *htt,
1075
+ u8 max_subfrms_ampdu,
1076
+ u8 max_subfrms_amsdu)
1077
+{
1078
+ struct ath10k *ar = htt->ar;
1079
+ struct htt_aggr_conf_v2 *aggr_conf;
1080
+ struct sk_buff *skb;
1081
+ struct htt_cmd *cmd;
1082
+ int len;
1083
+ int ret;
1084
+
1085
+ /* Firmware defaults are: amsdu = 3 and ampdu = 64 */
1086
+
1087
+ if (max_subfrms_ampdu == 0 || max_subfrms_ampdu > 64)
1088
+ return -EINVAL;
1089
+
1090
+ if (max_subfrms_amsdu == 0 || max_subfrms_amsdu > 31)
1091
+ return -EINVAL;
1092
+
1093
+ len = sizeof(cmd->hdr);
1094
+ len += sizeof(cmd->aggr_conf_v2);
1095
+
1096
+ skb = ath10k_htc_alloc_skb(ar, len);
1097
+ if (!skb)
1098
+ return -ENOMEM;
1099
+
1100
+ skb_put(skb, len);
1101
+ cmd = (struct htt_cmd *)skb->data;
1102
+ cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_AGGR_CFG;
1103
+
1104
+ aggr_conf = &cmd->aggr_conf_v2;
9711105 aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu;
9721106 aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu;
9731107
....@@ -1075,6 +1209,7 @@
10751209 int len = 0;
10761210 int msdu_id = -1;
10771211 int res;
1212
+ const u8 *peer_addr;
10781213 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
10791214
10801215 len += sizeof(cmd->hdr);
....@@ -1090,7 +1225,16 @@
10901225 ieee80211_is_deauth(hdr->frame_control) ||
10911226 ieee80211_is_disassoc(hdr->frame_control)) &&
10921227 ieee80211_has_protected(hdr->frame_control)) {
1093
- skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
1228
+ peer_addr = hdr->addr1;
1229
+ if (is_multicast_ether_addr(peer_addr)) {
1230
+ skb_put(msdu, sizeof(struct ieee80211_mmie_16));
1231
+ } else {
1232
+ if (skb_cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP ||
1233
+ skb_cb->ucast_cipher == WLAN_CIPHER_SUITE_GCMP_256)
1234
+ skb_put(msdu, IEEE80211_GCMP_MIC_LEN);
1235
+ else
1236
+ skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
1237
+ }
10941238 }
10951239
10961240 txdesc = ath10k_htc_alloc_skb(ar, len);
....@@ -1126,7 +1270,8 @@
11261270 return 0;
11271271
11281272 err_unmap_msdu:
1129
- dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
1273
+ if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
1274
+ dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
11301275 err_free_txdesc:
11311276 dev_kfree_skb_any(txdesc);
11321277 err_free_msdu_id:
....@@ -1134,6 +1279,123 @@
11341279 ath10k_htt_tx_free_msdu_id(htt, msdu_id);
11351280 spin_unlock_bh(&htt->tx_lock);
11361281 err:
1282
+ return res;
1283
+}
1284
+
1285
+#define HTT_TX_HL_NEEDED_HEADROOM \
1286
+ (unsigned int)(sizeof(struct htt_cmd_hdr) + \
1287
+ sizeof(struct htt_data_tx_desc) + \
1288
+ sizeof(struct ath10k_htc_hdr))
1289
+
1290
+static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
1291
+ struct sk_buff *msdu)
1292
+{
1293
+ struct ath10k *ar = htt->ar;
1294
+ int res, data_len;
1295
+ struct htt_cmd_hdr *cmd_hdr;
1296
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
1297
+ struct htt_data_tx_desc *tx_desc;
1298
+ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
1299
+ struct sk_buff *tmp_skb;
1300
+ bool is_eth = (txmode == ATH10K_HW_TXRX_ETHERNET);
1301
+ u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
1302
+ u8 tid = ath10k_htt_tx_get_tid(msdu, is_eth);
1303
+ u8 flags0 = 0;
1304
+ u16 flags1 = 0;
1305
+ u16 msdu_id = 0;
1306
+
1307
+ if ((ieee80211_is_action(hdr->frame_control) ||
1308
+ ieee80211_is_deauth(hdr->frame_control) ||
1309
+ ieee80211_is_disassoc(hdr->frame_control)) &&
1310
+ ieee80211_has_protected(hdr->frame_control)) {
1311
+ skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
1312
+ }
1313
+
1314
+ data_len = msdu->len;
1315
+
1316
+ switch (txmode) {
1317
+ case ATH10K_HW_TXRX_RAW:
1318
+ case ATH10K_HW_TXRX_NATIVE_WIFI:
1319
+ flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
1320
+ fallthrough;
1321
+ case ATH10K_HW_TXRX_ETHERNET:
1322
+ flags0 |= SM(txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
1323
+ break;
1324
+ case ATH10K_HW_TXRX_MGMT:
1325
+ flags0 |= SM(ATH10K_HW_TXRX_MGMT,
1326
+ HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
1327
+ flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
1328
+
1329
+ if (htt->disable_tx_comp)
1330
+ flags1 |= HTT_DATA_TX_DESC_FLAGS1_TX_COMPLETE;
1331
+ break;
1332
+ }
1333
+
1334
+ if (skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)
1335
+ flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
1336
+
1337
+ flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
1338
+ flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID);
1339
+ if (msdu->ip_summed == CHECKSUM_PARTIAL &&
1340
+ !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
1341
+ flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD;
1342
+ flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD;
1343
+ }
1344
+
1345
+ /* Prepend the HTT header and TX desc struct to the data message
1346
+ * and realloc the skb if it does not have enough headroom.
1347
+ */
1348
+ if (skb_headroom(msdu) < HTT_TX_HL_NEEDED_HEADROOM) {
1349
+ tmp_skb = msdu;
1350
+
1351
+ ath10k_dbg(htt->ar, ATH10K_DBG_HTT,
1352
+ "Not enough headroom in skb. Current headroom: %u, needed: %u. Reallocating...\n",
1353
+ skb_headroom(msdu), HTT_TX_HL_NEEDED_HEADROOM);
1354
+ msdu = skb_realloc_headroom(msdu, HTT_TX_HL_NEEDED_HEADROOM);
1355
+ kfree_skb(tmp_skb);
1356
+ if (!msdu) {
1357
+ ath10k_warn(htt->ar, "htt hl tx: Unable to realloc skb!\n");
1358
+ res = -ENOMEM;
1359
+ goto out;
1360
+ }
1361
+ }
1362
+
1363
+ if (ar->bus_param.hl_msdu_ids) {
1364
+ flags1 |= HTT_DATA_TX_DESC_FLAGS1_POSTPONED;
1365
+ res = ath10k_htt_tx_alloc_msdu_id(htt, msdu);
1366
+ if (res < 0) {
1367
+ ath10k_err(ar, "msdu_id allocation failed %d\n", res);
1368
+ goto out;
1369
+ }
1370
+ msdu_id = res;
1371
+ }
1372
+
1373
+ /* As msdu is freed by mac80211 (in ieee80211_tx_status()) and by
1374
+ * ath10k (in ath10k_htt_htc_tx_complete()) we have to increase
1375
+ * reference by one to avoid a use-after-free case and a double
1376
+ * free.
1377
+ */
1378
+ skb_get(msdu);
1379
+
1380
+ skb_push(msdu, sizeof(*cmd_hdr));
1381
+ skb_push(msdu, sizeof(*tx_desc));
1382
+ cmd_hdr = (struct htt_cmd_hdr *)msdu->data;
1383
+ tx_desc = (struct htt_data_tx_desc *)(msdu->data + sizeof(*cmd_hdr));
1384
+
1385
+ cmd_hdr->msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
1386
+ tx_desc->flags0 = flags0;
1387
+ tx_desc->flags1 = __cpu_to_le16(flags1);
1388
+ tx_desc->len = __cpu_to_le16(data_len);
1389
+ tx_desc->id = __cpu_to_le16(msdu_id);
1390
+ tx_desc->frags_paddr = 0; /* always zero */
1391
+ /* Initialize peer_id to INVALID_PEER because this is NOT
1392
+ * Reinjection path
1393
+ */
1394
+ tx_desc->peerid = __cpu_to_le32(HTT_INVALID_PEERID);
1395
+
1396
+ res = ath10k_htc_send_hl(&htt->ar->htc, htt->eid, msdu);
1397
+
1398
+out:
11371399 return res;
11381400 }
11391401
....@@ -1201,7 +1463,7 @@
12011463 case ATH10K_HW_TXRX_RAW:
12021464 case ATH10K_HW_TXRX_NATIVE_WIFI:
12031465 flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
1204
- /* fall through */
1466
+ fallthrough;
12051467 case ATH10K_HW_TXRX_ETHERNET:
12061468 if (ar->hw_params.continuous_frag_desc) {
12071469 ext_desc_t = htt->frag_desc.vaddr_desc_32;
....@@ -1360,7 +1622,7 @@
13601622 u16 msdu_id, flags1 = 0;
13611623 u16 freq = 0;
13621624 dma_addr_t frags_paddr = 0;
1363
- u32 txbuf_paddr;
1625
+ dma_addr_t txbuf_paddr;
13641626 struct htt_msdu_ext_desc_64 *ext_desc = NULL;
13651627 struct htt_msdu_ext_desc_64 *ext_desc_t = NULL;
13661628
....@@ -1403,7 +1665,7 @@
14031665 case ATH10K_HW_TXRX_RAW:
14041666 case ATH10K_HW_TXRX_NATIVE_WIFI:
14051667 flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
1406
- /* fall through */
1668
+ fallthrough;
14071669 case ATH10K_HW_TXRX_ETHERNET:
14081670 if (ar->hw_params.continuous_frag_desc) {
14091671 ext_desc_t = htt->frag_desc.vaddr_desc_64;
....@@ -1556,6 +1818,7 @@
15561818 .htt_tx = ath10k_htt_tx_32,
15571819 .htt_alloc_txbuff = ath10k_htt_tx_alloc_cont_txbuf_32,
15581820 .htt_free_txbuff = ath10k_htt_tx_free_cont_txbuf_32,
1821
+ .htt_h2t_aggr_cfg_msg = ath10k_htt_h2t_aggr_cfg_msg_32,
15591822 };
15601823
15611824 static const struct ath10k_htt_tx_ops htt_tx_ops_64 = {
....@@ -1566,13 +1829,24 @@
15661829 .htt_tx = ath10k_htt_tx_64,
15671830 .htt_alloc_txbuff = ath10k_htt_tx_alloc_cont_txbuf_64,
15681831 .htt_free_txbuff = ath10k_htt_tx_free_cont_txbuf_64,
1832
+ .htt_h2t_aggr_cfg_msg = ath10k_htt_h2t_aggr_cfg_msg_v2,
1833
+};
1834
+
1835
+static const struct ath10k_htt_tx_ops htt_tx_ops_hl = {
1836
+ .htt_send_rx_ring_cfg = ath10k_htt_send_rx_ring_cfg_hl,
1837
+ .htt_send_frag_desc_bank_cfg = ath10k_htt_send_frag_desc_bank_cfg_32,
1838
+ .htt_tx = ath10k_htt_tx_hl,
1839
+ .htt_h2t_aggr_cfg_msg = ath10k_htt_h2t_aggr_cfg_msg_32,
1840
+ .htt_flush_tx = ath10k_htt_flush_tx_queue,
15691841 };
15701842
15711843 void ath10k_htt_set_tx_ops(struct ath10k_htt *htt)
15721844 {
15731845 struct ath10k *ar = htt->ar;
15741846
1575
- if (ar->hw_params.target_64bit)
1847
+ if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
1848
+ htt->tx_ops = &htt_tx_ops_hl;
1849
+ else if (ar->hw_params.target_64bit)
15761850 htt->tx_ops = &htt_tx_ops_64;
15771851 else
15781852 htt->tx_ops = &htt_tx_ops_32;