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