lin
2025-07-31 065ea569db06206874bbfa18eb25ff6121aec09b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/* SPDX-License-Identifier: GPL-2.0 */
 
/******************************************************************************
 *
 * Copyright (C) 2020 SeekWave Technology Co.,Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 ******************************************************************************/
 
#ifndef __SKW_EDMA_H__
#define __SKW_EDMA_H__
 
#define SKW_NR_EDMA_NODE                                32
#define SKW_NR_EDMA_ELEMENT                             64
#define SKW_EDMA_DATA_LEN                               768
#define SKW_EDMA_SKB_DATA_LEN                           2048
 
#define SKW_EDMA_WIFI_CMD_CHN                           14
#define SKW_EDMA_WIFI_SHORT_EVENT_CHN                   15
#define SKW_EDMA_WIFI_LONG_EVENT_CHN                    16
#define SKW_EDMA_WIFI_RX0_FITER_CHN                     17
#define SKW_EDMA_WIFI_RX1_FITER_CHN                     18
#define SKW_EDMA_WIFI_TX0_CHN                           19
#define SKW_EDMA_WIFI_TX1_CHN                           20
#define SKW_EDMA_WIFI_TX0_FREE_CHN                      21
#define SKW_EDMA_WIFI_TX1_FREE_CHN                      22
#define SKW_EDMA_WIFI_RX0_FREE_CHN                      23
#define SKW_EDMA_WIFI_RX1_FREE_CHN                      24
#define SKW_EDMA_WIFI_RX0_CHN                           25
#define SKW_EDMA_WIFI_RX1_CHN                           26
 
 
#define SKW_EDMA_EVENT_CHN_NODE_NUM                     2
#define SKW_EDMA_FILTER_CHN_NODE_NUM                    8
#define SKW_EDMA_TX_CHN_NODE_NUM                        64
#define SKW_EDMA_TX_FREE_CHN_NODE_NUM                   16
#define SKW_EDMA_RX_CHN_NODE_NUM                        32
#define SKW_EDMA_RX_FREE_CHN_NODE_NUM                   24
 
#define SKW_EDMA_TX_CHN_CREDIT                          16
 
#define TX_BUF_ADDR_CNT                                 64
#define TX_FREE_BUF_ADDR_CNT                            64
#define RX_PKT_ADDR_BUF_CNT                             64
#define RX_FREE_BUF_ADDR_CNT                            32
 
#define SKW_EDMA_HEADR_RESVD                            8
#define skw_dma_to_pcie(addr)                           ((addr) + 0x8000000000)
#define skw_pcie_to_dma(addr)                           ((addr) - 0x8000000000)
#define skw_pcie_to_va(addr)                            phys_to_virt(skw_pcie_to_dma(addr))
 
typedef int (*skw_edma_isr)(void *priv, u64 first_pa, u64 last_pa, int cnt);
typedef int (*skw_edma_empty_isr)(void *priv);
 
enum SKW_EDMA_DIRECTION {
   SKW_HOST_TO_FW = 0,
   SKW_FW_TO_HOST,
};
 
enum SKW_EDMA_CHN_PRIORITY {
   SKW_EDMA_CHN_PRIORITY_0,
   SKW_EDMA_CHN_PRIORITY_1,
   SKW_EDMA_CHN_PRIORITY_2,
   SKW_EDMA_CHN_PRIORITY_3
};
 
enum SKW_EDMA_CHN_BUFF_ATTR {
   SKW_EDMA_CHN_BUFF_LINNER,
   SKW_EDMA_CHN_BUFF_NON_LINNER,
};
 
enum SKW_EDMA_CHN_BUFF_TYPE {
   SKW_EDMA_CHN_LIST_BUFF,
   SKW_EDMA_CHN_RING_BUFF
};
 
enum SKW_EDMA_CHN_TRANS_MODE {
   SKW_EDMA_CHN_STD_MODE,
   SKW_EDMA_CHN_LINKLIST_MODE,
};
 
