ARM: sc8830: fdl: remove build warnings
[profile/mobile/platform/kernel/u-boot-tm1.git] / nand_fdl / common / src / packet.c
1 #include <common.h>
2 #include <linux/string.h>
3 #include <asm/arch/sci_types.h>
4 #include <asm/arch/packet.h>
5 #include <asm/arch/fdl_stdio.h>
6 //#include "fdl_main.h"
7 #include <asm/arch/fdl_crc.h>
8 #include <asm/arch/sio_drv.h>
9 #include <asm/arch/usb_boot.h>
10 #include <asm/arch/virtual_com.h>
11 #include <asm/arch/fdl_channel.h>
12
13
14 extern void FDL_SendAckPacket (cmd_pkt_type pkt_type);
15 extern uint32 FDL_GetBootMode (void);
16
17 struct FDL_ChannelHandler *gFdlUsedChannel;
18
19
20 static PACKET_T  packet[ PACKET_MAX_NUM ];
21
22 static PACKET_T *packet_free_list;
23 static PACKET_T *packet_completed_list;
24 static PACKET_T *packet_receiving;
25
26 void FDL_PacketInit (void)
27 {
28     uint32 i = 0;
29
30     packet_free_list = &packet[0];
31
32     for (i = 0; i < PACKET_MAX_NUM; i++)
33     {
34         memset (&packet[i], 0, sizeof (PACKET_T));
35         packet[i].next   = &packet[i+1];
36     }
37
38     packet[PACKET_MAX_NUM-1].next = PNULL;
39
40     packet_completed_list = NULL;
41     packet_receiving      = NULL;
42
43     gFdlUsedChannel = FDL_ChannelGet();
44 }
45
46
47 PACKET_T *FDL_MallocPacket (void)
48 {
49     PACKET_T   *tmp_ptr = NULL;
50
51     if (NULL != packet_free_list)
52     {
53         tmp_ptr = packet_free_list;
54         packet_free_list = tmp_ptr->next;
55
56         // only clear the packet header
57         memset ((void *)tmp_ptr, 0, 32);
58
59         tmp_ptr->next       = NULL;
60         tmp_ptr->pkt_state  = PKT_NONE;
61         tmp_ptr->ack_flag   = 0;
62         tmp_ptr->data_size  = 0;
63     }
64
65     return tmp_ptr;
66 }
67
68 void FDL_FreePacket (PACKET_T *ptr)
69 {
70     ptr->next        = packet_free_list;
71     packet_free_list = ptr;
72 }
73
74 PACKET_T   *FDL_GetPacket (void)
75 {
76     PACKET_T *ptr;
77
78     // waiting for a packet
79     while (NULL == packet_completed_list)
80     {
81         FDL_PacketDoIdle();
82     }
83
84     // remove from completed list
85     ptr                     = packet_completed_list;
86     packet_completed_list   = ptr->next;
87     ptr->next               = NULL;
88     return ptr;
89 }
90
91 void FDL_PacketDoIdle (void)
92 {
93     //FDL_BOOT_MODE_E          boot_mode;
94     unsigned char *pdata      = NULL;
95     PACKET_T       *packet_ptr = NULL;
96     PACKET_T       *tmp_ptr    = NULL;
97     uint32          crc;
98     uint32 boot_mode = FDL_GetBootMode();
99     unsigned char   ch;
100     int ch1;
101
102     // try get a packet to handle the receive char
103     packet_ptr = packet_receiving;
104
105     if (NULL == packet_ptr)
106     {
107         packet_ptr = FDL_MallocPacket();
108
109         if (NULL != packet_ptr)
110         {
111             packet_receiving    = packet_ptr;
112             packet_ptr->next    = NULL;
113         }
114         else
115         {
116             return ;
117         }
118     }
119
120     pdata  = (unsigned char *) & (packet_ptr->packet_body);
121
122     while (1)
123     {
124         /*
125         * here the reason that we don't call GetChar is
126         * that GetChar() isnot exited until got data from
127         * outside,FDL_PacketDoIdle() is called also in norflash write and erase
128         * so we have to exited when no char recieived here,
129         * usb virtual com is the same handle
130         */
131         ch1 = gFdlUsedChannel->GetSingleChar (gFdlUsedChannel);
132
133         if (ch1 == -1)
134         {
135             return;
136         }
137
138         ch = ch1&0xff;
139
140         if (packet_ptr->data_size > MAX_PKT_SIZE)
141         {
142             packet_receiving = NULL;
143             FDL_FreePacket (packet_ptr);
144             sio_trace ("data_size error : datasize = %d  MAX_PKT_SIZE = %d\n", packet_ptr->data_size, MAX_PKT_SIZE);
145             printf("\n\n\n%s %s %d\n\n\n", __FILE__, __FUNCTION__, __LINE__);
146             SEND_ERROR_RSP (BSL_REP_VERIFY_ERROR)
147             //return;
148         }
149
150         // try handle this input data
151         //printf(" %02x  %d\n", ch1, packet_ptr->pkt_state);
152         switch (packet_ptr->pkt_state)
153         {
154             case PKT_NONE:
155                 if (HDLC_FLAG == ch)
156                 {
157                     packet_ptr->pkt_state = PKT_HEAD;
158                     packet_ptr->data_size = 0;
159                 }
160                 break;
161             case PKT_HEAD:
162                 if (HDLC_FLAG != ch)
163                 {
164                     if (HDLC_ESCAPE == ch)
165                     {
166                         // Try get the "true" data.
167                         //ch = sio_get_char();
168                         ch = gFdlUsedChannel->GetChar (gFdlUsedChannel);
169                         ch = ch ^ HDLC_ESCAPE_MASK;
170                     }
171                     packet_ptr->pkt_state = PKT_GATHER;
172                     *(pdata + packet_ptr->data_size) = ch;
173                     //*(pdata++) = ch;
174                     packet_ptr->data_size += 1;
175                 }
176                 break;
177             case PKT_GATHER:
178                 if (HDLC_FLAG == ch) 
179                                 {
180 end:
181                     packet_ptr->pkt_state = PKT_RECV;
182                     //check the packet. CRC should be 0
183 #ifndef CONFIG_FRMCHECK
184                     crc = crc_16_l_calc((char *)&packet_ptr->packet_body, packet_ptr->data_size);
185 #else
186                     crc = frm_chk((unsigned short *)&packet_ptr->packet_body, packet_ptr->data_size);
187 #endif
188                     if (0 != crc){
189                         int k;
190                         printf("%4x%4x", packet_ptr->packet_body.type, packet_ptr->packet_body.size);
191                         for(k = 0;  k  < packet_ptr->data_size - 4; k++)
192                         {
193                             printf("%2x", packet_ptr->packet_body.content[k]);
194                         }
195                         printf("\n\n\n\n");
196
197                         //Verify error, reject this packet.
198                         FDL_FreePacket(packet_ptr);
199                         packet_receiving = NULL;
200                         //if check result failed, notify PC
201                         SEND_ERROR_RSP (BSL_REP_VERIFY_ERROR)
202                         printf("crc failed\n\n\n%s %s %d\n\n\n", __FILE__, __FUNCTION__, __LINE__);
203                         //return ;
204                     } else {
205                         //Check there are free packet?
206                         if ((NULL != packet_free_list) && (BSL_CMD_MIDST_DATA == packet_ptr->packet_body.type)) {
207                         //send a ACK
208 #if defined (NOR_FDL_SC6600L) || defined (NOR_FDL_SC6800H)
209                             packet_ptr->ack_flag = 1;
210                             FDL_SendAckPacket (BSL_REP_ACK);
211 #endif
212                         }
213                         //It is a complete packet, move to completed list.
214                         packet_ptr->next = NULL;
215                         if (NULL == packet_completed_list) {
216                             packet_completed_list = packet_ptr;
217                         } else {
218                             //added to the tail
219                             tmp_ptr = packet_completed_list;
220                             while (NULL != tmp_ptr->next) {
221                             tmp_ptr = tmp_ptr->next;
222                             }
223                             tmp_ptr->next = packet_ptr;
224                         }
225                         //set to null for next transfer
226                         packet_receiving = NULL;
227                         return ;
228                     }
229                 } else {
230                     /** Process the byte read by GetSingleChar*/
231                     if(ch == HDLC_ESCAPE)
232                         ch = gFdlUsedChannel->GetChar(gFdlUsedChannel) 
233                                 ^ HDLC_ESCAPE_MASK;
234                     *(pdata + packet_ptr->data_size) = ch;
235                     packet_ptr->data_size += 1;
236                     if(boot_mode == 0x5A){ // In USB Mode
237                         packet_ptr->data_size += gFdlUsedChannel->Read(gFdlUsedChannel,
238                             pdata + packet_ptr->data_size, MAX_PKT_SIZE);
239                         goto end;
240                     }
241                 }
242                 break;
243             default:
244                 break;
245         }
246     }
247 }
248
249 /******************************************************************************
250  * write_packet
251  ******************************************************************************/
252 void FDL_WritePacket (const void *buf, int len)
253 {
254     gFdlUsedChannel->Write (gFdlUsedChannel, buf, len);
255
256 }
257
258 uint32  FDL_DataProcess (PACKET_T *packet_ptr_src, PACKET_T *packet_ptr_dest)
259 {
260     unsigned short  crc, size;
261     int32           write_len;  /*orginal length*/
262     int32           send_len;   /*length after encode*/
263     int32           i;
264     uint8           curval;
265
266     uint8          *des_ptr = NULL;
267     uint8          *src_ptr = NULL;
268
269     size = packet_ptr_src->packet_body.size;
270     write_len = size + sizeof (unsigned short) + PACKET_HEADER_SIZE;
271     src_ptr = (uint8 *) &packet_ptr_src->packet_body;
272
273     packet_ptr_src->packet_body.size = EndianConv_16 (packet_ptr_src->packet_body.size);
274     packet_ptr_src->packet_body.type = EndianConv_16 (packet_ptr_src->packet_body.type);
275
276     /*src CRC calculation*/
277 #ifndef  CONFIG_FRMCHECK
278     crc = crc_16_l_calc ( (char *) (& (packet_ptr_src->packet_body)), size + PACKET_HEADER_SIZE);
279 #else
280     crc = frm_chk ( (const unsigned short *) (& (packet_ptr_src->packet_body)), size + PACKET_HEADER_SIZE);
281
282     crc = EndianConv_16 (crc);
283 #endif
284     packet_ptr_src->packet_body.content[ size ] = (crc >> 8) & 0xFF;
285     packet_ptr_src->packet_body.content[ size+1 ] = (crc)    & 0xFF;
286
287     /*******************************************
288     *    des data preparation
289     ********************************************/
290
291     des_ptr = (uint8 *) &packet_ptr_dest->packet_body;
292     /*head flag*/
293     * (des_ptr++) = HDLC_FLAG;
294     send_len = 1;
295
296     /*middle part process*/
297     for (i = 0; i < write_len; i++)
298     {
299         curval = * (src_ptr + i);
300
301         if ( (HDLC_FLAG == curval) || (HDLC_ESCAPE == curval))
302         {
303             * (des_ptr++) = HDLC_ESCAPE;
304             * (des_ptr++) = ~HDLC_ESCAPE_MASK & curval;
305             send_len++;
306         }
307         else
308         {
309             * (des_ptr++) = curval;
310         }
311
312         send_len++;
313     }
314
315     /*end flag*/
316     * (des_ptr++) = HDLC_FLAG;
317     send_len++;
318
319     return send_len;
320 }
321 /******************************************************************************
322  * FDL_SendPacket
323  ******************************************************************************/
324 void FDL_SendPacket (PACKET_T *packet_ptr)
325 {
326     int32           send_len;   /*length after encode*/
327     PACKET_T       *tmp_packet_ptr = NULL;
328
329     // send a ACK packet to notify PC that we are ready.
330     tmp_packet_ptr = FDL_MallocPacket();
331
332     if (NULL == tmp_packet_ptr)
333     {
334
335         FDL_FreePacket (packet_receiving);
336         tmp_packet_ptr = FDL_MallocPacket();
337     }
338
339     send_len = FDL_DataProcess (packet_ptr, tmp_packet_ptr);
340
341     FDL_WritePacket ( (char *) (& (tmp_packet_ptr->packet_body)), send_len);
342
343     FDL_FreePacket (tmp_packet_ptr);
344
345 }
346
347 /******************************************************************************
348  * FDL_SendAckPacket_packet
349  ******************************************************************************/
350 void FDL_SendAckPacket (cmd_pkt_type  pkt_type)
351 {
352
353     unsigned long ack_packet_src[8];
354     unsigned long ack_packet_dst[8];
355     PACKET_T *packet_ptr = (PACKET_T *) ack_packet_src;
356
357     int32           send_len;   /*length after encode*/
358     PACKET_T       *tmp_packet_ptr = NULL;
359
360     packet_ptr->packet_body.type = pkt_type;
361     packet_ptr->packet_body.size = 0;
362
363     tmp_packet_ptr = (PACKET_T *) ack_packet_dst;
364
365     send_len = FDL_DataProcess (packet_ptr, tmp_packet_ptr);
366     FDL_WritePacket ( (char *) (& (tmp_packet_ptr->packet_body)), send_len);
367
368 }