Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Linux network driver for QLogic BR-series Converged Network Adapter.
0004  */
0005 /*
0006  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
0007  * Copyright (c) 2014-2015 QLogic Corporation
0008  * All rights reserved
0009  * www.qlogic.com
0010  */
0011 
0012 #include "bfa_cee.h"
0013 #include "bfi_cna.h"
0014 #include "bfa_ioc.h"
0015 
0016 static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg);
0017 static void bfa_cee_format_cee_cfg(void *buffer);
0018 
0019 static void
0020 bfa_cee_format_cee_cfg(void *buffer)
0021 {
0022     struct bfa_cee_attr *cee_cfg = buffer;
0023     bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote);
0024 }
0025 
0026 static void
0027 bfa_cee_stats_swap(struct bfa_cee_stats *stats)
0028 {
0029     u32 *buffer = (u32 *)stats;
0030     int i;
0031 
0032     for (i = 0; i < (sizeof(struct bfa_cee_stats) / sizeof(u32));
0033         i++) {
0034         buffer[i] = ntohl(buffer[i]);
0035     }
0036 }
0037 
0038 static void
0039 bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg)
0040 {
0041     lldp_cfg->time_to_live =
0042             ntohs(lldp_cfg->time_to_live);
0043     lldp_cfg->enabled_system_cap =
0044             ntohs(lldp_cfg->enabled_system_cap);
0045 }
0046 
0047 /**
0048  * bfa_cee_attr_meminfo - Returns the size of the DMA memory needed by CEE attributes
0049  */
0050 static u32
0051 bfa_cee_attr_meminfo(void)
0052 {
0053     return roundup(sizeof(struct bfa_cee_attr), BFA_DMA_ALIGN_SZ);
0054 }
0055 /**
0056  * bfa_cee_stats_meminfo - Returns the size of the DMA memory needed by CEE stats
0057  */
0058 static u32
0059 bfa_cee_stats_meminfo(void)
0060 {
0061     return roundup(sizeof(struct bfa_cee_stats), BFA_DMA_ALIGN_SZ);
0062 }
0063 
0064 /**
0065  * bfa_cee_get_attr_isr - CEE ISR for get-attributes responses from f/w
0066  *
0067  * @cee: Pointer to the CEE module
0068  * @status: Return status from the f/w
0069  */
0070 static void
0071 bfa_cee_get_attr_isr(struct bfa_cee *cee, enum bfa_status status)
0072 {
0073     cee->get_attr_status = status;
0074     if (status == BFA_STATUS_OK) {
0075         memcpy(cee->attr, cee->attr_dma.kva,
0076             sizeof(struct bfa_cee_attr));
0077         bfa_cee_format_cee_cfg(cee->attr);
0078     }
0079     cee->get_attr_pending = false;
0080     if (cee->cbfn.get_attr_cbfn)
0081         cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
0082 }
0083 
0084 /**
0085  * bfa_cee_get_stats_isr - CEE ISR for get-stats responses from f/w
0086  *
0087  * @cee: Pointer to the CEE module
0088  * @status: Return status from the f/w
0089  */
0090 static void
0091 bfa_cee_get_stats_isr(struct bfa_cee *cee, enum bfa_status status)
0092 {
0093     cee->get_stats_status = status;
0094     if (status == BFA_STATUS_OK) {
0095         memcpy(cee->stats, cee->stats_dma.kva,
0096             sizeof(struct bfa_cee_stats));
0097         bfa_cee_stats_swap(cee->stats);
0098     }
0099     cee->get_stats_pending = false;
0100     if (cee->cbfn.get_stats_cbfn)
0101         cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
0102 }
0103 
0104 /**
0105  * bfa_cee_reset_stats_isr - CEE ISR for reset-stats responses from f/w
0106  *
0107  * @cee: Input Pointer to the CEE module
0108  * @status: Return status from the f/w
0109  */
0110 static void
0111 bfa_cee_reset_stats_isr(struct bfa_cee *cee, enum bfa_status status)
0112 {
0113     cee->reset_stats_status = status;
0114     cee->reset_stats_pending = false;
0115     if (cee->cbfn.reset_stats_cbfn)
0116         cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
0117 }
0118 /**
0119  * bfa_nw_cee_meminfo - Returns the size of the DMA memory needed by CEE module
0120  */
0121 u32
0122 bfa_nw_cee_meminfo(void)
0123 {
0124     return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo();
0125 }
0126 
0127 /**
0128  * bfa_nw_cee_mem_claim - Initialized CEE DMA Memory
0129  *
0130  * @cee: CEE module pointer
0131  * @dma_kva: Kernel Virtual Address of CEE DMA Memory
0132  * @dma_pa:  Physical Address of CEE DMA Memory
0133  */
0134 void
0135 bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa)
0136 {
0137     cee->attr_dma.kva = dma_kva;
0138     cee->attr_dma.pa = dma_pa;
0139     cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo();
0140     cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo();
0141     cee->attr = (struct bfa_cee_attr *) dma_kva;
0142     cee->stats = (struct bfa_cee_stats *)
0143         (dma_kva + bfa_cee_attr_meminfo());
0144 }
0145 
0146 /**
0147  * bfa_nw_cee_get_attr - Send the request to the f/w to fetch CEE attributes.
0148  *
0149  * @cee: Pointer to the CEE module data structure.
0150  * @attr: attribute requested
0151  * @cbfn: function pointer
0152  * @cbarg: function pointer arguments
0153  *
0154  * Return: status
0155  */
0156 enum bfa_status
0157 bfa_nw_cee_get_attr(struct bfa_cee *cee, struct bfa_cee_attr *attr,
0158             bfa_cee_get_attr_cbfn_t cbfn, void *cbarg)
0159 {
0160     struct bfi_cee_get_req *cmd;
0161 
0162     BUG_ON(!((cee != NULL) && (cee->ioc != NULL)));
0163     if (!bfa_nw_ioc_is_operational(cee->ioc))
0164         return BFA_STATUS_IOC_FAILURE;
0165 
0166     if (cee->get_attr_pending)
0167         return  BFA_STATUS_DEVBUSY;
0168 
0169     cee->get_attr_pending = true;
0170     cmd = (struct bfi_cee_get_req *) cee->get_cfg_mb.msg;
0171     cee->attr = attr;
0172     cee->cbfn.get_attr_cbfn = cbfn;
0173     cee->cbfn.get_attr_cbarg = cbarg;
0174     bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ,
0175             bfa_ioc_portid(cee->ioc));
0176     bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa);
0177     bfa_nw_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb, NULL, NULL);
0178 
0179     return BFA_STATUS_OK;
0180 }
0181 
0182 /**
0183  * bfa_cee_isr - Handles Mail-box interrupts for CEE module.
0184  * @cbarg: argument passed containing pointer to the CEE module data structure.
0185  * @m: message pointer
0186  */
0187 
0188 static void
0189 bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m)
0190 {
0191     union bfi_cee_i2h_msg_u *msg;
0192     struct bfi_cee_get_rsp *get_rsp;
0193     struct bfa_cee *cee = (struct bfa_cee *) cbarg;
0194     msg = (union bfi_cee_i2h_msg_u *) m;
0195     get_rsp = (struct bfi_cee_get_rsp *) m;
0196     switch (msg->mh.msg_id) {
0197     case BFI_CEE_I2H_GET_CFG_RSP:
0198         bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
0199         break;
0200     case BFI_CEE_I2H_GET_STATS_RSP:
0201         bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
0202         break;
0203     case BFI_CEE_I2H_RESET_STATS_RSP:
0204         bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
0205         break;
0206     default:
0207         BUG_ON(1);
0208     }
0209 }
0210 
0211 /**
0212  * bfa_cee_notify - CEE module heart-beat failure handler.
0213  *
0214  * @arg: argument passed containing pointer to the CEE module data structure.
0215  * @event: IOC event type
0216  */
0217 
0218 static void
0219 bfa_cee_notify(void *arg, enum bfa_ioc_event event)
0220 {
0221     struct bfa_cee *cee;
0222     cee = (struct bfa_cee *) arg;
0223 
0224     switch (event) {
0225     case BFA_IOC_E_DISABLED:
0226     case BFA_IOC_E_FAILED:
0227         if (cee->get_attr_pending) {
0228             cee->get_attr_status = BFA_STATUS_FAILED;
0229             cee->get_attr_pending  = false;
0230             if (cee->cbfn.get_attr_cbfn) {
0231                 cee->cbfn.get_attr_cbfn(
0232                     cee->cbfn.get_attr_cbarg,
0233                     BFA_STATUS_FAILED);
0234             }
0235         }
0236         if (cee->get_stats_pending) {
0237             cee->get_stats_status = BFA_STATUS_FAILED;
0238             cee->get_stats_pending  = false;
0239             if (cee->cbfn.get_stats_cbfn) {
0240                 cee->cbfn.get_stats_cbfn(
0241                     cee->cbfn.get_stats_cbarg,
0242                     BFA_STATUS_FAILED);
0243             }
0244         }
0245         if (cee->reset_stats_pending) {
0246             cee->reset_stats_status = BFA_STATUS_FAILED;
0247             cee->reset_stats_pending  = false;
0248             if (cee->cbfn.reset_stats_cbfn) {
0249                 cee->cbfn.reset_stats_cbfn(
0250                     cee->cbfn.reset_stats_cbarg,
0251                     BFA_STATUS_FAILED);
0252             }
0253         }
0254         break;
0255 
0256     default:
0257         break;
0258     }
0259 }
0260 
0261 /**
0262  * bfa_nw_cee_attach - CEE module-attach API
0263  *
0264  * @cee: Pointer to the CEE module data structure
0265  * @ioc: Pointer to the ioc module data structure
0266  * @dev: Pointer to the device driver module data structure.
0267  *       The device driver specific mbox ISR functions have
0268  *       this pointer as one of the parameters.
0269  */
0270 void
0271 bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc,
0272         void *dev)
0273 {
0274     BUG_ON(!(cee != NULL));
0275     cee->dev = dev;
0276     cee->ioc = ioc;
0277 
0278     bfa_nw_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
0279     bfa_ioc_notify_init(&cee->ioc_notify, bfa_cee_notify, cee);
0280     bfa_nw_ioc_notify_register(cee->ioc, &cee->ioc_notify);
0281 }