[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: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
Родитель
148d61039c
Коммит
51e569aa1f
|
@ -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__ */
|
||||
|
|
|
@ -3364,3 +3364,460 @@ bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg)
|
|||
|
||||
return BFA_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* SFP module specific
|
||||
*/
|
||||
|
||||
/* forward declarations */
|
||||
static void bfa_sfp_getdata_send(struct bfa_sfp_s *sfp);
|
||||
static void bfa_sfp_media_get(struct bfa_sfp_s *sfp);
|
||||
static bfa_status_t bfa_sfp_speed_valid(struct bfa_sfp_s *sfp,
|
||||
enum bfa_port_speed portspeed);
|
||||
|
||||
static void
|
||||
bfa_cb_sfp_show(struct bfa_sfp_s *sfp)
|
||||
{
|
||||
bfa_trc(sfp, sfp->lock);
|
||||
if (sfp->cbfn)
|
||||
sfp->cbfn(sfp->cbarg, sfp->status);
|
||||
sfp->lock = 0;
|
||||
sfp->cbfn = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
bfa_cb_sfp_state_query(struct bfa_sfp_s *sfp)
|
||||
{
|
||||
bfa_trc(sfp, sfp->portspeed);
|
||||
if (sfp->media) {
|
||||
bfa_sfp_media_get(sfp);
|
||||
if (sfp->state_query_cbfn)
|
||||
sfp->state_query_cbfn(sfp->state_query_cbarg,
|
||||
sfp->status);
|
||||
sfp->media = NULL;
|
||||
}
|
||||
|
||||
if (sfp->portspeed) {
|
||||
sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed);
|
||||
if (sfp->state_query_cbfn)
|
||||
sfp->state_query_cbfn(sfp->state_query_cbarg,
|
||||
sfp->status);
|
||||
sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
|
||||
}
|
||||
|
||||
sfp->state_query_lock = 0;
|
||||
sfp->state_query_cbfn = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* IOC event handler.
|
||||
*/
|
||||
static void
|
||||
bfa_sfp_notify(void *sfp_arg, enum bfa_ioc_event_e event)
|
||||
{
|
||||
struct bfa_sfp_s *sfp = sfp_arg;
|
||||
|
||||
bfa_trc(sfp, event);
|
||||
bfa_trc(sfp, sfp->lock);
|
||||
bfa_trc(sfp, sfp->state_query_lock);
|
||||
|
||||
switch (event) {
|
||||
case BFA_IOC_E_DISABLED:
|
||||
case BFA_IOC_E_FAILED:
|
||||
if (sfp->lock) {
|
||||
sfp->status = BFA_STATUS_IOC_FAILURE;
|
||||
bfa_cb_sfp_show(sfp);
|
||||
}
|
||||
|
||||
if (sfp->state_query_lock) {
|
||||
sfp->status = BFA_STATUS_IOC_FAILURE;
|
||||
bfa_cb_sfp_state_query(sfp);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SFP get data send
|
||||
*/
|
||||
static void
|
||||
bfa_sfp_getdata_send(struct bfa_sfp_s *sfp)
|
||||
{
|
||||
struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
|
||||
|
||||
bfa_trc(sfp, req->memtype);
|
||||
|
||||
/* build host command */
|
||||
bfi_h2i_set(req->mh, BFI_MC_SFP, BFI_SFP_H2I_SHOW,
|
||||
bfa_ioc_portid(sfp->ioc));
|
||||
|
||||
/* send mbox cmd */
|
||||
bfa_ioc_mbox_queue(sfp->ioc, &sfp->mbcmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* SFP is valid, read sfp data
|
||||
*/
|
||||
static void
|
||||
bfa_sfp_getdata(struct bfa_sfp_s *sfp, enum bfi_sfp_mem_e memtype)
|
||||
{
|
||||
struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
|
||||
|
||||
WARN_ON(sfp->lock != 0);
|
||||
bfa_trc(sfp, sfp->state);
|
||||
|
||||
sfp->lock = 1;
|
||||
sfp->memtype = memtype;
|
||||
req->memtype = memtype;
|
||||
|
||||
/* Setup SG list */
|
||||
bfa_alen_set(&req->alen, sizeof(struct sfp_mem_s), sfp->dbuf_pa);
|
||||
|
||||
bfa_sfp_getdata_send(sfp);
|
||||
}
|
||||
|
||||
/*
|
||||
* SFP show complete
|
||||
*/
|
||||
static void
|
||||
bfa_sfp_show_comp(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg)
|
||||
{
|
||||
struct bfi_sfp_rsp_s *rsp = (struct bfi_sfp_rsp_s *) msg;
|
||||
|
||||
if (!sfp->lock) {
|
||||
/*
|
||||
* receiving response after ioc failure
|
||||
*/
|
||||
bfa_trc(sfp, sfp->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
bfa_trc(sfp, rsp->status);
|
||||
if (rsp->status == BFA_STATUS_OK) {
|
||||
sfp->data_valid = 1;
|
||||
if (sfp->state == BFA_SFP_STATE_VALID)
|
||||
sfp->status = BFA_STATUS_OK;
|
||||
else if (sfp->state == BFA_SFP_STATE_UNSUPPORT)
|
||||
sfp->status = BFA_STATUS_SFP_UNSUPP;
|
||||
else
|
||||
bfa_trc(sfp, sfp->state);
|
||||
} else {
|
||||
sfp->data_valid = 0;
|
||||
sfp->status = rsp->status;
|
||||
/* sfpshow shouldn't change sfp state */
|
||||
}
|
||||
|
||||
bfa_trc(sfp, sfp->memtype);
|
||||
if (sfp->memtype == BFI_SFP_MEM_DIAGEXT) {
|
||||
bfa_trc(sfp, sfp->data_valid);
|
||||
if (sfp->data_valid) {
|
||||
u32 size = sizeof(struct sfp_mem_s);
|
||||
u8 *des = (u8 *) &(sfp->sfpmem->srlid_base);
|
||||
memcpy(des, sfp->dbuf_kva, size);
|
||||
}
|
||||
/*
|
||||
* Queue completion callback.
|
||||
*/
|
||||
bfa_cb_sfp_show(sfp);
|
||||
} else
|
||||
sfp->lock = 0;
|
||||
|
||||
bfa_trc(sfp, sfp->state_query_lock);
|
||||
if (sfp->state_query_lock) {
|
||||
sfp->state = rsp->state;
|
||||
/* Complete callback */
|
||||
bfa_cb_sfp_state_query(sfp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SFP query fw sfp state
|
||||
*/
|
||||
static void
|
||||
bfa_sfp_state_query(struct bfa_sfp_s *sfp)
|
||||
{
|
||||
struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
|
||||
|
||||
/* Should not be doing query if not in _INIT state */
|
||||
WARN_ON(sfp->state != BFA_SFP_STATE_INIT);
|
||||
WARN_ON(sfp->state_query_lock != 0);
|
||||
bfa_trc(sfp, sfp->state);
|
||||
|
||||
sfp->state_query_lock = 1;
|
||||
req->memtype = 0;
|
||||
|
||||
if (!sfp->lock)
|
||||
bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
|
||||
}
|
||||
|
||||
static void
|
||||
bfa_sfp_media_get(struct bfa_sfp_s *sfp)
|
||||
{
|
||||
enum bfa_defs_sfp_media_e *media = sfp->media;
|
||||
|
||||
*media = BFA_SFP_MEDIA_UNKNOWN;
|
||||
|
||||
if (sfp->state == BFA_SFP_STATE_UNSUPPORT)
|
||||
*media = BFA_SFP_MEDIA_UNSUPPORT;
|
||||
else if (sfp->state == BFA_SFP_STATE_VALID) {
|
||||
union sfp_xcvr_e10g_code_u e10g;
|
||||
struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva;
|
||||
u16 xmtr_tech = (sfpmem->srlid_base.xcvr[4] & 0x3) << 7 |
|
||||
(sfpmem->srlid_base.xcvr[5] >> 1);
|
||||
|
||||
e10g.b = sfpmem->srlid_base.xcvr[0];
|
||||
bfa_trc(sfp, e10g.b);
|
||||
bfa_trc(sfp, xmtr_tech);
|
||||
/* check fc transmitter tech */
|
||||
if ((xmtr_tech & SFP_XMTR_TECH_CU) ||
|
||||
(xmtr_tech & SFP_XMTR_TECH_CP) ||
|
||||
(xmtr_tech & SFP_XMTR_TECH_CA))
|
||||
*media = BFA_SFP_MEDIA_CU;
|
||||
else if ((xmtr_tech & SFP_XMTR_TECH_EL_INTRA) ||
|
||||
(xmtr_tech & SFP_XMTR_TECH_EL_INTER))
|
||||
*media = BFA_SFP_MEDIA_EL;
|
||||
else if ((xmtr_tech & SFP_XMTR_TECH_LL) ||
|
||||
(xmtr_tech & SFP_XMTR_TECH_LC))
|
||||
*media = BFA_SFP_MEDIA_LW;
|
||||
else if ((xmtr_tech & SFP_XMTR_TECH_SL) ||
|
||||
(xmtr_tech & SFP_XMTR_TECH_SN) ||
|
||||
(xmtr_tech & SFP_XMTR_TECH_SA))
|
||||
*media = BFA_SFP_MEDIA_SW;
|
||||
/* Check 10G Ethernet Compilance code */
|
||||
else if (e10g.b & 0x10)
|
||||
*media = BFA_SFP_MEDIA_SW;
|
||||
else if (e10g.b & 0x60)
|
||||
*media = BFA_SFP_MEDIA_LW;
|
||||
else if (e10g.r.e10g_unall & 0x80)
|
||||
*media = BFA_SFP_MEDIA_UNKNOWN;
|
||||
else
|
||||
bfa_trc(sfp, 0);
|
||||
} else
|
||||
bfa_trc(sfp, sfp->state);
|
||||
}
|
||||
|
||||
static bfa_status_t
|
||||
bfa_sfp_speed_valid(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed)
|
||||
{
|
||||
struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva;
|
||||
struct sfp_xcvr_s *xcvr = (struct sfp_xcvr_s *) sfpmem->srlid_base.xcvr;
|
||||
union sfp_xcvr_fc3_code_u fc3 = xcvr->fc3;
|
||||
union sfp_xcvr_e10g_code_u e10g = xcvr->e10g;
|
||||
|
||||
if (portspeed == BFA_PORT_SPEED_10GBPS) {
|
||||
if (e10g.r.e10g_sr || e10g.r.e10g_lr)
|
||||
return BFA_STATUS_OK;
|
||||
else {
|
||||
bfa_trc(sfp, e10g.b);
|
||||
return BFA_STATUS_UNSUPP_SPEED;
|
||||
}
|
||||
}
|
||||
if (((portspeed & BFA_PORT_SPEED_16GBPS) && fc3.r.mb1600) ||
|
||||
((portspeed & BFA_PORT_SPEED_8GBPS) && fc3.r.mb800) ||
|
||||
((portspeed & BFA_PORT_SPEED_4GBPS) && fc3.r.mb400) ||
|
||||
((portspeed & BFA_PORT_SPEED_2GBPS) && fc3.r.mb200) ||
|
||||
((portspeed & BFA_PORT_SPEED_1GBPS) && fc3.r.mb100))
|
||||
return BFA_STATUS_OK;
|
||||
else {
|
||||
bfa_trc(sfp, portspeed);
|
||||
bfa_trc(sfp, fc3.b);
|
||||
bfa_trc(sfp, e10g.b);
|
||||
return BFA_STATUS_UNSUPP_SPEED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SFP hmbox handler
|
||||
*/
|
||||
void
|
||||
bfa_sfp_intr(void *sfparg, struct bfi_mbmsg_s *msg)
|
||||
{
|
||||
struct bfa_sfp_s *sfp = sfparg;
|
||||
|
||||
switch (msg->mh.msg_id) {
|
||||
case BFI_SFP_I2H_SHOW:
|
||||
bfa_sfp_show_comp(sfp, msg);
|
||||
break;
|
||||
|
||||
case BFI_SFP_I2H_SCN:
|
||||
bfa_trc(sfp, msg->mh.msg_id);
|
||||
break;
|
||||
|
||||
default:
|
||||
bfa_trc(sfp, msg->mh.msg_id);
|
||||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return DMA memory needed by sfp module.
|
||||
*/
|
||||
u32
|
||||
bfa_sfp_meminfo(void)
|
||||
{
|
||||
return BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach virtual and physical memory for SFP.
|
||||
*/
|
||||
void
|
||||
bfa_sfp_attach(struct bfa_sfp_s *sfp, struct bfa_ioc_s *ioc, void *dev,
|
||||
struct bfa_trc_mod_s *trcmod)
|
||||
{
|
||||
sfp->dev = dev;
|
||||
sfp->ioc = ioc;
|
||||
sfp->trcmod = trcmod;
|
||||
|
||||
sfp->cbfn = NULL;
|
||||
sfp->cbarg = NULL;
|
||||
sfp->sfpmem = NULL;
|
||||
sfp->lock = 0;
|
||||
sfp->data_valid = 0;
|
||||
sfp->state = BFA_SFP_STATE_INIT;
|
||||
sfp->state_query_lock = 0;
|
||||
sfp->state_query_cbfn = NULL;
|
||||
sfp->state_query_cbarg = NULL;
|
||||
sfp->media = NULL;
|
||||
sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
|
||||
sfp->is_elb = BFA_FALSE;
|
||||
|
||||
bfa_ioc_mbox_regisr(sfp->ioc, BFI_MC_SFP, bfa_sfp_intr, sfp);
|
||||
bfa_q_qe_init(&sfp->ioc_notify);
|
||||
bfa_ioc_notify_init(&sfp->ioc_notify, bfa_sfp_notify, sfp);
|
||||
list_add_tail(&sfp->ioc_notify.qe, &sfp->ioc->notify_q);
|
||||
}
|
||||
|
||||
/*
|
||||
* Claim Memory for SFP
|
||||
*/
|
||||
void
|
||||
bfa_sfp_memclaim(struct bfa_sfp_s *sfp, u8 *dm_kva, u64 dm_pa)
|
||||
{
|
||||
sfp->dbuf_kva = dm_kva;
|
||||
sfp->dbuf_pa = dm_pa;
|
||||
memset(sfp->dbuf_kva, 0, sizeof(struct sfp_mem_s));
|
||||
|
||||
dm_kva += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
|
||||
dm_pa += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show SFP eeprom content
|
||||
*
|
||||
* @param[in] sfp - bfa sfp module
|
||||
*
|
||||
* @param[out] sfpmem - sfp eeprom data
|
||||
*
|
||||
*/
|
||||
bfa_status_t
|
||||
bfa_sfp_show(struct bfa_sfp_s *sfp, struct sfp_mem_s *sfpmem,
|
||||
bfa_cb_sfp_t cbfn, void *cbarg)
|
||||
{
|
||||
|
||||
if (!bfa_ioc_is_operational(sfp->ioc)) {
|
||||
bfa_trc(sfp, 0);
|
||||
return BFA_STATUS_IOC_NON_OP;
|
||||
}
|
||||
|
||||
if (sfp->lock) {
|
||||
bfa_trc(sfp, 0);
|
||||
return BFA_STATUS_DEVBUSY;
|
||||
}
|
||||
|
||||
sfp->cbfn = cbfn;
|
||||
sfp->cbarg = cbarg;
|
||||
sfp->sfpmem = sfpmem;
|
||||
|
||||
bfa_sfp_getdata(sfp, BFI_SFP_MEM_DIAGEXT);
|
||||
return BFA_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return SFP Media type
|
||||
*
|
||||
* @param[in] sfp - bfa sfp module
|
||||
*
|
||||
* @param[out] media - port speed from user
|
||||
*
|
||||
*/
|
||||
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)
|
||||
{
|
||||
if (!bfa_ioc_is_operational(sfp->ioc)) {
|
||||
bfa_trc(sfp, 0);
|
||||
return BFA_STATUS_IOC_NON_OP;
|
||||
}
|
||||
|
||||
sfp->media = media;
|
||||
if (sfp->state == BFA_SFP_STATE_INIT) {
|
||||
if (sfp->state_query_lock) {
|
||||
bfa_trc(sfp, 0);
|
||||
return BFA_STATUS_DEVBUSY;
|
||||
} else {
|
||||
sfp->state_query_cbfn = cbfn;
|
||||
sfp->state_query_cbarg = cbarg;
|
||||
bfa_sfp_state_query(sfp);
|
||||
return BFA_STATUS_SFP_NOT_READY;
|
||||
}
|
||||
}
|
||||
|
||||
bfa_sfp_media_get(sfp);
|
||||
return BFA_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if user set port speed is allowed by the SFP
|
||||
*
|
||||
* @param[in] sfp - bfa sfp module
|
||||
* @param[in] portspeed - port speed from user
|
||||
*
|
||||
*/
|
||||
bfa_status_t
|
||||
bfa_sfp_speed(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed,
|
||||
bfa_cb_sfp_t cbfn, void *cbarg)
|
||||
{
|
||||
WARN_ON(portspeed == BFA_PORT_SPEED_UNKNOWN);
|
||||
|
||||
if (!bfa_ioc_is_operational(sfp->ioc))
|
||||
return BFA_STATUS_IOC_NON_OP;
|
||||
|
||||
/* For Mezz card, all speed is allowed */
|
||||
if (bfa_mfg_is_mezz(sfp->ioc->attr->card_type))
|
||||
return BFA_STATUS_OK;
|
||||
|
||||
/* Check SFP state */
|
||||
sfp->portspeed = portspeed;
|
||||
if (sfp->state == BFA_SFP_STATE_INIT) {
|
||||
if (sfp->state_query_lock) {
|
||||
bfa_trc(sfp, 0);
|
||||
return BFA_STATUS_DEVBUSY;
|
||||
} else {
|
||||
sfp->state_query_cbfn = cbfn;
|
||||
sfp->state_query_cbarg = cbarg;
|
||||
bfa_sfp_state_query(sfp);
|
||||
return BFA_STATUS_SFP_NOT_READY;
|
||||
}
|
||||
}
|
||||
|
||||
if (sfp->state == BFA_SFP_STATE_REMOVED ||
|
||||
sfp->state == BFA_SFP_STATE_FAILED) {
|
||||
bfa_trc(sfp, sfp->state);
|
||||
return BFA_STATUS_NO_SFP_DEV;
|
||||
}
|
||||
|
||||
if (sfp->state == BFA_SFP_STATE_INSERTED) {
|
||||
bfa_trc(sfp, sfp->state);
|
||||
return BFA_STATUS_DEVBUSY; /* sfp is reading data */
|
||||
}
|
||||
|
||||
/* For eloopback, all speed is allowed */
|
||||
if (sfp->is_elb)
|
||||
return BFA_STATUS_OK;
|
||||
|
||||
return bfa_sfp_speed_valid(sfp, portspeed);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче