f01efb1be7439bfe41b73832a1c35fc8e03dea0c
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / build / magpie_1_1 / sboot / fwd / fwd.c
1 #include <OTUS/OTUS_soc.h>
2 #include <cmnos_api.h>
3 #include <hif_api.h>
4 #include <Magpie_api.h>
5 #include <dma_lib.h>
6 #include <hif_pci.h>
7 #include <vbuf_api.h>
8
9 #include "fwd.h"
10
11 fwd_tgt_softc_t fwd_sc;
12
13 void    fwd_tgt_recv(VBUF *hdr_buf, VBUF *buf, void *ctx );
14 void    fwd_retbuf_handler(VBUF *buf, void *ServiceCtx);
15
16 hif_handle_t fwd_init() 
17  {
18     HIF_CALLBACK    hifconfig;
19     A_UINT32      size, res_headroom;
20     
21     hifconfig.send_buf_done = fwd_retbuf_handler;
22     hifconfig.recv_buf      = fwd_tgt_recv;
23     hifconfig.context       = &fwd_sc;
24     
25     res_headroom = HIF_get_reserved_headroom(NULL);
26     
27     size = sizeof(fwd_rsp_t) + res_headroom;
28
29     HIF_register_callback(NULL, &hifconfig);
30     
31     HIF_get_default_pipe(NULL, &fwd_sc.rx_pipe, &fwd_sc.tx_pipe);
32     
33     return NULL;
34  }
35  
36 void
37 fwd_retbuf_handler(VBUF *buf, void *ServiceCtx)
38 {
39  HIF_return_recv_buf(fwd_sc.hif_handle, fwd_sc.rx_pipe, buf);
40 }
41
42 a_status_t
43 fwd_tgt_process_last(A_UINT32 size, A_UINT32 cksum)
44 {
45     int i, checksum   = 0;
46     A_UINT32   *image = (A_UINT32 *)fwd_sc.addr;
47     
48     for (i = 0 ; i < size; i += 4, image++) 
49         checksum  =   checksum ^ *image;
50         
51     if (checksum == cksum)
52         return A_STATUS_OK;
53     else
54         return A_STATUS_FAILED;
55 }        
56         
57    
58
59 void 
60 fwd_tgt_recv(VBUF *hdr_buf, VBUF *buf, void *ctx )
61 {
62     volatile a_uint8_t *data;
63     A_UINT32 len, seglen, offset, i, more, eloc;
64     volatile A_UINT32 *image, *daddr;
65     volatile fwd_cmd_t *c;  
66     volatile fwd_rsp_t *r;
67     jmp_func funcptr;
68     a_status_t  status;
69     VDESC *desc = NULL;
70
71     data = buf->desc_list->buf_addr + buf->desc_list->data_offset;
72     seglen  = buf->desc_list->data_size;
73
74     c      =  (fwd_cmd_t *)data;
75     len    =  c->len;
76     offset =  c->offset;
77     more   =  c->more_data;
78     image  =  (A_UINT32 *)(c + 1);
79
80     if (offset == 0) {
81         fwd_sc.addr  = (A_UINT32)(*image);
82         image ++;
83     }
84
85     daddr = (A_UINT32 *)(fwd_sc.addr + offset);
86
87     if (!more) {
88         len -= 4;
89         }
90  
91     for (i = 0 ; i < len; i += 4) {
92         *daddr       =   *image; 
93         image ++;
94         daddr ++;
95     }
96     
97     desc = buf->desc_list; 
98      while(desc->next_desc != NULL)
99         desc = desc->next_desc;
100     desc->data_size -= seglen;
101     buf->buf_length -= seglen;
102
103     r = (fwd_rsp_t *)(desc->buf_addr + desc->data_offset + desc->data_size);
104     desc->data_size += sizeof(fwd_rsp_t); 
105     buf->buf_length += sizeof(fwd_rsp_t); 
106
107     r->offset = c->offset;
108
109     if (more) {
110         r->rsp = FWD_RSP_ACK;
111         goto done;
112     }
113     
114     status = fwd_tgt_process_last(offset + len,  *image);
115  
116     /* reach to the jump location */
117     image++;
118     eloc   =  *image;
119         
120     if (status == A_STATUS_OK)
121         r->rsp = FWD_RSP_SUCCESS;
122     else
123         r->rsp = FWD_RSP_FAILED;
124     
125      
126 done:       
127     HIF_send_buffer(fwd_sc.hif_handle, fwd_sc.tx_pipe, buf);
128
129     if (!more && (status == A_STATUS_OK)) {
130         funcptr = (jmp_func)eloc;
131         funcptr();
132     }
133 }