struct skw_edma_elem {
   u64 pa:40;
   u64 rsv:8;
 
   u64 eth_type:16;
 
   u8 id_rsv:2;
   u8 mac_id:2;
   u8 tid:4;
 
   u8 peer_idx:5;
   u8 prot:1;
   u8 encry_dis:1;
   u8 rate:1;
 
   u16 msdu_len:12;
   u16 resv:4;
} __packed;
 
struct skw_edma_hdr {
   u64 pcie_addr:40;
   u64 rsv0:16;
   u64 tx_int:1;
   u64 rsv1:6;
   u64 done:1;
 
   u64 hdr_next:40;
   u64 rsv2:8;
   u64 data_len:16;
} __packed;
 
struct skw_edma_node {
   struct list_head list;
   void *buffer;
   dma_addr_t dma_addr;
   int buffer_len;
   u16 used;
   u16 node_id;
};
 
struct skw_edma_chn {
   struct skw_core *skw;
   struct skw_lmac *lmac;
   struct list_head node_list;
   struct skw_edma_hdr *hdr;
   struct skw_edma_node *current_node;
   atomic_t nr_node;
   dma_addr_t edma_hdr_pa;
   u16 edma_hdr_size;
   u16 n_pld_size;
   u16 swtail;
   u16 channel;
   u16 max_node_num;
   u16 tx_node_count;
   u16 rx_node_count;
   u16 direction;
   atomic_t chn_refill;
   spinlock_t edma_chan_lock;
};
 
#ifdef CONFIG_SWT6621S_EDMA
int skw_edma_init(struct wiphy *wiphy);
void skw_edma_deinit(struct wiphy *wiphy);
int skw_edma_set_data(struct wiphy *wiphy, struct skw_edma_chn *edma,
           void *data, int len);
int skw_edma_tx(struct wiphy *wiphy, struct skw_edma_chn *edma, int tx_len);
int skw_edma_init_data_chan(void *priv, u8 lmac_id);
int skw_edma_get_refill(void *priv, u8 lmac_id);
void skw_edma_inc_refill(void *priv, u8 lmac_id);
void skw_edma_dec_refill(void *priv, u8 lmac_id);
bool skw_edma_is_txc_completed(struct skw_core *skw);
void skw_edma_mask_irq(struct skw_core *skw, u8 lmac_id);
void skw_edma_unmask_irq(struct skw_core *skw, u8 lmac_id);
 
static inline u16 skw_edma_hdr_tail(struct skw_edma_chn *edma_chn)
{
   return (edma_chn->swtail + 1) % edma_chn->max_node_num;
}
#else
static inline int skw_edma_init(struct wiphy *wiphy)
{
   return 0;
}
 
static inline void skw_edma_deinit(struct wiphy *wiphy)
{
}
 
static inline int skw_edma_set_data(struct wiphy *wiphy,
       struct skw_edma_chn *edma, void *data, int len)
{
   return 0;
}
 
static inline int skw_edma_tx(struct wiphy *wiphy,
       struct skw_edma_chn *edma, int tx_len)
{
   return 0;
}
 
static inline int skw_edma_init_data_chan(void *priv, u8 lmac_id)
{
   return 0;
}
 
static inline int skw_edma_get_refill(void *priv, u8 lmac_id)
{
   return 0;
}
 
static inline void skw_edma_inc_refill(void *priv, u8 lmac_id)
{
}
 
static inline void skw_edma_dec_refill(void *priv, u8 lmac_id)
{
}
 
static inline u16 skw_edma_hdr_tail(struct skw_edma_chn *edma_chn)
{
   return (edma_chn->swtail + 1) % edma_chn->max_node_num;
}
 
static inline bool skw_edma_is_txc_completed(struct skw_core *skw)
{
   return true;
}
 
static inline void skw_edma_mask_irq(struct skw_core *skw, u8 lmac_id)
{
}
 
static inline void skw_edma_unmask_irq(struct skw_core *skw, u8 lmac_id)
{
}
 
#endif
#endif