162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Linux network driver for QLogic BR-series Converged Network Adapter.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci/*
662306a36Sopenharmony_ci * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
762306a36Sopenharmony_ci * Copyright (c) 2014-2015 QLogic Corporation
862306a36Sopenharmony_ci * All rights reserved
962306a36Sopenharmony_ci * www.qlogic.com
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci#include <linux/firmware.h>
1262306a36Sopenharmony_ci#include "bnad.h"
1362306a36Sopenharmony_ci#include "bfi.h"
1462306a36Sopenharmony_ci#include "cna.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciconst struct firmware *bfi_fw;
1762306a36Sopenharmony_cistatic u32 *bfi_image_ct_cna, *bfi_image_ct2_cna;
1862306a36Sopenharmony_cistatic u32 bfi_image_ct_cna_size, bfi_image_ct2_cna_size;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistatic u32 *
2162306a36Sopenharmony_cicna_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
2262306a36Sopenharmony_ci			u32 *bfi_image_size, char *fw_name)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	const struct firmware *fw;
2562306a36Sopenharmony_ci	u32 n;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	if (request_firmware(&fw, fw_name, &pdev->dev)) {
2862306a36Sopenharmony_ci		dev_alert(&pdev->dev, "can't load firmware %s\n", fw_name);
2962306a36Sopenharmony_ci		goto error;
3062306a36Sopenharmony_ci	}
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	*bfi_image = (u32 *)fw->data;
3362306a36Sopenharmony_ci	*bfi_image_size = fw->size/sizeof(u32);
3462306a36Sopenharmony_ci	bfi_fw = fw;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	/* Convert loaded firmware to host order as it is stored in file
3762306a36Sopenharmony_ci	 * as sequence of LE32 integers.
3862306a36Sopenharmony_ci	 */
3962306a36Sopenharmony_ci	for (n = 0; n < *bfi_image_size; n++)
4062306a36Sopenharmony_ci		le32_to_cpus(*bfi_image + n);
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	return *bfi_image;
4362306a36Sopenharmony_cierror:
4462306a36Sopenharmony_ci	return NULL;
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ciu32 *
4862306a36Sopenharmony_cicna_get_firmware_buf(struct pci_dev *pdev)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	if (pdev->device == BFA_PCI_DEVICE_ID_CT2) {
5162306a36Sopenharmony_ci		if (bfi_image_ct2_cna_size == 0)
5262306a36Sopenharmony_ci			cna_read_firmware(pdev, &bfi_image_ct2_cna,
5362306a36Sopenharmony_ci				&bfi_image_ct2_cna_size, CNA_FW_FILE_CT2);
5462306a36Sopenharmony_ci		return bfi_image_ct2_cna;
5562306a36Sopenharmony_ci	} else if (bfa_asic_id_ct(pdev->device)) {
5662306a36Sopenharmony_ci		if (bfi_image_ct_cna_size == 0)
5762306a36Sopenharmony_ci			cna_read_firmware(pdev, &bfi_image_ct_cna,
5862306a36Sopenharmony_ci				&bfi_image_ct_cna_size, CNA_FW_FILE_CT);
5962306a36Sopenharmony_ci		return bfi_image_ct_cna;
6062306a36Sopenharmony_ci	}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	return NULL;
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ciu32 *
6662306a36Sopenharmony_cibfa_cb_image_get_chunk(enum bfi_asic_gen asic_gen, u32 off)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	switch (asic_gen) {
6962306a36Sopenharmony_ci	case BFI_ASIC_GEN_CT:
7062306a36Sopenharmony_ci		return (bfi_image_ct_cna + off);
7162306a36Sopenharmony_ci	case BFI_ASIC_GEN_CT2:
7262306a36Sopenharmony_ci		return (bfi_image_ct2_cna + off);
7362306a36Sopenharmony_ci	default:
7462306a36Sopenharmony_ci		return NULL;
7562306a36Sopenharmony_ci	}
7662306a36Sopenharmony_ci}
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ciu32
7962306a36Sopenharmony_cibfa_cb_image_get_size(enum bfi_asic_gen asic_gen)
8062306a36Sopenharmony_ci{
8162306a36Sopenharmony_ci	switch (asic_gen) {
8262306a36Sopenharmony_ci	case BFI_ASIC_GEN_CT:
8362306a36Sopenharmony_ci		return bfi_image_ct_cna_size;
8462306a36Sopenharmony_ci	case BFI_ASIC_GEN_CT2:
8562306a36Sopenharmony_ci		return bfi_image_ct2_cna_size;
8662306a36Sopenharmony_ci	default:
8762306a36Sopenharmony_ci		return 0;
8862306a36Sopenharmony_ci	}
8962306a36Sopenharmony_ci}
90