diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-24 23:27:13 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 18:23:29 -0400 |
commit | 5a54b1d576d1880eb249e906e0c8e2ffe64506d3 (patch) | |
tree | 642890240be4d1fed626ff591296f7cb59338132 | |
parent | 51e569aa1f0c10bd71af05e76e4ba0e42c51e4ab (diff) |
[SCSI] bfa: Added support for flash configuration
- Added flash sub-module.
- Implemented the interface to read/erase/update flash partition.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/bfa/bfa.h | 22 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_core.c | 15 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_defs.h | 106 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.c | 494 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.h | 72 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_modules.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.c | 117 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.h | 21 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi.h | 109 |
9 files changed, 910 insertions, 47 deletions
diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h index c7cfc585c656..3b0af1102bf4 100644 --- a/drivers/scsi/bfa/bfa.h +++ b/drivers/scsi/bfa/bfa.h | |||
@@ -27,7 +27,6 @@ | |||
27 | struct bfa_s; | 27 | struct bfa_s; |
28 | 28 | ||
29 | typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m); | 29 | typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m); |
30 | typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete); | ||
31 | 30 | ||
32 | /* | 31 | /* |
33 | * Interrupt message handlers | 32 | * Interrupt message handlers |
@@ -77,16 +76,6 @@ void bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m); | |||
77 | } while (0) | 76 | } while (0) |
78 | 77 | ||
79 | /* | 78 | /* |
80 | * Queue element to wait for room in request queue. FIFO order is | ||
81 | * maintained when fullfilling requests. | ||
82 | */ | ||
83 | struct bfa_reqq_wait_s { | ||
84 | struct list_head qe; | ||
85 | void (*qresume) (void *cbarg); | ||
86 | void *cbarg; | ||
87 | }; | ||
88 | |||
89 | /* | ||
90 | * Circular queue usage assignments | 79 | * Circular queue usage assignments |
91 | */ | 80 | */ |
92 | enum { | 81 | enum { |
@@ -129,17 +118,6 @@ bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg), | |||
129 | 118 | ||
130 | #define bfa_reqq_wcancel(__wqe) list_del(&(__wqe)->qe) | 119 | #define bfa_reqq_wcancel(__wqe) list_del(&(__wqe)->qe) |
131 | 120 | ||
132 | |||
133 | /* | ||
134 | * Generic BFA callback element. | ||
135 | */ | ||
136 | struct bfa_cb_qe_s { | ||
137 | struct list_head qe; | ||
138 | bfa_cb_cbfn_t cbfn; | ||
139 | bfa_boolean_t once; | ||
140 | void *cbarg; | ||
141 | }; | ||
142 | |||
143 | #define bfa_cb_queue(__bfa, __hcb_qe, __cbfn, __cbarg) do { \ | 121 | #define bfa_cb_queue(__bfa, __hcb_qe, __cbfn, __cbarg) do { \ |
144 | (__hcb_qe)->cbfn = (__cbfn); \ | 122 | (__hcb_qe)->cbfn = (__cbfn); \ |
145 | (__hcb_qe)->cbarg = (__cbarg); \ | 123 | (__hcb_qe)->cbarg = (__cbarg); \ |
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index 3ba73faf3713..04d362085360 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c | |||
@@ -132,6 +132,17 @@ bfa_com_sfp_attach(struct bfa_s *bfa) | |||
132 | bfa_sfp_memclaim(sfp, sfp_dma->kva_curp, sfp_dma->dma_curp); | 132 | bfa_sfp_memclaim(sfp, sfp_dma->kva_curp, sfp_dma->dma_curp); |
133 | } | 133 | } |
134 | 134 | ||
135 | static void | ||
136 | bfa_com_flash_attach(struct bfa_s *bfa, bfa_boolean_t mincfg) | ||
137 | { | ||
138 | struct bfa_flash_s *flash = BFA_FLASH(bfa); | ||
139 | struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa); | ||
140 | |||
141 | bfa_flash_attach(flash, &bfa->ioc, bfa, bfa->trcmod, mincfg); | ||
142 | bfa_flash_memclaim(flash, flash_dma->kva_curp, | ||
143 | flash_dma->dma_curp, mincfg); | ||
144 | } | ||
145 | |||
135 | /* | 146 | /* |
136 | * BFA IOC FC related definitions | 147 | * BFA IOC FC related definitions |
137 | */ | 148 | */ |
@@ -1371,6 +1382,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, | |||
1371 | struct bfa_mem_dma_s *ablk_dma = BFA_MEM_ABLK_DMA(bfa); | 1382 | struct bfa_mem_dma_s *ablk_dma = BFA_MEM_ABLK_DMA(bfa); |
1372 | struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa); | 1383 | struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa); |
1373 | struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa); | 1384 | struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa); |
1385 | struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa); | ||
1374 | 1386 | ||
1375 | WARN_ON((cfg == NULL) || (meminfo == NULL)); | 1387 | WARN_ON((cfg == NULL) || (meminfo == NULL)); |
1376 | 1388 | ||
@@ -1390,6 +1402,8 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, | |||
1390 | bfa_mem_dma_setup(meminfo, ablk_dma, bfa_ablk_meminfo()); | 1402 | bfa_mem_dma_setup(meminfo, ablk_dma, bfa_ablk_meminfo()); |
1391 | bfa_mem_dma_setup(meminfo, cee_dma, bfa_cee_meminfo()); | 1403 | bfa_mem_dma_setup(meminfo, cee_dma, bfa_cee_meminfo()); |
1392 | bfa_mem_dma_setup(meminfo, sfp_dma, bfa_sfp_meminfo()); | 1404 | bfa_mem_dma_setup(meminfo, sfp_dma, bfa_sfp_meminfo()); |
1405 | bfa_mem_dma_setup(meminfo, flash_dma, | ||
1406 | bfa_flash_meminfo(cfg->drvcfg.min_cfg)); | ||
1393 | } | 1407 | } |
1394 | 1408 | ||
1395 | /* | 1409 | /* |
@@ -1459,6 +1473,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
1459 | bfa_com_ablk_attach(bfa); | 1473 | bfa_com_ablk_attach(bfa); |
1460 | bfa_com_cee_attach(bfa); | 1474 | bfa_com_cee_attach(bfa); |
1461 | bfa_com_sfp_attach(bfa); | 1475 | bfa_com_sfp_attach(bfa); |
1476 | bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg); | ||
1462 | } | 1477 | } |
1463 | 1478 | ||
1464 | /* | 1479 | /* |
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index 715d9f9fe33d..97ad07c4aee0 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h | |||
@@ -133,6 +133,7 @@ enum bfa_status { | |||
133 | BFA_STATUS_SFP_UNSUPP = 10, /* Unsupported SFP - Replace SFP */ | 133 | BFA_STATUS_SFP_UNSUPP = 10, /* Unsupported SFP - Replace SFP */ |
134 | BFA_STATUS_UNKNOWN_VFID = 11, /* VF_ID not found */ | 134 | BFA_STATUS_UNKNOWN_VFID = 11, /* VF_ID not found */ |
135 | BFA_STATUS_DEVBUSY = 13, /* Device busy - Retry operation */ | 135 | BFA_STATUS_DEVBUSY = 13, /* Device busy - Retry operation */ |
136 | BFA_STATUS_FLASH_BAD_LEN = 17, /* Flash bad length */ | ||
136 | BFA_STATUS_UNKNOWN_LWWN = 18, /* LPORT PWWN not found */ | 137 | BFA_STATUS_UNKNOWN_LWWN = 18, /* LPORT PWWN not found */ |
137 | BFA_STATUS_UNKNOWN_RWWN = 19, /* RPORT PWWN not found */ | 138 | BFA_STATUS_UNKNOWN_RWWN = 19, /* RPORT PWWN not found */ |
138 | BFA_STATUS_VPORT_EXISTS = 21, /* VPORT already exists */ | 139 | BFA_STATUS_VPORT_EXISTS = 21, /* VPORT already exists */ |
@@ -384,31 +385,39 @@ struct bfa_ioc_attr_s { | |||
384 | * All numerical fields are in big-endian format. | 385 | * All numerical fields are in big-endian format. |
385 | */ | 386 | */ |
386 | struct bfa_mfg_block_s { | 387 | struct bfa_mfg_block_s { |
387 | u8 version; /* manufacturing block version */ | 388 | u8 version; /*!< manufacturing block version */ |
388 | u8 mfg_sig[3]; /* characters 'M', 'F', 'G' */ | 389 | u8 mfg_sig[3]; /*!< characters 'M', 'F', 'G' */ |
389 | u16 mfgsize; /* mfg block size */ | 390 | u16 mfgsize; /*!< mfg block size */ |
390 | u16 u16_chksum; /* old u16 checksum */ | 391 | u16 u16_chksum; /*!< old u16 checksum */ |
391 | char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)]; | 392 | char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)]; |
392 | char brcd_partnum[STRSZ(BFA_MFG_PARTNUM_SIZE)]; | 393 | char brcd_partnum[STRSZ(BFA_MFG_PARTNUM_SIZE)]; |
393 | u8 mfg_day; /* manufacturing day */ | 394 | u8 mfg_day; /*!< manufacturing day */ |
394 | u8 mfg_month; /* manufacturing month */ | 395 | u8 mfg_month; /*!< manufacturing month */ |
395 | u16 mfg_year; /* manufacturing year */ | 396 | u16 mfg_year; /*!< manufacturing year */ |
396 | wwn_t mfg_wwn; /* wwn base for this adapter */ | 397 | wwn_t mfg_wwn; /*!< wwn base for this adapter */ |
397 | u8 num_wwn; /* number of wwns assigned */ | 398 | u8 num_wwn; /*!< number of wwns assigned */ |
398 | u8 mfg_speeds; /* speeds allowed for this adapter */ | 399 | u8 mfg_speeds; /*!< speeds allowed for this adapter */ |
399 | u8 rsv[2]; | 400 | u8 rsv[2]; |
400 | char supplier_id[STRSZ(BFA_MFG_SUPPLIER_ID_SIZE)]; | 401 | char supplier_id[STRSZ(BFA_MFG_SUPPLIER_ID_SIZE)]; |
401 | char supplier_partnum[STRSZ(BFA_MFG_SUPPLIER_PARTNUM_SIZE)]; | 402 | char supplier_partnum[STRSZ(BFA_MFG_SUPPLIER_PARTNUM_SIZE)]; |
402 | char | 403 | char supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)]; |
403 | supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)]; | 404 | char supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)]; |
404 | char | 405 | mac_t mfg_mac; /*!< base mac address */ |
405 | supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)]; | 406 | u8 num_mac; /*!< number of mac addresses */ |
406 | mac_t mfg_mac; /* mac address */ | 407 | u8 rsv2; |
407 | u8 num_mac; /* number of mac addresses */ | 408 | u32 card_type; /*!< card type */ |
408 | u8 rsv2; | 409 | char cap_nic; /*!< capability nic */ |
409 | u32 mfg_type; /* card type */ | 410 | char cap_cna; /*!< capability cna */ |
410 | u8 rsv3[108]; | 411 | char cap_hba; /*!< capability hba */ |
411 | u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /* md5 checksum */ | 412 | char cap_fc16g; /*!< capability fc 16g */ |
413 | char cap_sriov; /*!< capability sriov */ | ||
414 | char cap_mezz; /*!< capability mezz */ | ||
415 | u8 rsv3; | ||
416 | u8 mfg_nports; /*!< number of ports */ | ||
417 | char media[8]; /*!< xfi/xaui */ | ||
418 | char initial_mode[8]; /*!< initial mode: hba/cna/nic */ | ||
419 | u8 rsv4[84]; | ||
420 | u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /*!< md5 checksum */ | ||
412 | }; | 421 | }; |
413 | 422 | ||
414 | #pragma pack() | 423 | #pragma pack() |
@@ -825,6 +834,53 @@ struct sfp_xcvr_s { | |||
825 | union sfp_xcvr_fc3_code_u fc3; | 834 | union sfp_xcvr_fc3_code_u fc3; |
826 | }; | 835 | }; |
827 | 836 | ||
837 | /* | ||
838 | * Flash module specific | ||
839 | */ | ||
840 | #define BFA_FLASH_PART_ENTRY_SIZE 32 /* partition entry size */ | ||
841 | #define BFA_FLASH_PART_MAX 32 /* maximal # of partitions */ | ||
842 | |||
843 | enum bfa_flash_part_type { | ||
844 | BFA_FLASH_PART_OPTROM = 1, /* option rom partition */ | ||
845 | BFA_FLASH_PART_FWIMG = 2, /* firmware image partition */ | ||
846 | BFA_FLASH_PART_FWCFG = 3, /* firmware tuneable config */ | ||
847 | BFA_FLASH_PART_DRV = 4, /* IOC driver config */ | ||
848 | BFA_FLASH_PART_BOOT = 5, /* boot config */ | ||
849 | BFA_FLASH_PART_ASIC = 6, /* asic bootstrap configuration */ | ||
850 | BFA_FLASH_PART_MFG = 7, /* manufacturing block partition */ | ||
851 | BFA_FLASH_PART_OPTROM2 = 8, /* 2nd option rom partition */ | ||
852 | BFA_FLASH_PART_VPD = 9, /* vpd data of OEM info */ | ||
853 | BFA_FLASH_PART_PBC = 10, /* pre-boot config */ | ||
854 | BFA_FLASH_PART_BOOTOVL = 11, /* boot overlay partition */ | ||
855 | BFA_FLASH_PART_LOG = 12, /* firmware log partition */ | ||
856 | BFA_FLASH_PART_PXECFG = 13, /* pxe boot config partition */ | ||
857 | BFA_FLASH_PART_PXEOVL = 14, /* pxe boot overlay partition */ | ||
858 | BFA_FLASH_PART_PORTCFG = 15, /* port cfg partition */ | ||
859 | BFA_FLASH_PART_ASICBK = 16, /* asic backup partition */ | ||
860 | }; | ||
861 | |||
862 | /* | ||
863 | * flash partition attributes | ||
864 | */ | ||
865 | struct bfa_flash_part_attr_s { | ||
866 | u32 part_type; /* partition type */ | ||
867 | u32 part_instance; /* partition instance */ | ||
868 | u32 part_off; /* partition offset */ | ||
869 | u32 part_size; /* partition size */ | ||
870 | u32 part_len; /* partition content length */ | ||
871 | u32 part_status; /* partition status */ | ||
872 | char rsv[BFA_FLASH_PART_ENTRY_SIZE - 24]; | ||
873 | }; | ||
874 | |||
875 | /* | ||
876 | * flash attributes | ||
877 | */ | ||
878 | struct bfa_flash_attr_s { | ||
879 | u32 status; /* flash overall status */ | ||
880 | u32 npart; /* num of partitions */ | ||
881 | struct bfa_flash_part_attr_s part[BFA_FLASH_PART_MAX]; | ||
882 | }; | ||
883 | |||
828 | #pragma pack() | 884 | #pragma pack() |
829 | 885 | ||
830 | #endif /* __BFA_DEFS_H__ */ | 886 | #endif /* __BFA_DEFS_H__ */ |
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index d579036b08b7..150607324132 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
@@ -3821,3 +3821,497 @@ bfa_sfp_speed(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed, | |||
3821 | 3821 | ||
3822 | return bfa_sfp_speed_valid(sfp, portspeed); | 3822 | return bfa_sfp_speed_valid(sfp, portspeed); |
3823 | } | 3823 | } |
3824 | |||
3825 | /* | ||
3826 | * Flash module specific | ||
3827 | */ | ||
3828 | |||
3829 | /* | ||
3830 | * FLASH DMA buffer should be big enough to hold both MFG block and | ||
3831 | * asic block(64k) at the same time and also should be 2k aligned to | ||
3832 | * avoid write segement to cross sector boundary. | ||
3833 | */ | ||
3834 | #define BFA_FLASH_SEG_SZ 2048 | ||
3835 | #define BFA_FLASH_DMA_BUF_SZ \ | ||
3836 | BFA_ROUNDUP(0x010000 + sizeof(struct bfa_mfg_block_s), BFA_FLASH_SEG_SZ) | ||
3837 | |||
3838 | static void | ||
3839 | bfa_flash_cb(struct bfa_flash_s *flash) | ||
3840 | { | ||
3841 | flash->op_busy = 0; | ||
3842 | if (flash->cbfn) | ||
3843 | flash->cbfn(flash->cbarg, flash->status); | ||
3844 | } | ||
3845 | |||
3846 | static void | ||
3847 | bfa_flash_notify(void *cbarg, enum bfa_ioc_event_e event) | ||
3848 | { | ||
3849 | struct bfa_flash_s *flash = cbarg; | ||
3850 | |||
3851 | bfa_trc(flash, event); | ||
3852 | switch (event) { | ||
3853 | case BFA_IOC_E_DISABLED: | ||
3854 | case BFA_IOC_E_FAILED: | ||
3855 | if (flash->op_busy) { | ||
3856 | flash->status = BFA_STATUS_IOC_FAILURE; | ||
3857 | flash->cbfn(flash->cbarg, flash->status); | ||
3858 | flash->op_busy = 0; | ||
3859 | } | ||
3860 | break; | ||
3861 | |||
3862 | default: | ||
3863 | break; | ||
3864 | } | ||
3865 | } | ||
3866 | |||
3867 | /* | ||
3868 | * Send flash attribute query request. | ||
3869 | * | ||
3870 | * @param[in] cbarg - callback argument | ||
3871 | */ | ||
3872 | static void | ||
3873 | bfa_flash_query_send(void *cbarg) | ||
3874 | { | ||
3875 | struct bfa_flash_s *flash = cbarg; | ||
3876 | struct bfi_flash_query_req_s *msg = | ||
3877 | (struct bfi_flash_query_req_s *) flash->mb.msg; | ||
3878 | |||
3879 | bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_QUERY_REQ, | ||
3880 | bfa_ioc_portid(flash->ioc)); | ||
3881 | bfa_alen_set(&msg->alen, sizeof(struct bfa_flash_attr_s), | ||
3882 | flash->dbuf_pa); | ||
3883 | bfa_ioc_mbox_queue(flash->ioc, &flash->mb); | ||
3884 | } | ||
3885 | |||
3886 | /* | ||
3887 | * Send flash write request. | ||
3888 | * | ||
3889 | * @param[in] cbarg - callback argument | ||
3890 | */ | ||
3891 | static void | ||
3892 | bfa_flash_write_send(struct bfa_flash_s *flash) | ||
3893 | { | ||
3894 | struct bfi_flash_write_req_s *msg = | ||
3895 | (struct bfi_flash_write_req_s *) flash->mb.msg; | ||
3896 | u32 len; | ||
3897 | |||
3898 | msg->type = be32_to_cpu(flash->type); | ||
3899 | msg->instance = flash->instance; | ||
3900 | msg->offset = be32_to_cpu(flash->addr_off + flash->offset); | ||
3901 | len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ? | ||
3902 | flash->residue : BFA_FLASH_DMA_BUF_SZ; | ||
3903 | msg->length = be32_to_cpu(len); | ||
3904 | |||
3905 | /* indicate if it's the last msg of the whole write operation */ | ||
3906 | msg->last = (len == flash->residue) ? 1 : 0; | ||
3907 | |||
3908 | bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_WRITE_REQ, | ||
3909 | bfa_ioc_portid(flash->ioc)); | ||
3910 | bfa_alen_set(&msg->alen, len, flash->dbuf_pa); | ||
3911 | memcpy(flash->dbuf_kva, flash->ubuf + flash->offset, len); | ||
3912 | bfa_ioc_mbox_queue(flash->ioc, &flash->mb); | ||
3913 | |||
3914 | flash->residue -= len; | ||
3915 | flash->offset += len; | ||
3916 | } | ||
3917 | |||
3918 | /* | ||
3919 | * Send flash read request. | ||
3920 | * | ||
3921 | * @param[in] cbarg - callback argument | ||
3922 | */ | ||
3923 | static void | ||
3924 | bfa_flash_read_send(void *cbarg) | ||
3925 | { | ||
3926 | struct bfa_flash_s *flash = cbarg; | ||
3927 | struct bfi_flash_read_req_s *msg = | ||
3928 | (struct bfi_flash_read_req_s *) flash->mb.msg; | ||
3929 | u32 len; | ||
3930 | |||
3931 | msg->type = be32_to_cpu(flash->type); | ||
3932 | msg->instance = flash->instance; | ||
3933 | msg->offset = be32_to_cpu(flash->addr_off + flash->offset); | ||
3934 | len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ? | ||
3935 | flash->residue : BFA_FLASH_DMA_BUF_SZ; | ||
3936 | msg->length = be32_to_cpu(len); | ||
3937 | bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_READ_REQ, | ||
3938 | bfa_ioc_portid(flash->ioc)); | ||
3939 | bfa_alen_set(&msg->alen, len, flash->dbuf_pa); | ||
3940 | bfa_ioc_mbox_queue(flash->ioc, &flash->mb); | ||
3941 | } | ||
3942 | |||
3943 | /* | ||
3944 | * Send flash erase request. | ||
3945 | * | ||
3946 | * @param[in] cbarg - callback argument | ||
3947 | */ | ||
3948 | static void | ||
3949 | bfa_flash_erase_send(void *cbarg) | ||
3950 | { | ||
3951 | struct bfa_flash_s *flash = cbarg; | ||
3952 | struct bfi_flash_erase_req_s *msg = | ||
3953 | (struct bfi_flash_erase_req_s *) flash->mb.msg; | ||
3954 | |||
3955 | msg->type = be32_to_cpu(flash->type); | ||
3956 | msg->instance = flash->instance; | ||
3957 | bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_ERASE_REQ, | ||
3958 | bfa_ioc_portid(flash->ioc)); | ||
3959 | bfa_ioc_mbox_queue(flash->ioc, &flash->mb); | ||
3960 | } | ||
3961 | |||
3962 | /* | ||
3963 | * Process flash response messages upon receiving interrupts. | ||
3964 | * | ||
3965 | * @param[in] flasharg - flash structure | ||
3966 | * @param[in] msg - message structure | ||
3967 | */ | ||
3968 | static void | ||
3969 | bfa_flash_intr(void *flasharg, struct bfi_mbmsg_s *msg) | ||
3970 | { | ||
3971 | struct bfa_flash_s *flash = flasharg; | ||
3972 | u32 status; | ||
3973 | |||
3974 | union { | ||
3975 | struct bfi_flash_query_rsp_s *query; | ||
3976 | struct bfi_flash_erase_rsp_s *erase; | ||
3977 | struct bfi_flash_write_rsp_s *write; | ||
3978 | struct bfi_flash_read_rsp_s *read; | ||
3979 | struct bfi_mbmsg_s *msg; | ||
3980 | } m; | ||
3981 | |||
3982 | m.msg = msg; | ||
3983 | bfa_trc(flash, msg->mh.msg_id); | ||
3984 | |||
3985 | if (!flash->op_busy && msg->mh.msg_id != BFI_FLASH_I2H_EVENT) { | ||
3986 | /* receiving response after ioc failure */ | ||
3987 | bfa_trc(flash, 0x9999); | ||
3988 | return; | ||
3989 | } | ||
3990 | |||
3991 | switch (msg->mh.msg_id) { | ||
3992 | case BFI_FLASH_I2H_QUERY_RSP: | ||
3993 | status = be32_to_cpu(m.query->status); | ||
3994 | bfa_trc(flash, status); | ||
3995 | if (status == BFA_STATUS_OK) { | ||
3996 | u32 i; | ||
3997 | struct bfa_flash_attr_s *attr, *f; | ||
3998 | |||
3999 | attr = (struct bfa_flash_attr_s *) flash->ubuf; | ||
4000 | f = (struct bfa_flash_attr_s *) flash->dbuf_kva; | ||
4001 | attr->status = be32_to_cpu(f->status); | ||
4002 | attr->npart = be32_to_cpu(f->npart); | ||
4003 | bfa_trc(flash, attr->status); | ||
4004 | bfa_trc(flash, attr->npart); | ||
4005 | for (i = 0; i < attr->npart; i++) { | ||
4006 | attr->part[i].part_type = | ||
4007 | be32_to_cpu(f->part[i].part_type); | ||
4008 | attr->part[i].part_instance = | ||
4009 | be32_to_cpu(f->part[i].part_instance); | ||
4010 | attr->part[i].part_off = | ||
4011 | be32_to_cpu(f->part[i].part_off); | ||
4012 | attr->part[i].part_size = | ||
4013 | be32_to_cpu(f->part[i].part_size); | ||
4014 | attr->part[i].part_len = | ||
4015 | be32_to_cpu(f->part[i].part_len); | ||
4016 | attr->part[i].part_status = | ||
4017 | be32_to_cpu(f->part[i].part_status); | ||
4018 | } | ||
4019 | } | ||
4020 | flash->status = status; | ||
4021 | bfa_flash_cb(flash); | ||
4022 | break; | ||
4023 | case BFI_FLASH_I2H_ERASE_RSP: | ||
4024 | status = be32_to_cpu(m.erase->status); | ||
4025 | bfa_trc(flash, status); | ||
4026 | flash->status = status; | ||
4027 | bfa_flash_cb(flash); | ||
4028 | break; | ||
4029 | case BFI_FLASH_I2H_WRITE_RSP: | ||
4030 | status = be32_to_cpu(m.write->status); | ||
4031 | bfa_trc(flash, status); | ||
4032 | if (status != BFA_STATUS_OK || flash->residue == 0) { | ||
4033 | flash->status = status; | ||
4034 | bfa_flash_cb(flash); | ||
4035 | } else { | ||
4036 | bfa_trc(flash, flash->offset); | ||
4037 | bfa_flash_write_send(flash); | ||
4038 | } | ||
4039 | break; | ||
4040 | case BFI_FLASH_I2H_READ_RSP: | ||
4041 | status = be32_to_cpu(m.read->status); | ||
4042 | bfa_trc(flash, status); | ||
4043 | if (status != BFA_STATUS_OK) { | ||
4044 | flash->status = status; | ||
4045 | bfa_flash_cb(flash); | ||
4046 | } else { | ||
4047 | u32 len = be32_to_cpu(m.read->length); | ||
4048 | bfa_trc(flash, flash->offset); | ||
4049 | bfa_trc(flash, len); | ||
4050 | memcpy(flash->ubuf + flash->offset, | ||
4051 | flash->dbuf_kva, len); | ||
4052 | flash->residue -= len; | ||
4053 | flash->offset += len; | ||
4054 | if (flash->residue == 0) { | ||
4055 | flash->status = status; | ||
4056 | bfa_flash_cb(flash); | ||
4057 | } else | ||
4058 | bfa_flash_read_send(flash); | ||
4059 | } | ||
4060 | break; | ||
4061 | case BFI_FLASH_I2H_BOOT_VER_RSP: | ||
4062 | case BFI_FLASH_I2H_EVENT: | ||
4063 | bfa_trc(flash, msg->mh.msg_id); | ||
4064 | break; | ||
4065 | |||
4066 | default: | ||
4067 | WARN_ON(1); | ||
4068 | } | ||
4069 | } | ||
4070 | |||
4071 | /* | ||
4072 | * Flash memory info API. | ||
4073 | * | ||
4074 | * @param[in] mincfg - minimal cfg variable | ||
4075 | */ | ||
4076 | u32 | ||
4077 | bfa_flash_meminfo(bfa_boolean_t mincfg) | ||
4078 | { | ||
4079 | /* min driver doesn't need flash */ | ||
4080 | if (mincfg) | ||
4081 | return 0; | ||
4082 | return BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
4083 | } | ||
4084 | |||
4085 | /* | ||
4086 | * Flash attach API. | ||
4087 | * | ||
4088 | * @param[in] flash - flash structure | ||
4089 | * @param[in] ioc - ioc structure | ||
4090 | * @param[in] dev - device structure | ||
4091 | * @param[in] trcmod - trace module | ||
4092 | * @param[in] logmod - log module | ||
4093 | */ | ||
4094 | void | ||
4095 | bfa_flash_attach(struct bfa_flash_s *flash, struct bfa_ioc_s *ioc, void *dev, | ||
4096 | struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg) | ||
4097 | { | ||
4098 | flash->ioc = ioc; | ||
4099 | flash->trcmod = trcmod; | ||
4100 | flash->cbfn = NULL; | ||
4101 | flash->cbarg = NULL; | ||
4102 | flash->op_busy = 0; | ||
4103 | |||
4104 | bfa_ioc_mbox_regisr(flash->ioc, BFI_MC_FLASH, bfa_flash_intr, flash); | ||
4105 | bfa_q_qe_init(&flash->ioc_notify); | ||
4106 | bfa_ioc_notify_init(&flash->ioc_notify, bfa_flash_notify, flash); | ||
4107 | list_add_tail(&flash->ioc_notify.qe, &flash->ioc->notify_q); | ||
4108 | |||
4109 | /* min driver doesn't need flash */ | ||
4110 | if (mincfg) { | ||
4111 | flash->dbuf_kva = NULL; | ||
4112 | flash->dbuf_pa = 0; | ||
4113 | } | ||
4114 | } | ||
4115 | |||
4116 | /* | ||
4117 | * Claim memory for flash | ||
4118 | * | ||
4119 | * @param[in] flash - flash structure | ||
4120 | * @param[in] dm_kva - pointer to virtual memory address | ||
4121 | * @param[in] dm_pa - physical memory address | ||
4122 | * @param[in] mincfg - minimal cfg variable | ||
4123 | */ | ||
4124 | void | ||
4125 | bfa_flash_memclaim(struct bfa_flash_s *flash, u8 *dm_kva, u64 dm_pa, | ||
4126 | bfa_boolean_t mincfg) | ||
4127 | { | ||
4128 | if (mincfg) | ||
4129 | return; | ||
4130 | |||
4131 | flash->dbuf_kva = dm_kva; | ||
4132 | flash->dbuf_pa = dm_pa; | ||
4133 | memset(flash->dbuf_kva, 0, BFA_FLASH_DMA_BUF_SZ); | ||
4134 | dm_kva += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
4135 | dm_pa += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
4136 | } | ||
4137 | |||
4138 | /* | ||
4139 | * Get flash attribute. | ||
4140 | * | ||
4141 | * @param[in] flash - flash structure | ||
4142 | * @param[in] attr - flash attribute structure | ||
4143 | * @param[in] cbfn - callback function | ||
4144 | * @param[in] cbarg - callback argument | ||
4145 | * | ||
4146 | * Return status. | ||
4147 | */ | ||
4148 | bfa_status_t | ||
4149 | bfa_flash_get_attr(struct bfa_flash_s *flash, struct bfa_flash_attr_s *attr, | ||
4150 | bfa_cb_flash_t cbfn, void *cbarg) | ||
4151 | { | ||
4152 | bfa_trc(flash, BFI_FLASH_H2I_QUERY_REQ); | ||
4153 | |||
4154 | if (!bfa_ioc_is_operational(flash->ioc)) | ||
4155 | return BFA_STATUS_IOC_NON_OP; | ||
4156 | |||
4157 | if (flash->op_busy) { | ||
4158 | bfa_trc(flash, flash->op_busy); | ||
4159 | return BFA_STATUS_DEVBUSY; | ||
4160 | } | ||
4161 | |||
4162 | flash->op_busy = 1; | ||
4163 | flash->cbfn = cbfn; | ||
4164 | flash->cbarg = cbarg; | ||
4165 | flash->ubuf = (u8 *) attr; | ||
4166 | bfa_flash_query_send(flash); | ||
4167 | |||
4168 | return BFA_STATUS_OK; | ||
4169 | } | ||
4170 | |||
4171 | /* | ||
4172 | * Erase flash partition. | ||
4173 | * | ||
4174 | * @param[in] flash - flash structure | ||
4175 | * @param[in] type - flash partition type | ||
4176 | * @param[in] instance - flash partition instance | ||
4177 | * @param[in] cbfn - callback function | ||
4178 | * @param[in] cbarg - callback argument | ||
4179 | * | ||
4180 | * Return status. | ||
4181 | */ | ||
4182 | bfa_status_t | ||
4183 | bfa_flash_erase_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, | ||
4184 | u8 instance, bfa_cb_flash_t cbfn, void *cbarg) | ||
4185 | { | ||
4186 | bfa_trc(flash, BFI_FLASH_H2I_ERASE_REQ); | ||
4187 | bfa_trc(flash, type); | ||
4188 | bfa_trc(flash, instance); | ||
4189 | |||
4190 | if (!bfa_ioc_is_operational(flash->ioc)) | ||
4191 | return BFA_STATUS_IOC_NON_OP; | ||
4192 | |||
4193 | if (flash->op_busy) { | ||
4194 | bfa_trc(flash, flash->op_busy); | ||
4195 | return BFA_STATUS_DEVBUSY; | ||
4196 | } | ||
4197 | |||
4198 | flash->op_busy = 1; | ||
4199 | flash->cbfn = cbfn; | ||
4200 | flash->cbarg = cbarg; | ||
4201 | flash->type = type; | ||
4202 | flash->instance = instance; | ||
4203 | |||
4204 | bfa_flash_erase_send(flash); | ||
4205 | return BFA_STATUS_OK; | ||
4206 | } | ||
4207 | |||
4208 | /* | ||
4209 | * Update flash partition. | ||
4210 | * | ||
4211 | * @param[in] flash - flash structure | ||
4212 | * @param[in] type - flash partition type | ||
4213 | * @param[in] instance - flash partition instance | ||
4214 | * @param[in] buf - update data buffer | ||
4215 | * @param[in] len - data buffer length | ||
4216 | * @param[in] offset - offset relative to the partition starting address | ||
4217 | * @param[in] cbfn - callback function | ||
4218 | * @param[in] cbarg - callback argument | ||
4219 | * | ||
4220 | * Return status. | ||
4221 | */ | ||
4222 | bfa_status_t | ||
4223 | bfa_flash_update_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, | ||
4224 | u8 instance, void *buf, u32 len, u32 offset, | ||
4225 | bfa_cb_flash_t cbfn, void *cbarg) | ||
4226 | { | ||
4227 | bfa_trc(flash, BFI_FLASH_H2I_WRITE_REQ); | ||
4228 | bfa_trc(flash, type); | ||
4229 | bfa_trc(flash, instance); | ||
4230 | bfa_trc(flash, len); | ||
4231 | bfa_trc(flash, offset); | ||
4232 | |||
4233 | if (!bfa_ioc_is_operational(flash->ioc)) | ||
4234 | return BFA_STATUS_IOC_NON_OP; | ||
4235 | |||
4236 | /* | ||
4237 | * 'len' must be in word (4-byte) boundary | ||
4238 | * 'offset' must be in sector (16kb) boundary | ||
4239 | */ | ||
4240 | if (!len || (len & 0x03) || (offset & 0x00003FFF)) | ||
4241 | return BFA_STATUS_FLASH_BAD_LEN; | ||
4242 | |||
4243 | if (type == BFA_FLASH_PART_MFG) | ||
4244 | return BFA_STATUS_EINVAL; | ||
4245 | |||
4246 | if (flash->op_busy) { | ||
4247 | bfa_trc(flash, flash->op_busy); | ||
4248 | return BFA_STATUS_DEVBUSY; | ||
4249 | } | ||
4250 | |||
4251 | flash->op_busy = 1; | ||
4252 | flash->cbfn = cbfn; | ||
4253 | flash->cbarg = cbarg; | ||
4254 | flash->type = type; | ||
4255 | flash->instance = instance; | ||
4256 | flash->residue = len; | ||
4257 | flash->offset = 0; | ||
4258 | flash->addr_off = offset; | ||
4259 | flash->ubuf = buf; | ||
4260 | |||
4261 | bfa_flash_write_send(flash); | ||
4262 | return BFA_STATUS_OK; | ||
4263 | } | ||
4264 | |||
4265 | /* | ||
4266 | * Read flash partition. | ||
4267 | * | ||
4268 | * @param[in] flash - flash structure | ||
4269 | * @param[in] type - flash partition type | ||
4270 | * @param[in] instance - flash partition instance | ||
4271 | * @param[in] buf - read data buffer | ||
4272 | * @param[in] len - data buffer length | ||
4273 | * @param[in] offset - offset relative to the partition starting address | ||
4274 | * @param[in] cbfn - callback function | ||
4275 | * @param[in] cbarg - callback argument | ||
4276 | * | ||
4277 | * Return status. | ||
4278 | */ | ||
4279 | bfa_status_t | ||
4280 | bfa_flash_read_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, | ||
4281 | u8 instance, void *buf, u32 len, u32 offset, | ||
4282 | bfa_cb_flash_t cbfn, void *cbarg) | ||
4283 | { | ||
4284 | bfa_trc(flash, BFI_FLASH_H2I_READ_REQ); | ||
4285 | bfa_trc(flash, type); | ||
4286 | bfa_trc(flash, instance); | ||
4287 | bfa_trc(flash, len); | ||
4288 | bfa_trc(flash, offset); | ||
4289 | |||
4290 | if (!bfa_ioc_is_operational(flash->ioc)) | ||
4291 | return BFA_STATUS_IOC_NON_OP; | ||
4292 | |||
4293 | /* | ||
4294 | * 'len' must be in word (4-byte) boundary | ||
4295 | * 'offset' must be in sector (16kb) boundary | ||
4296 | */ | ||
4297 | if (!len || (len & 0x03) || (offset & 0x00003FFF)) | ||
4298 | return BFA_STATUS_FLASH_BAD_LEN; | ||
4299 | |||
4300 | if (flash->op_busy) { | ||
4301 | bfa_trc(flash, flash->op_busy); | ||
4302 | return BFA_STATUS_DEVBUSY; | ||
4303 | } | ||
4304 | |||
4305 | flash->op_busy = 1; | ||
4306 | flash->cbfn = cbfn; | ||
4307 | flash->cbarg = cbarg; | ||
4308 | flash->type = type; | ||
4309 | flash->instance = instance; | ||
4310 | flash->residue = len; | ||
4311 | flash->offset = 0; | ||
4312 | flash->addr_off = offset; | ||
4313 | flash->ubuf = buf; | ||
4314 | bfa_flash_read_send(flash); | ||
4315 | |||
4316 | return BFA_STATUS_OK; | ||
4317 | } | ||
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index 1d51164faa81..c302b996b920 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h | |||
@@ -348,6 +348,28 @@ struct bfa_ioc_hwif_s { | |||
348 | }; | 348 | }; |
349 | 349 | ||
350 | /* | 350 | /* |
351 | * Queue element to wait for room in request queue. FIFO order is | ||
352 | * maintained when fullfilling requests. | ||
353 | */ | ||
354 | struct bfa_reqq_wait_s { | ||
355 | struct list_head qe; | ||
356 | void (*qresume) (void *cbarg); | ||
357 | void *cbarg; | ||
358 | }; | ||
359 | |||
360 | typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete); | ||
361 | |||
362 | /* | ||
363 | * Generic BFA callback element. | ||
364 | */ | ||
365 | struct bfa_cb_qe_s { | ||
366 | struct list_head qe; | ||
367 | bfa_cb_cbfn_t cbfn; | ||
368 | bfa_boolean_t once; | ||
369 | void *cbarg; | ||
370 | }; | ||
371 | |||
372 | /* | ||
351 | * ASIC block configurtion related | 373 | * ASIC block configurtion related |
352 | */ | 374 | */ |
353 | 375 | ||
@@ -419,6 +441,56 @@ bfa_status_t bfa_sfp_speed(struct bfa_sfp_s *sfp, | |||
419 | enum bfa_port_speed portspeed, | 441 | enum bfa_port_speed portspeed, |
420 | bfa_cb_sfp_t cbfn, void *cbarg); | 442 | bfa_cb_sfp_t cbfn, void *cbarg); |
421 | 443 | ||
444 | /* | ||
445 | * Flash module specific | ||
446 | */ | ||
447 | typedef void (*bfa_cb_flash_t) (void *cbarg, bfa_status_t status); | ||
448 | |||
449 | struct bfa_flash_s { | ||
450 | struct bfa_ioc_s *ioc; /* back pointer to ioc */ | ||
451 | struct bfa_trc_mod_s *trcmod; | ||
452 | u32 type; /* partition type */ | ||
453 | u8 instance; /* partition instance */ | ||
454 | u8 rsv[3]; | ||
455 | u32 op_busy; /* operation busy flag */ | ||
456 | u32 residue; /* residual length */ | ||
457 | u32 offset; /* offset */ | ||
458 | bfa_status_t status; /* status */ | ||
459 | u8 *dbuf_kva; /* dma buf virtual address */ | ||
460 | u64 dbuf_pa; /* dma buf physical address */ | ||
461 | struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ | ||
462 | bfa_cb_flash_t cbfn; /* user callback function */ | ||
463 | void *cbarg; /* user callback arg */ | ||
464 | u8 *ubuf; /* user supplied buffer */ | ||
465 | struct bfa_cb_qe_s hcb_qe; /* comp: BFA callback qelem */ | ||
466 | u32 addr_off; /* partition address offset */ | ||
467 | struct bfa_mbox_cmd_s mb; /* mailbox */ | ||
468 | struct bfa_ioc_notify_s ioc_notify; /* ioc event notify */ | ||
469 | struct bfa_mem_dma_s flash_dma; | ||
470 | }; | ||
471 | |||
472 | #define BFA_FLASH(__bfa) (&(__bfa)->modules.flash) | ||
473 | #define BFA_MEM_FLASH_DMA(__bfa) (&(BFA_FLASH(__bfa)->flash_dma)) | ||
474 | |||
475 | bfa_status_t bfa_flash_get_attr(struct bfa_flash_s *flash, | ||
476 | struct bfa_flash_attr_s *attr, | ||
477 | bfa_cb_flash_t cbfn, void *cbarg); | ||
478 | bfa_status_t bfa_flash_erase_part(struct bfa_flash_s *flash, | ||
479 | enum bfa_flash_part_type type, u8 instance, | ||
480 | bfa_cb_flash_t cbfn, void *cbarg); | ||
481 | bfa_status_t bfa_flash_update_part(struct bfa_flash_s *flash, | ||
482 | enum bfa_flash_part_type type, u8 instance, | ||
483 | void *buf, u32 len, u32 offset, | ||
484 | bfa_cb_flash_t cbfn, void *cbarg); | ||
485 | bfa_status_t bfa_flash_read_part(struct bfa_flash_s *flash, | ||
486 | enum bfa_flash_part_type type, u8 instance, void *buf, | ||
487 | u32 len, u32 offset, bfa_cb_flash_t cbfn, void *cbarg); | ||
488 | u32 bfa_flash_meminfo(bfa_boolean_t mincfg); | ||
489 | void bfa_flash_attach(struct bfa_flash_s *flash, struct bfa_ioc_s *ioc, | ||
490 | void *dev, struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg); | ||
491 | void bfa_flash_memclaim(struct bfa_flash_s *flash, | ||
492 | u8 *dm_kva, u64 dm_pa, bfa_boolean_t mincfg); | ||
493 | |||
422 | #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) | 494 | #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) |
423 | #define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id) | 495 | #define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id) |
424 | #define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva) | 496 | #define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva) |
diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h index d8ea708db9b7..f7783f0d3267 100644 --- a/drivers/scsi/bfa/bfa_modules.h +++ b/drivers/scsi/bfa/bfa_modules.h | |||
@@ -40,6 +40,7 @@ struct bfa_modules_s { | |||
40 | struct bfa_ablk_s ablk; /* ASIC block config module */ | 40 | struct bfa_ablk_s ablk; /* ASIC block config module */ |
41 | struct bfa_cee_s cee; /* CEE Module */ | 41 | struct bfa_cee_s cee; /* CEE Module */ |
42 | struct bfa_sfp_s sfp; /* SFP module */ | 42 | struct bfa_sfp_s sfp; /* SFP module */ |
43 | struct bfa_flash_s flash; /* flash module */ | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | /* | 46 | /* |
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index e4409e57e3a9..5444661f1150 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c | |||
@@ -1109,6 +1109,111 @@ out: | |||
1109 | return 0; | 1109 | return 0; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | int | ||
1113 | bfad_iocmd_flash_get_attr(struct bfad_s *bfad, void *cmd) | ||
1114 | { | ||
1115 | struct bfa_bsg_flash_attr_s *iocmd = | ||
1116 | (struct bfa_bsg_flash_attr_s *)cmd; | ||
1117 | struct bfad_hal_comp fcomp; | ||
1118 | unsigned long flags; | ||
1119 | |||
1120 | init_completion(&fcomp.comp); | ||
1121 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1122 | iocmd->status = bfa_flash_get_attr(BFA_FLASH(&bfad->bfa), &iocmd->attr, | ||
1123 | bfad_hcb_comp, &fcomp); | ||
1124 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1125 | if (iocmd->status != BFA_STATUS_OK) | ||
1126 | goto out; | ||
1127 | wait_for_completion(&fcomp.comp); | ||
1128 | iocmd->status = fcomp.status; | ||
1129 | out: | ||
1130 | return 0; | ||
1131 | } | ||
1132 | |||
1133 | int | ||
1134 | bfad_iocmd_flash_erase_part(struct bfad_s *bfad, void *cmd) | ||
1135 | { | ||
1136 | struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd; | ||
1137 | struct bfad_hal_comp fcomp; | ||
1138 | unsigned long flags; | ||
1139 | |||
1140 | init_completion(&fcomp.comp); | ||
1141 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1142 | iocmd->status = bfa_flash_erase_part(BFA_FLASH(&bfad->bfa), iocmd->type, | ||
1143 | iocmd->instance, bfad_hcb_comp, &fcomp); | ||
1144 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1145 | if (iocmd->status != BFA_STATUS_OK) | ||
1146 | goto out; | ||
1147 | wait_for_completion(&fcomp.comp); | ||
1148 | iocmd->status = fcomp.status; | ||
1149 | out: | ||
1150 | return 0; | ||
1151 | } | ||
1152 | |||
1153 | int | ||
1154 | bfad_iocmd_flash_update_part(struct bfad_s *bfad, void *cmd, | ||
1155 | unsigned int payload_len) | ||
1156 | { | ||
1157 | struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd; | ||
1158 | void *iocmd_bufptr; | ||
1159 | struct bfad_hal_comp fcomp; | ||
1160 | unsigned long flags; | ||
1161 | |||
1162 | if (bfad_chk_iocmd_sz(payload_len, | ||
1163 | sizeof(struct bfa_bsg_flash_s), | ||
1164 | iocmd->bufsz) != BFA_STATUS_OK) { | ||
1165 | iocmd->status = BFA_STATUS_VERSION_FAIL; | ||
1166 | return 0; | ||
1167 | } | ||
1168 | |||
1169 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_flash_s); | ||
1170 | |||
1171 | init_completion(&fcomp.comp); | ||
1172 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1173 | iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), | ||
1174 | iocmd->type, iocmd->instance, iocmd_bufptr, | ||
1175 | iocmd->bufsz, 0, bfad_hcb_comp, &fcomp); | ||
1176 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1177 | if (iocmd->status != BFA_STATUS_OK) | ||
1178 | goto out; | ||
1179 | wait_for_completion(&fcomp.comp); | ||
1180 | iocmd->status = fcomp.status; | ||
1181 | out: | ||
1182 | return 0; | ||
1183 | } | ||
1184 | |||
1185 | int | ||
1186 | bfad_iocmd_flash_read_part(struct bfad_s *bfad, void *cmd, | ||
1187 | unsigned int payload_len) | ||
1188 | { | ||
1189 | struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd; | ||
1190 | struct bfad_hal_comp fcomp; | ||
1191 | void *iocmd_bufptr; | ||
1192 | unsigned long flags; | ||
1193 | |||
1194 | if (bfad_chk_iocmd_sz(payload_len, | ||
1195 | sizeof(struct bfa_bsg_flash_s), | ||
1196 | iocmd->bufsz) != BFA_STATUS_OK) { | ||
1197 | iocmd->status = BFA_STATUS_VERSION_FAIL; | ||
1198 | return 0; | ||
1199 | } | ||
1200 | |||
1201 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_flash_s); | ||
1202 | |||
1203 | init_completion(&fcomp.comp); | ||
1204 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1205 | iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), iocmd->type, | ||
1206 | iocmd->instance, iocmd_bufptr, iocmd->bufsz, 0, | ||
1207 | bfad_hcb_comp, &fcomp); | ||
1208 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1209 | if (iocmd->status != BFA_STATUS_OK) | ||
1210 | goto out; | ||
1211 | wait_for_completion(&fcomp.comp); | ||
1212 | iocmd->status = fcomp.status; | ||
1213 | out: | ||
1214 | return 0; | ||
1215 | } | ||
1216 | |||
1112 | static int | 1217 | static int |
1113 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | 1218 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, |
1114 | unsigned int payload_len) | 1219 | unsigned int payload_len) |
@@ -1243,6 +1348,18 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | |||
1243 | case IOCMD_SFP_SPEED: | 1348 | case IOCMD_SFP_SPEED: |
1244 | rc = bfad_iocmd_sfp_speed(bfad, iocmd); | 1349 | rc = bfad_iocmd_sfp_speed(bfad, iocmd); |
1245 | break; | 1350 | break; |
1351 | case IOCMD_FLASH_GET_ATTR: | ||
1352 | rc = bfad_iocmd_flash_get_attr(bfad, iocmd); | ||
1353 | break; | ||
1354 | case IOCMD_FLASH_ERASE_PART: | ||
1355 | rc = bfad_iocmd_flash_erase_part(bfad, iocmd); | ||
1356 | break; | ||
1357 | case IOCMD_FLASH_UPDATE_PART: | ||
1358 | rc = bfad_iocmd_flash_update_part(bfad, iocmd, payload_len); | ||
1359 | break; | ||
1360 | case IOCMD_FLASH_READ_PART: | ||
1361 | rc = bfad_iocmd_flash_read_part(bfad, iocmd, payload_len); | ||
1362 | break; | ||
1246 | default: | 1363 | default: |
1247 | rc = EINVAL; | 1364 | rc = EINVAL; |
1248 | break; | 1365 | break; |
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index faafd35f88ae..6bece6c1d876 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h | |||
@@ -67,6 +67,10 @@ enum { | |||
67 | IOCMD_CEE_RESET_STATS, | 67 | IOCMD_CEE_RESET_STATS, |
68 | IOCMD_SFP_MEDIA, | 68 | IOCMD_SFP_MEDIA, |
69 | IOCMD_SFP_SPEED, | 69 | IOCMD_SFP_SPEED, |
70 | IOCMD_FLASH_GET_ATTR, | ||
71 | IOCMD_FLASH_ERASE_PART, | ||
72 | IOCMD_FLASH_UPDATE_PART, | ||
73 | IOCMD_FLASH_READ_PART, | ||
70 | }; | 74 | }; |
71 | 75 | ||
72 | struct bfa_bsg_gen_s { | 76 | struct bfa_bsg_gen_s { |
@@ -336,6 +340,23 @@ struct bfa_bsg_sfp_speed_s { | |||
336 | enum bfa_port_speed speed; | 340 | enum bfa_port_speed speed; |
337 | }; | 341 | }; |
338 | 342 | ||
343 | struct bfa_bsg_flash_attr_s { | ||
344 | bfa_status_t status; | ||
345 | u16 bfad_num; | ||
346 | u16 rsvd; | ||
347 | struct bfa_flash_attr_s attr; | ||
348 | }; | ||
349 | |||
350 | struct bfa_bsg_flash_s { | ||
351 | bfa_status_t status; | ||
352 | u16 bfad_num; | ||
353 | u8 instance; | ||
354 | u8 rsvd; | ||
355 | enum bfa_flash_part_type type; | ||
356 | int bufsz; | ||
357 | u64 buf_ptr; | ||
358 | }; | ||
359 | |||
339 | struct bfa_bsg_fcpt_s { | 360 | struct bfa_bsg_fcpt_s { |
340 | bfa_status_t status; | 361 | bfa_status_t status; |
341 | u16 vf_id; | 362 | u16 vf_id; |
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index 0d249984fd08..b7eb3dc27d5b 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h | |||
@@ -190,6 +190,7 @@ enum bfi_pcifn_class { | |||
190 | */ | 190 | */ |
191 | enum bfi_mclass { | 191 | enum bfi_mclass { |
192 | BFI_MC_IOC = 1, /* IO Controller (IOC) */ | 192 | BFI_MC_IOC = 1, /* IO Controller (IOC) */ |
193 | BFI_MC_FLASH = 3, /* Flash message class */ | ||
193 | BFI_MC_CEE = 4, /* CEE */ | 194 | BFI_MC_CEE = 4, /* CEE */ |
194 | BFI_MC_FCPORT = 5, /* FC port */ | 195 | BFI_MC_FCPORT = 5, /* FC port */ |
195 | BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */ | 196 | BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */ |
@@ -814,6 +815,114 @@ struct bfi_sfp_rsp_s { | |||
814 | u8 rsvd[2]; | 815 | u8 rsvd[2]; |
815 | }; | 816 | }; |
816 | 817 | ||
818 | /* | ||
819 | * FLASH module specific | ||
820 | */ | ||
821 | enum bfi_flash_h2i_msgs { | ||
822 | BFI_FLASH_H2I_QUERY_REQ = 1, | ||
823 | BFI_FLASH_H2I_ERASE_REQ = 2, | ||
824 | BFI_FLASH_H2I_WRITE_REQ = 3, | ||
825 | BFI_FLASH_H2I_READ_REQ = 4, | ||
826 | BFI_FLASH_H2I_BOOT_VER_REQ = 5, | ||
827 | }; | ||
828 | |||
829 | enum bfi_flash_i2h_msgs { | ||
830 | BFI_FLASH_I2H_QUERY_RSP = BFA_I2HM(1), | ||
831 | BFI_FLASH_I2H_ERASE_RSP = BFA_I2HM(2), | ||
832 | BFI_FLASH_I2H_WRITE_RSP = BFA_I2HM(3), | ||
833 | BFI_FLASH_I2H_READ_RSP = BFA_I2HM(4), | ||
834 | BFI_FLASH_I2H_BOOT_VER_RSP = BFA_I2HM(5), | ||
835 | BFI_FLASH_I2H_EVENT = BFA_I2HM(127), | ||
836 | }; | ||
837 | |||
838 | /* | ||
839 | * Flash query request | ||
840 | */ | ||
841 | struct bfi_flash_query_req_s { | ||
842 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
843 | struct bfi_alen_s alen; | ||
844 | }; | ||
845 | |||
846 | /* | ||
847 | * Flash erase request | ||
848 | */ | ||
849 | struct bfi_flash_erase_req_s { | ||
850 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
851 | u32 type; /* partition type */ | ||
852 | u8 instance; /* partition instance */ | ||
853 | u8 rsv[3]; | ||
854 | }; | ||
855 | |||
856 | /* | ||
857 | * Flash write request | ||
858 | */ | ||
859 | struct bfi_flash_write_req_s { | ||
860 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
861 | struct bfi_alen_s alen; | ||
862 | u32 type; /* partition type */ | ||
863 | u8 instance; /* partition instance */ | ||
864 | u8 last; | ||
865 | u8 rsv[2]; | ||
866 | u32 offset; | ||
867 | u32 length; | ||
868 | }; | ||
869 | |||
870 | /* | ||
871 | * Flash read request | ||
872 | */ | ||
873 | struct bfi_flash_read_req_s { | ||
874 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
875 | u32 type; /* partition type */ | ||
876 | u8 instance; /* partition instance */ | ||
877 | u8 rsv[3]; | ||
878 | u32 offset; | ||
879 | u32 length; | ||
880 | struct bfi_alen_s alen; | ||
881 | }; | ||
882 | |||
883 | /* | ||
884 | * Flash query response | ||
885 | */ | ||
886 | struct bfi_flash_query_rsp_s { | ||
887 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
888 | u32 status; | ||
889 | }; | ||
890 | |||
891 | /* | ||
892 | * Flash read response | ||
893 | */ | ||
894 | struct bfi_flash_read_rsp_s { | ||
895 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
896 | u32 type; /* partition type */ | ||
897 | u8 instance; /* partition instance */ | ||
898 | u8 rsv[3]; | ||
899 | u32 status; | ||
900 | u32 length; | ||
901 | }; | ||
902 | |||
903 | /* | ||
904 | * Flash write response | ||
905 | */ | ||
906 | struct bfi_flash_write_rsp_s { | ||
907 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
908 | u32 type; /* partition type */ | ||
909 | u8 instance; /* partition instance */ | ||
910 | u8 rsv[3]; | ||
911 | u32 status; | ||
912 | u32 length; | ||
913 | }; | ||
914 | |||
915 | /* | ||
916 | * Flash erase response | ||
917 | */ | ||
918 | struct bfi_flash_erase_rsp_s { | ||
919 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
920 | u32 type; /* partition type */ | ||
921 | u8 instance; /* partition instance */ | ||
922 | u8 rsv[3]; | ||
923 | u32 status; | ||
924 | }; | ||
925 | |||
817 | #pragma pack() | 926 | #pragma pack() |
818 | 927 | ||
819 | #endif /* __BFI_H__ */ | 928 | #endif /* __BFI_H__ */ |