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>
14 extern void FDL_SendAckPacket (cmd_pkt_type pkt_type);
15 extern uint32 FDL_GetBootMode (void);
17 struct FDL_ChannelHandler *gFdlUsedChannel;
20 static PACKET_T packet[ PACKET_MAX_NUM ];
22 static PACKET_T *packet_free_list;
23 static PACKET_T *packet_completed_list;
24 static PACKET_T *packet_receiving;
26 void FDL_PacketInit (void)
30 packet_free_list = &packet[0];
32 for (i = 0; i < PACKET_MAX_NUM; i++)
34 memset (&packet[i], 0, sizeof (PACKET_T));
35 packet[i].next = &packet[i+1];
38 packet[PACKET_MAX_NUM-1].next = PNULL;
40 packet_completed_list = NULL;
41 packet_receiving = NULL;
43 gFdlUsedChannel = FDL_ChannelGet();
47 PACKET_T *FDL_MallocPacket (void)
49 PACKET_T *tmp_ptr = NULL;
51 if (NULL != packet_free_list)
53 tmp_ptr = packet_free_list;
54 packet_free_list = tmp_ptr->next;
56 // only clear the packet header
57 memset ((void *)tmp_ptr, 0, 32);
60 tmp_ptr->pkt_state = PKT_NONE;
61 tmp_ptr->ack_flag = 0;
62 tmp_ptr->data_size = 0;
68 void FDL_FreePacket (PACKET_T *ptr)
70 ptr->next = packet_free_list;
71 packet_free_list = ptr;
74 PACKET_T *FDL_GetPacket (void)
78 // waiting for a packet
79 while (NULL == packet_completed_list)
84 // remove from completed list
85 ptr = packet_completed_list;
86 packet_completed_list = ptr->next;
91 void FDL_PacketDoIdle (void)
93 //FDL_BOOT_MODE_E boot_mode;
94 unsigned char *pdata = NULL;
95 PACKET_T *packet_ptr = NULL;
96 PACKET_T *tmp_ptr = NULL;
98 uint32 boot_mode = FDL_GetBootMode();
102 // try get a packet to handle the receive char
103 packet_ptr = packet_receiving;
105 if (NULL == packet_ptr)
107 packet_ptr = FDL_MallocPacket();
109 if (NULL != packet_ptr)
111 packet_receiving = packet_ptr;
112 packet_ptr->next = NULL;
120 pdata = (unsigned char *) & (packet_ptr->packet_body);
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
131 ch1 = gFdlUsedChannel->GetSingleChar (gFdlUsedChannel);
140 if (packet_ptr->data_size > MAX_PKT_SIZE)
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)
150 // try handle this input data
151 //printf(" %02x %d\n", ch1, packet_ptr->pkt_state);
152 switch (packet_ptr->pkt_state)
157 packet_ptr->pkt_state = PKT_HEAD;
158 packet_ptr->data_size = 0;
164 if (HDLC_ESCAPE == ch)
166 // Try get the "true" data.
167 //ch = sio_get_char();
168 ch = gFdlUsedChannel->GetChar (gFdlUsedChannel);
169 ch = ch ^ HDLC_ESCAPE_MASK;
171 packet_ptr->pkt_state = PKT_GATHER;
172 *(pdata + packet_ptr->data_size) = ch;
174 packet_ptr->data_size += 1;
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);
186 crc = frm_chk((unsigned short *)&packet_ptr->packet_body, packet_ptr->data_size);
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++)
193 printf("%2x", packet_ptr->packet_body.content[k]);
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__);
205 //Check there are free packet?
206 if ((NULL != packet_free_list) && (BSL_CMD_MIDST_DATA == packet_ptr->packet_body.type)) {
208 #if defined (NOR_FDL_SC6600L) || defined (NOR_FDL_SC6800H)
209 packet_ptr->ack_flag = 1;
210 FDL_SendAckPacket (BSL_REP_ACK);
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;
219 tmp_ptr = packet_completed_list;
220 while (NULL != tmp_ptr->next) {
221 tmp_ptr = tmp_ptr->next;
223 tmp_ptr->next = packet_ptr;
225 //set to null for next transfer
226 packet_receiving = NULL;
230 /** Process the byte read by GetSingleChar*/
231 if(ch == HDLC_ESCAPE)
232 ch = gFdlUsedChannel->GetChar(gFdlUsedChannel)
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);
249 /******************************************************************************
251 ******************************************************************************/
252 void FDL_WritePacket (const void *buf, int len)
254 gFdlUsedChannel->Write (gFdlUsedChannel, buf, len);
258 uint32 FDL_DataProcess (PACKET_T *packet_ptr_src, PACKET_T *packet_ptr_dest)
260 unsigned short crc, size;
261 int32 write_len; /*orginal length*/
262 int32 send_len; /*length after encode*/
266 uint8 *des_ptr = NULL;
267 uint8 *src_ptr = NULL;
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;
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);
276 /*src CRC calculation*/
277 #ifndef CONFIG_FRMCHECK
278 crc = crc_16_l_calc ( (char *) (& (packet_ptr_src->packet_body)), size + PACKET_HEADER_SIZE);
280 crc = frm_chk ( (const unsigned short *) (& (packet_ptr_src->packet_body)), size + PACKET_HEADER_SIZE);
282 crc = EndianConv_16 (crc);
284 packet_ptr_src->packet_body.content[ size ] = (crc >> 8) & 0xFF;
285 packet_ptr_src->packet_body.content[ size+1 ] = (crc) & 0xFF;
287 /*******************************************
288 * des data preparation
289 ********************************************/
291 des_ptr = (uint8 *) &packet_ptr_dest->packet_body;
293 * (des_ptr++) = HDLC_FLAG;
296 /*middle part process*/
297 for (i = 0; i < write_len; i++)
299 curval = * (src_ptr + i);
301 if ( (HDLC_FLAG == curval) || (HDLC_ESCAPE == curval))
303 * (des_ptr++) = HDLC_ESCAPE;
304 * (des_ptr++) = ~HDLC_ESCAPE_MASK & curval;
309 * (des_ptr++) = curval;
316 * (des_ptr++) = HDLC_FLAG;
321 /******************************************************************************
323 ******************************************************************************/
324 void FDL_SendPacket (PACKET_T *packet_ptr)
326 int32 send_len; /*length after encode*/
327 PACKET_T *tmp_packet_ptr = NULL;
329 // send a ACK packet to notify PC that we are ready.
330 tmp_packet_ptr = FDL_MallocPacket();
332 if (NULL == tmp_packet_ptr)
335 FDL_FreePacket (packet_receiving);
336 tmp_packet_ptr = FDL_MallocPacket();
339 send_len = FDL_DataProcess (packet_ptr, tmp_packet_ptr);
341 FDL_WritePacket ( (char *) (& (tmp_packet_ptr->packet_body)), send_len);
343 FDL_FreePacket (tmp_packet_ptr);
347 /******************************************************************************
348 * FDL_SendAckPacket_packet
349 ******************************************************************************/
350 void FDL_SendAckPacket (cmd_pkt_type pkt_type)
353 unsigned long ack_packet_src[8];
354 unsigned long ack_packet_dst[8];
355 PACKET_T *packet_ptr = (PACKET_T *) ack_packet_src;
357 int32 send_len; /*length after encode*/
358 PACKET_T *tmp_packet_ptr = NULL;
360 packet_ptr->packet_body.type = pkt_type;
361 packet_ptr->packet_body.size = 0;
363 tmp_packet_ptr = (PACKET_T *) ack_packet_dst;
365 send_len = FDL_DataProcess (packet_ptr, tmp_packet_ptr);
366 FDL_WritePacket ( (char *) (& (tmp_packet_ptr->packet_body)), send_len);