root/usr/src/uts/common/io/qede/579xx/hsi/common_nvm.h
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, v.1,  (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/

/*
* Copyright 2014-2017 Cavium, Inc. 
* The contents of this file are subject to the terms of the Common Development 
* and Distribution License, v.1,  (the "License").

* You may not use this file except in compliance with the License.

* You can obtain a copy of the License at available 
* at http://opensource.org/licenses/CDDL-1.0

* See the License for the specific language governing permissions and 
* limitations under the License.
*/


#ifndef _COMMON_NVM_H_ 
#define _COMMON_NVM_H_ 

#include "nvm_map.h"
#include "append.h"
// Callbacks:

#ifndef MFW
#ifndef UEFI
        #define TRACE(module, ...)      EDIAG_ERR(__VA_ARGS__)
#else // UEFI   
        #define TRACE   
#endif
#else // MFW
extern void memset32(u32 *ptr, u32 val, u32 byte_cnt);
extern void memcpy32(u32 *ptr, u32 *src, u32 byte_cnt);
#endif

extern int nvm_read(u32 nvm_addr, u32 n_bytes, u32 *read_buf);
extern void compute_crc_from_buf(u32 *buf_p, u32 len, u32 *crc_p);
extern int nvm_write(u32 nvm_addr, u32 byte_cnt, u32 *buf);
extern int validate_dir(u32 bundle_id, u32 num_images);
extern void nvm_write_progress_cb(u32 byte_cnt, u32 orig_byte_cnt);

#ifndef ERROR
#define ERROR (-1)
#endif

#ifndef OK
#define OK (0)
#endif

#define ROMIMG_NUM_MAX          8

#define PCIR_OFFSET(f)  ((u32)((int_ptr_t) &(((pci30_rom_hdr *)0)->f)))

typedef enum {
        MBA_MBA_LEGACY_IDX = 0,
        MBA_MBA_PCI3CLP_IDX,
        MBA_MBA_PCI3_IDX,
        MBA_FCODE_IDX,
        EFI_X86_IDX,
        EFI_IPF_IDX,
        EFI_EBC_IDX,
        EFI_X64_IDX
} mba_image_t;

typedef struct _exp_rom_hdr_t
{
#define ROM_HEADER_SIG          0x0AA55
        u16 Signature;
        u8  Size;
        u8  Entry[4];
        u8  Cksum;
        u16 VendorOffset;             /* Offset to vendor_data_t structure */
        u8  reserved1[12];
        u16 ROMIDoffset;
        u16 PCIdsOffset;
        u16 PnPehOffset;              /* Offset to pci_rom_hdr_t structure */
        u8  reserved2[4];
} exp_rom_hdr;

typedef struct _pci30_rom_hdr_t
{
        u8  Signature[4]; /* PCIR */
        u16 VendorID;
        u16 DeviceID;
        u16 VP;
        u16 StructLength;
        u8  StructRev; /* PCI30 or not */
        u8  BaseClass;
        u8  SubClass;
        u8  Interface;
        u16 ImageLength;
        u16 ImageRev;
        u8  CodeType;
        u8  Indicator;
        u16 RunTimeImgLen;
        u16 CfgCodeHdr;
        u16 DmtfEntry;
} pci30_rom_hdr;

/*****************************************************************************
 *
 * FUNCTION:       validate_image_header
 *
 * DESCRIPTION:    Returns the flash size in bytes.
 *
 * INPUT:          p_img_hdr
 *         
 * OUTPUT:         None
 * 
 * RETURNS:        Flash size in bytes
 *****************************************************************************/
int validate_image_header(struct image_header *p_img_hdr);

/*****************************************************************************
 *
 * FUNCTION:       get_flash_size
 *
 * DESCRIPTION:    Returns the flash size in bytes.
 *
 * INPUT:          None
 *         
 * OUTPUT:         None
 * 
 * RETURNS:        Flash size in bytes
 *****************************************************************************/
u32 get_flash_size(void);

/*****************************************************************************
 *
 * FUNCTION:       allocate_nvram_for_image
 *
 * DESCRIPTION:    Responsible allocating nvram room for an image.
 *                 1. Remove the image from the directory (if exists)
 *                 2. In case it is MIM or LIM, select the fixed nvram offset,
 *                    otherwise, use the "find_room_for_image" to find room.
 *                 3. Add the new image_header to the directory.
 *                
 * INPUT:          p_dir - Pointer to directory
 *                 p_image_header - Pointer to the requested image header.
 * 
 * OUTPUT:         o_nvm_offset - nvm offset of the allocated room.
 * 
 * RETURNS:        OK / ERROR
 *****************************************************************************/
int allocate_nvram_for_image(struct nvm_dir *p_dir, struct image_header *p_image_header, u32 *o_nvm_offset);

/*****************************************************************************
 *
 * FUNCTION:       find_room_for_image
 *
 * DESCRIPTION:    Finds room for new nvm image
 *
 * INPUT           image_type
 *                 byte_cnt
 *                 p_dir
 * OUTPUT:         out_nvm_offset
 *
 * RETURNS:        OK/ERROR
 *
 *****************************************************************************/
int find_room_for_image(u32 image_type,
                                                u32 byte_cnt,
                                                struct nvm_dir *p_dir,
                                                u32 *out_nvm_offset);

/*****************************************************************************
 *
 * FUNCTION:       get_active_dir
 *
 * DESCRIPTION:    Responsible allocating nvram room for an image.
 *                 1. Read headers of both directories
 *                 2. Validate their CRC with accordance to their sequence number.
 *                 3. In case a directory is valid, return its id along with its next MFW.
 * OUTPUT:         o_dir_id - Active Dir ID
 *                 o_next_mfw - Next MFW scheduled to run from the dir.
 * 
 * RETURNS:        OK / ERROR
 *****************************************************************************/
int get_active_dir(u32 *o_dir_id, u32 *o_next_mfw);

/*****************************************************************************
 *
 * FUNCTION:       prepare_bootstrap
 *
 * DESCRIPTION:    This function updates the active NVM bootstrap. The active bootstrap is
 *                 read by the device ROM upon reset, and according to the bootstrap
 *                 information it loads LIM, which starts running the MFW.
 *
 * INPUT:          i_lim_header - Image header of LIM
 * 
 * OUTPUT:         o_bootstrap - Bootstrap struct to be stored in nvram.
 * 
 * RETURNS:        none
 *****************************************************************************/
void prepare_bootstrap(struct image_header *i_lim_header,
                       struct legacy_bootstrap_region *o_bootstrap);

/*****************************************************************************
 *
 * FUNCTION:       nvm_update_dir
 *
 * DESCRIPTION:    Update directory to nvram.
 *
 * INPUT:          p_dir - Pointer to the directory
 *                 is_mfw - true/false
 * INPUT/OUTPUT:   dir_id - Input - the current dir id. Output - The updated dir id
 * 
 * RETURNS:        none
 *****************************************************************************/
int nvm_update_dir(struct nvm_dir *p_dir, u32 *dir_id, u32 is_mfw);

/*****************************************************************************
 *
 * FUNCTION:       add_nvm_entry_to_dir
 *
 * DESCRIPTION:    Adds new image entry to a given directory.
 *                 1. Verify number of images doesn't exceed some crazy number - 200
 *                 2. Since the dir is sorted according to nvram offset, move up
 *                    all image entries higher than the requested offset for the
 *                    new image entry
 *                 3. Insert the new image entry
 *                 4. Increase the number of entries in the directory.
 *
 * INPUT/OUTPUT    p_dir - Pointer to the directory buffer
 *                 nvm_offset - The nvram address for the new image
 *                 p_image_header - Pointer to the image header.
 *
 * RETURNS:        ERROR/OK
 *****************************************************************************/
int add_nvm_entry_to_dir(struct nvm_dir *p_dir,
                         u32 nvm_offset,
                         struct image_header *p_image_header);

/*****************************************************************************
 * FUNCTION:       get_alt_image_type
 *
 * DESCRIPTION:    If image type is part of the MFW bundle (which has two
 *                 bundles/slots in the nvram), then set the image type as the
 *                 non-running one, otherwise, change nothing.
 * 
 * INPUT:          running_mfw - 0/1
 *                 image_type
 *
 * RETURNS:        Alternate image type
 *****************************************************************************/
u32 get_alt_image_type(u32 running_mfw, u32 image_type);

/*****************************************************************************
 * FUNCTION:       load_active_nvm_dir
 *
 * DESCRIPTION:    Loads the active nvm dir to the o_dir_p
 * 
 * INPUT:          None
 * 
 * OUTPUT:         o_dir_p - Pointer to directory structure to be populated.
 *                 o_cur_dir_id - Active Dir ID
 *
 * RETURNS:        OK/ERROR
 *****************************************************************************/
int load_active_nvm_dir(struct nvm_dir *o_dir_p, u32 *o_cur_dir_id);

/*****************************************************************************
 *
 * FUNCTION:       remove_image_from_dir
 *
 * DESCRIPTION:    Removes requested images from a giveN dir pointer, and
 *                 squeeze images back. In case the requested image is not found,
 *                 it does nothing.
 *                 NOTE: This function doesn't recalc the CRC, or write the dir
 *                 back to nvram !
 *
 * INPUT:          p_dir - pointer to the directory
 *                 image_type - Requested image type to remove
 *
 * RETURNS:        OK - Image removed
 *                 ERROR - Image not found
 *****************************************************************************/
int remove_image_from_dir(struct nvm_dir *p_dir,
                          u32 image_type);

/*****************************************************************************
 *
 * FUNCTION:       inner_nvm_block_write
 *
 * DESCRIPTION:    Internal function for writting block of data to nvram.
 *                 NOTE: 1. This function doesn't take nvram lock to allow multiple
 *                          transactions within the same page.
 *                       2. When calling this function, please use the nvm_flags
 *                          correctly:
 *                          MCP_REG_NVM_COMMAND_FIRST - Sets the FIRST flag on the first
 *                                              transaction.
 *                          MCP_REG_NVM_COMMAND_LAST  - Sets the LAST flag on the last byte write.
 *                                               Avoid setting this flag for multiple
 *                                               transaction on the same page, and set it
 *                                               only for the last one.
 *                                               In any case, the LAST flag will be set at
 *                                               the end of NVM page (4KB).
 *
 * INPUT:          nvm_flags - MCP_REG_NVM_COMMAND_FIRST/MCP_REG_NVM_COMMAND_LAST/0 - See above
 *                 nvm_addr  - Destination nvm address
 *                 byte_cnt  - Number of bytes
 *                 p_buf     - Pointer to the input buffer.
 *
 * RETURNS:        OK - Image removed
 *                 ERROR - Image not found
 *****************************************************************************/
#define MCP_REG_NVM_COMMAND_DISPLAY  (0x1<<31)
int inner_nvm_write(u32 nvm_flags, u32 nvm_addr, u32 byte_cnt, u32 *p_buf);

/**********************************************************************
 * FUNCTION:       find_image_by_type_in_dir
 *
 * DESCRIPTION:    Checks if the requested image type exist in the directory.
 *                 If so, it provide it in the output parameter index, and returns OK
 *                 Otherwise it returns ERROR;
 *
 * INPUT:          dir_p          - Pointer to directory
 *                 requested_type - Image type to look for
 *
 * RETURNS:        OK - If requested image found
 *                 ERROR - Otherwise.
 ***********************************************************************/
int find_image_by_type_in_dir(struct nvm_dir *dir_p,
                              u32 requested_type,
                              u32 *index);

#endif /* _COMMON_NVM_H_ */