]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/mwl/if_mwlvar.h
Merge ^/vendor/lvm-project/master up to its last change (upstream commit
[FreeBSD/FreeBSD.git] / sys / dev / mwl / if_mwlvar.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
5  * Copyright (c) 2007-2009 Marvell Semiconductor, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer,
13  *    without modification.
14  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
16  *    redistribution must be conditioned upon including a substantially
17  *    similar Disclaimer requirement for further binary redistribution.
18  *
19  * NO WARRANTY
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
23  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
24  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
25  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
28  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGES.
31  *
32  * $FreeBSD$
33  */
34
35 /*
36  * Definitions for the Marvell 88W8363 Wireless LAN controller.
37  */
38 #ifndef _DEV_MWL_MVVAR_H
39 #define _DEV_MWL_MVVAR_H
40
41 #include <sys/endian.h>
42 #include <sys/bus.h>
43 #include <net80211/ieee80211_radiotap.h>
44 #include <dev/mwl/mwlhal.h>
45 #include <dev/mwl/mwlreg.h>
46 #include <dev/mwl/if_mwlioctl.h>
47
48 #ifndef MWL_TXBUF
49 #define MWL_TXBUF       256             /* number of TX descriptors/buffers */
50 #endif
51 #ifndef MWL_TXACKBUF
52 #define MWL_TXACKBUF    (MWL_TXBUF/2)   /* number of TX ACK desc's/buffers */
53 #endif
54 #ifndef MWL_RXDESC
55 #define MWL_RXDESC      256             /* number of RX descriptors */
56 #endif
57 #ifndef MWL_RXBUF
58 #define MWL_RXBUF       ((5*MWL_RXDESC)/2)/* number of RX dma buffers */
59 #endif
60 #ifndef MWL_MAXBA
61 #define MWL_MAXBA       2               /* max BA streams/sta */
62 #endif
63
64 #ifdef MWL_SGDMA_SUPPORT
65 #define MWL_TXDESC      6               /* max tx descriptors/segments */
66 #else
67 #define MWL_TXDESC      1               /* max tx descriptors/segments */
68 #endif
69 #ifndef MWL_AGGR_SIZE
70 #define MWL_AGGR_SIZE   3839            /* max tx aggregation size */
71 #endif
72 #define MWL_AGEINTERVAL 1               /* poke f/w every sec to age q's */ 
73 #define MWL_MAXSTAID    64              /* max of 64 stations */
74
75 /*
76  * DMA state for tx/rx descriptors.
77  */
78
79 /*
80  * Software backed version of tx/rx descriptors.  We keep
81  * the software state out of the h/w descriptor structure
82  * so that may be allocated in uncached memory w/o paying
83  * performance hit.
84  */
85 struct mwl_txbuf {
86         STAILQ_ENTRY(mwl_txbuf) bf_list;
87         void            *bf_desc;       /* h/w descriptor */
88         bus_addr_t      bf_daddr;       /* physical addr of desc */
89         bus_dmamap_t    bf_dmamap;      /* DMA map for descriptors */
90         int             bf_nseg;
91         bus_dma_segment_t bf_segs[MWL_TXDESC];
92         struct mbuf     *bf_m;
93         struct ieee80211_node *bf_node;
94         struct mwl_txq  *bf_txq;                /* backpointer to tx q/ring */
95 };
96 typedef STAILQ_HEAD(, mwl_txbuf) mwl_txbufhead;
97
98 /*
99  * Common "base class" for tx/rx descriptor resources
100  * allocated using the bus dma api.
101  */
102 struct mwl_descdma {
103         const char*             dd_name;
104         void                    *dd_desc;       /* descriptors */
105         bus_addr_t              dd_desc_paddr;  /* physical addr of dd_desc */
106         bus_size_t              dd_desc_len;    /* size of dd_desc */
107         bus_dma_segment_t       dd_dseg;
108         int                     dd_dnseg;       /* number of segments */
109         bus_dma_tag_t           dd_dmat;        /* bus DMA tag */
110         bus_dmamap_t            dd_dmamap;      /* DMA map for descriptors */
111         void                    *dd_bufptr;     /* associated buffers */
112 };
113
114 /*
115  * TX/RX ring definitions.  There are 4 tx rings, one
116  * per AC, and 1 rx ring.  Note carefully that transmit
117  * descriptors are treated as a contiguous chunk and the
118  * firmware pre-fetches descriptors.  This means that we
119  * must preserve order when moving descriptors between
120  * the active+free lists; otherwise we may stall transmit.
121  */
122 struct mwl_txq {
123         struct mwl_descdma dma;         /* bus dma resources */
124         struct mtx      lock;           /* tx q lock */
125         char            name[12];       /* e.g. "mwl0_txq4" */
126         int             qnum;           /* f/w q number */
127         int             txpri;          /* f/w tx priority */
128         int             nfree;          /* # buffers on free list */
129         mwl_txbufhead   free;           /* queue of free buffers */
130         mwl_txbufhead   active;         /* queue of active buffers */
131 };
132
133 #define MWL_TXQ_LOCK_INIT(_sc, _tq) do { \
134         snprintf((_tq)->name, sizeof((_tq)->name), "%s_txq%u", \
135                 device_get_nameunit((_sc)->sc_dev), (_tq)->qnum); \
136         mtx_init(&(_tq)->lock, (_tq)->name, NULL, MTX_DEF); \
137 } while (0)
138 #define MWL_TXQ_LOCK_DESTROY(_tq)       mtx_destroy(&(_tq)->lock)
139 #define MWL_TXQ_LOCK(_tq)               mtx_lock(&(_tq)->lock)
140 #define MWL_TXQ_UNLOCK(_tq)             mtx_unlock(&(_tq)->lock)
141 #define MWL_TXQ_LOCK_ASSERT(_tq)        mtx_assert(&(_tq)->lock, MA_OWNED)
142
143 #define MWL_TXDESC_SYNC(txq, ds, how) do { \
144         bus_dmamap_sync((txq)->dma.dd_dmat, (txq)->dma.dd_dmamap, how); \
145 } while(0)
146
147 /*
148  * RX dma buffers that are not in use are kept on a list.
149  */
150 struct mwl_jumbo {
151         SLIST_ENTRY(mwl_jumbo) next;
152 };
153 typedef SLIST_HEAD(, mwl_jumbo) mwl_jumbohead;
154
155 #define MWL_JUMBO_DATA2BUF(_data)       ((struct mwl_jumbo *)(_data))
156 #define MWL_JUMBO_BUF2DATA(_buf)                ((uint8_t *)(_buf))
157 #define MWL_JUMBO_OFFSET(_sc, _data) \
158         (((const uint8_t *)(_data)) - (const uint8_t *)((_sc)->sc_rxmem))
159 #define MWL_JUMBO_DMA_ADDR(_sc, _data) \
160         ((_sc)->sc_rxmem_paddr + MWL_JUMBO_OFFSET(_sc, _data))
161
162 struct mwl_rxbuf {
163         STAILQ_ENTRY(mwl_rxbuf) bf_list;
164         void            *bf_desc;       /* h/w descriptor */
165         bus_addr_t      bf_daddr;       /* physical addr of desc */
166         uint8_t         *bf_data;       /* rx data area */
167 };
168 typedef STAILQ_HEAD(, mwl_rxbuf) mwl_rxbufhead;
169
170 #define MWL_RXDESC_SYNC(sc, ds, how) do { \
171         bus_dmamap_sync((sc)->sc_rxdma.dd_dmat, (sc)->sc_rxdma.dd_dmamap, how);\
172 } while (0)
173
174 /*
175  * BA stream state.  One of these is setup for each stream
176  * allocated/created for use.  We pre-allocate the h/w stream
177  * before sending ADDBA request then complete the setup when
178  * get ADDBA response (success).  The completed state is setup
179  * to optimize the fast path in mwl_txstart--we precalculate
180  * the QoS control bits in the outbound frame and use those
181  * to identify which BA stream to use (assigning the h/w q to
182  * the TxPriority field of the descriptor).
183  *
184  * NB: Each station may have at most MWL_MAXBA streams at one time.  
185  */
186 struct mwl_bastate {
187         uint16_t        qos;            /* QoS ctl for BA stream */
188         uint8_t         txq;            /* h/w q for BA stream */
189         const MWL_HAL_BASTREAM *bastream; /* A-MPDU BA stream */
190 };
191
192 static __inline__ void
193 mwl_bastream_setup(struct mwl_bastate *bas, int tid, int txq)
194 {
195         bas->txq = txq;
196         bas->qos = htole16(tid | IEEE80211_QOS_ACKPOLICY_BA);
197 }
198
199 static __inline__ void
200 mwl_bastream_free(struct mwl_bastate *bas)
201 {
202         bas->qos = 0;
203         bas->bastream = NULL;
204         /* NB: don't need to clear txq */
205 }
206
207 /*
208  * Check the QoS control bits from an outbound frame against the
209  * value calculated when a BA stream is setup (above).  We need
210  * to match the TID and also the ACK policy so we only match AMPDU
211  * frames.  The bits from the frame are assumed in network byte
212  * order, hence the potential byte swap.
213  */
214 static __inline__ int
215 mwl_bastream_match(const struct mwl_bastate *bas, uint16_t qos)
216 {
217         return (qos & htole16(IEEE80211_QOS_TID|IEEE80211_QOS_ACKPOLICY)) ==
218             bas->qos;
219 }
220
221 /* driver-specific node state */
222 struct mwl_node {
223         struct ieee80211_node mn_node;  /* base class */
224         struct mwl_ant_info mn_ai;      /* antenna info */
225         uint32_t        mn_avgrssi;     /* average rssi over all rx frames */
226         uint16_t        mn_staid;       /* firmware station id */
227         struct mwl_bastate mn_ba[MWL_MAXBA];
228         struct mwl_hal_vap *mn_hvap;    /* hal vap handle */
229 };
230 #define MWL_NODE(ni)            ((struct mwl_node *)(ni))
231 #define MWL_NODE_CONST(ni)      ((const struct mwl_node *)(ni))
232
233 /*
234  * Driver-specific vap state.
235  */
236 struct mwl_vap {
237         struct ieee80211vap mv_vap;             /* base class */
238         struct mwl_hal_vap *mv_hvap;            /* hal vap handle */
239         struct mwl_hal_vap *mv_ap_hvap;         /* ap hal vap handle for wds */
240         uint16_t        mv_last_ps_sta;         /* last count of ps sta's */
241         uint16_t        mv_eapolformat;         /* fixed tx rate for EAPOL */
242         int             (*mv_newstate)(struct ieee80211vap *,
243                                     enum ieee80211_state, int);
244         int             (*mv_set_tim)(struct ieee80211_node *, int);
245 };
246 #define MWL_VAP(vap)    ((struct mwl_vap *)(vap))
247 #define MWL_VAP_CONST(vap)      ((const struct mwl_vap *)(vap))
248
249 struct mwl_softc {
250         struct ieee80211com     sc_ic;
251         struct mbufq            sc_snd;
252         struct mwl_stats        sc_stats;       /* interface statistics */
253         int                     sc_debug;
254         device_t                sc_dev;
255         bus_dma_tag_t           sc_dmat;        /* bus DMA tag */
256         bus_space_handle_t      sc_io0h;        /* BAR 0 */
257         bus_space_tag_t         sc_io0t;
258         bus_space_handle_t      sc_io1h;        /* BAR 1 */
259         bus_space_tag_t         sc_io1t;
260         struct mtx              sc_mtx;         /* master lock (recursive) */
261         struct taskqueue        *sc_tq;         /* private task queue */
262         struct callout  sc_watchdog;
263         int                     sc_tx_timer;
264         unsigned int            sc_running : 1,
265                                 sc_invalid : 1, /* disable hardware accesses */
266                                 sc_recvsetup:1, /* recv setup */
267                                 sc_csapending:1,/* 11h channel switch pending */
268                                 sc_radarena : 1,/* radar detection enabled */
269                                 sc_rxblocked: 1;/* rx waiting for dma buffers */
270
271         struct mwl_hal          *sc_mh;         /* h/w access layer */
272         struct mwl_hal_vap      *sc_hvap;       /* hal vap handle */
273         struct mwl_hal_hwspec   sc_hwspecs;     /* h/w capabilities */
274         uint32_t                sc_fwrelease;   /* release # of loaded f/w */
275         struct mwl_hal_txrxdma  sc_hwdma;       /* h/w dma setup */
276         uint32_t                sc_imask;       /* interrupt mask copy */
277         enum ieee80211_phymode  sc_curmode;
278         u_int16_t               sc_curaid;      /* current association id */
279         u_int8_t                sc_curbssid[IEEE80211_ADDR_LEN];
280         MWL_HAL_CHANNEL         sc_curchan;
281         MWL_HAL_TXRATE_HANDLING sc_txratehandling;
282         u_int16_t               sc_rxantenna;   /* rx antenna */
283         u_int16_t               sc_txantenna;   /* tx antenna */
284         uint8_t                 sc_napvaps;     /* # ap mode vaps */
285         uint8_t                 sc_nwdsvaps;    /* # wds mode vaps */
286         uint8_t                 sc_nstavaps;    /* # sta mode vaps */
287         uint8_t                 sc_ndwdsvaps;   /* # sta mode dwds vaps */
288         uint8_t                 sc_nbssid0;     /* # vap's using base mac */
289         uint32_t                sc_bssidmask;   /* bssid mask */
290
291         void                    (*sc_recv_mgmt)(struct ieee80211com *,
292                                     struct mbuf *,
293                                     struct ieee80211_node *,
294                                     int, int, int, u_int32_t);
295         int                     (*sc_newstate)(struct ieee80211com *,
296                                     enum ieee80211_state, int);
297         void                    (*sc_node_cleanup)(struct ieee80211_node *);
298         void                    (*sc_node_drain)(struct ieee80211_node *);
299         int                     (*sc_recv_action)(struct ieee80211_node *,
300                                     const struct ieee80211_frame *,
301                                     const uint8_t *, const uint8_t *);
302         int                     (*sc_addba_request)(struct ieee80211_node *,
303                                     struct ieee80211_tx_ampdu *,
304                                     int dialogtoken, int baparamset,
305                                     int batimeout);
306         int                     (*sc_addba_response)(struct ieee80211_node *,
307                                     struct ieee80211_tx_ampdu *,
308                                     int status, int baparamset,
309                                     int batimeout);
310         void                    (*sc_addba_stop)(struct ieee80211_node *,
311                                     struct ieee80211_tx_ampdu *);
312
313         struct mwl_descdma      sc_rxdma;       /* rx bus dma resources */
314         mwl_rxbufhead           sc_rxbuf;       /* rx buffers */
315         struct mwl_rxbuf        *sc_rxnext;     /* next rx buffer to process */
316         struct task             sc_rxtask;      /* rx int processing */
317         void                    *sc_rxmem;      /* rx dma buffer pool */
318         bus_dma_tag_t           sc_rxdmat;      /* rx bus DMA tag */
319         bus_size_t              sc_rxmemsize;   /* rx dma buffer pool size */
320         bus_dmamap_t            sc_rxmap;       /* map for rx dma buffers */
321         bus_addr_t              sc_rxmem_paddr; /* physical addr of sc_rxmem */
322         mwl_jumbohead           sc_rxfree;      /* list of free dma buffers */
323         int                     sc_nrxfree;     /* # buffers on rx free list */
324         struct mtx              sc_rxlock;      /* lock on sc_rxfree */
325
326         struct mwl_txq          sc_txq[MWL_NUM_TX_QUEUES];
327         struct mwl_txq          *sc_ac2q[5];    /* WME AC -> h/w q map */
328         struct mbuf             *sc_aggrq;      /* aggregation q */
329         struct task             sc_txtask;      /* tx int processing */
330         struct task             sc_bawatchdogtask;/* BA watchdog processing */
331
332         struct task             sc_radartask;   /* radar detect processing */
333         struct task             sc_chanswitchtask;/* chan switch processing */
334
335         uint8_t                 sc_staid[MWL_MAXSTAID/NBBY];
336         int                     sc_ageinterval;
337         struct callout          sc_timer;       /* periodic work */
338
339         struct mwl_tx_radiotap_header sc_tx_th;
340         struct mwl_rx_radiotap_header sc_rx_th;
341 };
342
343 #define MWL_LOCK_INIT(_sc) \
344         mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
345                  NULL, MTX_DEF | MTX_RECURSE)
346 #define MWL_LOCK_DESTROY(_sc)   mtx_destroy(&(_sc)->sc_mtx)
347 #define MWL_LOCK(_sc)           mtx_lock(&(_sc)->sc_mtx)
348 #define MWL_UNLOCK(_sc)         mtx_unlock(&(_sc)->sc_mtx)
349 #define MWL_LOCK_ASSERT(_sc)    mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
350
351 #define MWL_RXFREE_INIT(_sc) \
352         mtx_init(&(_sc)->sc_rxlock, device_get_nameunit((_sc)->sc_dev), \
353                  NULL, MTX_DEF)
354 #define MWL_RXFREE_DESTROY(_sc) mtx_destroy(&(_sc)->sc_rxlock)
355 #define MWL_RXFREE_LOCK(_sc)    mtx_lock(&(_sc)->sc_rxlock)
356 #define MWL_RXFREE_UNLOCK(_sc)  mtx_unlock(&(_sc)->sc_rxlock)
357 #define MWL_RXFREE_ASSERT(_sc)  mtx_assert(&(_sc)->sc_rxlock, MA_OWNED)
358
359 int     mwl_attach(u_int16_t, struct mwl_softc *);
360 int     mwl_detach(struct mwl_softc *);
361 void    mwl_resume(struct mwl_softc *);
362 void    mwl_suspend(struct mwl_softc *);
363 void    mwl_shutdown(void *);
364 void    mwl_intr(void *);
365
366 #endif /* _DEV_MWL_MVVAR_H */