forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
....@@ -7,6 +7,7 @@
77 *
88 * Copyright(c) 2015 Intel Mobile Communications GmbH
99 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
10
+ * Copyright(c) 2019 - 2020 Intel Corporation
1011 *
1112 * This program is free software; you can redistribute it and/or modify
1213 * it under the terms of version 2 of the GNU General Public License as
....@@ -16,11 +17,6 @@
1617 * WITHOUT ANY WARRANTY; without even the implied warranty of
1718 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1819 * General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU General Public License
21
- * along with this program; if not, write to the Free Software
22
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
23
- * USA
2420 *
2521 * The full GNU General Public License is included in this distribution
2622 * in the file called COPYING.
....@@ -33,6 +29,7 @@
3329 *
3430 * Copyright(c) 2015 Intel Mobile Communications GmbH
3531 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
32
+ * Copyright(c) 2019 - 2020 Intel Corporation
3633 * All rights reserved.
3734 *
3835 * Redistribution and use in source and binary forms, with or without
....@@ -65,16 +62,20 @@
6562 #include <linux/kernel.h>
6663 #include <linux/bsearch.h>
6764
65
+#include "fw/api/tx.h"
6866 #include "iwl-trans.h"
6967 #include "iwl-drv.h"
7068 #include "iwl-fh.h"
69
+#include "queue/tx.h"
70
+#include <linux/dmapool.h>
7171
7272 struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
7373 struct device *dev,
74
- const struct iwl_cfg *cfg,
75
- const struct iwl_trans_ops *ops)
74
+ const struct iwl_trans_ops *ops,
75
+ const struct iwl_cfg_trans_params *cfg_trans)
7676 {
7777 struct iwl_trans *trans;
78
+ int txcmd_size, txcmd_align;
7879 #ifdef CONFIG_LOCKDEP
7980 static struct lock_class_key __key;
8081 #endif
....@@ -83,34 +84,96 @@
8384 if (!trans)
8485 return NULL;
8586
87
+ trans->trans_cfg = cfg_trans;
88
+ if (!cfg_trans->gen2) {
89
+ txcmd_size = sizeof(struct iwl_tx_cmd);
90
+ txcmd_align = sizeof(void *);
91
+ } else if (cfg_trans->device_family < IWL_DEVICE_FAMILY_AX210) {
92
+ txcmd_size = sizeof(struct iwl_tx_cmd_gen2);
93
+ txcmd_align = 64;
94
+ } else {
95
+ txcmd_size = sizeof(struct iwl_tx_cmd_gen3);
96
+ txcmd_align = 128;
97
+ }
98
+
99
+ txcmd_size += sizeof(struct iwl_cmd_header);
100
+ txcmd_size += 36; /* biggest possible 802.11 header */
101
+
102
+ /* Ensure device TX cmd cannot reach/cross a page boundary in gen2 */
103
+ if (WARN_ON(cfg_trans->gen2 && txcmd_size >= txcmd_align))
104
+ return ERR_PTR(-EINVAL);
105
+
86106 #ifdef CONFIG_LOCKDEP
87107 lockdep_init_map(&trans->sync_cmd_lockdep_map, "sync_cmd_lockdep_map",
88108 &__key, 0);
89109 #endif
90110
91111 trans->dev = dev;
92
- trans->cfg = cfg;
93112 trans->ops = ops;
94113 trans->num_rx_queues = 1;
114
+
115
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
116
+ trans->txqs.bc_tbl_size = sizeof(struct iwl_gen3_bc_tbl);
117
+ else
118
+ trans->txqs.bc_tbl_size = sizeof(struct iwlagn_scd_bc_tbl);
119
+ /*
120
+ * For gen2 devices, we use a single allocation for each byte-count
121
+ * table, but they're pretty small (1k) so use a DMA pool that we
122
+ * allocate here.
123
+ */
124
+ if (trans->trans_cfg->gen2) {
125
+ trans->txqs.bc_pool = dmam_pool_create("iwlwifi:bc", dev,
126
+ trans->txqs.bc_tbl_size,
127
+ 256, 0);
128
+ if (!trans->txqs.bc_pool)
129
+ return NULL;
130
+ }
131
+
132
+ if (trans->trans_cfg->use_tfh) {
133
+ trans->txqs.tfd.addr_size = 64;
134
+ trans->txqs.tfd.max_tbs = IWL_TFH_NUM_TBS;
135
+ trans->txqs.tfd.size = sizeof(struct iwl_tfh_tfd);
136
+ } else {
137
+ trans->txqs.tfd.addr_size = 36;
138
+ trans->txqs.tfd.max_tbs = IWL_NUM_OF_TBS;
139
+ trans->txqs.tfd.size = sizeof(struct iwl_tfd);
140
+ }
141
+ trans->max_skb_frags = IWL_TRANS_MAX_FRAGS(trans);
95142
96143 snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name),
97144 "iwl_cmd_pool:%s", dev_name(trans->dev));
98145 trans->dev_cmd_pool =
99146 kmem_cache_create(trans->dev_cmd_pool_name,
100
- sizeof(struct iwl_device_cmd),
101
- sizeof(void *),
102
- SLAB_HWCACHE_ALIGN,
103
- NULL);
147
+ txcmd_size, txcmd_align,
148
+ SLAB_HWCACHE_ALIGN, NULL);
104149 if (!trans->dev_cmd_pool)
105150 return NULL;
106151
107152 WARN_ON(!ops->wait_txq_empty && !ops->wait_tx_queues_empty);
153
+
154
+ trans->txqs.tso_hdr_page = alloc_percpu(struct iwl_tso_hdr_page);
155
+ if (!trans->txqs.tso_hdr_page) {
156
+ kmem_cache_destroy(trans->dev_cmd_pool);
157
+ return NULL;
158
+ }
108159
109160 return trans;
110161 }
111162
112163 void iwl_trans_free(struct iwl_trans *trans)
113164 {
165
+ int i;
166
+
167
+ for_each_possible_cpu(i) {
168
+ struct iwl_tso_hdr_page *p =
169
+ per_cpu_ptr(trans->txqs.tso_hdr_page, i);
170
+
171
+ if (p->page)
172
+ __free_page(p->page);
173
+ }
174
+
175
+ free_percpu(trans->txqs.tso_hdr_page);
176
+
114177 kmem_cache_destroy(trans->dev_cmd_pool);
115178 }
116179
....@@ -207,17 +270,3 @@
207270 return 0;
208271 }
209272 IWL_EXPORT_SYMBOL(iwl_cmd_groups_verify_sorted);
210
-
211
-void iwl_trans_ref(struct iwl_trans *trans)
212
-{
213
- if (trans->ops->ref)
214
- trans->ops->ref(trans);
215
-}
216
-IWL_EXPORT_SYMBOL(iwl_trans_ref);
217
-
218
-void iwl_trans_unref(struct iwl_trans *trans)
219
-{
220
- if (trans->ops->unref)
221
- trans->ops->unref(trans);
222
-}
223
-IWL_EXPORT_SYMBOL(iwl_trans_unref);