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