Commit 3350d98d authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley

[SCSI] bfa: Added support to query PHY.

- Added PHY sub-module.
- Implemented interface to obtain stats and to
  read/update the fw from the PHY module.
Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 3d7fc66d
...@@ -154,6 +154,16 @@ bfa_com_diag_attach(struct bfa_s *bfa) ...@@ -154,6 +154,16 @@ bfa_com_diag_attach(struct bfa_s *bfa)
bfa_diag_memclaim(diag, diag_dma->kva_curp, diag_dma->dma_curp); bfa_diag_memclaim(diag, diag_dma->kva_curp, diag_dma->dma_curp);
} }
static void
bfa_com_phy_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)
{
struct bfa_phy_s *phy = BFA_PHY(bfa);
struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa);
bfa_phy_attach(phy, &bfa->ioc, bfa, bfa->trcmod, mincfg);
bfa_phy_memclaim(phy, phy_dma->kva_curp, phy_dma->dma_curp, mincfg);
}
/* /*
* BFA IOC FC related definitions * BFA IOC FC related definitions
*/ */
...@@ -1395,6 +1405,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, ...@@ -1395,6 +1405,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa); struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa);
struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa); struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa);
struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa); struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa);
struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa);
WARN_ON((cfg == NULL) || (meminfo == NULL)); WARN_ON((cfg == NULL) || (meminfo == NULL));
...@@ -1417,6 +1428,8 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, ...@@ -1417,6 +1428,8 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
bfa_mem_dma_setup(meminfo, flash_dma, bfa_mem_dma_setup(meminfo, flash_dma,
bfa_flash_meminfo(cfg->drvcfg.min_cfg)); bfa_flash_meminfo(cfg->drvcfg.min_cfg));
bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo()); bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo());
bfa_mem_dma_setup(meminfo, phy_dma,
bfa_phy_meminfo(cfg->drvcfg.min_cfg));
} }
/* /*
...@@ -1488,6 +1501,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ...@@ -1488,6 +1501,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa_com_sfp_attach(bfa); bfa_com_sfp_attach(bfa);
bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg); bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg);
bfa_com_diag_attach(bfa); bfa_com_diag_attach(bfa);
bfa_com_phy_attach(bfa, cfg->drvcfg.min_cfg);
} }
/* /*
......
...@@ -170,6 +170,7 @@ enum bfa_status { ...@@ -170,6 +170,7 @@ enum bfa_status {
BFA_STATUS_TRUNK_DISABLED = 165, /* Trunking is disabled on BFA_STATUS_TRUNK_DISABLED = 165, /* Trunking is disabled on
* the adapter */ * the adapter */
BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */ BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */
BFA_STATUS_PHY_NOT_PRESENT = 183, /* PHY module not present */
BFA_STATUS_FEATURE_NOT_SUPPORTED = 192, /* Feature not supported */ BFA_STATUS_FEATURE_NOT_SUPPORTED = 192, /* Feature not supported */
BFA_STATUS_FAA_ENABLED = 197, /* FAA is already enabled */ BFA_STATUS_FAA_ENABLED = 197, /* FAA is already enabled */
BFA_STATUS_FAA_DISABLED = 198, /* FAA is already disabled */ BFA_STATUS_FAA_DISABLED = 198, /* FAA is already disabled */
...@@ -939,6 +940,42 @@ struct bfa_diag_loopback_s { ...@@ -939,6 +940,42 @@ struct bfa_diag_loopback_s {
u8 rsvd[2]; u8 rsvd[2];
}; };
/*
* PHY module specific
*/
enum bfa_phy_status_e {
BFA_PHY_STATUS_GOOD = 0, /* phy is good */
BFA_PHY_STATUS_NOT_PRESENT = 1, /* phy does not exist */
BFA_PHY_STATUS_BAD = 2, /* phy is bad */
};
/*
* phy attributes for phy query
*/
struct bfa_phy_attr_s {
u32 status; /* phy present/absent status */
u32 length; /* firmware length */
u32 fw_ver; /* firmware version */
u32 an_status; /* AN status */
u32 pma_pmd_status; /* PMA/PMD link status */
u32 pma_pmd_signal; /* PMA/PMD signal detect */
u32 pcs_status; /* PCS link status */
};
/*
* phy stats
*/
struct bfa_phy_stats_s {
u32 status; /* phy stats status */
u32 link_breaks; /* Num of link breaks after linkup */
u32 pma_pmd_fault; /* NPMA/PMD fault */
u32 pcs_fault; /* PCS fault */
u32 speed_neg; /* Num of speed negotiation */
u32 tx_eq_training; /* Num of TX EQ training */
u32 tx_eq_timeout; /* Num of TX EQ timeout */
u32 crc_error; /* Num of CRC errors */
};
#pragma pack() #pragma pack()
#endif /* __BFA_DEFS_H__ */ #endif /* __BFA_DEFS_H__ */
This diff is collapsed.
...@@ -632,6 +632,60 @@ bfa_status_t bfa_diag_beacon_port(struct bfa_diag_s *diag, ...@@ -632,6 +632,60 @@ bfa_status_t bfa_diag_beacon_port(struct bfa_diag_s *diag,
bfa_boolean_t beacon, bfa_boolean_t link_e2e_beacon, bfa_boolean_t beacon, bfa_boolean_t link_e2e_beacon,
u32 sec); u32 sec);
/*
* PHY module specific
*/
typedef void (*bfa_cb_phy_t) (void *cbarg, bfa_status_t status);
struct bfa_phy_s {
struct bfa_ioc_s *ioc; /* back pointer to ioc */
struct bfa_trc_mod_s *trcmod; /* trace module */
u8 instance; /* port instance */
u8 op_busy; /* operation busy flag */
u8 rsv[2];
u32 residue; /* residual length */
u32 offset; /* offset */
bfa_status_t status; /* status */
u8 *dbuf_kva; /* dma buf virtual address */
u64 dbuf_pa; /* dma buf physical address */
struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
bfa_cb_phy_t cbfn; /* user callback function */
void *cbarg; /* user callback arg */
u8 *ubuf; /* user supplied buffer */
struct bfa_cb_qe_s hcb_qe; /* comp: BFA callback qelem */
u32 addr_off; /* phy address offset */
struct bfa_mbox_cmd_s mb; /* mailbox */
struct bfa_ioc_notify_s ioc_notify; /* ioc event notify */
struct bfa_mem_dma_s phy_dma;
};
#define BFA_PHY(__bfa) (&(__bfa)->modules.phy)
#define BFA_MEM_PHY_DMA(__bfa) (&(BFA_PHY(__bfa)->phy_dma))
bfa_boolean_t bfa_phy_busy(struct bfa_ioc_s *ioc);
bfa_status_t bfa_phy_get_attr(struct bfa_phy_s *phy, u8 instance,
struct bfa_phy_attr_s *attr,
bfa_cb_phy_t cbfn, void *cbarg);
bfa_status_t bfa_phy_get_stats(struct bfa_phy_s *phy, u8 instance,
struct bfa_phy_stats_s *stats,
bfa_cb_phy_t cbfn, void *cbarg);
bfa_status_t bfa_phy_update(struct bfa_phy_s *phy, u8 instance,
void *buf, u32 len, u32 offset,
bfa_cb_phy_t cbfn, void *cbarg);
bfa_status_t bfa_phy_read(struct bfa_phy_s *phy, u8 instance,
void *buf, u32 len, u32 offset,
bfa_cb_phy_t cbfn, void *cbarg);
u32 bfa_phy_meminfo(bfa_boolean_t mincfg);
void bfa_phy_attach(struct bfa_phy_s *phy, struct bfa_ioc_s *ioc,
void *dev, struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg);
void bfa_phy_memclaim(struct bfa_phy_s *phy,
u8 *dm_kva, u64 dm_pa, bfa_boolean_t mincfg);
void bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg);
/*
* IOC specfic macros
*/
#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
#define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id) #define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id)
#define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva) #define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva)
......
...@@ -43,6 +43,7 @@ struct bfa_modules_s { ...@@ -43,6 +43,7 @@ struct bfa_modules_s {
struct bfa_sfp_s sfp; /* SFP module */ struct bfa_sfp_s sfp; /* SFP module */
struct bfa_flash_s flash; /* flash module */ struct bfa_flash_s flash; /* flash module */
struct bfa_diag_s diag_mod; /* diagnostics module */ struct bfa_diag_s diag_mod; /* diagnostics module */
struct bfa_phy_s phy; /* phy module */
}; };
/* /*
......
...@@ -469,6 +469,7 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, ...@@ -469,6 +469,7 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
port->pbc_disabled = BFA_FALSE; port->pbc_disabled = BFA_FALSE;
bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port); bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
bfa_q_qe_init(&port->ioc_notify);
bfa_ioc_notify_init(&port->ioc_notify, bfa_port_notify, port); bfa_ioc_notify_init(&port->ioc_notify, bfa_port_notify, port);
list_add_tail(&port->ioc_notify.qe, &port->ioc->notify_q); list_add_tail(&port->ioc_notify.qe, &port->ioc->notify_q);
......
...@@ -1393,6 +1393,110 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) ...@@ -1393,6 +1393,110 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd)
return 0; return 0;
} }
int
bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_phy_attr_s *iocmd =
(struct bfa_bsg_phy_attr_s *)cmd;
struct bfad_hal_comp fcomp;
unsigned long flags;
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_phy_get_attr(BFA_PHY(&bfad->bfa), iocmd->instance,
&iocmd->attr, bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (iocmd->status != BFA_STATUS_OK)
goto out;
wait_for_completion(&fcomp.comp);
iocmd->status = fcomp.status;
out:
return 0;
}
int
bfad_iocmd_phy_get_stats(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_phy_stats_s *iocmd =
(struct bfa_bsg_phy_stats_s *)cmd;
struct bfad_hal_comp fcomp;
unsigned long flags;
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_phy_get_stats(BFA_PHY(&bfad->bfa), iocmd->instance,
&iocmd->stats, bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (iocmd->status != BFA_STATUS_OK)
goto out;
wait_for_completion(&fcomp.comp);
iocmd->status = fcomp.status;
out:
return 0;
}
int
bfad_iocmd_phy_read(struct bfad_s *bfad, void *cmd, unsigned int payload_len)
{
struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd;
struct bfad_hal_comp fcomp;
void *iocmd_bufptr;
unsigned long flags;
if (bfad_chk_iocmd_sz(payload_len,
sizeof(struct bfa_bsg_phy_s),
iocmd->bufsz) != BFA_STATUS_OK) {
iocmd->status = BFA_STATUS_VERSION_FAIL;
return 0;
}
iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s);
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_phy_read(BFA_PHY(&bfad->bfa),
iocmd->instance, iocmd_bufptr, iocmd->bufsz,
0, bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (iocmd->status != BFA_STATUS_OK)
goto out;
wait_for_completion(&fcomp.comp);
iocmd->status = fcomp.status;
if (iocmd->status != BFA_STATUS_OK)
goto out;
out:
return 0;
}
int
bfad_iocmd_phy_update(struct bfad_s *bfad, void *cmd, unsigned int payload_len)
{
struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd;
void *iocmd_bufptr;
struct bfad_hal_comp fcomp;
unsigned long flags;
if (bfad_chk_iocmd_sz(payload_len,
sizeof(struct bfa_bsg_phy_s),
iocmd->bufsz) != BFA_STATUS_OK) {
iocmd->status = BFA_STATUS_VERSION_FAIL;
return 0;
}
iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s);
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_phy_update(BFA_PHY(&bfad->bfa),
iocmd->instance, iocmd_bufptr, iocmd->bufsz,
0, bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (iocmd->status != BFA_STATUS_OK)
goto out;
wait_for_completion(&fcomp.comp);
iocmd->status = fcomp.status;
out:
return 0;
}
static int static int
bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
unsigned int payload_len) unsigned int payload_len)
...@@ -1566,6 +1670,18 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, ...@@ -1566,6 +1670,18 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
case IOCMD_DIAG_LB_STAT: case IOCMD_DIAG_LB_STAT:
rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); rc = bfad_iocmd_diag_lb_stat(bfad, iocmd);
break; break;
case IOCMD_PHY_GET_ATTR:
rc = bfad_iocmd_phy_get_attr(bfad, iocmd);
break;
case IOCMD_PHY_GET_STATS:
rc = bfad_iocmd_phy_get_stats(bfad, iocmd);
break;
case IOCMD_PHY_UPDATE_FW:
rc = bfad_iocmd_phy_update(bfad, iocmd, payload_len);
break;
case IOCMD_PHY_READ_FW:
rc = bfad_iocmd_phy_read(bfad, iocmd, payload_len);
break;
default: default:
rc = EINVAL; rc = EINVAL;
break; break;
......
...@@ -80,6 +80,10 @@ enum { ...@@ -80,6 +80,10 @@ enum {
IOCMD_DIAG_LED, IOCMD_DIAG_LED,
IOCMD_DIAG_BEACON_LPORT, IOCMD_DIAG_BEACON_LPORT,
IOCMD_DIAG_LB_STAT, IOCMD_DIAG_LB_STAT,
IOCMD_PHY_GET_ATTR,
IOCMD_PHY_GET_STATS,
IOCMD_PHY_UPDATE_FW,
IOCMD_PHY_READ_FW,
}; };
struct bfa_bsg_gen_s { struct bfa_bsg_gen_s {
...@@ -440,6 +444,28 @@ struct bfa_bsg_diag_lb_stat_s { ...@@ -440,6 +444,28 @@ struct bfa_bsg_diag_lb_stat_s {
u16 rsvd; u16 rsvd;
}; };
struct bfa_bsg_phy_attr_s {
bfa_status_t status;
u16 bfad_num;
u16 instance;
struct bfa_phy_attr_s attr;
};
struct bfa_bsg_phy_s {
bfa_status_t status;
u16 bfad_num;
u16 instance;
u64 bufsz;
u64 buf_ptr;
};
struct bfa_bsg_phy_stats_s {
bfa_status_t status;
u16 bfad_num;
u16 instance;
struct bfa_phy_stats_s stats;
};
struct bfa_bsg_fcpt_s { struct bfa_bsg_fcpt_s {
bfa_status_t status; bfa_status_t status;
u16 vf_id; u16 vf_id;
......
...@@ -209,6 +209,7 @@ enum bfi_mclass { ...@@ -209,6 +209,7 @@ enum bfi_mclass {
BFI_MC_TSKIM = 18, /* Initiator Task management */ BFI_MC_TSKIM = 18, /* Initiator Task management */
BFI_MC_PORT = 21, /* Physical port */ BFI_MC_PORT = 21, /* Physical port */
BFI_MC_SFP = 22, /* SFP module */ BFI_MC_SFP = 22, /* SFP module */
BFI_MC_PHY = 25, /* External PHY message class */
BFI_MC_MAX = 32 BFI_MC_MAX = 32
}; };
...@@ -1030,6 +1031,102 @@ struct bfi_diag_qtest_req_s { ...@@ -1030,6 +1031,102 @@ struct bfi_diag_qtest_req_s {
}; };
#define bfi_diag_qtest_rsp_t struct bfi_diag_qtest_req_s #define bfi_diag_qtest_rsp_t struct bfi_diag_qtest_req_s
/*
* PHY module specific
*/
enum bfi_phy_h2i_msgs_e {
BFI_PHY_H2I_QUERY_REQ = 1,
BFI_PHY_H2I_STATS_REQ = 2,
BFI_PHY_H2I_WRITE_REQ = 3,
BFI_PHY_H2I_READ_REQ = 4,
};
enum bfi_phy_i2h_msgs_e {
BFI_PHY_I2H_QUERY_RSP = BFA_I2HM(1),
BFI_PHY_I2H_STATS_RSP = BFA_I2HM(2),
BFI_PHY_I2H_WRITE_RSP = BFA_I2HM(3),
BFI_PHY_I2H_READ_RSP = BFA_I2HM(4),
};
/*
* External PHY query request
*/
struct bfi_phy_query_req_s {
struct bfi_mhdr_s mh; /* Common msg header */
u8 instance;
u8 rsv[3];
struct bfi_alen_s alen;
};
/*
* External PHY stats request
*/
struct bfi_phy_stats_req_s {
struct bfi_mhdr_s mh; /* Common msg header */
u8 instance;
u8 rsv[3];
struct bfi_alen_s alen;
};
/*
* External PHY write request
*/
struct bfi_phy_write_req_s {
struct bfi_mhdr_s mh; /* Common msg header */
u8 instance;
u8 last;
u8 rsv[2];
u32 offset;
u32 length;
struct bfi_alen_s alen;
};
/*
* External PHY read request
*/
struct bfi_phy_read_req_s {
struct bfi_mhdr_s mh; /* Common msg header */
u8 instance;
u8 rsv[3];
u32 offset;
u32 length;
struct bfi_alen_s alen;
};
/*
* External PHY query response
*/
struct bfi_phy_query_rsp_s {
struct bfi_mhdr_s mh; /* Common msg header */
u32 status;
};
/*
* External PHY stats response
*/
struct bfi_phy_stats_rsp_s {
struct bfi_mhdr_s mh; /* Common msg header */
u32 status;
};
/*
* External PHY read response
*/
struct bfi_phy_read_rsp_s {
struct bfi_mhdr_s mh; /* Common msg header */
u32 status;
u32 length;
};
/*
* External PHY write response
*/
struct bfi_phy_write_rsp_s {
struct bfi_mhdr_s mh; /* Common msg header */
u32 status;
u32 length;
};
#pragma pack() #pragma pack()
#endif /* __BFI_H__ */ #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