Commit 51e569aa authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley

[SCSI] bfa: Added support to obtain SFP info.

- Added SFP sub-module to BFA.
- Added interface to collect sfp media info and sfp speed.
Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 148d6103
......@@ -122,6 +122,16 @@ bfa_com_cee_attach(struct bfa_s *bfa)
bfa_cee_mem_claim(cee, cee_dma->kva_curp, cee_dma->dma_curp);
}
static void
bfa_com_sfp_attach(struct bfa_s *bfa)
{
struct bfa_sfp_s *sfp = BFA_SFP_MOD(bfa);
struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa);
bfa_sfp_attach(sfp, &bfa->ioc, bfa, bfa->trcmod);
bfa_sfp_memclaim(sfp, sfp_dma->kva_curp, sfp_dma->dma_curp);
}
/*
* BFA IOC FC related definitions
*/
......@@ -1360,6 +1370,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
struct bfa_mem_dma_s *port_dma = BFA_MEM_PORT_DMA(bfa);
struct bfa_mem_dma_s *ablk_dma = BFA_MEM_ABLK_DMA(bfa);
struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa);
struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa);
WARN_ON((cfg == NULL) || (meminfo == NULL));
......@@ -1378,6 +1389,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
bfa_mem_dma_setup(meminfo, port_dma, bfa_port_meminfo());
bfa_mem_dma_setup(meminfo, ablk_dma, bfa_ablk_meminfo());
bfa_mem_dma_setup(meminfo, cee_dma, bfa_cee_meminfo());
bfa_mem_dma_setup(meminfo, sfp_dma, bfa_sfp_meminfo());
}
/*
......@@ -1446,6 +1458,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa_com_port_attach(bfa);
bfa_com_ablk_attach(bfa);
bfa_com_cee_attach(bfa);
bfa_com_sfp_attach(bfa);
}
/*
......
......@@ -130,6 +130,7 @@ enum bfa_status {
BFA_STATUS_ETIMER = 5, /* Timer expired - Retry, if persists,
* contact support */
BFA_STATUS_EPROTOCOL = 6, /* Protocol error */
BFA_STATUS_SFP_UNSUPP = 10, /* Unsupported SFP - Replace SFP */
BFA_STATUS_UNKNOWN_VFID = 11, /* VF_ID not found */
BFA_STATUS_DEVBUSY = 13, /* Device busy - Retry operation */
BFA_STATUS_UNKNOWN_LWWN = 18, /* LPORT PWWN not found */
......@@ -150,9 +151,11 @@ enum bfa_status {
BFA_STATUS_DIAG_BUSY = 71, /* diag busy */
BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */
BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */
BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */
BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */
BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot
* configuration */
BFA_STATUS_SFP_NOT_READY = 159, /* SFP info is not ready. Retry */
BFA_STATUS_TRUNK_ENABLED = 164, /* Trunk is already enabled on
* this adapter */
BFA_STATUS_TRUNK_DISABLED = 165, /* Trunking is disabled on
......@@ -559,6 +562,269 @@ struct bfa_ablk_cfg_inst_s {
struct bfa_ablk_cfg_s {
struct bfa_ablk_cfg_inst_s inst[BFA_ABLK_MAX];
};
/*
* SFP module specific
*/
#define SFP_DIAGMON_SIZE 10 /* num bytes of diag monitor data */
enum bfa_defs_sfp_media_e {
BFA_SFP_MEDIA_UNKNOWN = 0x00,
BFA_SFP_MEDIA_CU = 0x01,
BFA_SFP_MEDIA_LW = 0x02,
BFA_SFP_MEDIA_SW = 0x03,
BFA_SFP_MEDIA_EL = 0x04,
BFA_SFP_MEDIA_UNSUPPORT = 0x05,
};
/*
* values for xmtr_tech above
*/
enum {
SFP_XMTR_TECH_CU = (1 << 0), /* copper FC-BaseT */
SFP_XMTR_TECH_CP = (1 << 1), /* copper passive */
SFP_XMTR_TECH_CA = (1 << 2), /* copper active */
SFP_XMTR_TECH_LL = (1 << 3), /* longwave laser */
SFP_XMTR_TECH_SL = (1 << 4), /* shortwave laser w/ OFC */
SFP_XMTR_TECH_SN = (1 << 5), /* shortwave laser w/o OFC */
SFP_XMTR_TECH_EL_INTRA = (1 << 6), /* elec intra-enclosure */
SFP_XMTR_TECH_EL_INTER = (1 << 7), /* elec inter-enclosure */
SFP_XMTR_TECH_LC = (1 << 8), /* longwave laser */
SFP_XMTR_TECH_SA = (1 << 9)
};
/*
* Serial ID: Data Fields -- Address A0h
* Basic ID field total 64 bytes
*/
struct sfp_srlid_base_s {
u8 id; /* 00: Identifier */
u8 extid; /* 01: Extended Identifier */
u8 connector; /* 02: Connector */
u8 xcvr[8]; /* 03-10: Transceiver */
u8 encoding; /* 11: Encoding */
u8 br_norm; /* 12: BR, Nominal */
u8 rate_id; /* 13: Rate Identifier */
u8 len_km; /* 14: Length single mode km */
u8 len_100m; /* 15: Length single mode 100m */
u8 len_om2; /* 16: Length om2 fiber 10m */
u8 len_om1; /* 17: Length om1 fiber 10m */
u8 len_cu; /* 18: Length copper 1m */
u8 len_om3; /* 19: Length om3 fiber 10m */
u8 vendor_name[16];/* 20-35 */
u8 unalloc1;
u8 vendor_oui[3]; /* 37-39 */
u8 vendor_pn[16]; /* 40-55 */
u8 vendor_rev[4]; /* 56-59 */
u8 wavelen[2]; /* 60-61 */
u8 unalloc2;
u8 cc_base; /* 63: check code for base id field */
};
/*
* Serial ID: Data Fields -- Address A0h
* Extended id field total 32 bytes
*/
struct sfp_srlid_ext_s {
u8 options[2];
u8 br_max;
u8 br_min;
u8 vendor_sn[16];
u8 date_code[8];
u8 diag_mon_type; /* 92: Diagnostic Monitoring type */
u8 en_options;
u8 sff_8472;
u8 cc_ext;
};
/*
* Diagnostic: Data Fields -- Address A2h
* Diagnostic and control/status base field total 96 bytes
*/
struct sfp_diag_base_s {
/*
* Alarm and warning Thresholds 40 bytes
*/
u8 temp_high_alarm[2]; /* 00-01 */
u8 temp_low_alarm[2]; /* 02-03 */
u8 temp_high_warning[2]; /* 04-05 */
u8 temp_low_warning[2]; /* 06-07 */
u8 volt_high_alarm[2]; /* 08-09 */
u8 volt_low_alarm[2]; /* 10-11 */
u8 volt_high_warning[2]; /* 12-13 */
u8 volt_low_warning[2]; /* 14-15 */
u8 bias_high_alarm[2]; /* 16-17 */
u8 bias_low_alarm[2]; /* 18-19 */
u8 bias_high_warning[2]; /* 20-21 */
u8 bias_low_warning[2]; /* 22-23 */
u8 tx_pwr_high_alarm[2]; /* 24-25 */
u8 tx_pwr_low_alarm[2]; /* 26-27 */
u8 tx_pwr_high_warning[2]; /* 28-29 */
u8 tx_pwr_low_warning[2]; /* 30-31 */
u8 rx_pwr_high_alarm[2]; /* 32-33 */
u8 rx_pwr_low_alarm[2]; /* 34-35 */
u8 rx_pwr_high_warning[2]; /* 36-37 */
u8 rx_pwr_low_warning[2]; /* 38-39 */
u8 unallocate_1[16];
/*
* ext_cal_const[36]
*/
u8 rx_pwr[20];
u8 tx_i[4];
u8 tx_pwr[4];
u8 temp[4];
u8 volt[4];
u8 unallocate_2[3];
u8 cc_dmi;
};
/*
* Diagnostic: Data Fields -- Address A2h
* Diagnostic and control/status extended field total 24 bytes
*/
struct sfp_diag_ext_s {
u8 diag[SFP_DIAGMON_SIZE];
u8 unalloc1[4];
u8 status_ctl;
u8 rsvd;
u8 alarm_flags[2];
u8 unalloc2[2];
u8 warning_flags[2];
u8 ext_status_ctl[2];
};
struct sfp_mem_s {
struct sfp_srlid_base_s srlid_base;
struct sfp_srlid_ext_s srlid_ext;
struct sfp_diag_base_s diag_base;
struct sfp_diag_ext_s diag_ext;
};
/*
* transceiver codes (SFF-8472 Rev 10.2 Table 3.5)
*/
union sfp_xcvr_e10g_code_u {
u8 b;
struct {
#ifdef __BIGENDIAN
u8 e10g_unall:1; /* 10G Ethernet compliance */
u8 e10g_lrm:1;
u8 e10g_lr:1;
u8 e10g_sr:1;
u8 ib_sx:1; /* Infiniband compliance */
u8 ib_lx:1;
u8 ib_cu_a:1;
u8 ib_cu_p:1;
#else
u8 ib_cu_p:1;
u8 ib_cu_a:1;
u8 ib_lx:1;
u8 ib_sx:1; /* Infiniband compliance */
u8 e10g_sr:1;
u8 e10g_lr:1;
u8 e10g_lrm:1;
u8 e10g_unall:1; /* 10G Ethernet compliance */
#endif
} r;
};
union sfp_xcvr_so1_code_u {
u8 b;
struct {
u8 escon:2; /* ESCON compliance code */
u8 oc192_reach:1; /* SONET compliance code */
u8 so_reach:2;
u8 oc48_reach:3;
} r;
};
union sfp_xcvr_so2_code_u {
u8 b;
struct {
u8 reserved:1;
u8 oc12_reach:3; /* OC12 reach */
u8 reserved1:1;
u8 oc3_reach:3; /* OC3 reach */
} r;
};
union sfp_xcvr_eth_code_u {
u8 b;
struct {
u8 base_px:1;
u8 base_bx10:1;
u8 e100base_fx:1;
u8 e100base_lx:1;
u8 e1000base_t:1;
u8 e1000base_cx:1;
u8 e1000base_lx:1;
u8 e1000base_sx:1;
} r;
};
struct sfp_xcvr_fc1_code_s {
u8 link_len:5; /* FC link length */
u8 xmtr_tech2:3;
u8 xmtr_tech1:7; /* FC transmitter technology */
u8 reserved1:1;
};
union sfp_xcvr_fc2_code_u {
u8 b;
struct {
u8 tw_media:1; /* twin axial pair (tw) */
u8 tp_media:1; /* shielded twisted pair (sp) */
u8 mi_media:1; /* miniature coax (mi) */
u8 tv_media:1; /* video coax (tv) */
u8 m6_media:1; /* multimode, 62.5m (m6) */
u8 m5_media:1; /* multimode, 50m (m5) */
u8 reserved:1;
u8 sm_media:1; /* single mode (sm) */
} r;
};
union sfp_xcvr_fc3_code_u {
u8 b;
struct {
#ifdef __BIGENDIAN
u8 rsv4:1;
u8 mb800:1; /* 800 Mbytes/sec */
u8 mb1600:1; /* 1600 Mbytes/sec */
u8 mb400:1; /* 400 Mbytes/sec */
u8 rsv2:1;
u8 mb200:1; /* 200 Mbytes/sec */
u8 rsv1:1;
u8 mb100:1; /* 100 Mbytes/sec */
#else
u8 mb100:1; /* 100 Mbytes/sec */
u8 rsv1:1;
u8 mb200:1; /* 200 Mbytes/sec */
u8 rsv2:1;
u8 mb400:1; /* 400 Mbytes/sec */
u8 mb1600:1; /* 1600 Mbytes/sec */
u8 mb800:1; /* 800 Mbytes/sec */
u8 rsv4:1;
#endif
} r;
};
struct sfp_xcvr_s {
union sfp_xcvr_e10g_code_u e10g;
union sfp_xcvr_so1_code_u so1;
union sfp_xcvr_so2_code_u so2;
union sfp_xcvr_eth_code_u eth;
struct sfp_xcvr_fc1_code_s fc1;
union sfp_xcvr_fc2_code_u fc2;
union sfp_xcvr_fc3_code_u fc3;
};
#pragma pack()
#endif /* __BFA_DEFS_H__ */
This diff is collapsed.
......@@ -367,6 +367,58 @@ struct bfa_ablk_s {
};
#define BFA_MEM_ABLK_DMA(__bfa) (&((__bfa)->modules.ablk.ablk_dma))
/*
* SFP module specific
*/
typedef void (*bfa_cb_sfp_t) (void *cbarg, bfa_status_t status);
struct bfa_sfp_s {
void *dev;
struct bfa_ioc_s *ioc;
struct bfa_trc_mod_s *trcmod;
struct sfp_mem_s *sfpmem;
bfa_cb_sfp_t cbfn;
void *cbarg;
enum bfi_sfp_mem_e memtype; /* mem access type */
u32 status;
struct bfa_mbox_cmd_s mbcmd;
u8 *dbuf_kva; /* dma buf virtual address */
u64 dbuf_pa; /* dma buf physical address */
struct bfa_ioc_notify_s ioc_notify;
enum bfa_defs_sfp_media_e *media;
enum bfa_port_speed portspeed;
bfa_cb_sfp_t state_query_cbfn;
void *state_query_cbarg;
u8 lock;
u8 data_valid; /* data in dbuf is valid */
u8 state; /* sfp state */
u8 state_query_lock;
struct bfa_mem_dma_s sfp_dma;
u8 is_elb; /* eloopback */
};
#define BFA_SFP_MOD(__bfa) (&(__bfa)->modules.sfp)
#define BFA_MEM_SFP_DMA(__bfa) (&(BFA_SFP_MOD(__bfa)->sfp_dma))
u32 bfa_sfp_meminfo(void);
void bfa_sfp_attach(struct bfa_sfp_s *sfp, struct bfa_ioc_s *ioc,
void *dev, struct bfa_trc_mod_s *trcmod);
void bfa_sfp_memclaim(struct bfa_sfp_s *diag, u8 *dm_kva, u64 dm_pa);
void bfa_sfp_intr(void *bfaarg, struct bfi_mbmsg_s *msg);
bfa_status_t bfa_sfp_show(struct bfa_sfp_s *sfp, struct sfp_mem_s *sfpmem,
bfa_cb_sfp_t cbfn, void *cbarg);
bfa_status_t bfa_sfp_media(struct bfa_sfp_s *sfp,
enum bfa_defs_sfp_media_e *media,
bfa_cb_sfp_t cbfn, void *cbarg);
bfa_status_t bfa_sfp_speed(struct bfa_sfp_s *sfp,
enum bfa_port_speed portspeed,
bfa_cb_sfp_t cbfn, void *cbarg);
#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
#define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id)
#define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva)
......
......@@ -39,6 +39,7 @@ struct bfa_modules_s {
struct bfa_port_s port; /* Physical port module */
struct bfa_ablk_s ablk; /* ASIC block config module */
struct bfa_cee_s cee; /* CEE Module */
struct bfa_sfp_s sfp; /* SFP module */
};
/*
......
......@@ -1066,6 +1066,49 @@ bfad_iocmd_cee_reset_stats(struct bfad_s *bfad, void *cmd)
return 0;
}
int
bfad_iocmd_sfp_media(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_sfp_media_s *iocmd = (struct bfa_bsg_sfp_media_s *)cmd;
struct bfad_hal_comp fcomp;
unsigned long flags;
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_sfp_media(BFA_SFP_MOD(&bfad->bfa), &iocmd->media,
bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
bfa_trc(bfad, iocmd->status);
if (iocmd->status != BFA_STATUS_SFP_NOT_READY)
goto out;
wait_for_completion(&fcomp.comp);
iocmd->status = fcomp.status;
out:
return 0;
}
int
bfad_iocmd_sfp_speed(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_sfp_speed_s *iocmd = (struct bfa_bsg_sfp_speed_s *)cmd;
struct bfad_hal_comp fcomp;
unsigned long flags;
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_sfp_speed(BFA_SFP_MOD(&bfad->bfa), iocmd->speed,
bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
bfa_trc(bfad, iocmd->status);
if (iocmd->status != BFA_STATUS_SFP_NOT_READY)
goto out;
wait_for_completion(&fcomp.comp);
iocmd->status = fcomp.status;
out:
return 0;
}
static int
bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
unsigned int payload_len)
......@@ -1194,6 +1237,12 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
case IOCMD_CEE_RESET_STATS:
rc = bfad_iocmd_cee_reset_stats(bfad, iocmd);
break;
case IOCMD_SFP_MEDIA:
rc = bfad_iocmd_sfp_media(bfad, iocmd);
break;
case IOCMD_SFP_SPEED:
rc = bfad_iocmd_sfp_speed(bfad, iocmd);
break;
default:
rc = EINVAL;
break;
......
......@@ -65,6 +65,8 @@ enum {
IOCMD_CEE_GET_ATTR,
IOCMD_CEE_GET_STATS,
IOCMD_CEE_RESET_STATS,
IOCMD_SFP_MEDIA,
IOCMD_SFP_SPEED,
};
struct bfa_bsg_gen_s {
......@@ -320,6 +322,20 @@ struct bfa_bsg_cee_stats_s {
u64 buf_ptr;
};
struct bfa_bsg_sfp_media_s {
bfa_status_t status;
u16 bfad_num;
u16 rsvd;
enum bfa_defs_sfp_media_e media;
};
struct bfa_bsg_sfp_speed_s {
bfa_status_t status;
u16 bfad_num;
u16 rsvd;
enum bfa_port_speed speed;
};
struct bfa_bsg_fcpt_s {
bfa_status_t status;
u16 vf_id;
......
......@@ -206,6 +206,7 @@ enum bfi_mclass {
BFI_MC_IOIM_IOCOM = 17, /* good IO completion */
BFI_MC_TSKIM = 18, /* Initiator Task management */
BFI_MC_PORT = 21, /* Physical port */
BFI_MC_SFP = 22, /* SFP module */
BFI_MC_MAX = 32
};
......@@ -765,6 +766,54 @@ union bfi_cee_i2h_msg_u {
struct bfi_cee_stats_rsp_s stats_rsp;
};
/*
* SFP related
*/
enum bfi_sfp_h2i_e {
BFI_SFP_H2I_SHOW = 1,
BFI_SFP_H2I_SCN = 2,
};
enum bfi_sfp_i2h_e {
BFI_SFP_I2H_SHOW = BFA_I2HM(BFI_SFP_H2I_SHOW),
BFI_SFP_I2H_SCN = BFA_I2HM(BFI_SFP_H2I_SCN),
};
/*
* SFP state
*/
enum bfa_sfp_stat_e {
BFA_SFP_STATE_INIT = 0, /* SFP state is uninit */
BFA_SFP_STATE_REMOVED = 1, /* SFP is removed */
BFA_SFP_STATE_INSERTED = 2, /* SFP is inserted */
BFA_SFP_STATE_VALID = 3, /* SFP is valid */
BFA_SFP_STATE_UNSUPPORT = 4, /* SFP is unsupport */
BFA_SFP_STATE_FAILED = 5, /* SFP i2c read fail */
};
/*
* SFP memory access type
*/
enum bfi_sfp_mem_e {
BFI_SFP_MEM_ALL = 0x1, /* access all data field */
BFI_SFP_MEM_DIAGEXT = 0x2, /* access diag ext data field only */
};
struct bfi_sfp_req_s {
struct bfi_mhdr_s mh;
u8 memtype;
u8 rsvd[3];
struct bfi_alen_s alen;
};
struct bfi_sfp_rsp_s {
struct bfi_mhdr_s mh;
u8 status;
u8 state;
u8 rsvd[2];
};
#pragma pack()
#endif /* __BFI_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment