1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #include <string.h>
19 #include "nfc_hal_int.h"
20 #include "userial.h"
21
22 /*****************************************************************************
23 * Definitions
24 *****************************************************************************/
25
26 /* Internal flags */
27 #define NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF 0x01 /* Application provided patchram in a single buffer */
28 #define NFC_HAL_PRM_FLAGS_RFU 0x02 /* Reserved for future use */
29 #define NFC_HAL_PRM_FLAGS_SIGNATURE_SENT 0x04 /* Signature sent to NFCC */
30 #define NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED 0x08 /* PreI2C patch required */
31 #define NFC_HAL_PRM_FLAGS_NO_NVM 0x10 /* Not NVM available (patch downloaded to SRAM) */
32 #define NFC_HAL_PRM_FLAGS_SUPPORT_RESET_NTF 0x20 /* Support RESET_NTF from NFCC after sending signature */
33 #define NFC_HAL_PRM_FLAGS_NVM_FPM_CORRUPTED 0x40 /* FPM patch in NVM failed CRC check */
34 #define NFC_HAL_PRM_FLAGS_NVM_LPM_CORRUPTED 0x80 /* LPM patch in NVM failed CRC check */
35
36 /* Secure patch download definitions */
37 #define NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN 7 /* PRJID + MAJORVER + MINORVER + COUNT */
38 #define NFC_HAL_PRM_NCD_PATCH_VERSION_LEN 16
39
40 #define NFC_HAL_PRM_SPD_PRE_DOWNLOAD_DELAY (500) /* Delay before starting to patch download (in ms) */
41
42 /* Enumeration of power modes IDs */
43 #define NFC_HAL_PRM_SPD_POWER_MODE_LPM 0
44 #define NFC_HAL_PRM_SPD_POWER_MODE_FPM 1
45
46 /* Version string for BCM20791B3 */
47 const UINT8 NFC_HAL_PRM_BCM20791B3_STR[] = "20791B3";
48 #define NFC_HAL_PRM_BCM20791B3_STR_LEN (sizeof (NFC_HAL_PRM_BCM20791B3_STR)-1)
49
50 #define NFC_HAL_PRM_SPD_TOUT (6000) /* timeout for SPD events (in ms) */
51 #define NFC_HAL_PRM_END_DELAY (250) /* delay before sending any new command (ms)*/
52
53 /* command to get currently downloaded patch version */
54 static UINT8 nfc_hal_prm_get_patch_version_cmd [NCI_MSG_HDR_SIZE] =
55 {
56 NCI_MTS_CMD|NCI_GID_PROP,
57 NCI_MSG_GET_PATCH_VERSION,
58 0x00
59 };
60
61 #if (NFC_HAL_PRM_DEBUG == TRUE)
62 #define NFC_HAL_PRM_STATE(str) NCI_TRACE_DEBUG2 ("%s st: %d", str, nfc_hal_cb.prm.state)
63 #else
64 #define NFC_HAL_PRM_STATE(str)
65 #endif
66
67 void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status);
68
69 /*****************************************************************************
70 ** Extern variable from nfc_hal_dm_cfg.c
71 *****************************************************************************/
72 extern BOOLEAN nfc_hal_prm_nvm_required;
73
74 /*******************************************************************************
75 **
76 ** Function nfc_hal_prm_spd_handle_download_complete
77 **
78 ** Description Patch download complete (for secure patch download)
79 **
80 ** Returns void
81 **
82 *******************************************************************************/
nfc_hal_prm_spd_handle_download_complete(UINT8 event)83 void nfc_hal_prm_spd_handle_download_complete (UINT8 event)
84 {
85 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_IDLE;
86
87 /* Notify application now */
88 if (nfc_hal_cb.prm.p_cback)
89 (nfc_hal_cb.prm.p_cback) (event);
90 }
91
92 /*******************************************************************************
93 **
94 ** Function nfc_hal_prm_spd_send_next_segment
95 **
96 ** Description Send next patch segment (for secure patch download)
97 **
98 ** Returns void
99 **
100 *******************************************************************************/
nfc_hal_prm_spd_send_next_segment(void)101 void nfc_hal_prm_spd_send_next_segment (void)
102 {
103 UINT8 *p_src;
104 UINT16 len, offset = nfc_hal_cb.prm.cur_patch_offset;
105 UINT8 hcit, oid, hdr0, type;
106 UINT8 chipverlen;
107 UINT8 chipverstr[NCI_SPD_HEADER_CHIPVER_LEN];
108 UINT8 patch_hdr_size = NCI_MSG_HDR_SIZE + 1; /* 1 is for HCIT */
109
110 /* Validate that segment is at least big enought to have NCI_MSG_HDR_SIZE + 1 (hcit) */
111 if (nfc_hal_cb.prm.cur_patch_len_remaining < patch_hdr_size)
112 {
113 NCI_TRACE_ERROR0 ("Unexpected end of patch.");
114 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
115 return;
116 }
117
118 /* Parse NCI command header */
119 p_src = (UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset);
120 STREAM_TO_UINT8 (hcit, p_src);
121 STREAM_TO_UINT8 (hdr0, p_src);
122 STREAM_TO_UINT8 (oid, p_src);
123 STREAM_TO_UINT8 (len, p_src);
124 STREAM_TO_UINT8 (type, p_src);
125
126
127 /* Update number of bytes comsumed */
128 nfc_hal_cb.prm.cur_patch_offset += (len + patch_hdr_size);
129 nfc_hal_cb.prm.cur_patch_len_remaining -= (len + patch_hdr_size);
130
131 /* Check if sending signature byte */
132 if ( (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD )
133 &&(type == NCI_SPD_TYPE_SIGNATURE) )
134 {
135 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
136 }
137 /* Check for header */
138 else if ( (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD )
139 &&(type == NCI_SPD_TYPE_HEADER) )
140 {
141 /* Check if patch is for BCM20791B3 */
142 p_src += NCI_SPD_HEADER_OFFSET_CHIPVERLEN;
143 STREAM_TO_UINT8 (chipverlen, p_src);
144 STREAM_TO_ARRAY (chipverstr, p_src, NCI_SPD_HEADER_CHIPVER_LEN);
145
146 if (memcmp (NFC_HAL_PRM_BCM20791B3_STR, chipverstr, NFC_HAL_PRM_BCM20791B3_STR_LEN) == 0)
147 {
148 /* Patch is for BCM2079B3 - do not wait for RESET_NTF after patch download */
149 nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SUPPORT_RESET_NTF;
150 }
151 else
152 {
153 /* Patch is for BCM2079B4 or newer - wait for RESET_NTF after patch download */
154 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_SUPPORT_RESET_NTF;
155 }
156 }
157
158 /* Send the command (not including HCIT here) */
159 nfc_hal_dm_send_nci_cmd ((UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset + 1), (UINT8) (len + NCI_MSG_HDR_SIZE),
160 nfc_hal_prm_nci_command_complete_cback);
161 }
162
163 /*******************************************************************************
164 **
165 ** Function nfc_hal_prm_spd_handle_next_patch_start
166 **
167 ** Description Handle start of next patch (for secure patch download)
168 **
169 ** Returns void
170 **
171 *******************************************************************************/
nfc_hal_prm_spd_handle_next_patch_start(void)172 void nfc_hal_prm_spd_handle_next_patch_start (void)
173 {
174 UINT32 cur_patch_mask;
175 UINT32 cur_patch_len;
176 BOOLEAN found_patch_to_download = FALSE;
177
178 while (!found_patch_to_download)
179 {
180 /* Get length of current patch */
181 cur_patch_len = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len;
182
183 /* Check if this is a patch we need to download */
184 cur_patch_mask = ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
185 if (nfc_hal_cb.prm.spd_patch_needed_mask & cur_patch_mask)
186 {
187 found_patch_to_download = TRUE;
188 }
189 else
190 {
191 /* Do not need to download this patch. Skip to next patch */
192 NCI_TRACE_DEBUG1 ("Skipping patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
193
194 nfc_hal_cb.prm.spd_cur_patch_idx++;
195 if (nfc_hal_cb.prm.spd_cur_patch_idx >= nfc_hal_cb.prm.spd_patch_count)
196 {
197 /* No more to download */
198 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
199 return;
200 }
201 else if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
202 {
203 /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch header */
204 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
205 return;
206 }
207 else
208 {
209 /* Patch in buffer. Skip over current patch. Check next patch */
210 nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) cur_patch_len;
211 nfc_hal_cb.prm.cur_patch_offset += (UINT16) cur_patch_len;
212 }
213 }
214 }
215
216
217 /* Begin downloading patch */
218 NCI_TRACE_DEBUG1 ("Downloading patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
219 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_DOWNLOADING;
220 nfc_hal_prm_spd_send_next_segment ();
221 }
222
223 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
224 /*******************************************************************************
225 **
226 ** Function nfc_hal_prm_spd_download_i2c_fix
227 **
228 ** Description Start downloading patch for i2c fix
229 **
230 ** Returns void
231 **
232 *******************************************************************************/
nfc_hal_prm_spd_download_i2c_fix(void)233 void nfc_hal_prm_spd_download_i2c_fix (void)
234 {
235 UINT8 *p, *p_start;
236 UINT16 patchfile_project_id;
237 UINT16 patchfile_ver_major;
238 UINT16 patchfile_ver_minor;
239 UINT16 patchfile_patchsize;
240 UINT8 u8;
241
242 NCI_TRACE_DEBUG0 ("Downloading I2C fix...");
243
244 /* Save pointer and offset of patchfile, so we can resume after downloading the i2c fix */
245 nfc_hal_cb.prm.spd_patch_offset = nfc_hal_cb.prm.cur_patch_offset;
246 nfc_hal_cb.prm.spd_patch_len_remaining = nfc_hal_cb.prm.cur_patch_len_remaining;
247
248 /* Initialize pointers for downloading i2c fix */
249 nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm_i2c.p_patch;
250 nfc_hal_cb.prm.cur_patch_offset = 0;
251 nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm_i2c.len;
252
253 /* Parse the i2c patchfile */
254 if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
255 {
256 /* Parse patchfile header */
257 p = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data;
258 p_start = p;
259 STREAM_TO_UINT16 (patchfile_project_id, p);
260 STREAM_TO_UINT16 (patchfile_ver_major, p);
261 STREAM_TO_UINT16 (patchfile_ver_minor, p);
262
263 /* RFU */
264 p++;
265
266 /* Check how many patches are in the patch file */
267 STREAM_TO_UINT8 (u8, p);
268
269 /* Should only be one patch */
270 if (u8 > 1)
271 {
272 NCI_TRACE_ERROR1 ("Invalid i2c fix: invalid number of patches (%i)", u8);
273 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
274 return;
275 }
276
277
278 /* Get info about the i2c patch*/
279 STREAM_TO_UINT8 (u8, p); /* power mode (not needed for i2c patch) */
280 STREAM_TO_UINT16 (patchfile_patchsize, p); /* size of patch */
281
282 /* 5 byte RFU */
283 p += 5;
284
285 /* Adjust length to exclude patchfiloe header */
286 nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start); /* Adjust size of patchfile */
287 nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start); /* Bytes of patchfile transmitted/processed so far */
288
289 /* Begin sending patch to the NFCC */
290 nfc_hal_prm_spd_send_next_segment ();
291 }
292 else
293 {
294 /* ERROR: Bad length for patchfile */
295 NCI_TRACE_ERROR0 ("Invalid i2c fix: unexpected end of patch");
296 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
297 }
298 }
299 #endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
300
301 /*******************************************************************************
302 **
303 ** Function nfc_hal_prm_spd_check_version
304 **
305 ** Description Check patchfile version with current downloaded version
306 **
307 ** Returns void
308 **
309 *******************************************************************************/
nfc_hal_prm_spd_check_version(void)310 void nfc_hal_prm_spd_check_version (void)
311 {
312 UINT8 *p, *p_start, i;
313 UINT32 patchfile_patch_present_mask;
314 UINT16 patchfile_project_id;
315 UINT16 patchfile_ver_major = 0;
316 UINT16 patchfile_ver_minor;
317 UINT16 patchfile_patchsize;
318
319 UINT8 return_code = NFC_HAL_PRM_COMPLETE_EVT;
320
321 /* Initialize patchfile offset pointers */
322 p = p_start = NULL;
323 patchfile_patchsize = 0;
324
325 /* Get patchfile version */
326 if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
327 {
328 /* Parse patchfile header */
329 p = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data;
330 p_start = p;
331 STREAM_TO_UINT16 (patchfile_project_id, p);
332 STREAM_TO_UINT16 (patchfile_ver_major, p);
333 STREAM_TO_UINT16 (patchfile_ver_minor, p);
334
335 /* RFU */
336 p++;
337
338 /* Check how many patches are in the patch file */
339 STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_count, p);
340
341 if (nfc_hal_cb.prm.spd_patch_count > NFC_HAL_PRM_MAX_PATCH_COUNT)
342 {
343 NCI_TRACE_ERROR2 ("Unsupported patchfile (number of patches (%i) exceeds maximum (%i)",
344 nfc_hal_cb.prm.spd_patch_count, NFC_HAL_PRM_MAX_PATCH_COUNT);
345 }
346
347 /* Mask of patches that are present in the patchfile */
348 patchfile_patch_present_mask = 0;
349
350 /* Get lengths for each patch */
351 for (i = 0; i < nfc_hal_cb.prm.spd_patch_count; i++)
352 {
353 /* Get power mode for this patch */
354 STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_desc[i].power_mode, p);
355
356 /* Update mask of power-modes present in the patchfile */
357 patchfile_patch_present_mask |= ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[i].power_mode);
358
359 /* Get length of patch */
360 STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_patch_desc[i].len, p);
361
362 /* Add total size of patches */
363 patchfile_patchsize += nfc_hal_cb.prm.spd_patch_desc[i].len;
364
365 /* 5 byte RFU */
366 p += 5;
367 }
368
369 /* Adjust offset to after the patch file header */
370 nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start); /* Bytes of patchfile transmitted/processed so far */
371 nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start); /* Adjust size of patchfile */
372
373
374 NCI_TRACE_DEBUG6 ("Patchfile info: ProjID=0x%04x, Ver=%i.%i, Num patches=%i, PatchMask=0x%08x, PatchSize=%i",
375 patchfile_project_id, patchfile_ver_major, patchfile_ver_minor,
376 nfc_hal_cb.prm.spd_patch_count, patchfile_patch_present_mask, patchfile_patchsize);
377
378 /*********************************************************************
379 * Version check of patchfile against NVM
380 *********************************************************************/
381
382 #if (!defined (NFC_HAL_PRM_SKIP_VERSION_CHECK) || (NFC_HAL_PRM_SKIP_VERSION_CHECK == FALSE))
383 /* Download the patchfile if no patches in NVM */
384 if ((nfc_hal_cb.prm.spd_project_id == 0) || (nfc_hal_cb.prm.spd_nvm_patch_mask == 0))
385 {
386 /* No patch in NVM, need to download all */
387 nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
388
389 NCI_TRACE_DEBUG2 ("No previous patch detected. Downloading patch %i.%i",
390 patchfile_ver_major, patchfile_ver_minor);
391 }
392 /* Skip download if project ID of patchfile does not match NVM */
393 else if (nfc_hal_cb.prm.spd_project_id != patchfile_project_id)
394 {
395 /* Project IDs mismatch */
396 NCI_TRACE_DEBUG2 ("Patch download skipped: Mismatched Project ID (NVM ProjId: 0x%04x, Patchfile ProjId: 0x%04x)",
397 nfc_hal_cb.prm.spd_project_id, patchfile_project_id);
398
399 return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
400 }
401 /* Skip download if version of patchfile older or equal to version in NVM */
402 /* unless NVM is corrupted (then don't skip download if patchfile has the same major ver)*/
403 else if ( (nfc_hal_cb.prm.spd_ver_major > patchfile_ver_major)
404 ||( (nfc_hal_cb.prm.spd_ver_major == patchfile_ver_major) && (nfc_hal_cb.prm.spd_ver_minor == patchfile_ver_minor)
405 && !((patchfile_patch_present_mask & ( 1 << NFC_HAL_PRM_SPD_POWER_MODE_LPM)) && (nfc_hal_cb.prm.spd_lpm_patch_size == 0)) /* Do not skip download: patchfile has LPM, but NVM does not */
406 && !((patchfile_patch_present_mask & ( 1 << NFC_HAL_PRM_SPD_POWER_MODE_FPM)) && (nfc_hal_cb.prm.spd_fpm_patch_size == 0)) /* Do not skip download: patchfile has FPM, but NVM does not */
407 && !(nfc_hal_cb.prm.flags & (NFC_HAL_PRM_FLAGS_NVM_FPM_CORRUPTED |NFC_HAL_PRM_FLAGS_NVM_LPM_CORRUPTED)) ) )
408 {
409 /* NVM version is newer than patchfile */
410 NCI_TRACE_DEBUG2 ("Patch download skipped. NVM patch (version %i.%i) is newer than the patchfile ",
411 nfc_hal_cb.prm.spd_ver_major, nfc_hal_cb.prm.spd_ver_minor);
412
413 return_code = NFC_HAL_PRM_COMPLETE_EVT;
414 }
415 /* Remaining cases: patchfile major version is newer than NVM; or major version is the same with different minor version */
416 /* Download all patches in the patchfile */
417 else
418 {
419 nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
420
421 NCI_TRACE_DEBUG4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
422 patchfile_ver_major, patchfile_ver_minor,
423 nfc_hal_cb.prm.spd_ver_major, nfc_hal_cb.prm.spd_ver_minor);
424 }
425 #else /* NFC_HAL_PRM_SKIP_VERSION_CHECK */
426 nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
427 #endif
428 }
429 else
430 {
431 /* Invalid patch file header */
432 NCI_TRACE_ERROR0 ("Invalid patch file header.");
433
434 return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
435 }
436
437 /* If we need to download anything, get the first patch to download */
438 if (nfc_hal_cb.prm.spd_patch_needed_mask)
439 {
440 NCI_TRACE_ERROR4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
441 patchfile_ver_major, patchfile_ver_minor,
442 nfc_hal_cb.prm.spd_ver_major, nfc_hal_cb.prm.spd_ver_minor);
443 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
444 /* Check if I2C patch is needed: if */
445 /* - I2C patch file was provided using HAL_NfcPrmSetI2cPatch, and */
446 /* - current patch in NVM has ProjectID=0, or */
447 /* FPM is not present or corrupted, or */
448 /* or patchfile is major-ver 76+ */
449 if ( (nfc_hal_cb.prm_i2c.p_patch)
450 &&( (nfc_hal_cb.prm.spd_project_id == 0)
451 ||(nfc_hal_cb.prm.spd_fpm_patch_size == 0)
452 ||(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_NVM_FPM_CORRUPTED)
453 ||(patchfile_ver_major >= 76)))
454 {
455 NCI_TRACE_DEBUG0 ("I2C patch fix required.");
456 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
457
458 /* Download i2c fix first */
459 nfc_hal_prm_spd_download_i2c_fix ();
460 return;
461 }
462 #endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
463
464 /* Download first segment */
465 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
466 if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
467 {
468 /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch segment */
469 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
470 }
471 else
472 {
473 nfc_hal_prm_spd_handle_next_patch_start ();
474 }
475 }
476 else
477 {
478 static BOOLEAN firstTime = TRUE;
479 if (firstTime) {
480 NCI_TRACE_ERROR2 ("BCM2079x: NVM patch version is %d.%d",
481 nfc_hal_cb.prm.spd_ver_major, nfc_hal_cb.prm.spd_ver_minor);
482 firstTime = FALSE;
483 }
484 /* Download complete */
485 nfc_hal_prm_spd_handle_download_complete (return_code);
486 }
487 }
488
489 #if (NFC_HAL_TRACE_VERBOSE == TRUE)
490 /*******************************************************************************
491 **
492 ** Function nfc_hal_prm_spd_status_str
493 **
494 ** Description Return status string for a given spd status code
495 **
496 ** Returns Status string
497 **
498 *******************************************************************************/
nfc_hal_prm_spd_status_str(UINT8 spd_status_code)499 UINT8 *nfc_hal_prm_spd_status_str (UINT8 spd_status_code)
500 {
501 char *p_str;
502
503 switch (spd_status_code)
504 {
505 case NCI_STATUS_SPD_ERROR_DEST:
506 p_str = "SPD_ERROR_DEST";
507 break;
508
509 case NCI_STATUS_SPD_ERROR_PROJECTID:
510 p_str = "SPD_ERROR_PROJECTID";
511 break;
512
513 case NCI_STATUS_SPD_ERROR_CHIPVER:
514 p_str = "SPD_ERROR_CHIPVER";
515 break;
516
517 case NCI_STATUS_SPD_ERROR_MAJORVER:
518 p_str = "SPD_ERROR_MAJORVER";
519 break;
520
521 case NCI_STATUS_SPD_ERROR_INVALID_PARAM:
522 p_str = "SPD_ERROR_INVALID_PARAM";
523 break;
524
525 case NCI_STATUS_SPD_ERROR_INVALID_SIG:
526 p_str = "SPD_ERROR_INVALID_SIG";
527 break;
528
529 case NCI_STATUS_SPD_ERROR_NVM_CORRUPTED:
530 p_str = "SPD_ERROR_NVM_CORRUPTED";
531 break;
532
533 case NCI_STATUS_SPD_ERROR_PWR_MODE:
534 p_str = "SPD_ERROR_PWR_MODE";
535 break;
536
537 case NCI_STATUS_SPD_ERROR_MSG_LEN:
538 p_str = "SPD_ERROR_MSG_LEN";
539 break;
540
541 case NCI_STATUS_SPD_ERROR_PATCHSIZE:
542 p_str = "SPD_ERROR_PATCHSIZE";
543 break;
544
545 default:
546 p_str = "Unspecified Error";
547 break;
548
549 }
550
551 return ((UINT8*) p_str);
552 }
553 #endif /* (NFC_HAL_TRACE_VERBOSE == TRUE) */
554
555 /*******************************************************************************
556 **
557 ** Function nfc_hal_prm_nci_command_complete_cback
558 **
559 ** Description Callback for NCI vendor specific command complete
560 ** (for secure patch download)
561 **
562 ** Returns void
563 **
564 *******************************************************************************/
nfc_hal_prm_nci_command_complete_cback(tNFC_HAL_NCI_EVT event,UINT16 data_len,UINT8 * p_data)565 void nfc_hal_prm_nci_command_complete_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
566 {
567 UINT8 status, u8;
568 UINT8 *p;
569 UINT32 post_signature_delay;
570
571 NFC_HAL_PRM_STATE ("nfc_hal_prm_nci_command_complete_cback");
572
573 /* Stop the command-timeout timer */
574 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
575
576 /* Skip over NCI header */
577 p = p_data + NCI_MSG_HDR_SIZE;
578
579 /* Handle GET_PATCH_VERSION Rsp */
580 if (event == NFC_VS_GET_PATCH_VERSION_EVT)
581 {
582 /* Get project id */
583 STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_project_id, p);
584
585 /* RFU */
586 p++;
587
588 /* Get chip version string */
589 STREAM_TO_UINT8 (u8, p);
590 p += NFC_HAL_PRM_NCD_PATCH_VERSION_LEN;
591
592 /* Get major/minor version */
593 STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_ver_major, p);
594 STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_ver_minor, p);
595 STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_nvm_max_size, p);
596 STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_patch_max_size, p);
597 STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_lpm_patch_size, p);
598 STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_fpm_patch_size, p);
599
600 /* LPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */
601 STREAM_TO_UINT8 (u8, p);
602 if (!u8)
603 {
604 nfc_hal_cb.prm.spd_nvm_patch_mask |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_LPM);
605 }
606 else
607 {
608 /* LPM patch in NVM fails CRC check */
609 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_NVM_LPM_CORRUPTED;
610 }
611
612
613 /* FPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */
614 STREAM_TO_UINT8 (u8, p);
615 if (!u8)
616 {
617 nfc_hal_cb.prm.spd_nvm_patch_mask |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_FPM);
618 }
619 else
620 {
621 /* FPM patch in NVM fails CRC check */
622 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_NVM_FPM_CORRUPTED;
623 }
624
625 /* Check if downloading patch to RAM only (no NVM) */
626 STREAM_TO_UINT8 (u8, p);
627 if (!u8)
628 {
629 if (nfc_hal_prm_nvm_required)
630 {
631 NCI_TRACE_ERROR0 ("This platform requires NVM and the NVM is not available - Abort");
632 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_NO_NVM_EVT);
633 return;
634 }
635 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_NO_NVM;
636 }
637 /* Get patchfile version number */
638 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_COMPARE_VERSION;
639
640 if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
641 {
642 /* If patch is in a buffer, get patch version from buffer */
643 nfc_hal_prm_spd_check_version ();
644 }
645 else
646 {
647 /* Notify adaptation layer to send patch version (via HAL_NfcPrmDownloadContinue) */
648 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT);
649 }
650
651 }
652 /* Handle SECURE_PATCH_DOWNLOAD Rsp */
653 else if (event == NFC_VS_SEC_PATCH_DOWNLOAD_EVT)
654 {
655 /* Status and error code */
656 STREAM_TO_UINT8 (status, p);
657 STREAM_TO_UINT8 (u8, p);
658
659 if (status != NCI_STATUS_OK)
660 {
661 #if (NFC_HAL_TRACE_VERBOSE == TRUE)
662 NCI_TRACE_ERROR2 ("Patch download failed, reason code=0x%X (%s)", status, nfc_hal_prm_spd_status_str (status));
663 #else
664 NCI_TRACE_ERROR1 ("Patch download failed, reason code=0x%X", status);
665 #endif
666
667 /* Notify application */
668 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
669 return;
670 }
671
672 /* If last segment (SIGNATURE) sent */
673 if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_SIGNATURE_SENT)
674 {
675 /* Wait for authentication complate (SECURE_PATCH_DOWNLOAD NTF) */
676 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTHENTICATING;
677 nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
678 (NFC_HAL_PRM_SPD_TOUT * QUICK_TIMER_TICKS_PER_SEC) / 1000);
679 return;
680 }
681 /* Download next segment */
682 else if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
683 {
684 /* If patch is in a buffer, get next patch from buffer */
685 nfc_hal_prm_spd_send_next_segment ();
686 }
687 else
688 {
689 /* Notify adaptation layer to get next patch segment (via HAL_NfcPrmDownloadContinue) */
690 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_CONTINUE_EVT);
691 }
692 }
693 /* Handle SECURE_PATCH_DOWNLOAD NTF */
694 else if (event == NFC_VS_SEC_PATCH_AUTH_EVT)
695 {
696 NCI_TRACE_DEBUG1 ("prm flags:0x%x.", nfc_hal_cb.prm.flags);
697 /* Status and error code */
698 STREAM_TO_UINT8 (status, p);
699 STREAM_TO_UINT8 (u8, p);
700
701 /* Sanity check - should only get this NTF while in AUTHENTICATING stage */
702 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTHENTICATING)
703 {
704 if (status != NCI_STATUS_OK)
705 {
706 NCI_TRACE_ERROR0 ("Patch authentication failed");
707 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT);
708 return;
709 }
710
711 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
712 if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED)
713 {
714 NCI_TRACE_DEBUG1 ("PreI2C patch downloaded...waiting %i ms for NFCC to reboot.", nfc_hal_cb.prm_i2c.prei2c_delay);
715
716 /* Restore pointers to patchfile */
717 nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
718 nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm.p_spd_patch;
719 nfc_hal_cb.prm.cur_patch_offset = nfc_hal_cb.prm.spd_patch_offset;
720 nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm.spd_patch_len_remaining;
721
722 /* Resume normal patch download */
723 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
724 nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
725
726 /* Post PreI2C delay */
727 nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00, (nfc_hal_cb.prm_i2c.prei2c_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000);
728
729 return;
730 }
731 #endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
732
733
734 /* Wait for NFCC to save the patch to NVM */
735 if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_SUPPORT_RESET_NTF)
736 {
737 /* 20791B4 or newer - wait for RESET_NTF */
738 post_signature_delay = NFC_HAL_PRM_RESET_NTF_DELAY;
739 NCI_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for RESET NTF...", post_signature_delay);
740
741 }
742 else if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_NO_NVM)
743 {
744 /* No NVM. Wait for NFCC to restart */
745 post_signature_delay = NFC_HAL_PRM_END_DELAY;
746 NCI_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NFCC to restart...", post_signature_delay);
747 }
748 else
749 {
750 /* Wait for NFCC to save the patch to NVM (need about 1 ms per byte) */
751 post_signature_delay = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len;
752 if (post_signature_delay < nfc_hal_cb.prm.patchram_delay)
753 post_signature_delay = nfc_hal_cb.prm.patchram_delay;
754 NCI_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NVM update to complete...", post_signature_delay);
755 }
756
757 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTH_DONE;
758
759 nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
760 (post_signature_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000);
761 }
762 else
763 {
764 NCI_TRACE_ERROR0 ("Got unexpected SECURE_PATCH_DOWNLOAD NTF");
765 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
766 }
767 }
768 else
769 {
770 /* Invalid response from NFCC during patch download */
771 NCI_TRACE_ERROR1 ("Invalid response from NFCC during patch download (opcode=0x%02X)", event);
772 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
773 }
774
775 NFC_HAL_PRM_STATE ("prm_nci_command_complete_cback");
776 }
777
778 /*******************************************************************************
779 **
780 ** Function nfc_hal_prm_nfcc_ready_to_continue
781 **
782 ** Description Continue to download patch or notify application completition
783 **
784 ** Returns void
785 **
786 *******************************************************************************/
nfc_hal_prm_nfcc_ready_to_continue(void)787 void nfc_hal_prm_nfcc_ready_to_continue (void)
788 {
789 /* Clear the bit for the patch we just downloaded */
790 nfc_hal_cb.prm.spd_patch_needed_mask &= ~ ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
791
792 /* Check if another patch to download */
793 nfc_hal_cb.prm.spd_cur_patch_idx++;
794 if ((nfc_hal_cb.prm.spd_patch_needed_mask) && (nfc_hal_cb.prm.spd_cur_patch_idx < nfc_hal_cb.prm.spd_patch_count))
795 {
796 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
797 nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
798
799 if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
800 {
801 /* If patch is in a buffer, get next patch from buffer */
802 nfc_hal_prm_spd_handle_next_patch_start ();
803 }
804 else
805 {
806 /* Notify adaptation layer to get next patch header (via HAL_NfcPrmDownloadContinue) */
807 (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
808 }
809
810 }
811 else
812 {
813 /* Done downloading */
814 NCI_TRACE_DEBUG0 ("Patch downloaded and authenticated.");
815 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
816 }
817 }
818
819 /*******************************************************************************
820 **
821 ** Function nfc_hal_prm_spd_reset_ntf
822 **
823 ** Description Received RESET NTF from NFCC, indicating it has completed
824 ** reset after patch download.
825 **
826 ** Returns void
827 **
828 *******************************************************************************/
nfc_hal_prm_spd_reset_ntf(UINT8 reset_reason,UINT8 reset_type)829 void nfc_hal_prm_spd_reset_ntf (UINT8 reset_reason, UINT8 reset_type)
830 {
831 /* Check if we were expecting a RESET NTF */
832 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
833 {
834 NCI_TRACE_DEBUG2 ("Received RESET NTF after patch download (reset_reason=%i, reset_type=%i)", reset_reason, reset_type);
835
836 /* Stop waiting for RESET NTF */
837 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
838
839 {
840 /* Continue with patch download */
841 nfc_hal_prm_nfcc_ready_to_continue ();
842 }
843 }
844 else
845 {
846 NCI_TRACE_ERROR2 ("Received unexpected RESET NTF (reset_reason=%i, reset_type=%i)", reset_reason, reset_type);
847 }
848 }
849
850 /*******************************************************************************
851 **
852 ** Function: nfc_post_final_baud_update
853 **
854 ** Description: Called after baud rate udate
855 **
856 ** Returns: Nothing
857 **
858 *******************************************************************************/
nfc_hal_prm_post_baud_update(tHAL_NFC_STATUS status)859 void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status)
860 {
861 NFC_HAL_PRM_STATE ("nfc_hal_prm_post_baud_update");
862
863 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
864 {
865 /* Proceed with next step of patch download sequence */
866 nfc_hal_prm_nfcc_ready_to_continue ();
867 }
868 }
869
870 /*******************************************************************************
871 **
872 ** Function nfc_hal_prm_process_timeout
873 **
874 ** Description Process timer expireation for patch download
875 **
876 ** Returns void
877 **
878 *******************************************************************************/
nfc_hal_prm_process_timeout(void * p_tle)879 void nfc_hal_prm_process_timeout (void *p_tle)
880 {
881 NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout");
882
883 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_IDLE)
884 {
885 nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_VERSION;
886
887 /* Get currently downloaded patch version */
888 nfc_hal_dm_send_nci_cmd (nfc_hal_prm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, nfc_hal_prm_nci_command_complete_cback);
889 }
890 else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
891 {
892 if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_SUPPORT_RESET_NTF)
893 {
894 /* Timeout waiting for RESET NTF after signature sent */
895 NCI_TRACE_ERROR0 ("Timeout waiting for RESET NTF after patch download");
896 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
897 }
898 else
899 {
900 nfc_hal_prm_nfcc_ready_to_continue ();
901 }
902 }
903 else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
904 {
905 NCI_TRACE_DEBUG0 ("Delay after PreI2C patch download...proceeding to download firmware patch");
906 nfc_hal_prm_spd_handle_next_patch_start ();
907 }
908 else
909 {
910 NCI_TRACE_ERROR1 ("Patch download: command timeout (state=%i)", nfc_hal_cb.prm.state);
911
912 nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
913 }
914
915 NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout");
916 }
917
918
919 /*******************************************************************************
920 **
921 ** Function HAL_NfcPrmDownloadStart
922 **
923 ** Description Initiate patch download
924 **
925 ** Input Params
926 ** format_type patch format type
927 ** (NFC_HAL_PRM_FORMAT_BIN, NFC_HAL_PRM_FORMAT_HCD, or
928 ** NFC_HAL_PRM_FORMAT_NCD)
929 **
930 ** dest_address destination adderess (needed for BIN format only)
931 **
932 ** p_patchram_buf pointer to patchram buffer. If NULL,
933 ** then app must call HAL_NfcPrmDownloadContinue when
934 ** NFC_HAL_PRM_CONTINUE_EVT is received, to send the next
935 ** segment of patchram
936 **
937 ** patchram_len size of p_patchram_buf (if non-NULL)
938 **
939 ** patchram_delay The delay after each patch.
940 ** If the given value is less than the size of the patchram,
941 ** the size of patchram is used instead.
942 **
943 ** p_cback callback for download status
944 **
945 **
946 ** Returns TRUE if successful, otherwise FALSE
947 **
948 **
949 *******************************************************************************/
HAL_NfcPrmDownloadStart(tNFC_HAL_PRM_FORMAT format_type,UINT32 dest_address,UINT8 * p_patchram_buf,UINT32 patchram_len,UINT32 patchram_delay,tNFC_HAL_PRM_CBACK * p_cback)950 BOOLEAN HAL_NfcPrmDownloadStart (tNFC_HAL_PRM_FORMAT format_type,
951 UINT32 dest_address,
952 UINT8 *p_patchram_buf,
953 UINT32 patchram_len,
954 UINT32 patchram_delay,
955 tNFC_HAL_PRM_CBACK *p_cback)
956 {
957 NCI_TRACE_API0 ("HAL_NfcPrmDownloadStart ()");
958
959 memset (&nfc_hal_cb.prm, 0, sizeof (tNFC_HAL_PRM_CB));
960
961 if (p_patchram_buf)
962 {
963 nfc_hal_cb.prm.p_cur_patch_data = p_patchram_buf;
964 nfc_hal_cb.prm.cur_patch_offset = 0;
965 nfc_hal_cb.prm.cur_patch_len_remaining = (UINT16) patchram_len;
966 nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF;
967
968 if (patchram_len == 0)
969 return FALSE;
970 }
971
972 nfc_hal_cb.prm.p_cback = p_cback;
973 nfc_hal_cb.prm.dest_ram = dest_address;
974 nfc_hal_cb.prm.format = format_type;
975 nfc_hal_cb.prm.patchram_delay = patchram_delay;
976
977 nfc_hal_cb.prm.timer.p_cback = nfc_hal_prm_process_timeout;
978
979 if (format_type == NFC_HAL_PRM_FORMAT_NCD)
980 {
981 /* Store patch buffer pointer and length */
982 nfc_hal_cb.prm.p_spd_patch = p_patchram_buf;
983 nfc_hal_cb.prm.spd_patch_len_remaining = (UINT16)patchram_len;
984 nfc_hal_cb.prm.spd_patch_offset = 0;
985
986 /* Need delay for controller to finish resetting */
987 nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
988 (NFC_HAL_PRM_SPD_PRE_DOWNLOAD_DELAY * QUICK_TIMER_TICKS_PER_SEC) / 1000);
989 }
990 else
991 {
992 NCI_TRACE_ERROR0 ("Unexpected patch format.");
993 return FALSE;
994 }
995
996 return TRUE;
997 }
998
999 /*******************************************************************************
1000 **
1001 ** Function HAL_NfcPrmDownloadContinue
1002 **
1003 ** Description Send next segment of patchram to controller. Called when
1004 ** NFC_HAL_PRM_CONTINUE_EVT is received.
1005 **
1006 ** Only needed if HAL_NfcPrmDownloadStart was called with
1007 ** p_patchram_buf=NULL
1008 **
1009 ** Input Params p_patch_data pointer to patch data
1010 ** patch_data_len patch data len
1011 **
1012 ** Returns TRUE if successful, otherwise FALSE
1013 **
1014 *******************************************************************************/
HAL_NfcPrmDownloadContinue(UINT8 * p_patch_data,UINT16 patch_data_len)1015 BOOLEAN HAL_NfcPrmDownloadContinue (UINT8 *p_patch_data,
1016 UINT16 patch_data_len)
1017 {
1018 NCI_TRACE_API2 ("HAL_NfcPrmDownloadContinue ():state = %d, patch_data_len=%d",
1019 nfc_hal_cb.prm.state, patch_data_len);
1020
1021 /* Check if we are in a valid state for this API */
1022 if ( (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_COMPARE_VERSION)
1023 &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
1024 &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_DOWNLOADING) )
1025 return FALSE;
1026
1027 if (patch_data_len == 0)
1028 return FALSE;
1029
1030 nfc_hal_cb.prm.cur_patch_offset = 0;
1031 nfc_hal_cb.prm.p_cur_patch_data = p_patch_data;
1032 nfc_hal_cb.prm.cur_patch_len_remaining = patch_data_len;
1033
1034 /* Call appropriate handler */
1035 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_COMPARE_VERSION)
1036 {
1037 nfc_hal_prm_spd_check_version ();
1038 }
1039 else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
1040 {
1041 nfc_hal_prm_spd_handle_next_patch_start ();
1042 }
1043 else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_DOWNLOADING)
1044 {
1045 nfc_hal_prm_spd_send_next_segment ();
1046 }
1047 else
1048 {
1049 NCI_TRACE_ERROR1 ("Unexpected patch state:%d.", nfc_hal_cb.prm.state);
1050 }
1051
1052 return TRUE;
1053 }
1054
1055 /*******************************************************************************
1056 **
1057 ** Function HAL_NfcPrmSetI2cPatch
1058 **
1059 ** Description Specify patchfile for BCM20791B3 I2C fix. This fix
1060 ** must be downloaded prior to initial patch download for I2C
1061 ** transport
1062 **
1063 ** Input Params p_i2c_patchfile_buf: pointer to patch for i2c fix
1064 ** i2c_patchfile_len: length of patch
1065 ** prei2c_delay: the delay before downloading main patch
1066 ** if 0 is given, NFC_HAL_PRM_POST_I2C_FIX_DELAY is used instead.
1067 **
1068 ** Returns Nothing
1069 **
1070 **
1071 *******************************************************************************/
HAL_NfcPrmSetI2cPatch(UINT8 * p_i2c_patchfile_buf,UINT16 i2c_patchfile_len,UINT32 prei2c_delay)1072 void HAL_NfcPrmSetI2cPatch (UINT8 *p_i2c_patchfile_buf, UINT16 i2c_patchfile_len, UINT32 prei2c_delay)
1073 {
1074 #if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
1075 NCI_TRACE_API0 ("HAL_NfcPrmSetI2cPatch ()");
1076
1077 nfc_hal_cb.prm_i2c.prei2c_delay = NFC_HAL_PRM_POST_I2C_FIX_DELAY;
1078 if (prei2c_delay)
1079 nfc_hal_cb.prm_i2c.prei2c_delay = prei2c_delay;
1080 nfc_hal_cb.prm_i2c.p_patch = p_i2c_patchfile_buf;
1081 nfc_hal_cb.prm_i2c.len = i2c_patchfile_len;
1082 #endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
1083 }
1084
1085 /*******************************************************************************
1086 **
1087 ** Function HAL_NfcPrmSetSpdNciCmdPayloadSize
1088 **
1089 ** Description Set Host-to-NFCC NCI message size for secure patch download
1090 **
1091 ** This API must be called before calling HAL_NfcPrmDownloadStart.
1092 ** If the API is not called, then PRM will use the default
1093 ** message size.
1094 **
1095 ** Typically, this API is only called for platforms that have
1096 ** message-size limitations in the transport/driver.
1097 **
1098 ** Valid message size range: NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE to 255.
1099 **
1100 ** Returns HAL_NFC_STATUS_OK if successful
1101 ** HAL_NFC_STATUS_FAILED otherwise
1102 **
1103 **
1104 *******************************************************************************/
HAL_NfcPrmSetSpdNciCmdPayloadSize(UINT8 max_payload_size)1105 tHAL_NFC_STATUS HAL_NfcPrmSetSpdNciCmdPayloadSize (UINT8 max_payload_size)
1106 {
1107 /* Validate: minimum size is NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE */
1108 if (max_payload_size < NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE)
1109 {
1110 NCI_TRACE_ERROR2 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: invalid size (%i). Must be between %i and 255", max_payload_size, NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE);
1111 return (HAL_NFC_STATUS_FAILED);
1112 }
1113 else
1114 {
1115 NCI_TRACE_API1 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: new message size during download: %i", max_payload_size);
1116 nfc_hal_cb.ncit_cb.nci_ctrl_size = max_payload_size;
1117 return (HAL_NFC_STATUS_OK);
1118 }
1119 }
1120