mirror of
https://github.com/torvalds/linux.git
synced 2024-11-01 09:41:44 +00:00
bna: Added flash sub-module and ethtool eeprom entry points.
Change details: - The patch adds flash sub-module to the bna driver. - Added ethtool set_eeprom() and get_eeprom() entry points to support flash partition read/write operations. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6fc0d0f2e3
commit
72a9730b3f
@ -219,41 +219,39 @@ enum {
|
||||
* All numerical fields are in big-endian format.
|
||||
*/
|
||||
struct bfa_mfg_block {
|
||||
u8 version; /*!< manufacturing block version */
|
||||
u8 mfg_sig[3]; /*!< characters 'M', 'F', 'G' */
|
||||
u16 mfgsize; /*!< mfg block size */
|
||||
u16 u16_chksum; /*!< old u16 checksum */
|
||||
u8 version; /* manufacturing block version */
|
||||
u8 mfg_sig[3]; /* characters 'M', 'F', 'G' */
|
||||
u16 mfgsize; /* mfg block size */
|
||||
u16 u16_chksum; /* old u16 checksum */
|
||||
char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)];
|
||||
char brcd_partnum[STRSZ(BFA_MFG_PARTNUM_SIZE)];
|
||||
u8 mfg_day; /*!< manufacturing day */
|
||||
u8 mfg_month; /*!< manufacturing month */
|
||||
u16 mfg_year; /*!< manufacturing year */
|
||||
u64 mfg_wwn; /*!< wwn base for this adapter */
|
||||
u8 num_wwn; /*!< number of wwns assigned */
|
||||
u8 mfg_speeds; /*!< speeds allowed for this adapter */
|
||||
u8 mfg_day; /* manufacturing day */
|
||||
u8 mfg_month; /* manufacturing month */
|
||||
u16 mfg_year; /* manufacturing year */
|
||||
u64 mfg_wwn; /* wwn base for this adapter */
|
||||
u8 num_wwn; /* number of wwns assigned */
|
||||
u8 mfg_speeds; /* speeds allowed for this adapter */
|
||||
u8 rsv[2];
|
||||
char supplier_id[STRSZ(BFA_MFG_SUPPLIER_ID_SIZE)];
|
||||
char supplier_partnum[STRSZ(BFA_MFG_SUPPLIER_PARTNUM_SIZE)];
|
||||
char
|
||||
supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)];
|
||||
char
|
||||
supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)];
|
||||
mac_t mfg_mac; /*!< mac address */
|
||||
u8 num_mac; /*!< number of mac addresses */
|
||||
char supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)];
|
||||
char supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)];
|
||||
mac_t mfg_mac; /* base mac address */
|
||||
u8 num_mac; /* number of mac addresses */
|
||||
u8 rsv2;
|
||||
u32 card_type; /*!< card type */
|
||||
char cap_nic; /*!< capability nic */
|
||||
char cap_cna; /*!< capability cna */
|
||||
char cap_hba; /*!< capability hba */
|
||||
char cap_fc16g; /*!< capability fc 16g */
|
||||
char cap_sriov; /*!< capability sriov */
|
||||
char cap_mezz; /*!< capability mezz */
|
||||
u32 card_type; /* card type */
|
||||
char cap_nic; /* capability nic */
|
||||
char cap_cna; /* capability cna */
|
||||
char cap_hba; /* capability hba */
|
||||
char cap_fc16g; /* capability fc 16g */
|
||||
char cap_sriov; /* capability sriov */
|
||||
char cap_mezz; /* capability mezz */
|
||||
u8 rsv3;
|
||||
u8 mfg_nports; /*!< number of ports */
|
||||
char media[8]; /*!< xfi/xaui */
|
||||
char initial_mode[8];/*!< initial mode: hba/cna/nic */
|
||||
u8 mfg_nports; /* number of ports */
|
||||
char media[8]; /* xfi/xaui */
|
||||
char initial_mode[8]; /* initial mode: hba/cna/nic */
|
||||
u8 rsv4[84];
|
||||
u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /*!< md5 checksum */
|
||||
u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /* md5 checksum */
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
@ -293,4 +291,34 @@ enum bfa_mode {
|
||||
BFA_MODE_NIC = 3
|
||||
};
|
||||
|
||||
/*
|
||||
* Flash module specific
|
||||
*/
|
||||
#define BFA_FLASH_PART_ENTRY_SIZE 32 /* partition entry size */
|
||||
#define BFA_FLASH_PART_MAX 32 /* maximal # of partitions */
|
||||
#define BFA_TOTAL_FLASH_SIZE 0x400000
|
||||
#define BFA_FLASH_PART_MFG 7
|
||||
|
||||
/*
|
||||
* flash partition attributes
|
||||
*/
|
||||
struct bfa_flash_part_attr {
|
||||
u32 part_type; /* partition type */
|
||||
u32 part_instance; /* partition instance */
|
||||
u32 part_off; /* partition offset */
|
||||
u32 part_size; /* partition size */
|
||||
u32 part_len; /* partition content length */
|
||||
u32 part_status; /* partition status */
|
||||
char rsv[BFA_FLASH_PART_ENTRY_SIZE - 24];
|
||||
};
|
||||
|
||||
/*
|
||||
* flash attributes
|
||||
*/
|
||||
struct bfa_flash_attr {
|
||||
u32 status; /* flash overall status */
|
||||
u32 npart; /* num of partitions */
|
||||
struct bfa_flash_part_attr part[BFA_FLASH_PART_MAX];
|
||||
};
|
||||
|
||||
#endif /* __BFA_DEFS_H__ */
|
||||
|
@ -2171,6 +2171,15 @@ bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc)
|
||||
bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* return true if IOC is operational
|
||||
*/
|
||||
bool
|
||||
bfa_nw_ioc_is_operational(struct bfa_ioc *ioc)
|
||||
{
|
||||
return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to IOC heartbeat failure notification queue. To be used by common
|
||||
* modules such as cee, port, diag.
|
||||
@ -2471,3 +2480,366 @@ bfa_ioc_poll_fwinit(struct bfa_ioc *ioc)
|
||||
msecs_to_jiffies(BFA_IOC_POLL_TOV));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Flash module specific
|
||||
*/
|
||||
|
||||
/*
|
||||
* FLASH DMA buffer should be big enough to hold both MFG block and
|
||||
* asic block(64k) at the same time and also should be 2k aligned to
|
||||
* avoid write segement to cross sector boundary.
|
||||
*/
|
||||
#define BFA_FLASH_SEG_SZ 2048
|
||||
#define BFA_FLASH_DMA_BUF_SZ \
|
||||
roundup(0x010000 + sizeof(struct bfa_mfg_block), BFA_FLASH_SEG_SZ)
|
||||
|
||||
static void
|
||||
bfa_flash_cb(struct bfa_flash *flash)
|
||||
{
|
||||
flash->op_busy = 0;
|
||||
if (flash->cbfn)
|
||||
flash->cbfn(flash->cbarg, flash->status);
|
||||
}
|
||||
|
||||
static void
|
||||
bfa_flash_notify(void *cbarg, enum bfa_ioc_event event)
|
||||
{
|
||||
struct bfa_flash *flash = cbarg;
|
||||
|
||||
switch (event) {
|
||||
case BFA_IOC_E_DISABLED:
|
||||
case BFA_IOC_E_FAILED:
|
||||
if (flash->op_busy) {
|
||||
flash->status = BFA_STATUS_IOC_FAILURE;
|
||||
flash->cbfn(flash->cbarg, flash->status);
|
||||
flash->op_busy = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send flash write request.
|
||||
*
|
||||
* @param[in] cbarg - callback argument
|
||||
*/
|
||||
static void
|
||||
bfa_flash_write_send(struct bfa_flash *flash)
|
||||
{
|
||||
struct bfi_flash_write_req *msg =
|
||||
(struct bfi_flash_write_req *) flash->mb.msg;
|
||||
u32 len;
|
||||
|
||||
msg->type = be32_to_cpu(flash->type);
|
||||
msg->instance = flash->instance;
|
||||
msg->offset = be32_to_cpu(flash->addr_off + flash->offset);
|
||||
len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ?
|
||||
flash->residue : BFA_FLASH_DMA_BUF_SZ;
|
||||
msg->length = be32_to_cpu(len);
|
||||
|
||||
/* indicate if it's the last msg of the whole write operation */
|
||||
msg->last = (len == flash->residue) ? 1 : 0;
|
||||
|
||||
bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_WRITE_REQ,
|
||||
bfa_ioc_portid(flash->ioc));
|
||||
bfa_alen_set(&msg->alen, len, flash->dbuf_pa);
|
||||
memcpy(flash->dbuf_kva, flash->ubuf + flash->offset, len);
|
||||
bfa_nw_ioc_mbox_queue(flash->ioc, &flash->mb, NULL, NULL);
|
||||
|
||||
flash->residue -= len;
|
||||
flash->offset += len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send flash read request.
|
||||
*
|
||||
* @param[in] cbarg - callback argument
|
||||
*/
|
||||
static void
|
||||
bfa_flash_read_send(void *cbarg)
|
||||
{
|
||||
struct bfa_flash *flash = cbarg;
|
||||
struct bfi_flash_read_req *msg =
|
||||
(struct bfi_flash_read_req *) flash->mb.msg;
|
||||
u32 len;
|
||||
|
||||
msg->type = be32_to_cpu(flash->type);
|
||||
msg->instance = flash->instance;
|
||||
msg->offset = be32_to_cpu(flash->addr_off + flash->offset);
|
||||
len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ?
|
||||
flash->residue : BFA_FLASH_DMA_BUF_SZ;
|
||||
msg->length = be32_to_cpu(len);
|
||||
bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_READ_REQ,
|
||||
bfa_ioc_portid(flash->ioc));
|
||||
bfa_alen_set(&msg->alen, len, flash->dbuf_pa);
|
||||
bfa_nw_ioc_mbox_queue(flash->ioc, &flash->mb, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process flash response messages upon receiving interrupts.
|
||||
*
|
||||
* @param[in] flasharg - flash structure
|
||||
* @param[in] msg - message structure
|
||||
*/
|
||||
static void
|
||||
bfa_flash_intr(void *flasharg, struct bfi_mbmsg *msg)
|
||||
{
|
||||
struct bfa_flash *flash = flasharg;
|
||||
u32 status;
|
||||
|
||||
union {
|
||||
struct bfi_flash_query_rsp *query;
|
||||
struct bfi_flash_write_rsp *write;
|
||||
struct bfi_flash_read_rsp *read;
|
||||
struct bfi_mbmsg *msg;
|
||||
} m;
|
||||
|
||||
m.msg = msg;
|
||||
|
||||
/* receiving response after ioc failure */
|
||||
if (!flash->op_busy && msg->mh.msg_id != BFI_FLASH_I2H_EVENT)
|
||||
return;
|
||||
|
||||
switch (msg->mh.msg_id) {
|
||||
case BFI_FLASH_I2H_QUERY_RSP:
|
||||
status = be32_to_cpu(m.query->status);
|
||||
if (status == BFA_STATUS_OK) {
|
||||
u32 i;
|
||||
struct bfa_flash_attr *attr, *f;
|
||||
|
||||
attr = (struct bfa_flash_attr *) flash->ubuf;
|
||||
f = (struct bfa_flash_attr *) flash->dbuf_kva;
|
||||
attr->status = be32_to_cpu(f->status);
|
||||
attr->npart = be32_to_cpu(f->npart);
|
||||
for (i = 0; i < attr->npart; i++) {
|
||||
attr->part[i].part_type =
|
||||
be32_to_cpu(f->part[i].part_type);
|
||||
attr->part[i].part_instance =
|
||||
be32_to_cpu(f->part[i].part_instance);
|
||||
attr->part[i].part_off =
|
||||
be32_to_cpu(f->part[i].part_off);
|
||||
attr->part[i].part_size =
|
||||
be32_to_cpu(f->part[i].part_size);
|
||||
attr->part[i].part_len =
|
||||
be32_to_cpu(f->part[i].part_len);
|
||||
attr->part[i].part_status =
|
||||
be32_to_cpu(f->part[i].part_status);
|
||||
}
|
||||
}
|
||||
flash->status = status;
|
||||
bfa_flash_cb(flash);
|
||||
break;
|
||||
case BFI_FLASH_I2H_WRITE_RSP:
|
||||
status = be32_to_cpu(m.write->status);
|
||||
if (status != BFA_STATUS_OK || flash->residue == 0) {
|
||||
flash->status = status;
|
||||
bfa_flash_cb(flash);
|
||||
} else
|
||||
bfa_flash_write_send(flash);
|
||||
break;
|
||||
case BFI_FLASH_I2H_READ_RSP:
|
||||
status = be32_to_cpu(m.read->status);
|
||||
if (status != BFA_STATUS_OK) {
|
||||
flash->status = status;
|
||||
bfa_flash_cb(flash);
|
||||
} else {
|
||||
u32 len = be32_to_cpu(m.read->length);
|
||||
memcpy(flash->ubuf + flash->offset,
|
||||
flash->dbuf_kva, len);
|
||||
flash->residue -= len;
|
||||
flash->offset += len;
|
||||
if (flash->residue == 0) {
|
||||
flash->status = status;
|
||||
bfa_flash_cb(flash);
|
||||
} else
|
||||
bfa_flash_read_send(flash);
|
||||
}
|
||||
break;
|
||||
case BFI_FLASH_I2H_BOOT_VER_RSP:
|
||||
case BFI_FLASH_I2H_EVENT:
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Flash memory info API.
|
||||
*/
|
||||
u32
|
||||
bfa_nw_flash_meminfo(void)
|
||||
{
|
||||
return roundup(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flash attach API.
|
||||
*
|
||||
* @param[in] flash - flash structure
|
||||
* @param[in] ioc - ioc structure
|
||||
* @param[in] dev - device structure
|
||||
*/
|
||||
void
|
||||
bfa_nw_flash_attach(struct bfa_flash *flash, struct bfa_ioc *ioc, void *dev)
|
||||
{
|
||||
flash->ioc = ioc;
|
||||
flash->cbfn = NULL;
|
||||
flash->cbarg = NULL;
|
||||
flash->op_busy = 0;
|
||||
|
||||
bfa_nw_ioc_mbox_regisr(flash->ioc, BFI_MC_FLASH, bfa_flash_intr, flash);
|
||||
bfa_q_qe_init(&flash->ioc_notify);
|
||||
bfa_ioc_notify_init(&flash->ioc_notify, bfa_flash_notify, flash);
|
||||
list_add_tail(&flash->ioc_notify.qe, &flash->ioc->notify_q);
|
||||
}
|
||||
|
||||
/*
|
||||
* Claim memory for flash
|
||||
*
|
||||
* @param[in] flash - flash structure
|
||||
* @param[in] dm_kva - pointer to virtual memory address
|
||||
* @param[in] dm_pa - physical memory address
|
||||
*/
|
||||
void
|
||||
bfa_nw_flash_memclaim(struct bfa_flash *flash, u8 *dm_kva, u64 dm_pa)
|
||||
{
|
||||
flash->dbuf_kva = dm_kva;
|
||||
flash->dbuf_pa = dm_pa;
|
||||
memset(flash->dbuf_kva, 0, BFA_FLASH_DMA_BUF_SZ);
|
||||
dm_kva += roundup(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
|
||||
dm_pa += roundup(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get flash attribute.
|
||||
*
|
||||
* @param[in] flash - flash structure
|
||||
* @param[in] attr - flash attribute structure
|
||||
* @param[in] cbfn - callback function
|
||||
* @param[in] cbarg - callback argument
|
||||
*
|
||||
* Return status.
|
||||
*/
|
||||
enum bfa_status
|
||||
bfa_nw_flash_get_attr(struct bfa_flash *flash, struct bfa_flash_attr *attr,
|
||||
bfa_cb_flash cbfn, void *cbarg)
|
||||
{
|
||||
struct bfi_flash_query_req *msg =
|
||||
(struct bfi_flash_query_req *) flash->mb.msg;
|
||||
|
||||
if (!bfa_nw_ioc_is_operational(flash->ioc))
|
||||
return BFA_STATUS_IOC_NON_OP;
|
||||
|
||||
if (flash->op_busy)
|
||||
return BFA_STATUS_DEVBUSY;
|
||||
|
||||
flash->op_busy = 1;
|
||||
flash->cbfn = cbfn;
|
||||
flash->cbarg = cbarg;
|
||||
flash->ubuf = (u8 *) attr;
|
||||
|
||||
bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_QUERY_REQ,
|
||||
bfa_ioc_portid(flash->ioc));
|
||||
bfa_alen_set(&msg->alen, sizeof(struct bfa_flash_attr), flash->dbuf_pa);
|
||||
bfa_nw_ioc_mbox_queue(flash->ioc, &flash->mb, NULL, NULL);
|
||||
|
||||
return BFA_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update flash partition.
|
||||
*
|
||||
* @param[in] flash - flash structure
|
||||
* @param[in] type - flash partition type
|
||||
* @param[in] instance - flash partition instance
|
||||
* @param[in] buf - update data buffer
|
||||
* @param[in] len - data buffer length
|
||||
* @param[in] offset - offset relative to the partition starting address
|
||||
* @param[in] cbfn - callback function
|
||||
* @param[in] cbarg - callback argument
|
||||
*
|
||||
* Return status.
|
||||
*/
|
||||
enum bfa_status
|
||||
bfa_nw_flash_update_part(struct bfa_flash *flash, u32 type, u8 instance,
|
||||
void *buf, u32 len, u32 offset,
|
||||
bfa_cb_flash cbfn, void *cbarg)
|
||||
{
|
||||
if (!bfa_nw_ioc_is_operational(flash->ioc))
|
||||
return BFA_STATUS_IOC_NON_OP;
|
||||
|
||||
/*
|
||||
* 'len' must be in word (4-byte) boundary
|
||||
*/
|
||||
if (!len || (len & 0x03))
|
||||
return BFA_STATUS_FLASH_BAD_LEN;
|
||||
|
||||
if (type == BFA_FLASH_PART_MFG)
|
||||
return BFA_STATUS_EINVAL;
|
||||
|
||||
if (flash->op_busy)
|
||||
return BFA_STATUS_DEVBUSY;
|
||||
|
||||
flash->op_busy = 1;
|
||||
flash->cbfn = cbfn;
|
||||
flash->cbarg = cbarg;
|
||||
flash->type = type;
|
||||
flash->instance = instance;
|
||||
flash->residue = len;
|
||||
flash->offset = 0;
|
||||
flash->addr_off = offset;
|
||||
flash->ubuf = buf;
|
||||
|
||||
bfa_flash_write_send(flash);
|
||||
|
||||
return BFA_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read flash partition.
|
||||
*
|
||||
* @param[in] flash - flash structure
|
||||
* @param[in] type - flash partition type
|
||||
* @param[in] instance - flash partition instance
|
||||
* @param[in] buf - read data buffer
|
||||
* @param[in] len - data buffer length
|
||||
* @param[in] offset - offset relative to the partition starting address
|
||||
* @param[in] cbfn - callback function
|
||||
* @param[in] cbarg - callback argument
|
||||
*
|
||||
* Return status.
|
||||
*/
|
||||
enum bfa_status
|
||||
bfa_nw_flash_read_part(struct bfa_flash *flash, u32 type, u8 instance,
|
||||
void *buf, u32 len, u32 offset,
|
||||
bfa_cb_flash cbfn, void *cbarg)
|
||||
{
|
||||
if (!bfa_nw_ioc_is_operational(flash->ioc))
|
||||
return BFA_STATUS_IOC_NON_OP;
|
||||
|
||||
/*
|
||||
* 'len' must be in word (4-byte) boundary
|
||||
*/
|
||||
if (!len || (len & 0x03))
|
||||
return BFA_STATUS_FLASH_BAD_LEN;
|
||||
|
||||
if (flash->op_busy)
|
||||
return BFA_STATUS_DEVBUSY;
|
||||
|
||||
flash->op_busy = 1;
|
||||
flash->cbfn = cbfn;
|
||||
flash->cbarg = cbarg;
|
||||
flash->type = type;
|
||||
flash->instance = instance;
|
||||
flash->residue = len;
|
||||
flash->offset = 0;
|
||||
flash->addr_off = offset;
|
||||
flash->ubuf = buf;
|
||||
|
||||
bfa_flash_read_send(flash);
|
||||
|
||||
return BFA_STATUS_OK;
|
||||
}
|
||||
|
@ -68,6 +68,16 @@ __bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa)
|
||||
dma_addr->a32.addr_hi = (u32) htonl(upper_32_bits(pa));
|
||||
}
|
||||
|
||||
#define bfa_alen_set(__alen, __len, __pa) \
|
||||
__bfa_alen_set(__alen, __len, (u64)__pa)
|
||||
|
||||
static inline void
|
||||
__bfa_alen_set(struct bfi_alen *alen, u32 len, u64 pa)
|
||||
{
|
||||
alen->al_len = cpu_to_be32(len);
|
||||
bfa_dma_be_addr_set(alen->al_addr, pa);
|
||||
}
|
||||
|
||||
struct bfa_ioc_regs {
|
||||
void __iomem *hfn_mbox_cmd;
|
||||
void __iomem *hfn_mbox;
|
||||
@ -322,4 +332,42 @@ void bfa_nw_iocpf_sem_timeout(void *ioc);
|
||||
u32 *bfa_cb_image_get_chunk(enum bfi_asic_gen asic_gen, u32 off);
|
||||
u32 bfa_cb_image_get_size(enum bfi_asic_gen asic_gen);
|
||||
|
||||
/*
|
||||
* Flash module specific
|
||||
*/
|
||||
typedef void (*bfa_cb_flash) (void *cbarg, enum bfa_status status);
|
||||
|
||||
struct bfa_flash {
|
||||
struct bfa_ioc *ioc; /* back pointer to ioc */
|
||||
u32 type; /* partition type */
|
||||
u8 instance; /* partition instance */
|
||||
u8 rsv[3];
|
||||
u32 op_busy; /* operation busy flag */
|
||||
u32 residue; /* residual length */
|
||||
u32 offset; /* offset */
|
||||
enum bfa_status status; /* status */
|
||||
u8 *dbuf_kva; /* dma buf virtual address */
|
||||
u64 dbuf_pa; /* dma buf physical address */
|
||||
bfa_cb_flash cbfn; /* user callback function */
|
||||
void *cbarg; /* user callback arg */
|
||||
u8 *ubuf; /* user supplied buffer */
|
||||
u32 addr_off; /* partition address offset */
|
||||
struct bfa_mbox_cmd mb; /* mailbox */
|
||||
struct bfa_ioc_notify ioc_notify; /* ioc event notify */
|
||||
};
|
||||
|
||||
enum bfa_status bfa_nw_flash_get_attr(struct bfa_flash *flash,
|
||||
struct bfa_flash_attr *attr,
|
||||
bfa_cb_flash cbfn, void *cbarg);
|
||||
enum bfa_status bfa_nw_flash_update_part(struct bfa_flash *flash,
|
||||
u32 type, u8 instance, void *buf, u32 len, u32 offset,
|
||||
bfa_cb_flash cbfn, void *cbarg);
|
||||
enum bfa_status bfa_nw_flash_read_part(struct bfa_flash *flash,
|
||||
u32 type, u8 instance, void *buf, u32 len, u32 offset,
|
||||
bfa_cb_flash cbfn, void *cbarg);
|
||||
u32 bfa_nw_flash_meminfo(void);
|
||||
void bfa_nw_flash_attach(struct bfa_flash *flash,
|
||||
struct bfa_ioc *ioc, void *dev);
|
||||
void bfa_nw_flash_memclaim(struct bfa_flash *flash, u8 *dm_kva, u64 dm_pa);
|
||||
|
||||
#endif /* __BFA_IOC_H__ */
|
||||
|
@ -83,6 +83,14 @@ union bfi_addr_u {
|
||||
} a32;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic DMA addr-len pair.
|
||||
*/
|
||||
struct bfi_alen {
|
||||
union bfi_addr_u al_addr; /* DMA addr of buffer */
|
||||
u32 al_len; /* length of buffer */
|
||||
};
|
||||
|
||||
/*
|
||||
* Large Message structure - 128 Bytes size Msgs
|
||||
*/
|
||||
@ -476,6 +484,93 @@ struct bfi_msgq_i2h_cmdq_copy_req {
|
||||
u16 len;
|
||||
};
|
||||
|
||||
/*
|
||||
* FLASH module specific
|
||||
*/
|
||||
enum bfi_flash_h2i_msgs {
|
||||
BFI_FLASH_H2I_QUERY_REQ = 1,
|
||||
BFI_FLASH_H2I_ERASE_REQ = 2,
|
||||
BFI_FLASH_H2I_WRITE_REQ = 3,
|
||||
BFI_FLASH_H2I_READ_REQ = 4,
|
||||
BFI_FLASH_H2I_BOOT_VER_REQ = 5,
|
||||
};
|
||||
|
||||
enum bfi_flash_i2h_msgs {
|
||||
BFI_FLASH_I2H_QUERY_RSP = BFA_I2HM(1),
|
||||
BFI_FLASH_I2H_ERASE_RSP = BFA_I2HM(2),
|
||||
BFI_FLASH_I2H_WRITE_RSP = BFA_I2HM(3),
|
||||
BFI_FLASH_I2H_READ_RSP = BFA_I2HM(4),
|
||||
BFI_FLASH_I2H_BOOT_VER_RSP = BFA_I2HM(5),
|
||||
BFI_FLASH_I2H_EVENT = BFA_I2HM(127),
|
||||
};
|
||||
|
||||
/*
|
||||
* Flash query request
|
||||
*/
|
||||
struct bfi_flash_query_req {
|
||||
struct bfi_mhdr mh; /* Common msg header */
|
||||
struct bfi_alen alen;
|
||||
};
|
||||
|
||||
/*
|
||||
* Flash write request
|
||||
*/
|
||||
struct bfi_flash_write_req {
|
||||
struct bfi_mhdr mh; /* Common msg header */
|
||||
struct bfi_alen alen;
|
||||
u32 type; /* partition type */
|
||||
u8 instance; /* partition instance */
|
||||
u8 last;
|
||||
u8 rsv[2];
|
||||
u32 offset;
|
||||
u32 length;
|
||||
};
|
||||
|
||||
/*
|
||||
* Flash read request
|
||||
*/
|
||||
struct bfi_flash_read_req {
|
||||
struct bfi_mhdr mh; /* Common msg header */
|
||||
u32 type; /* partition type */
|
||||
u8 instance; /* partition instance */
|
||||
u8 rsv[3];
|
||||
u32 offset;
|
||||
u32 length;
|
||||
struct bfi_alen alen;
|
||||
};
|
||||
|
||||
/*
|
||||
* Flash query response
|
||||
*/
|
||||
struct bfi_flash_query_rsp {
|
||||
struct bfi_mhdr mh; /* Common msg header */
|
||||
u32 status;
|
||||
};
|
||||
|
||||
/*
|
||||
* Flash read response
|
||||
*/
|
||||
struct bfi_flash_read_rsp {
|
||||
struct bfi_mhdr mh; /* Common msg header */
|
||||
u32 type; /* partition type */
|
||||
u8 instance; /* partition instance */
|
||||
u8 rsv[3];
|
||||
u32 status;
|
||||
u32 length;
|
||||
};
|
||||
|
||||
/*
|
||||
* Flash write response
|
||||
*/
|
||||
struct bfi_flash_write_rsp {
|
||||
struct bfi_mhdr mh; /* Common msg header */
|
||||
u32 type; /* partition type */
|
||||
u8 instance; /* partition instance */
|
||||
u8 rsv[3];
|
||||
u32 status;
|
||||
u32 length;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif /* __BFI_H__ */
|
||||
|
@ -1740,6 +1740,11 @@ bna_ioceth_init(struct bna_ioceth *ioceth, struct bna *bna,
|
||||
kva += bfa_nw_cee_meminfo();
|
||||
dma += bfa_nw_cee_meminfo();
|
||||
|
||||
bfa_nw_flash_attach(&bna->flash, &ioceth->ioc, bna);
|
||||
bfa_nw_flash_memclaim(&bna->flash, kva, dma);
|
||||
kva += bfa_nw_flash_meminfo();
|
||||
dma += bfa_nw_flash_meminfo();
|
||||
|
||||
bfa_msgq_attach(&bna->msgq, &ioceth->ioc);
|
||||
bfa_msgq_memclaim(&bna->msgq, kva, dma);
|
||||
bfa_msgq_regisr(&bna->msgq, BFI_MC_ENET, bna_msgq_rsp_handler, bna);
|
||||
@ -1892,6 +1897,7 @@ bna_res_req(struct bna_res_info *res_info)
|
||||
res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1;
|
||||
res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN(
|
||||
(bfa_nw_cee_meminfo() +
|
||||
bfa_nw_flash_meminfo() +
|
||||
bfa_msgq_meminfo()), PAGE_SIZE);
|
||||
|
||||
/* DMA memory for retrieving IOC attributes */
|
||||
|
@ -966,6 +966,7 @@ struct bna {
|
||||
|
||||
struct bna_ioceth ioceth;
|
||||
struct bfa_cee cee;
|
||||
struct bfa_flash flash;
|
||||
struct bfa_msgq msgq;
|
||||
|
||||
struct bna_ethport ethport;
|
||||
|
@ -48,7 +48,9 @@ MODULE_PARM_DESC(bnad_ioc_auto_recover, "Enable / Disable auto recovery");
|
||||
* Global variables
|
||||
*/
|
||||
u32 bnad_rxqs_per_cq = 2;
|
||||
|
||||
u32 bna_id;
|
||||
struct mutex bnad_list_mutex;
|
||||
LIST_HEAD(bnad_list);
|
||||
static const u8 bnad_bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
/*
|
||||
@ -75,6 +77,23 @@ do { \
|
||||
|
||||
#define BNAD_TXRX_SYNC_MDELAY 250 /* 250 msecs */
|
||||
|
||||
static void
|
||||
bnad_add_to_list(struct bnad *bnad)
|
||||
{
|
||||
mutex_lock(&bnad_list_mutex);
|
||||
list_add_tail(&bnad->list_entry, &bnad_list);
|
||||
bnad->id = bna_id++;
|
||||
mutex_unlock(&bnad_list_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
bnad_remove_from_list(struct bnad *bnad)
|
||||
{
|
||||
mutex_lock(&bnad_list_mutex);
|
||||
list_del(&bnad->list_entry);
|
||||
mutex_unlock(&bnad_list_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reinitialize completions in CQ, once Rx is taken down
|
||||
*/
|
||||
@ -1084,6 +1103,16 @@ bnad_cb_enet_mtu_set(struct bnad *bnad)
|
||||
complete(&bnad->bnad_completions.mtu_comp);
|
||||
}
|
||||
|
||||
void
|
||||
bnad_cb_completion(void *arg, enum bfa_status status)
|
||||
{
|
||||
struct bnad_iocmd_comp *iocmd_comp =
|
||||
(struct bnad_iocmd_comp *)arg;
|
||||
|
||||
iocmd_comp->comp_status = (u32) status;
|
||||
complete(&iocmd_comp->comp);
|
||||
}
|
||||
|
||||
/* Resource allocation, free functions */
|
||||
|
||||
static void
|
||||
@ -3167,12 +3196,14 @@ bnad_lock_init(struct bnad *bnad)
|
||||
{
|
||||
spin_lock_init(&bnad->bna_lock);
|
||||
mutex_init(&bnad->conf_mutex);
|
||||
mutex_init(&bnad_list_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
bnad_lock_uninit(struct bnad *bnad)
|
||||
{
|
||||
mutex_destroy(&bnad->conf_mutex);
|
||||
mutex_destroy(&bnad_list_mutex);
|
||||
}
|
||||
|
||||
/* PCI Initialization */
|
||||
@ -3253,8 +3284,8 @@ bnad_pci_probe(struct pci_dev *pdev,
|
||||
return err;
|
||||
}
|
||||
bnad = netdev_priv(netdev);
|
||||
|
||||
bnad_lock_init(bnad);
|
||||
bnad_add_to_list(bnad);
|
||||
|
||||
mutex_lock(&bnad->conf_mutex);
|
||||
/*
|
||||
@ -3407,6 +3438,7 @@ pci_uninit:
|
||||
bnad_pci_uninit(pdev);
|
||||
unlock_mutex:
|
||||
mutex_unlock(&bnad->conf_mutex);
|
||||
bnad_remove_from_list(bnad);
|
||||
bnad_lock_uninit(bnad);
|
||||
free_netdev(netdev);
|
||||
return err;
|
||||
@ -3445,6 +3477,7 @@ bnad_pci_remove(struct pci_dev *pdev)
|
||||
bnad_disable_msix(bnad);
|
||||
bnad_pci_uninit(pdev);
|
||||
mutex_unlock(&bnad->conf_mutex);
|
||||
bnad_remove_from_list(bnad);
|
||||
bnad_lock_uninit(bnad);
|
||||
bnad_uninit(bnad);
|
||||
free_netdev(netdev);
|
||||
|
@ -124,6 +124,12 @@ enum bnad_link_state {
|
||||
BNAD_LS_UP = 1
|
||||
};
|
||||
|
||||
struct bnad_iocmd_comp {
|
||||
struct bnad *bnad;
|
||||
struct completion comp;
|
||||
int comp_status;
|
||||
};
|
||||
|
||||
struct bnad_completion {
|
||||
struct completion ioc_comp;
|
||||
struct completion ucast_comp;
|
||||
@ -251,6 +257,8 @@ struct bnad_unmap_q {
|
||||
|
||||
struct bnad {
|
||||
struct net_device *netdev;
|
||||
u32 id;
|
||||
struct list_head list_entry;
|
||||
|
||||
/* Data path */
|
||||
struct bnad_tx_info tx_info[BNAD_MAX_TX];
|
||||
@ -340,6 +348,7 @@ extern int bnad_mac_addr_set_locked(struct bnad *bnad, u8 *mac_addr);
|
||||
extern int bnad_enable_default_bcast(struct bnad *bnad);
|
||||
extern void bnad_restore_vlans(struct bnad *bnad, u32 rx_id);
|
||||
extern void bnad_set_ethtool_ops(struct net_device *netdev);
|
||||
extern void bnad_cb_completion(void *arg, enum bfa_status status);
|
||||
|
||||
/* Configuration & setup */
|
||||
extern void bnad_tx_coalescing_timeo_set(struct bnad *bnad);
|
||||
|
@ -935,6 +935,143 @@ bnad_get_sset_count(struct net_device *netdev, int sset)
|
||||
}
|
||||
}
|
||||
|
||||
static u32
|
||||
bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
|
||||
u32 *base_offset)
|
||||
{
|
||||
struct bfa_flash_attr *flash_attr;
|
||||
struct bnad_iocmd_comp fcomp;
|
||||
u32 i, flash_part = 0, ret;
|
||||
unsigned long flags = 0;
|
||||
|
||||
flash_attr = kzalloc(sizeof(struct bfa_flash_attr), GFP_KERNEL);
|
||||
if (!flash_attr)
|
||||
return -ENOMEM;
|
||||
|
||||
fcomp.bnad = bnad;
|
||||
fcomp.comp_status = 0;
|
||||
|
||||
init_completion(&fcomp.comp);
|
||||
spin_lock_irqsave(&bnad->bna_lock, flags);
|
||||
ret = bfa_nw_flash_get_attr(&bnad->bna.flash, flash_attr,
|
||||
bnad_cb_completion, &fcomp);
|
||||
if (ret != BFA_STATUS_OK) {
|
||||
spin_unlock_irqrestore(&bnad->bna_lock, flags);
|
||||
kfree(flash_attr);
|
||||
goto out_err;
|
||||
}
|
||||
spin_unlock_irqrestore(&bnad->bna_lock, flags);
|
||||
wait_for_completion(&fcomp.comp);
|
||||
ret = fcomp.comp_status;
|
||||
|
||||
/* Check for the flash type & base offset value */
|
||||
if (ret == BFA_STATUS_OK) {
|
||||
for (i = 0; i < flash_attr->npart; i++) {
|
||||
if (offset >= flash_attr->part[i].part_off &&
|
||||
offset < (flash_attr->part[i].part_off +
|
||||
flash_attr->part[i].part_size)) {
|
||||
flash_part = flash_attr->part[i].part_type;
|
||||
*base_offset = flash_attr->part[i].part_off;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
kfree(flash_attr);
|
||||
return flash_part;
|
||||
out_err:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
bnad_get_eeprom_len(struct net_device *netdev)
|
||||
{
|
||||
return BFA_TOTAL_FLASH_SIZE;
|
||||
}
|
||||
|
||||
static int
|
||||
bnad_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
|
||||
u8 *bytes)
|
||||
{
|
||||
struct bnad *bnad = netdev_priv(netdev);
|
||||
struct bnad_iocmd_comp fcomp;
|
||||
u32 flash_part = 0, base_offset = 0;
|
||||
unsigned long flags = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* Check if the flash read request is valid */
|
||||
if (eeprom->magic != (bnad->pcidev->vendor |
|
||||
(bnad->pcidev->device << 16)))
|
||||
return -EFAULT;
|
||||
|
||||
/* Query the flash partition based on the offset */
|
||||
flash_part = bnad_get_flash_partition_by_offset(bnad,
|
||||
eeprom->offset, &base_offset);
|
||||
if (flash_part <= 0)
|
||||
return -EFAULT;
|
||||
|
||||
fcomp.bnad = bnad;
|
||||
fcomp.comp_status = 0;
|
||||
|
||||
init_completion(&fcomp.comp);
|
||||
spin_lock_irqsave(&bnad->bna_lock, flags);
|
||||
ret = bfa_nw_flash_read_part(&bnad->bna.flash, flash_part,
|
||||
bnad->id, bytes, eeprom->len,
|
||||
eeprom->offset - base_offset,
|
||||
bnad_cb_completion, &fcomp);
|
||||
if (ret != BFA_STATUS_OK) {
|
||||
spin_unlock_irqrestore(&bnad->bna_lock, flags);
|
||||
goto done;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&bnad->bna_lock, flags);
|
||||
wait_for_completion(&fcomp.comp);
|
||||
ret = fcomp.comp_status;
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
bnad_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
|
||||
u8 *bytes)
|
||||
{
|
||||
struct bnad *bnad = netdev_priv(netdev);
|
||||
struct bnad_iocmd_comp fcomp;
|
||||
u32 flash_part = 0, base_offset = 0;
|
||||
unsigned long flags = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* Check if the flash update request is valid */
|
||||
if (eeprom->magic != (bnad->pcidev->vendor |
|
||||
(bnad->pcidev->device << 16)))
|
||||
return -EINVAL;
|
||||
|
||||
/* Query the flash partition based on the offset */
|
||||
flash_part = bnad_get_flash_partition_by_offset(bnad,
|
||||
eeprom->offset, &base_offset);
|
||||
if (flash_part <= 0)
|
||||
return -EFAULT;
|
||||
|
||||
fcomp.bnad = bnad;
|
||||
fcomp.comp_status = 0;
|
||||
|
||||
init_completion(&fcomp.comp);
|
||||
spin_lock_irqsave(&bnad->bna_lock, flags);
|
||||
ret = bfa_nw_flash_update_part(&bnad->bna.flash, flash_part,
|
||||
bnad->id, bytes, eeprom->len,
|
||||
eeprom->offset - base_offset,
|
||||
bnad_cb_completion, &fcomp);
|
||||
if (ret != BFA_STATUS_OK) {
|
||||
spin_unlock_irqrestore(&bnad->bna_lock, flags);
|
||||
goto done;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&bnad->bna_lock, flags);
|
||||
wait_for_completion(&fcomp.comp);
|
||||
ret = fcomp.comp_status;
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct ethtool_ops bnad_ethtool_ops = {
|
||||
.get_settings = bnad_get_settings,
|
||||
.set_settings = bnad_set_settings,
|
||||
@ -949,7 +1086,10 @@ static struct ethtool_ops bnad_ethtool_ops = {
|
||||
.set_pauseparam = bnad_set_pauseparam,
|
||||
.get_strings = bnad_get_strings,
|
||||
.get_ethtool_stats = bnad_get_ethtool_stats,
|
||||
.get_sset_count = bnad_get_sset_count
|
||||
.get_sset_count = bnad_get_sset_count,
|
||||
.get_eeprom_len = bnad_get_eeprom_len,
|
||||
.get_eeprom = bnad_get_eeprom,
|
||||
.set_eeprom = bnad_set_eeprom,
|
||||
};
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user