linux/drivers/net/ethernet/brocade/bna/bfa_cee.c
<<
>>
Prefs
   1/*
   2 * Linux network driver for Brocade Converged Network Adapter.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms of the GNU General Public License (GPL) Version 2 as
   6 * published by the Free Software Foundation
   7 *
   8 * This program is distributed in the hope that it will be useful, but
   9 * WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11 * General Public License for more details.
  12 */
  13/*
  14 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
  15 * All rights reserved
  16 * www.brocade.com
  17 */
  18
  19#include "bfa_cee.h"
  20#include "bfi_cna.h"
  21#include "bfa_ioc.h"
  22
  23static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg);
  24static void bfa_cee_format_cee_cfg(void *buffer);
  25
  26static void
  27bfa_cee_format_cee_cfg(void *buffer)
  28{
  29        struct bfa_cee_attr *cee_cfg = buffer;
  30        bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote);
  31}
  32
  33static void
  34bfa_cee_stats_swap(struct bfa_cee_stats *stats)
  35{
  36        u32 *buffer = (u32 *)stats;
  37        int i;
  38
  39        for (i = 0; i < (sizeof(struct bfa_cee_stats) / sizeof(u32));
  40                i++) {
  41                buffer[i] = ntohl(buffer[i]);
  42        }
  43}
  44
  45static void
  46bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg)
  47{
  48        lldp_cfg->time_to_live =
  49                        ntohs(lldp_cfg->time_to_live);
  50        lldp_cfg->enabled_system_cap =
  51                        ntohs(lldp_cfg->enabled_system_cap);
  52}
  53
  54/**
  55 * bfa_cee_attr_meminfo - Returns the size of the DMA memory needed by CEE attributes
  56 */
  57static u32
  58bfa_cee_attr_meminfo(void)
  59{
  60        return roundup(sizeof(struct bfa_cee_attr), BFA_DMA_ALIGN_SZ);
  61}
  62/**
  63 * bfa_cee_stats_meminfo - Returns the size of the DMA memory needed by CEE stats
  64 */
  65static u32
  66bfa_cee_stats_meminfo(void)
  67{
  68        return roundup(sizeof(struct bfa_cee_stats), BFA_DMA_ALIGN_SZ);
  69}
  70
  71/**
  72 * bfa_cee_get_attr_isr - CEE ISR for get-attributes responses from f/w
  73 *
  74 * @cee: Pointer to the CEE module
  75 * @status: Return status from the f/w
  76 */
  77static void
  78bfa_cee_get_attr_isr(struct bfa_cee *cee, enum bfa_status status)
  79{
  80        cee->get_attr_status = status;
  81        if (status == BFA_STATUS_OK) {
  82                memcpy(cee->attr, cee->attr_dma.kva,
  83                    sizeof(struct bfa_cee_attr));
  84                bfa_cee_format_cee_cfg(cee->attr);
  85        }
  86        cee->get_attr_pending = false;
  87        if (cee->cbfn.get_attr_cbfn)
  88                cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
  89}
  90
  91/**
  92 * bfa_cee_get_attr_isr - CEE ISR for get-stats responses from f/w
  93 *
  94 * @cee: Pointer to the CEE module
  95 * @status: Return status from the f/w
  96 */
  97static void
  98bfa_cee_get_stats_isr(struct bfa_cee *cee, enum bfa_status status)
  99{
 100        cee->get_stats_status = status;
 101        if (status == BFA_STATUS_OK) {
 102                memcpy(cee->stats, cee->stats_dma.kva,
 103                        sizeof(struct bfa_cee_stats));
 104                bfa_cee_stats_swap(cee->stats);
 105        }
 106        cee->get_stats_pending = false;
 107        if (cee->cbfn.get_stats_cbfn)
 108                cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
 109}
 110
 111/**
 112 * bfa_cee_get_attr_isr()
 113 *
 114 * @brief CEE ISR for reset-stats responses from f/w
 115 *
 116 * @param[in] cee - Pointer to the CEE module
 117 *            status - Return status from the f/w
 118 *
 119 * @return void
 120 */
 121static void
 122bfa_cee_reset_stats_isr(struct bfa_cee *cee, enum bfa_status status)
 123{
 124        cee->reset_stats_status = status;
 125        cee->reset_stats_pending = false;
 126        if (cee->cbfn.reset_stats_cbfn)
 127                cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
 128}
 129/**
 130 * bfa_nw_cee_meminfo - Returns the size of the DMA memory needed by CEE module
 131 */
 132u32
 133bfa_nw_cee_meminfo(void)
 134{
 135        return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo();
 136}
 137
 138/**
 139 * bfa_nw_cee_mem_claim - Initialized CEE DMA Memory
 140 *
 141 * @cee: CEE module pointer
 142 * @dma_kva: Kernel Virtual Address of CEE DMA Memory
 143 * @dma_pa:  Physical Address of CEE DMA Memory
 144 */
 145void
 146bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa)
 147{
 148        cee->attr_dma.kva = dma_kva;
 149        cee->attr_dma.pa = dma_pa;
 150        cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo();
 151        cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo();
 152        cee->attr = (struct bfa_cee_attr *) dma_kva;
 153        cee->stats = (struct bfa_cee_stats *)
 154                (dma_kva + bfa_cee_attr_meminfo());
 155}
 156
 157/**
 158 * bfa_cee_get_attr - Send the request to the f/w to fetch CEE attributes.
 159 *
 160 * @cee: Pointer to the CEE module data structure.
 161 *
 162 * Return: status
 163 */
 164enum bfa_status
 165bfa_nw_cee_get_attr(struct bfa_cee *cee, struct bfa_cee_attr *attr,
 166                    bfa_cee_get_attr_cbfn_t cbfn, void *cbarg)
 167{
 168        struct bfi_cee_get_req *cmd;
 169
 170        BUG_ON(!((cee != NULL) && (cee->ioc != NULL)));
 171        if (!bfa_nw_ioc_is_operational(cee->ioc))
 172                return BFA_STATUS_IOC_FAILURE;
 173
 174        if (cee->get_attr_pending)
 175                return  BFA_STATUS_DEVBUSY;
 176
 177        cee->get_attr_pending = true;
 178        cmd = (struct bfi_cee_get_req *) cee->get_cfg_mb.msg;
 179        cee->attr = attr;
 180        cee->cbfn.get_attr_cbfn = cbfn;
 181        cee->cbfn.get_attr_cbarg = cbarg;
 182        bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ,
 183                    bfa_ioc_portid(cee->ioc));
 184        bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa);
 185        bfa_nw_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb, NULL, NULL);
 186
 187        return BFA_STATUS_OK;
 188}
 189
 190/**
 191 * bfa_cee_isrs - Handles Mail-box interrupts for CEE module.
 192 */
 193
 194static void
 195bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m)
 196{
 197        union bfi_cee_i2h_msg_u *msg;
 198        struct bfi_cee_get_rsp *get_rsp;
 199        struct bfa_cee *cee = (struct bfa_cee *) cbarg;
 200        msg = (union bfi_cee_i2h_msg_u *) m;
 201        get_rsp = (struct bfi_cee_get_rsp *) m;
 202        switch (msg->mh.msg_id) {
 203        case BFI_CEE_I2H_GET_CFG_RSP:
 204                bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
 205                break;
 206        case BFI_CEE_I2H_GET_STATS_RSP:
 207                bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
 208                break;
 209        case BFI_CEE_I2H_RESET_STATS_RSP:
 210                bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
 211                break;
 212        default:
 213                BUG_ON(1);
 214        }
 215}
 216
 217/**
 218 * bfa_cee_notify - CEE module heart-beat failure handler.
 219 *
 220 * @event: IOC event type
 221 */
 222
 223static void
 224bfa_cee_notify(void *arg, enum bfa_ioc_event event)
 225{
 226        struct bfa_cee *cee;
 227        cee = (struct bfa_cee *) arg;
 228
 229        switch (event) {
 230        case BFA_IOC_E_DISABLED:
 231        case BFA_IOC_E_FAILED:
 232                if (cee->get_attr_pending) {
 233                        cee->get_attr_status = BFA_STATUS_FAILED;
 234                        cee->get_attr_pending  = false;
 235                        if (cee->cbfn.get_attr_cbfn) {
 236                                cee->cbfn.get_attr_cbfn(
 237                                        cee->cbfn.get_attr_cbarg,
 238                                        BFA_STATUS_FAILED);
 239                        }
 240                }
 241                if (cee->get_stats_pending) {
 242                        cee->get_stats_status = BFA_STATUS_FAILED;
 243                        cee->get_stats_pending  = false;
 244                        if (cee->cbfn.get_stats_cbfn) {
 245                                cee->cbfn.get_stats_cbfn(
 246                                        cee->cbfn.get_stats_cbarg,
 247                                        BFA_STATUS_FAILED);
 248                        }
 249                }
 250                if (cee->reset_stats_pending) {
 251                        cee->reset_stats_status = BFA_STATUS_FAILED;
 252                        cee->reset_stats_pending  = false;
 253                        if (cee->cbfn.reset_stats_cbfn) {
 254                                cee->cbfn.reset_stats_cbfn(
 255                                        cee->cbfn.reset_stats_cbarg,
 256                                        BFA_STATUS_FAILED);
 257                        }
 258                }
 259                break;
 260
 261        default:
 262                break;
 263        }
 264}
 265
 266/**
 267 * bfa_nw_cee_attach - CEE module-attach API
 268 *
 269 * @cee: Pointer to the CEE module data structure
 270 * @ioc: Pointer to the ioc module data structure
 271 * @dev: Pointer to the device driver module data structure.
 272 *       The device driver specific mbox ISR functions have
 273 *       this pointer as one of the parameters.
 274 */
 275void
 276bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc,
 277                void *dev)
 278{
 279        BUG_ON(!(cee != NULL));
 280        cee->dev = dev;
 281        cee->ioc = ioc;
 282
 283        bfa_nw_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
 284        bfa_q_qe_init(&cee->ioc_notify);
 285        bfa_ioc_notify_init(&cee->ioc_notify, bfa_cee_notify, cee);
 286        bfa_nw_ioc_notify_register(cee->ioc, &cee->ioc_notify);
 287}
 288