1 #include <linux/string.h>
2 #include <asm/arch/sci_types.h>
3 #include <asm/arch/packet.h>
4 #include <asm/arch/fdl_stdio.h>
5 //#include "fdl_main.h"
6 #include <asm/arch/fdl_crc.h>
7 #include <asm/arch/sio_drv.h>
8 #include <asm/arch/usb_boot.h>
9 #include <asm/arch/virtual_com.h>
10 #include <asm/arch/fdl_channel.h>
13 extern void FDL_SendAckPacket (cmd_pkt_type pkt_type);
16 struct FDL_ChannelHandler *gFdlUsedChannel;
19 static PACKET_T packet[ PACKET_MAX_NUM ];
21 static PACKET_T *packet_free_list;
22 static PACKET_T *packet_completed_list;
23 static PACKET_T *packet_receiving;
25 void FDL_PacketInit (void)
29 packet_free_list = &packet[0];
31 for (i = 0; i < PACKET_MAX_NUM; i++)
33 memset (&packet[i], 0, sizeof (PACKET_T));
34 packet[i].next = &packet[i+1];
37 packet[PACKET_MAX_NUM-1].next = PNULL;
39 packet_completed_list = NULL;
40 packet_receiving = NULL;
42 gFdlUsedChannel = FDL_ChannelGet();
46 PACKET_T *FDL_MallocPacket (void)
48 PACKET_T *tmp_ptr = NULL;
50 if (NULL != packet_free_list)
52 tmp_ptr = packet_free_list;
53 packet_free_list = tmp_ptr->next;
55 // only clear the packet header
56 memset ((void *)tmp_ptr, 0, 32);
59 tmp_ptr->pkt_state = PKT_NONE;
60 tmp_ptr->ack_flag = 0;
61 tmp_ptr->data_size = 0;
67 void FDL_FreePacket (PACKET_T *ptr)
69 ptr->next = packet_free_list;
70 packet_free_list = ptr;
73 PACKET_T *FDL_GetPacket (void)
77 // waiting for a packet
78 while (NULL == packet_completed_list)
83 // remove from completed list
84 ptr = packet_completed_list;
85 packet_completed_list = ptr->next;
90 void FDL_PacketDoIdle (void)
92 //FDL_BOOT_MODE_E boot_mode;
93 unsigned char *pdata = NULL;
94 PACKET_T *packet_ptr = NULL;
95 PACKET_T *tmp_ptr = NULL;
97 uint32 boot_mode = FDL_GetBootMode();
101 // try get a packet to handle the receive char
102 packet_ptr = packet_receiving;
104 if (NULL == packet_ptr)
106 packet_ptr = FDL_MallocPacket();
108 if (NULL != packet_ptr)
110 packet_receiving = packet_ptr;
111 packet_ptr->next = NULL;
119 pdata = (unsigned char *) & (packet_ptr->packet_body);
124 * here the reason that we don't call GetChar is
125 * that GetChar() isnot exited until got data from
126 * outside,FDL_PacketDoIdle() is called also in norflash write and erase
127 * so we have to exited when no char recieived here,
128 * usb virtual com is the same handle
130 ch1 = gFdlUsedChannel->GetSingleChar (gFdlUsedChannel);
139 if (packet_ptr->data_size > MAX_PKT_SIZE)
141 packet_receiving = NULL;
142 FDL_FreePacket (packet_ptr);
143 sio_trace ("data_size error : datasize = %d MAX_PKT_SIZE = %d\n", packet_ptr->data_size, MAX_PKT_SIZE);
144 printf("\n\n\n%s %s %d\n\n\n", __FILE__, __FUNCTION__, __LINE__);
145 SEND_ERROR_RSP (BSL_REP_VERIFY_ERROR)
149 // try handle this input data
150 //printf(" %02x %d\n", ch1, packet_ptr->pkt_state);
151 switch (packet_ptr->pkt_state)
156 packet_ptr->pkt_state = PKT_HEAD;
157 packet_ptr->data_size = 0;
163 if (HDLC_ESCAPE == ch)
165 // Try get the "true" data.
166 //ch = sio_get_char();
167 ch = gFdlUsedChannel->GetChar (gFdlUsedChannel);
168 ch = ch ^ HDLC_ESCAPE_MASK;
170 packet_ptr->pkt_state = PKT_GATHER;
171 *(pdata + packet_ptr->data_size) = ch;
173 packet_ptr->data_size += 1;
180 packet_ptr->pkt_state = PKT_RECV;
181 //check the packet. CRC should be 0
182 #ifndef CONFIG_FRMCHECK
183 crc = crc_16_l_calc((unsigned short *)&packet_ptr->packet_body, packet_ptr->data_size);
185 crc = frm_chk((unsigned short *)&packet_ptr->packet_body, packet_ptr->data_size);
189 printf("%4x%4x", packet_ptr->packet_body.type, packet_ptr->packet_body.size);
190 for(k = 0; k < packet_ptr->data_size - 4; k++)
192 printf("%2x", packet_ptr->packet_body.content[k]);
196 //Verify error, reject this packet.
197 FDL_FreePacket(packet_ptr);
198 packet_receiving = NULL;
199 //if check result failed, notify PC
200 SEND_ERROR_RSP (BSL_REP_VERIFY_ERROR)
201 printf("crc failed\n\n\n%s %s %d\n\n\n", __FILE__, __FUNCTION__, __LINE__);
204 //Check there are free packet?
205 if ((NULL != packet_free_list) && (BSL_CMD_MIDST_DATA == packet_ptr->packet_body.type)) {
207 #if defined (NOR_FDL_SC6600L) || defined (NOR_FDL_SC6800H)
208 packet_ptr->ack_flag = 1;
209 FDL_SendAckPacket (BSL_REP_ACK);
212 //It is a complete packet, move to completed list.
213 packet_ptr->next = NULL;
214 if (NULL == packet_completed_list) {
215 packet_completed_list = packet_ptr;
218 tmp_ptr = packet_completed_list;
219 while (NULL != tmp_ptr->next) {
220 tmp_ptr = tmp_ptr->next;
222 tmp_ptr->next = packet_ptr;
224 //set to null for next transfer
225 packet_receiving = NULL;
229 /** Process the byte read by GetSingleChar*/
230 if(ch == HDLC_ESCAPE)
231 ch = gFdlUsedChannel->GetChar(gFdlUsedChannel)
233 *(pdata + packet_ptr->data_size) = ch;
234 packet_ptr->data_size += 1;
235 if(boot_mode == 0x5A){ // In USB Mode
236 packet_ptr->data_size += gFdlUsedChannel->Read(gFdlUsedChannel,
237 pdata + packet_ptr->data_size, MAX_PKT_SIZE);
248 /******************************************************************************
250 ******************************************************************************/
251 void FDL_WritePacket (const void *buf, int len)
253 gFdlUsedChannel->Write (gFdlUsedChannel, buf, len);
257 uint32 FDL_DataProcess (PACKET_T *packet_ptr_src, PACKET_T *packet_ptr_dest)
259 unsigned short crc, size;
260 int32 write_len; /*orginal length*/
261 int32 send_len; /*length after encode*/
265 uint8 *des_ptr = NULL;
266 uint8 *src_ptr = NULL;
268 size = packet_ptr_src->packet_body.size;
269 write_len = size + sizeof (unsigned short) + PACKET_HEADER_SIZE;
270 src_ptr = (uint8 *) &packet_ptr_src->packet_body;
272 packet_ptr_src->packet_body.size = EndianConv_16 (packet_ptr_src->packet_body.size);
273 packet_ptr_src->packet_body.type = EndianConv_16 (packet_ptr_src->packet_body.type);
275 /*src CRC calculation*/
276 #ifndef CONFIG_FRMCHECK
277 crc = crc_16_l_calc ( (const unsigned short *) (& (packet_ptr_src->packet_body)), size + PACKET_HEADER_SIZE);
279 crc = frm_chk ( (const unsigned short *) (& (packet_ptr_src->packet_body)), size + PACKET_HEADER_SIZE);
281 crc = EndianConv_16 (crc);
283 packet_ptr_src->packet_body.content[ size ] = (crc >> 8) & 0xFF;
284 packet_ptr_src->packet_body.content[ size+1 ] = (crc) & 0xFF;
286 /*******************************************
287 * des data preparation
288 ********************************************/
290 des_ptr = (uint8 *) &packet_ptr_dest->packet_body;
292 * (des_ptr++) = HDLC_FLAG;
295 /*middle part process*/
296 for (i = 0; i < write_len; i++)
298 curval = * (src_ptr + i);
300 if ( (HDLC_FLAG == curval) || (HDLC_ESCAPE == curval))
302 * (des_ptr++) = HDLC_ESCAPE;
303 * (des_ptr++) = ~HDLC_ESCAPE_MASK & curval;
308 * (des_ptr++) = curval;
315 * (des_ptr++) = HDLC_FLAG;
320 /******************************************************************************
322 ******************************************************************************/
323 void FDL_SendPacket (PACKET_T *packet_ptr)
325 int32 send_len; /*length after encode*/
326 PACKET_T *tmp_packet_ptr = NULL;
328 // send a ACK packet to notify PC that we are ready.
329 tmp_packet_ptr = FDL_MallocPacket();
331 if (NULL == tmp_packet_ptr)
334 FDL_FreePacket (packet_receiving);
335 tmp_packet_ptr = FDL_MallocPacket();
338 send_len = FDL_DataProcess (packet_ptr, tmp_packet_ptr);
340 FDL_WritePacket ( (char *) (& (tmp_packet_ptr->packet_body)), send_len);
342 FDL_FreePacket (tmp_packet_ptr);
346 /******************************************************************************
347 * FDL_SendAckPacket_packet
348 ******************************************************************************/
349 void FDL_SendAckPacket (cmd_pkt_type pkt_type)
352 unsigned long ack_packet_src[8];
353 unsigned long ack_packet_dst[8];
354 PACKET_T *packet_ptr = (PACKET_T *) ack_packet_src;
356 int32 send_len; /*length after encode*/
357 PACKET_T *tmp_packet_ptr = NULL;
359 packet_ptr->packet_body.type = pkt_type;
360 packet_ptr->packet_body.size = 0;
362 tmp_packet_ptr = (PACKET_T *) ack_packet_dst;
364 send_len = FDL_DataProcess (packet_ptr, tmp_packet_ptr);
365 FDL_WritePacket ( (char *) (& (tmp_packet_ptr->packet_body)), send_len);