root/drivers/net/ethernet/brocade/bna/bfa_msgq.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cmdq_sm_stopped_entry
  2. cmdq_sm_stopped
  3. cmdq_sm_init_wait_entry
  4. cmdq_sm_init_wait
  5. cmdq_sm_ready_entry
  6. cmdq_sm_ready
  7. cmdq_sm_dbell_wait_entry
  8. cmdq_sm_dbell_wait
  9. bfa_msgq_cmdq_dbell_ready
  10. bfa_msgq_cmdq_dbell
  11. __cmd_copy
  12. bfa_msgq_cmdq_ci_update
  13. bfa_msgq_cmdq_copy_next
  14. bfa_msgq_cmdq_copy_req
  15. bfa_msgq_cmdq_copy_rsp
  16. bfa_msgq_cmdq_attach
  17. rspq_sm_stopped_entry
  18. rspq_sm_stopped
  19. rspq_sm_init_wait_entry
  20. rspq_sm_init_wait
  21. rspq_sm_ready_entry
  22. rspq_sm_ready
  23. rspq_sm_dbell_wait_entry
  24. rspq_sm_dbell_wait
  25. bfa_msgq_rspq_dbell_ready
  26. bfa_msgq_rspq_dbell
  27. bfa_msgq_rspq_pi_update
  28. bfa_msgq_rspq_attach
  29. bfa_msgq_init_rsp
  30. bfa_msgq_init
  31. bfa_msgq_isr
  32. bfa_msgq_notify
  33. bfa_msgq_meminfo
  34. bfa_msgq_memclaim
  35. bfa_msgq_attach
  36. bfa_msgq_regisr
  37. bfa_msgq_cmd_post
  38. bfa_msgq_rsp_copy

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Linux network driver for QLogic BR-series Converged Network Adapter.
   4  */
   5 /*
   6  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
   7  * Copyright (c) 2014-2015 QLogic Corporation
   8  * All rights reserved
   9  * www.qlogic.com
  10  */
  11 
  12 /* MSGQ module source file. */
  13 
  14 #include "bfi.h"
  15 #include "bfa_msgq.h"
  16 #include "bfa_ioc.h"
  17 
  18 #define call_cmdq_ent_cbfn(_cmdq_ent, _status)                          \
  19 {                                                                       \
  20         bfa_msgq_cmdcbfn_t cbfn;                                        \
  21         void *cbarg;                                                    \
  22         cbfn = (_cmdq_ent)->cbfn;                                       \
  23         cbarg = (_cmdq_ent)->cbarg;                                     \
  24         (_cmdq_ent)->cbfn = NULL;                                       \
  25         (_cmdq_ent)->cbarg = NULL;                                      \
  26         if (cbfn) {                                                     \
  27                 cbfn(cbarg, (_status));                                 \
  28         }                                                               \
  29 }
  30 
  31 static void bfa_msgq_cmdq_dbell(struct bfa_msgq_cmdq *cmdq);
  32 static void bfa_msgq_cmdq_copy_rsp(struct bfa_msgq_cmdq *cmdq);
  33 
  34 enum cmdq_event {
  35         CMDQ_E_START                    = 1,
  36         CMDQ_E_STOP                     = 2,
  37         CMDQ_E_FAIL                     = 3,
  38         CMDQ_E_POST                     = 4,
  39         CMDQ_E_INIT_RESP                = 5,
  40         CMDQ_E_DB_READY                 = 6,
  41 };
  42 
  43 bfa_fsm_state_decl(cmdq, stopped, struct bfa_msgq_cmdq, enum cmdq_event);
  44 bfa_fsm_state_decl(cmdq, init_wait, struct bfa_msgq_cmdq, enum cmdq_event);
  45 bfa_fsm_state_decl(cmdq, ready, struct bfa_msgq_cmdq, enum cmdq_event);
  46 bfa_fsm_state_decl(cmdq, dbell_wait, struct bfa_msgq_cmdq,
  47                         enum cmdq_event);
  48 
  49 static void
  50 cmdq_sm_stopped_entry(struct bfa_msgq_cmdq *cmdq)
  51 {
  52         struct bfa_msgq_cmd_entry *cmdq_ent;
  53 
  54         cmdq->producer_index = 0;
  55         cmdq->consumer_index = 0;
  56         cmdq->flags = 0;
  57         cmdq->token = 0;
  58         cmdq->offset = 0;
  59         cmdq->bytes_to_copy = 0;
  60         while (!list_empty(&cmdq->pending_q)) {
  61                 cmdq_ent = list_first_entry(&cmdq->pending_q,
  62                                             struct bfa_msgq_cmd_entry, qe);
  63                 list_del(&cmdq_ent->qe);
  64                 call_cmdq_ent_cbfn(cmdq_ent, BFA_STATUS_FAILED);
  65         }
  66 }
  67 
  68 static void
  69 cmdq_sm_stopped(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
  70 {
  71         switch (event) {
  72         case CMDQ_E_START:
  73                 bfa_fsm_set_state(cmdq, cmdq_sm_init_wait);
  74                 break;
  75 
  76         case CMDQ_E_STOP:
  77         case CMDQ_E_FAIL:
  78                 /* No-op */
  79                 break;
  80 
  81         case CMDQ_E_POST:
  82                 cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
  83                 break;
  84 
  85         default:
  86                 bfa_sm_fault(event);
  87         }
  88 }
  89 
  90 static void
  91 cmdq_sm_init_wait_entry(struct bfa_msgq_cmdq *cmdq)
  92 {
  93         bfa_wc_down(&cmdq->msgq->init_wc);
  94 }
  95 
  96 static void
  97 cmdq_sm_init_wait(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
  98 {
  99         switch (event) {
 100         case CMDQ_E_STOP:
 101         case CMDQ_E_FAIL:
 102                 bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
 103                 break;
 104 
 105         case CMDQ_E_POST:
 106                 cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
 107                 break;
 108 
 109         case CMDQ_E_INIT_RESP:
 110                 if (cmdq->flags & BFA_MSGQ_CMDQ_F_DB_UPDATE) {
 111                         cmdq->flags &= ~BFA_MSGQ_CMDQ_F_DB_UPDATE;
 112                         bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
 113                 } else
 114                         bfa_fsm_set_state(cmdq, cmdq_sm_ready);
 115                 break;
 116 
 117         default:
 118                 bfa_sm_fault(event);
 119         }
 120 }
 121 
 122 static void
 123 cmdq_sm_ready_entry(struct bfa_msgq_cmdq *cmdq)
 124 {
 125 }
 126 
 127 static void
 128 cmdq_sm_ready(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
 129 {
 130         switch (event) {
 131         case CMDQ_E_STOP:
 132         case CMDQ_E_FAIL:
 133                 bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
 134                 break;
 135 
 136         case CMDQ_E_POST:
 137                 bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
 138                 break;
 139 
 140         default:
 141                 bfa_sm_fault(event);
 142         }
 143 }
 144 
 145 static void
 146 cmdq_sm_dbell_wait_entry(struct bfa_msgq_cmdq *cmdq)
 147 {
 148         bfa_msgq_cmdq_dbell(cmdq);
 149 }
 150 
 151 static void
 152 cmdq_sm_dbell_wait(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
 153 {
 154         switch (event) {
 155         case CMDQ_E_STOP:
 156         case CMDQ_E_FAIL:
 157                 bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
 158                 break;
 159 
 160         case CMDQ_E_POST:
 161                 cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
 162                 break;
 163 
 164         case CMDQ_E_DB_READY:
 165                 if (cmdq->flags & BFA_MSGQ_CMDQ_F_DB_UPDATE) {
 166                         cmdq->flags &= ~BFA_MSGQ_CMDQ_F_DB_UPDATE;
 167                         bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
 168                 } else
 169                         bfa_fsm_set_state(cmdq, cmdq_sm_ready);
 170                 break;
 171 
 172         default:
 173                 bfa_sm_fault(event);
 174         }
 175 }
 176 
 177 static void
 178 bfa_msgq_cmdq_dbell_ready(void *arg)
 179 {
 180         struct bfa_msgq_cmdq *cmdq = (struct bfa_msgq_cmdq *)arg;
 181         bfa_fsm_send_event(cmdq, CMDQ_E_DB_READY);
 182 }
 183 
 184 static void
 185 bfa_msgq_cmdq_dbell(struct bfa_msgq_cmdq *cmdq)
 186 {
 187         struct bfi_msgq_h2i_db *dbell =
 188                 (struct bfi_msgq_h2i_db *)(&cmdq->dbell_mb.msg[0]);
 189 
 190         memset(dbell, 0, sizeof(struct bfi_msgq_h2i_db));
 191         bfi_h2i_set(dbell->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_DOORBELL_PI, 0);
 192         dbell->mh.mtag.i2htok = 0;
 193         dbell->idx.cmdq_pi = htons(cmdq->producer_index);
 194 
 195         if (!bfa_nw_ioc_mbox_queue(cmdq->msgq->ioc, &cmdq->dbell_mb,
 196                                 bfa_msgq_cmdq_dbell_ready, cmdq)) {
 197                 bfa_msgq_cmdq_dbell_ready(cmdq);
 198         }
 199 }
 200 
 201 static void
 202 __cmd_copy(struct bfa_msgq_cmdq *cmdq, struct bfa_msgq_cmd_entry *cmd)
 203 {
 204         size_t len = cmd->msg_size;
 205         int num_entries = 0;
 206         size_t to_copy;
 207         u8 *src, *dst;
 208 
 209         src = (u8 *)cmd->msg_hdr;
 210         dst = (u8 *)cmdq->addr.kva;
 211         dst += (cmdq->producer_index * BFI_MSGQ_CMD_ENTRY_SIZE);
 212 
 213         while (len) {
 214                 to_copy = (len < BFI_MSGQ_CMD_ENTRY_SIZE) ?
 215                                 len : BFI_MSGQ_CMD_ENTRY_SIZE;
 216                 memcpy(dst, src, to_copy);
 217                 len -= to_copy;
 218                 src += BFI_MSGQ_CMD_ENTRY_SIZE;
 219                 BFA_MSGQ_INDX_ADD(cmdq->producer_index, 1, cmdq->depth);
 220                 dst = (u8 *)cmdq->addr.kva;
 221                 dst += (cmdq->producer_index * BFI_MSGQ_CMD_ENTRY_SIZE);
 222                 num_entries++;
 223         }
 224 
 225 }
 226 
 227 static void
 228 bfa_msgq_cmdq_ci_update(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
 229 {
 230         struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
 231         struct bfa_msgq_cmd_entry *cmd;
 232         int posted = 0;
 233 
 234         cmdq->consumer_index = ntohs(dbell->idx.cmdq_ci);
 235 
 236         /* Walk through pending list to see if the command can be posted */
 237         while (!list_empty(&cmdq->pending_q)) {
 238                 cmd = list_first_entry(&cmdq->pending_q,
 239                                        struct bfa_msgq_cmd_entry, qe);
 240                 if (ntohs(cmd->msg_hdr->num_entries) <=
 241                         BFA_MSGQ_FREE_CNT(cmdq)) {
 242                         list_del(&cmd->qe);
 243                         __cmd_copy(cmdq, cmd);
 244                         posted = 1;
 245                         call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
 246                 } else {
 247                         break;
 248                 }
 249         }
 250 
 251         if (posted)
 252                 bfa_fsm_send_event(cmdq, CMDQ_E_POST);
 253 }
 254 
 255 static void
 256 bfa_msgq_cmdq_copy_next(void *arg)
 257 {
 258         struct bfa_msgq_cmdq *cmdq = (struct bfa_msgq_cmdq *)arg;
 259 
 260         if (cmdq->bytes_to_copy)
 261                 bfa_msgq_cmdq_copy_rsp(cmdq);
 262 }
 263 
 264 static void
 265 bfa_msgq_cmdq_copy_req(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
 266 {
 267         struct bfi_msgq_i2h_cmdq_copy_req *req =
 268                 (struct bfi_msgq_i2h_cmdq_copy_req *)mb;
 269 
 270         cmdq->token = 0;
 271         cmdq->offset = ntohs(req->offset);
 272         cmdq->bytes_to_copy = ntohs(req->len);
 273         bfa_msgq_cmdq_copy_rsp(cmdq);
 274 }
 275 
 276 static void
 277 bfa_msgq_cmdq_copy_rsp(struct bfa_msgq_cmdq *cmdq)
 278 {
 279         struct bfi_msgq_h2i_cmdq_copy_rsp *rsp =
 280                 (struct bfi_msgq_h2i_cmdq_copy_rsp *)&cmdq->copy_mb.msg[0];
 281         int copied;
 282         u8 *addr = (u8 *)cmdq->addr.kva;
 283 
 284         memset(rsp, 0, sizeof(struct bfi_msgq_h2i_cmdq_copy_rsp));
 285         bfi_h2i_set(rsp->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_CMDQ_COPY_RSP, 0);
 286         rsp->mh.mtag.i2htok = htons(cmdq->token);
 287         copied = (cmdq->bytes_to_copy >= BFI_CMD_COPY_SZ) ? BFI_CMD_COPY_SZ :
 288                 cmdq->bytes_to_copy;
 289         addr += cmdq->offset;
 290         memcpy(rsp->data, addr, copied);
 291 
 292         cmdq->token++;
 293         cmdq->offset += copied;
 294         cmdq->bytes_to_copy -= copied;
 295 
 296         if (!bfa_nw_ioc_mbox_queue(cmdq->msgq->ioc, &cmdq->copy_mb,
 297                                 bfa_msgq_cmdq_copy_next, cmdq)) {
 298                 bfa_msgq_cmdq_copy_next(cmdq);
 299         }
 300 }
 301 
 302 static void
 303 bfa_msgq_cmdq_attach(struct bfa_msgq_cmdq *cmdq, struct bfa_msgq *msgq)
 304 {
 305         cmdq->depth = BFA_MSGQ_CMDQ_NUM_ENTRY;
 306         INIT_LIST_HEAD(&cmdq->pending_q);
 307         cmdq->msgq = msgq;
 308         bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
 309 }
 310 
 311 static void bfa_msgq_rspq_dbell(struct bfa_msgq_rspq *rspq);
 312 
 313 enum rspq_event {
 314         RSPQ_E_START                    = 1,
 315         RSPQ_E_STOP                     = 2,
 316         RSPQ_E_FAIL                     = 3,
 317         RSPQ_E_RESP                     = 4,
 318         RSPQ_E_INIT_RESP                = 5,
 319         RSPQ_E_DB_READY                 = 6,
 320 };
 321 
 322 bfa_fsm_state_decl(rspq, stopped, struct bfa_msgq_rspq, enum rspq_event);
 323 bfa_fsm_state_decl(rspq, init_wait, struct bfa_msgq_rspq,
 324                         enum rspq_event);
 325 bfa_fsm_state_decl(rspq, ready, struct bfa_msgq_rspq, enum rspq_event);
 326 bfa_fsm_state_decl(rspq, dbell_wait, struct bfa_msgq_rspq,
 327                         enum rspq_event);
 328 
 329 static void
 330 rspq_sm_stopped_entry(struct bfa_msgq_rspq *rspq)
 331 {
 332         rspq->producer_index = 0;
 333         rspq->consumer_index = 0;
 334         rspq->flags = 0;
 335 }
 336 
 337 static void
 338 rspq_sm_stopped(struct bfa_msgq_rspq *rspq, enum rspq_event event)
 339 {
 340         switch (event) {
 341         case RSPQ_E_START:
 342                 bfa_fsm_set_state(rspq, rspq_sm_init_wait);
 343                 break;
 344 
 345         case RSPQ_E_STOP:
 346         case RSPQ_E_FAIL:
 347                 /* No-op */
 348                 break;
 349 
 350         default:
 351                 bfa_sm_fault(event);
 352         }
 353 }
 354 
 355 static void
 356 rspq_sm_init_wait_entry(struct bfa_msgq_rspq *rspq)
 357 {
 358         bfa_wc_down(&rspq->msgq->init_wc);
 359 }
 360 
 361 static void
 362 rspq_sm_init_wait(struct bfa_msgq_rspq *rspq, enum rspq_event event)
 363 {
 364         switch (event) {
 365         case RSPQ_E_FAIL:
 366         case RSPQ_E_STOP:
 367                 bfa_fsm_set_state(rspq, rspq_sm_stopped);
 368                 break;
 369 
 370         case RSPQ_E_INIT_RESP:
 371                 bfa_fsm_set_state(rspq, rspq_sm_ready);
 372                 break;
 373 
 374         default:
 375                 bfa_sm_fault(event);
 376         }
 377 }
 378 
 379 static void
 380 rspq_sm_ready_entry(struct bfa_msgq_rspq *rspq)
 381 {
 382 }
 383 
 384 static void
 385 rspq_sm_ready(struct bfa_msgq_rspq *rspq, enum rspq_event event)
 386 {
 387         switch (event) {
 388         case RSPQ_E_STOP:
 389         case RSPQ_E_FAIL:
 390                 bfa_fsm_set_state(rspq, rspq_sm_stopped);
 391                 break;
 392 
 393         case RSPQ_E_RESP:
 394                 bfa_fsm_set_state(rspq, rspq_sm_dbell_wait);
 395                 break;
 396 
 397         default:
 398                 bfa_sm_fault(event);
 399         }
 400 }
 401 
 402 static void
 403 rspq_sm_dbell_wait_entry(struct bfa_msgq_rspq *rspq)
 404 {
 405         if (!bfa_nw_ioc_is_disabled(rspq->msgq->ioc))
 406                 bfa_msgq_rspq_dbell(rspq);
 407 }
 408 
 409 static void
 410 rspq_sm_dbell_wait(struct bfa_msgq_rspq *rspq, enum rspq_event event)
 411 {
 412         switch (event) {
 413         case RSPQ_E_STOP:
 414         case RSPQ_E_FAIL:
 415                 bfa_fsm_set_state(rspq, rspq_sm_stopped);
 416                 break;
 417 
 418         case RSPQ_E_RESP:
 419                 rspq->flags |= BFA_MSGQ_RSPQ_F_DB_UPDATE;
 420                 break;
 421 
 422         case RSPQ_E_DB_READY:
 423                 if (rspq->flags & BFA_MSGQ_RSPQ_F_DB_UPDATE) {
 424                         rspq->flags &= ~BFA_MSGQ_RSPQ_F_DB_UPDATE;
 425                         bfa_fsm_set_state(rspq, rspq_sm_dbell_wait);
 426                 } else
 427                         bfa_fsm_set_state(rspq, rspq_sm_ready);
 428                 break;
 429 
 430         default:
 431                 bfa_sm_fault(event);
 432         }
 433 }
 434 
 435 static void
 436 bfa_msgq_rspq_dbell_ready(void *arg)
 437 {
 438         struct bfa_msgq_rspq *rspq = (struct bfa_msgq_rspq *)arg;
 439         bfa_fsm_send_event(rspq, RSPQ_E_DB_READY);
 440 }
 441 
 442 static void
 443 bfa_msgq_rspq_dbell(struct bfa_msgq_rspq *rspq)
 444 {
 445         struct bfi_msgq_h2i_db *dbell =
 446                 (struct bfi_msgq_h2i_db *)(&rspq->dbell_mb.msg[0]);
 447 
 448         memset(dbell, 0, sizeof(struct bfi_msgq_h2i_db));
 449         bfi_h2i_set(dbell->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_DOORBELL_CI, 0);
 450         dbell->mh.mtag.i2htok = 0;
 451         dbell->idx.rspq_ci = htons(rspq->consumer_index);
 452 
 453         if (!bfa_nw_ioc_mbox_queue(rspq->msgq->ioc, &rspq->dbell_mb,
 454                                 bfa_msgq_rspq_dbell_ready, rspq)) {
 455                 bfa_msgq_rspq_dbell_ready(rspq);
 456         }
 457 }
 458 
 459 static void
 460 bfa_msgq_rspq_pi_update(struct bfa_msgq_rspq *rspq, struct bfi_mbmsg *mb)
 461 {
 462         struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
 463         struct bfi_msgq_mhdr *msghdr;
 464         int num_entries;
 465         int mc;
 466         u8 *rspq_qe;
 467 
 468         rspq->producer_index = ntohs(dbell->idx.rspq_pi);
 469 
 470         while (rspq->consumer_index != rspq->producer_index) {
 471                 rspq_qe = (u8 *)rspq->addr.kva;
 472                 rspq_qe += (rspq->consumer_index * BFI_MSGQ_RSP_ENTRY_SIZE);
 473                 msghdr = (struct bfi_msgq_mhdr *)rspq_qe;
 474 
 475                 mc = msghdr->msg_class;
 476                 num_entries = ntohs(msghdr->num_entries);
 477 
 478                 if ((mc >= BFI_MC_MAX) || (rspq->rsphdlr[mc].cbfn == NULL))
 479                         break;
 480 
 481                 (rspq->rsphdlr[mc].cbfn)(rspq->rsphdlr[mc].cbarg, msghdr);
 482 
 483                 BFA_MSGQ_INDX_ADD(rspq->consumer_index, num_entries,
 484                                 rspq->depth);
 485         }
 486 
 487         bfa_fsm_send_event(rspq, RSPQ_E_RESP);
 488 }
 489 
 490 static void
 491 bfa_msgq_rspq_attach(struct bfa_msgq_rspq *rspq, struct bfa_msgq *msgq)
 492 {
 493         rspq->depth = BFA_MSGQ_RSPQ_NUM_ENTRY;
 494         rspq->msgq = msgq;
 495         bfa_fsm_set_state(rspq, rspq_sm_stopped);
 496 }
 497 
 498 static void
 499 bfa_msgq_init_rsp(struct bfa_msgq *msgq,
 500                  struct bfi_mbmsg *mb)
 501 {
 502         bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_INIT_RESP);
 503         bfa_fsm_send_event(&msgq->rspq, RSPQ_E_INIT_RESP);
 504 }
 505 
 506 static void
 507 bfa_msgq_init(void *arg)
 508 {
 509         struct bfa_msgq *msgq = (struct bfa_msgq *)arg;
 510         struct bfi_msgq_cfg_req *msgq_cfg =
 511                 (struct bfi_msgq_cfg_req *)&msgq->init_mb.msg[0];
 512 
 513         memset(msgq_cfg, 0, sizeof(struct bfi_msgq_cfg_req));
 514         bfi_h2i_set(msgq_cfg->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_INIT_REQ, 0);
 515         msgq_cfg->mh.mtag.i2htok = 0;
 516 
 517         bfa_dma_be_addr_set(msgq_cfg->cmdq.addr, msgq->cmdq.addr.pa);
 518         msgq_cfg->cmdq.q_depth = htons(msgq->cmdq.depth);
 519         bfa_dma_be_addr_set(msgq_cfg->rspq.addr, msgq->rspq.addr.pa);
 520         msgq_cfg->rspq.q_depth = htons(msgq->rspq.depth);
 521 
 522         bfa_nw_ioc_mbox_queue(msgq->ioc, &msgq->init_mb, NULL, NULL);
 523 }
 524 
 525 static void
 526 bfa_msgq_isr(void *cbarg, struct bfi_mbmsg *msg)
 527 {
 528         struct bfa_msgq *msgq = (struct bfa_msgq *)cbarg;
 529 
 530         switch (msg->mh.msg_id) {
 531         case BFI_MSGQ_I2H_INIT_RSP:
 532                 bfa_msgq_init_rsp(msgq, msg);
 533                 break;
 534 
 535         case BFI_MSGQ_I2H_DOORBELL_PI:
 536                 bfa_msgq_rspq_pi_update(&msgq->rspq, msg);
 537                 break;
 538 
 539         case BFI_MSGQ_I2H_DOORBELL_CI:
 540                 bfa_msgq_cmdq_ci_update(&msgq->cmdq, msg);
 541                 break;
 542 
 543         case BFI_MSGQ_I2H_CMDQ_COPY_REQ:
 544                 bfa_msgq_cmdq_copy_req(&msgq->cmdq, msg);
 545                 break;
 546 
 547         default:
 548                 BUG_ON(1);
 549         }
 550 }
 551 
 552 static void
 553 bfa_msgq_notify(void *cbarg, enum bfa_ioc_event event)
 554 {
 555         struct bfa_msgq *msgq = (struct bfa_msgq *)cbarg;
 556 
 557         switch (event) {
 558         case BFA_IOC_E_ENABLED:
 559                 bfa_wc_init(&msgq->init_wc, bfa_msgq_init, msgq);
 560                 bfa_wc_up(&msgq->init_wc);
 561                 bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_START);
 562                 bfa_wc_up(&msgq->init_wc);
 563                 bfa_fsm_send_event(&msgq->rspq, RSPQ_E_START);
 564                 bfa_wc_wait(&msgq->init_wc);
 565                 break;
 566 
 567         case BFA_IOC_E_DISABLED:
 568                 bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_STOP);
 569                 bfa_fsm_send_event(&msgq->rspq, RSPQ_E_STOP);
 570                 break;
 571 
 572         case BFA_IOC_E_FAILED:
 573                 bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_FAIL);
 574                 bfa_fsm_send_event(&msgq->rspq, RSPQ_E_FAIL);
 575                 break;
 576 
 577         default:
 578                 break;
 579         }
 580 }
 581 
 582 u32
 583 bfa_msgq_meminfo(void)
 584 {
 585         return roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ) +
 586                 roundup(BFA_MSGQ_RSPQ_SIZE, BFA_DMA_ALIGN_SZ);
 587 }
 588 
 589 void
 590 bfa_msgq_memclaim(struct bfa_msgq *msgq, u8 *kva, u64 pa)
 591 {
 592         msgq->cmdq.addr.kva = kva;
 593         msgq->cmdq.addr.pa  = pa;
 594 
 595         kva += roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ);
 596         pa += roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ);
 597 
 598         msgq->rspq.addr.kva = kva;
 599         msgq->rspq.addr.pa = pa;
 600 }
 601 
 602 void
 603 bfa_msgq_attach(struct bfa_msgq *msgq, struct bfa_ioc *ioc)
 604 {
 605         msgq->ioc    = ioc;
 606 
 607         bfa_msgq_cmdq_attach(&msgq->cmdq, msgq);
 608         bfa_msgq_rspq_attach(&msgq->rspq, msgq);
 609 
 610         bfa_nw_ioc_mbox_regisr(msgq->ioc, BFI_MC_MSGQ, bfa_msgq_isr, msgq);
 611         bfa_ioc_notify_init(&msgq->ioc_notify, bfa_msgq_notify, msgq);
 612         bfa_nw_ioc_notify_register(msgq->ioc, &msgq->ioc_notify);
 613 }
 614 
 615 void
 616 bfa_msgq_regisr(struct bfa_msgq *msgq, enum bfi_mclass mc,
 617                 bfa_msgq_mcfunc_t cbfn, void *cbarg)
 618 {
 619         msgq->rspq.rsphdlr[mc].cbfn     = cbfn;
 620         msgq->rspq.rsphdlr[mc].cbarg    = cbarg;
 621 }
 622 
 623 void
 624 bfa_msgq_cmd_post(struct bfa_msgq *msgq,  struct bfa_msgq_cmd_entry *cmd)
 625 {
 626         if (ntohs(cmd->msg_hdr->num_entries) <=
 627                 BFA_MSGQ_FREE_CNT(&msgq->cmdq)) {
 628                 __cmd_copy(&msgq->cmdq, cmd);
 629                 call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
 630                 bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_POST);
 631         } else {
 632                 list_add_tail(&cmd->qe, &msgq->cmdq.pending_q);
 633         }
 634 }
 635 
 636 void
 637 bfa_msgq_rsp_copy(struct bfa_msgq *msgq, u8 *buf, size_t buf_len)
 638 {
 639         struct bfa_msgq_rspq *rspq = &msgq->rspq;
 640         size_t len = buf_len;
 641         size_t to_copy;
 642         int ci;
 643         u8 *src, *dst;
 644 
 645         ci = rspq->consumer_index;
 646         src = (u8 *)rspq->addr.kva;
 647         src += (ci * BFI_MSGQ_RSP_ENTRY_SIZE);
 648         dst = buf;
 649 
 650         while (len) {
 651                 to_copy = (len < BFI_MSGQ_RSP_ENTRY_SIZE) ?
 652                                 len : BFI_MSGQ_RSP_ENTRY_SIZE;
 653                 memcpy(dst, src, to_copy);
 654                 len -= to_copy;
 655                 dst += BFI_MSGQ_RSP_ENTRY_SIZE;
 656                 BFA_MSGQ_INDX_ADD(ci, 1, rspq->depth);
 657                 src = (u8 *)rspq->addr.kva;
 658                 src += (ci * BFI_MSGQ_RSP_ENTRY_SIZE);
 659         }
 660 }

/* [<][>][^][v][top][bottom][index][help] */