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