Initial cut of the open ath9k htc firmware.
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / build / magpie_1_1 / sboot / hif / pci / hif_pci.c
1 #include <hif_api.h>
2 #include <Magpie_api.h>
3 #include <cmnos_api.h>
4
5 #include <dma_lib.h>
6 #include "hif_pci.h"
7
8
9 /**************************Constants******************************/
10
11 /*************************Data types*******************************/
12 enum pci_regs{
13     MAG_REG_AHB_RESET   = 0x00050010,
14     MAG_REG_AHB_ARB     = 0x00050018
15 };
16
17 #define PCI_AHB_ARB_ENB             (1 << 3) 
18 #define PCI_AHB_RESET_DMA           (1 << 13) 
19 #define PCI_AHB_RESET_DMA_HST_RAW   (1 << 14)
20 #define PCI_AHB_RESET_DMA_HST       (1 << 15)
21
22 /*********************************softC************************/
23 typedef struct __pci_softc{
24     HIF_CALLBACK       sw;
25 }__pci_softc_t;
26
27
28 #define ret_pkt         sw.send_buf_done
29 #define indicate_pkt    sw.recv_buf
30 #define htc_ctx         sw.context
31 /*********************************DEFINES**********************************/
32 #define  hdl_to_softc(_hdl)     (__pci_softc_t *)(_hdl)
33
34 #define  PCI_ENG_NUM(_eng)     HIF_PCI_PIPE_##_eng
35
36 #define PCI_INIT_PIPE   {   \
37     PCI_ENG_NUM(RX0),       \
38     PCI_ENG_NUM(RX1),       \
39     PCI_ENG_NUM(RX2),       \
40     PCI_ENG_NUM(RX3),       \
41     PCI_ENG_NUM(TX0),       \
42     PCI_ENG_NUM(TX1),       \
43 }
44
45 #define rx_pipe0                    DMA_ENGINE_RX0
46 #define rx_pipe1                    DMA_ENGINE_RX1
47 #define tx_pipe0                    DMA_ENGINE_TX0
48 #define tx_pipe1                    DMA_ENGINE_TX1
49 #define dbg_pci                     0
50 #define dbg_pci_loopback            0
51
52 #define PCI_DBG_MODE                0
53
54 void    __pci_cfg_pipe(hif_handle_t hdl, int pipe, int num_desc);
55 int     __pci_get_max_msg_len(hif_handle_t hdl, int pipe);
56 void    __pci_return_recv(hif_handle_t hdl, int pipe, VBUF *buf);
57 void    __pci_reset(void);
58 void    __pci_enable(void);
59
60
61 /***********************************Globals********************************/
62 /**
63  * @brief Engines are fixed
64  */
65 __pci_softc_t    pci_sc = {0};
66
67
68 /**************************************APIs********************************/
69
70 A_UINT32
71 __pci_reg_read(A_UINT32 addr)
72 {
73     return *((volatile A_UINT32 *)addr);
74 }
75
76 void
77 __pci_reg_write(A_UINT32 addr, A_UINT32 val)
78 {
79     *((volatile A_UINT32 *)addr) = val;
80 }
81
82 A_UINT8
83 __pci_get_pipe(dma_engine_t   eng)
84 {
85     switch (eng) {
86     case DMA_ENGINE_RX0:
87         return HIF_PCI_PIPE_RX0;
88     case DMA_ENGINE_RX1:
89         return HIF_PCI_PIPE_RX1;
90     case DMA_ENGINE_RX2:
91         return HIF_PCI_PIPE_RX2;
92     case DMA_ENGINE_RX3:
93         return HIF_PCI_PIPE_RX3;
94     case DMA_ENGINE_TX0:
95         return HIF_PCI_PIPE_TX0;
96     case DMA_ENGINE_TX1:
97         return HIF_PCI_PIPE_TX1;
98     default:
99         adf_os_assert(0);
100     }
101 }
102
103 dma_engine_t
104 __pci_get_tx_eng(hif_pci_pipe_tx_t  pipe)
105 {
106     switch (pipe) {
107     case HIF_PCI_PIPE_TX0:
108         return DMA_ENGINE_TX0;
109
110     case HIF_PCI_PIPE_TX1:
111         return DMA_ENGINE_TX1;
112
113     default:
114         return DMA_ENGINE_MAX;
115     }
116 }
117 dma_engine_t
118 __pci_get_rx_eng(hif_pci_pipe_rx_t  pipe)
119 {
120     switch (pipe) {
121     case HIF_PCI_PIPE_RX0:
122         return DMA_ENGINE_RX0;
123         
124     case HIF_PCI_PIPE_RX1:
125         return DMA_ENGINE_RX1;
126         
127     case HIF_PCI_PIPE_RX2:
128         return DMA_ENGINE_RX2;
129         
130     case HIF_PCI_PIPE_RX3:
131         return DMA_ENGINE_RX3;
132     
133     default:
134         return DMA_ENGINE_MAX;
135     }
136 }
137
138
139
140 void
141 __pci_enable(void)
142 {
143     A_UINT32      r_data;
144     /**
145      * Grant access to the internal memory for PCI DMA
146      */
147     
148     r_data  = __pci_reg_read(MAG_REG_AHB_ARB);
149     r_data |= PCI_AHB_ARB_ENB;
150     __pci_reg_write(MAG_REG_AHB_ARB, r_data);
151 }
152
153 /**
154  * @brief PCI reset 
155  * XXX: Move this to RAM
156  */ 
157 void
158 __pci_reset(void)
159 {
160     volatile A_UINT32      r_data;
161     
162     /**
163      * Poll until the Host has reset
164      */ 
165     A_PRINTF("Waiting for host reset..");
166     for (;;) {
167         r_data =  __pci_reg_read(MAG_REG_AHB_RESET);
168
169         if ( r_data & PCI_AHB_RESET_DMA_HST_RAW)
170             break;
171     } 
172     A_PRINTF("received.\n");
173
174     /**
175      * Pull the AHB out of reset
176      */ 
177
178     r_data = __pci_reg_read(MAG_REG_AHB_RESET);
179     r_data &= ~PCI_AHB_RESET_DMA;
180     __pci_reg_write(MAG_REG_AHB_RESET, r_data);
181
182     A_DELAY_USECS(10);
183
184     /**
185      * Put the AHB into reset
186      */ 
187     
188     r_data = __pci_reg_read(MAG_REG_AHB_RESET);
189     r_data |= PCI_AHB_RESET_DMA;
190     __pci_reg_write(MAG_REG_AHB_RESET, r_data);
191
192     A_DELAY_USECS(10);
193     
194     /**
195      * Pull the AHB out of reset
196      */ 
197     
198     r_data = __pci_reg_read(MAG_REG_AHB_RESET);
199     r_data &= ~PCI_AHB_RESET_DMA;
200     __pci_reg_write(MAG_REG_AHB_RESET, r_data);
201
202     A_DELAY_USECS(10);
203 }
204 /**
205  * @brief Boot init
206  */
207 void
208 __pci_boot_init(void)
209 {
210     __pci_reset();
211     __pci_enable();
212     
213     dma_lib_tx_init(DMA_ENGINE_TX0, DMA_IF_PCI);
214     dma_lib_rx_init(DMA_ENGINE_RX0, DMA_IF_PCI); 
215     
216     dma_lib_rx_config(DMA_ENGINE_RX0, PCI_MAX_BOOT_DESC, 
217                       PCI_MAX_DATA_PKT_LEN);
218
219 }
220 /**
221  * @brief
222  * 
223  * @param pConfig
224  * 
225  * @return hif_handle_t
226  */
227 hif_handle_t 
228 __pci_init(HIF_CONFIG *pConfig)
229 {
230     __pci_reset();
231     __pci_enable();    
232     
233     /**
234      * Initializing the other TX engines
235      */
236     dma_lib_tx_init(DMA_ENGINE_TX0, DMA_IF_PCI);
237     dma_lib_tx_init(DMA_ENGINE_TX1, DMA_IF_PCI);
238     
239     /**
240      * Initializing the other RX engines
241      */
242     dma_lib_rx_init(DMA_ENGINE_RX0, DMA_IF_PCI);
243     dma_lib_rx_init(DMA_ENGINE_RX1, DMA_IF_PCI); 
244     dma_lib_rx_init(DMA_ENGINE_RX2, DMA_IF_PCI); 
245     dma_lib_rx_init(DMA_ENGINE_RX3, DMA_IF_PCI);
246
247     return &pci_sc;
248 }
249 /**
250  * @brief Configure the receive pipe
251  * 
252  * @param hdl
253  * @param pipe
254  * @param num_desc
255  */
256 void
257 __pci_cfg_pipe(hif_handle_t hdl, int pipe, int num_desc)
258 {
259     dma_engine_t    eng;
260     A_UINT16        desc_len;
261
262     eng = __pci_get_rx_eng(pipe);
263     
264     if (eng == DMA_ENGINE_MAX) {
265         A_PRINTF("Bad Engine number\n");
266         return;
267     }
268     
269     desc_len = __pci_get_max_msg_len(hdl, pipe);
270     
271     dma_lib_rx_config(eng, num_desc, desc_len);
272 }
273 /**
274  * @brief Start the interface
275  * 
276  * @param hdl
277  */
278 void
279 __pci_start(hif_handle_t  hdl)
280 {
281     return;
282 }
283 /**
284  * @brief Register callback of thre HTC
285  * 
286  * @param hdl
287  * @param sw
288  */
289 void
290 __pci_reg_callback(hif_handle_t hdl, HIF_CALLBACK *sw)
291 {
292     __pci_softc_t   *sc = &pci_sc;
293     
294     sc->htc_ctx       = sw->context;
295     sc->indicate_pkt  = sw->recv_buf;
296     sc->ret_pkt       = sw->send_buf_done;
297 }
298
299 /**
300  * @brief reap the transmit queue for trasnmitted packets
301  * 
302  * @param sc
303  * @param eng_no
304  */
305 void
306 __pci_reap_xmitted(__pci_softc_t  *sc, dma_engine_t  eng_no)
307 {
308     VBUF *vbuf = NULL;
309     A_UINT8     pipe;
310    
311     pipe = __pci_get_pipe(eng_no);
312     
313     vbuf = dma_lib_reap_xmitted(eng_no);
314
315     if ( vbuf )
316         sc->ret_pkt(vbuf, sc->htc_ctx);
317     else
318         A_PRINTF("Empty RX Reap\n");
319     
320
321 }
322
323 /**
324  * @brief reap the receive queue for vbuf's on the specified
325  *        engine number
326  * 
327  * @param sc
328  * @param eng_no
329  */
330 void
331 __pci_reap_recv(__pci_softc_t  *sc, dma_engine_t  eng_no)
332 {
333     VBUF   *vbuf = NULL;
334
335     vbuf = dma_lib_reap_recv(eng_no);
336     
337     if(vbuf)
338         sc->indicate_pkt(NULL, vbuf, sc->htc_ctx);
339     else
340         A_PRINTF("Empty TX Reap \n");
341 }
342 /**
343  * @brief The interrupt handler
344  * 
345  * @param hdl
346  */
347 void
348 __pci_isr_handler(hif_handle_t hdl)
349 {
350     __pci_softc_t  *sc = &pci_sc;
351     A_UINT16      more = 0;
352     
353     do {
354
355         more = 0;
356
357         if( dma_lib_xmit_done(DMA_ENGINE_TX1) ) {
358             __pci_reap_xmitted(sc,DMA_ENGINE_TX1);
359             more = 1;
360         }
361         if( dma_lib_recv_pkt(DMA_ENGINE_RX3) ) {
362             __pci_reap_recv(sc, DMA_ENGINE_RX3);
363             more = 1;
364         }
365
366     } while( more );
367
368     do {
369
370         more = 0;
371
372         if( dma_lib_xmit_done(DMA_ENGINE_TX1) ) {
373             __pci_reap_xmitted(sc,DMA_ENGINE_TX1);
374             more = 1;
375         }
376         if( dma_lib_recv_pkt(DMA_ENGINE_RX2) ) {
377             __pci_reap_recv(sc, DMA_ENGINE_RX2);
378             more = 1;
379         }
380
381     } while( more );
382
383     do {
384
385         more = 0;
386
387         if( dma_lib_xmit_done(DMA_ENGINE_TX1) ) {
388             __pci_reap_xmitted(sc,DMA_ENGINE_TX1);
389             more = 1;
390         }
391         if( dma_lib_recv_pkt(DMA_ENGINE_RX1) ) {
392             __pci_reap_recv(sc, DMA_ENGINE_RX1);
393             more = 1;
394         }
395
396     } while( more );
397     
398     do {
399         
400         more = 0;
401         
402         if( dma_lib_xmit_done(DMA_ENGINE_TX0) ) {
403             __pci_reap_xmitted(sc,DMA_ENGINE_TX0);
404             more = 1;
405         }
406         
407         if( dma_lib_recv_pkt(DMA_ENGINE_RX0) ) {
408             __pci_reap_recv(sc, DMA_ENGINE_RX0);
409             more = 1;
410         }
411         
412     } while( more );
413
414 }
415 /**
416  * @brief transmit the vbuf from the specified pipe
417  * 
418  * @param hdl
419  * @param pipe
420  * @param buf
421  * 
422  * @return int
423  */
424 int
425 __pci_xmit_buf(hif_handle_t hdl, int pipe, VBUF *vbuf)
426 {
427     dma_engine_t   eng;
428    
429     eng = __pci_get_tx_eng(pipe);
430
431     if (eng == DMA_ENGINE_MAX) {
432         A_PRINTF("Invalid Pipe number\n");
433         return -1;
434     }
435
436     return dma_lib_hard_xmit(eng, vbuf);
437 }
438 /**
439  * @brief Submit the receive vbuf into the receive queue
440  * 
441  * @param handle
442  * @param pipe
443  * @param buf
444  */
445 void
446 __pci_return_recv(hif_handle_t hdl, int pipe, VBUF *buf)
447 {
448     dma_engine_t   eng;
449
450     eng = __pci_get_rx_eng(pipe);
451
452     if (eng == DMA_ENGINE_MAX)
453         return;
454
455     dma_lib_return_recv(eng, buf);
456 }
457 /**
458  * @brief Is this pipe number supported
459  * 
460  * @param handle
461  * @param pipe
462  * 
463  * @return int
464  */
465 int
466 __pci_is_pipe_supported(hif_handle_t hdl, int pipe)
467 {
468     if (pipe >= 0 && pipe <= 4)
469         return 1;
470     else
471         return 0;
472 }
473 /**
474  * @brief maximum message length this pipe can support
475  * 
476  * @param handle
477  * @param pipe
478  * 
479  * @return int
480  */
481 int  
482 __pci_get_max_msg_len(hif_handle_t hdl, int pipe)
483 {
484     if( pipe == HIF_PCI_PIPE_TX0 || pipe == HIF_PCI_PIPE_RX0)
485         return PCI_MAX_CMD_PKT_LEN;
486     
487     return PCI_MAX_DATA_PKT_LEN;
488 }
489 /**
490  * @brief return the header room required by this HIF
491  * 
492  * @param hdl
493  * 
494  * @return int
495  */
496 int
497 __pci_get_reserved_headroom(hif_handle_t  hdl)
498 {
499     return 0;
500 }
501 /**
502  * @brief Device shutdown, HIF reset required
503  * 
504  * @param hdl
505  */
506 void
507 __pci_shutdown(hif_handle_t hdl)
508 {
509     return;
510 }
511
512 void
513 __pci_get_def_pipe(hif_handle_t handle, A_UINT8 *pipe_rx, A_UINT8 *pipe_tx)
514 {
515     *pipe_rx = HIF_PCI_PIPE_RX0;
516     *pipe_tx = HIF_PCI_PIPE_TX0;
517 }
518 /**
519  * @brief This install the API's of the HIF
520  * 
521  * @param apis
522  */
523 void 
524 hif_pci_module_install(struct hif_api *apis)
525 {
526     /* hook in APIs */
527     apis->_init         = __pci_init;
528     apis->_start        = __pci_start;
529     apis->_config_pipe  = __pci_cfg_pipe;
530     apis->_isr_handler  = __pci_isr_handler;
531     apis->_send_buffer  = __pci_xmit_buf;
532     apis->_return_recv_buf       = __pci_return_recv;
533     apis->_is_pipe_supported     = __pci_is_pipe_supported;
534     apis->_get_max_msg_len       = __pci_get_max_msg_len;
535     apis->_register_callback     = __pci_reg_callback;
536     apis->_shutdown              = __pci_shutdown;
537     apis->_get_reserved_headroom = __pci_get_reserved_headroom;
538     apis->_get_default_pipe      = __pci_get_def_pipe;
539 }
540
541 void 
542 cmnos_pci_module_install(struct pci_api *apis)
543 {
544     apis->pci_boot_init     = __pci_boot_init;
545 }