xref: /illumos-gate/usr/src/uts/common/io/bnxe/bnxe_mm.c (revision 45ede40b2394db7967e59f19288fae9b62efd4aa)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2014 QLogic Corporation
24  * The contents of this file are subject to the terms of the
25  * QLogic End User License (the "License").
26  * You may not use this file except in compliance with the License.
27  *
28  * You can obtain a copy of the License at
29  * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
30  * QLogic_End_User_Software_License.txt
31  * See the License for the specific language governing permissions
32  * and limitations under the License.
33  */
34 
35 /*
36  * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
37  */
38 
39 #include "bnxe.h"
40 
41 #define BNXE_DEF_TX_BD_PAGE_CNT  12
42 #define BNXE_DEF_TX_COAL_BUF_CNT 10
43 
44 typedef struct
45 {
46     int bufCnt;
47     int txBdPageCnt;
48     int txCoalBufCnt;
49 } BnxeHwPageConfig;
50 
51 static BnxeHwPageConfig bnxeHwPageConfigs[] =
52 {
53     /* Buffers   TX BD Pages   TX Coalesce Bufs */
54     {  1000,     4,            10 },
55     {  1500,     6,            10 },
56     {  3000,     12,           10 },
57     {  0,        0,            0 }
58 };
59 
60 #if 0
61 #define MEM_LOG BnxeLogInfo
62 #else
63 #define MEM_LOG
64 #endif
65 
66 ddi_device_acc_attr_t bnxeAccessAttribBAR =
67 {
68     DDI_DEVICE_ATTR_V0,   /* devacc_attr_version */
69     DDI_STRUCTURE_LE_ACC, /* devacc_attr_endian_flags */
70     DDI_STRICTORDER_ACC,  /* devacc_attr_dataorder */
71     DDI_DEFAULT_ACC       /* devacc_attr_access */
72 };
73 
74 ddi_device_acc_attr_t bnxeAccessAttribBUF =
75 {
76     DDI_DEVICE_ATTR_V0,   /* devacc_attr_version */
77     DDI_NEVERSWAP_ACC,    /* devacc_attr_endian_flags */
78     DDI_STRICTORDER_ACC,  /* devacc_attr_dataorder */
79     DDI_DEFAULT_ACC       /* devacc_attr_access */
80 };
81 
82 ddi_dma_attr_t bnxeDmaPageAttrib =
83 {
84     DMA_ATTR_V0,         /* dma_attr_version */
85     0,                   /* dma_attr_addr_lo */
86     0xffffffffffffffff,  /* dma_attr_addr_hi */
87     0xffffffffffffffff,  /* dma_attr_count_max */
88     0,                   /* dma_attr_align */
89     0xffffffff,          /* dma_attr_burstsizes */
90     1,                   /* dma_attr_minxfer */
91     0xffffffffffffffff,  /* dma_attr_maxxfer */
92     0xffffffffffffffff,  /* dma_attr_seg */
93     1,                   /* dma_attr_sgllen */
94     1,                   /* dma_attr_granular */
95     0,                   /* dma_attr_flags */
96 };
97 
98 
99 void mm_wait(lm_device_t * pDev,
100              u32_t         delayUs)
101 {
102     (void)pDev;
103     drv_usecwait(delayUs);
104 }
105 
106 
107 lm_status_t mm_read_pci(lm_device_t * pDev,
108                         u32_t         pciReg,
109                         u32_t *       pRegValue)
110 {
111     um_device_t * pUM = (um_device_t *)pDev;
112 
113     *pRegValue = pci_config_get32(pUM->pPciCfg, (off_t)pciReg);
114 
115     return LM_STATUS_SUCCESS;
116 }
117 
118 
119 lm_status_t mm_write_pci(lm_device_t * pDev,
120                          u32_t         pciReg,
121                          u32_t         regValue)
122 {
123     um_device_t * pUM = (um_device_t *)pDev;
124 
125     pci_config_put32(pUM->pPciCfg, (off_t)pciReg, regValue);
126 
127     return LM_STATUS_SUCCESS;
128 }
129 
130 
131 void BnxeInitBdCnts(um_device_t * pUM,
132                     int           cli_idx)
133 {
134     lm_device_t *      pLM = (lm_device_t *)pUM;
135     BnxeHwPageConfig * pPageCfg;
136 
137     pLM->params.l2_tx_bd_page_cnt[cli_idx]  = BNXE_DEF_TX_BD_PAGE_CNT;
138     pLM->params.l2_tx_coal_buf_cnt[cli_idx] = BNXE_DEF_TX_COAL_BUF_CNT;
139 
140     pPageCfg = &bnxeHwPageConfigs[0];
141     while (pPageCfg->bufCnt)
142     {
143         if (pLM->params.l2_rx_desc_cnt[cli_idx] <= pPageCfg->bufCnt)
144         {
145             pLM->params.l2_tx_bd_page_cnt[cli_idx]  = pPageCfg->txBdPageCnt;
146             pLM->params.l2_tx_coal_buf_cnt[cli_idx] = pPageCfg->txCoalBufCnt;
147             break;
148         }
149 
150         pPageCfg++;
151     }
152 }
153 
154 
155 extern u32_t LOG2(u32_t v);
156 unsigned long log2_align(unsigned long n);
157 
158 lm_status_t mm_get_user_config(lm_device_t * pLM)
159 {
160     um_device_t * pUM = (um_device_t *)pLM;
161     u32_t         total_size;
162     u32_t         required_page_size;
163 
164     BnxeCfgInit(pUM);
165 
166     pLM->params.sw_config = LM_SWCFG_10G;
167 
168     pLM->params.ofld_cap = (LM_OFFLOAD_TX_IP_CKSUM   |
169                             LM_OFFLOAD_RX_IP_CKSUM   |
170                             LM_OFFLOAD_TX_TCP_CKSUM  |
171                             LM_OFFLOAD_RX_TCP_CKSUM  |
172                             LM_OFFLOAD_TX_TCP6_CKSUM |
173                             LM_OFFLOAD_RX_TCP6_CKSUM |
174                             LM_OFFLOAD_TX_UDP_CKSUM  |
175                             LM_OFFLOAD_RX_UDP_CKSUM  |
176                             LM_OFFLOAD_TX_UDP6_CKSUM |
177                             LM_OFFLOAD_RX_UDP6_CKSUM);
178 
179     /* XXX Wake on LAN? */
180     //pLM->params.wol_cap = (LM_WAKE_UP_MODE_MAGIC_PACKET | LM_WAKE_UP_MODE_NWUF);
181 
182     /* keep the VLAN tag in the mac header when receiving */
183     pLM->params.keep_vlan_tag = 1;
184 
185     /* set in BnxeIntrInit based on the allocated number of MSIX interrupts */
186     //pLM->params.rss_chain_cnt = pUM->devParams.numRings;
187     //pLM->params.tss_chain_cnt = pUM->devParams.numRings;
188 
189     pLM->params.l2_rx_desc_cnt[LM_CLI_IDX_NDIS] = pUM->devParams.numRxDesc[LM_CLI_IDX_NDIS];
190     pLM->params.l2_tx_bd_page_cnt[LM_CLI_IDX_NDIS] = 0;
191     pLM->params.l2_tx_coal_buf_cnt[LM_CLI_IDX_NDIS] = 0;
192 
193     BnxeInitBdCnts(pUM, LM_CLI_IDX_NDIS);
194 
195     pLM->params.l2_rx_desc_cnt[LM_CLI_IDX_FWD] = 0;
196     pLM->params.l2_tx_bd_page_cnt[LM_CLI_IDX_FWD] = 0;
197     pLM->params.l2_tx_coal_buf_cnt[LM_CLI_IDX_FWD] = 0;
198 
199     pLM->params.l2_rx_desc_cnt[LM_CLI_IDX_ISCSI] = 0;
200     pLM->params.l2_tx_bd_page_cnt[LM_CLI_IDX_ISCSI] = 0;
201     pLM->params.l2_tx_coal_buf_cnt[LM_CLI_IDX_ISCSI] = 0;
202 
203     pLM->params.l2_rx_desc_cnt[LM_CLI_IDX_FCOE] = 0;
204     pLM->params.l2_tx_bd_page_cnt[LM_CLI_IDX_FCOE] = 0;
205     pLM->params.l2_tx_coal_buf_cnt[LM_CLI_IDX_FCOE] = 0;
206 
207     pLM->params.max_func_toe_cons    = 0;
208     pLM->params.max_func_iscsi_cons  = 0;
209     pLM->params.max_func_rdma_cons   = 0;
210     pLM->params.max_func_fcoe_cons   = pUM->lm_dev.hw_info.max_port_fcoe_conn;
211     pLM->params.max_func_connections =
212         log2_align(pLM->params.max_func_toe_cons +
213                    pLM->params.max_func_rdma_cons +
214                    pLM->params.max_func_iscsi_cons +
215                    pLM->params.max_func_fcoe_cons +
216                    MAX_ETH_CONS);
217 
218     /* determine: 1. itl_client_page_size, #context in page*/
219 
220     /* based on PCIe block INIT document */
221 
222     /* We now need to calculate the page size based on the maximum number of
223      * connections supported. Since this property is identical to all ports, and
224      * is configured in COMMON registers, we need to use the maximum number of
225      * connections in all ports. */
226 
227     /* The L2P table is used to map logical addresses to physical ones. There
228      * are four clients that use this table.  We want to use only the ILT
229      * (Internal), we need to calculate the total size required for all clients,
230      * divide it by the number of entries in the ILT table and that will give us
231      * the page size we want. The following table describes the needs of each of
232      * these clients:
233      *
234      *  HW block(L2P client)    Area name       Size [B]
235      *  Searcher                T1              ROUNDUP(LOG2(N)) * 64
236      *  Timers                  Linear Array    N * 8
237      *  QM                      Queues          N * 32 * 4
238      *  CDU                     Context         N * S + W * ROUNDUP (N/m)  (W=0)
239      *
240      * N: Number of connections
241      * S: Context Size
242      * W: Block Waste (not really interesting) we configure the context size to
243      *    be a power of 2.
244      * m: Number of cids in a block (not really interesting, since W will always
245      *    be 0)
246      */
247     total_size = (pLM->hw_info.max_common_conns *
248                   (SEARCHER_TOTAL_MEM_REQUIRED_PER_CON +
249                    TIMERS_TOTAL_MEM_REQUIRED_PER_CON +
250                    QM_TOTAL_MEM_REQUIRED_PER_CON +
251                    pLM->params.context_line_size));
252 
253     required_page_size = (total_size / ILT_NUM_PAGE_ENTRIES_PER_FUNC);
254     required_page_size = (2 << LOG2(required_page_size));
255 
256     if (required_page_size < LM_PAGE_SIZE)
257     {
258         required_page_size = LM_PAGE_SIZE;
259     }
260 
261     pLM->params.ilt_client_page_size = required_page_size;
262     pLM->params.num_context_in_page  = (pLM->params.ilt_client_page_size /
263                                         pLM->params.context_line_size);
264 
265     if (pUM->devParams.intrCoalesce)
266     {
267         pLM->params.int_coalesing_mode = LM_INT_COAL_PERIODIC_SYNC;
268         pLM->params.int_per_sec_rx_override = pUM->devParams.intrRxPerSec;
269         pLM->params.int_per_sec_tx_override = pUM->devParams.intrTxPerSec;
270     }
271     else
272     {
273         pLM->params.int_coalesing_mode = LM_INT_COAL_NONE;
274     }
275 
276     pLM->params.enable_dynamic_hc[0] = 0;
277     pLM->params.enable_dynamic_hc[1] = 0;
278     pLM->params.enable_dynamic_hc[2] = 0;
279     pLM->params.enable_dynamic_hc[3] = 0;
280 
281     /*
282      * l2_fw_flow_ctrl is read from the shmem in MF mode in E2 and above. In
283      * all other cases this parameter is read from the driver conf. We also
284      * read this parameter from the driver conf in E1.5 MF mode since 57711
285      * boot code does not have the struct func_ext_cfg.
286      */
287     if (((pLM->hw_info.mf_info.mf_mode != MULTI_FUNCTION_SI) &&
288          (pLM->hw_info.mf_info.mf_mode != MULTI_FUNCTION_AFEX)) ||
289         (CHIP_IS_E1x(pLM)))
290     {
291         pLM->params.l2_fw_flow_ctrl = (pUM->devParams.l2_fw_flow_ctrl) ? 1 : 0;
292     }
293 
294     pLM->params.rcv_buffer_offset = BNXE_DMA_RX_OFFSET;
295 
296     pLM->params.debug_cap_flags = DEFAULT_DEBUG_CAP_FLAGS_VAL;
297 
298     pLM->params.max_fcoe_task = lm_fc_max_fcoe_task_sup(pLM);
299 
300     /* enable rate shaping */
301     pLM->params.cmng_enable = 1;
302 
303     pLM->params.validate_sq_complete = 1;
304 
305     return LM_STATUS_SUCCESS;
306 }
307 
308 
309 static boolean_t BnxeIsBarUsed(um_device_t * pUM,
310                                int           regNumber,
311                                offset_t      offset,
312                                u32_t         size)
313 {
314     BnxeMemRegion * pMem;
315 
316     BNXE_LOCK_ENTER_MEM(pUM);
317 
318     pMem = (BnxeMemRegion *)d_list_peek_head(&pUM->memRegionList);
319 
320     while (pMem)
321     {
322         if ((pMem->regNumber == regNumber) &&
323             (pMem->offset == offset) &&
324             (pMem->size == size))
325         {
326             BNXE_LOCK_EXIT_MEM(pUM);
327             return B_TRUE;
328         }
329 
330         pMem = (BnxeMemRegion *)d_list_next_entry(D_LINK_CAST(pMem));
331     }
332 
333     BNXE_LOCK_EXIT_MEM(pUM);
334     return B_FALSE;
335 }
336 
337 
338 void * mm_map_io_base(lm_device_t * pLM,
339                       lm_address_t  baseAddr,
340                       u32_t         size,
341                       u8_t          bar)
342 {
343     um_device_t *   pUM = (um_device_t *)pLM;
344     BnxeMemRegion * pMem;
345     //int             numRegs;
346     off_t           regSize;
347     int rc;
348 
349     /*
350      * Solaris identifies:
351      *   BAR 0 - size 0 (pci config regs?)
352      *   BAR 1 - size 0x800000  (Everest 1/2 LM BAR 0)
353      *   BAR 2 - size 0x4000000 (Everest 1   LM BAR 1)
354      *                0x800000  (Everest 2   LM BAR 1)
355      *   BAR 3 - size 0x10000   (Everest 2   LM BAR 2)
356      */
357     bar++;
358 
359     //ddi_dev_nregs(pUM->pDev, &numRegs);
360 
361     ddi_dev_regsize(pUM->pDev, bar, &regSize);
362 
363     if ((size > regSize) || BnxeIsBarUsed(pUM, bar, 0, size))
364     {
365         BnxeLogWarn(pUM, "BAR %d at offset %d and size %d is already being used!",
366                     bar, 0, (int)regSize);
367         return NULL;
368     }
369 
370     if ((pMem = kmem_zalloc(sizeof(BnxeMemRegion), KM_NOSLEEP)) == NULL)
371     {
372         BnxeLogWarn(pUM, "Memory allocation for BAR %d at offset %d and size %d failed!",
373                     bar, 0, (int)regSize);
374         return NULL;
375     }
376 
377     if ((rc = ddi_regs_map_setup(pUM->pDev,
378                                  bar, // bar number
379                                  &pMem->pRegAddr,
380                                  0, // region map offset,
381                                  size, // region memory window size (0=all)
382                                  &bnxeAccessAttribBAR,
383                                  &pMem->regAccess)) != DDI_SUCCESS)
384     {
385         BnxeLogWarn(pUM, "Failed to memory map device (BAR=%d, offset=%d, size=%d) (%d)",
386                     bar, 0, size, rc);
387         kmem_free(pMem, sizeof(BnxeMemRegion));
388         return NULL;
389     }
390 
391     pMem->baseAddr  = baseAddr;
392     pMem->regNumber = bar;
393     pMem->offset    = 0;
394     pMem->size      = size;
395 
396     BNXE_LOCK_ENTER_MEM(pUM);
397     d_list_push_head(&pUM->memRegionList, D_LINK_CAST(pMem));
398     BNXE_LOCK_EXIT_MEM(pUM);
399 
400     bar--;
401     pLM->vars.reg_handle[bar] = pMem->regAccess;
402 
403     return pMem->pRegAddr;
404 }
405 
406 
407 void * mm_map_io_space_solaris(lm_device_t *      pLM,
408                                lm_address_t       physAddr,
409                                u8_t               bar,
410                                u32_t              offset,
411                                u32_t              size,
412                                ddi_acc_handle_t * pRegAccHandle)
413 {
414     um_device_t *   pUM = (um_device_t *)pLM;
415     BnxeMemRegion * pMem;
416     off_t           regSize;
417     int rc;
418 
419     /* see bar mapping described in mm_map_io_base above */
420     bar++;
421 
422     ddi_dev_regsize(pUM->pDev, bar, &regSize);
423 
424     if ((size > regSize) || BnxeIsBarUsed(pUM, bar, offset, size))
425     {
426         BnxeLogWarn(pUM, "BAR %d at offset %d and size %d is already being used!",
427                     bar, offset, (int)regSize);
428         return NULL;
429     }
430 
431     if ((pMem = kmem_zalloc(sizeof(BnxeMemRegion), KM_NOSLEEP)) == NULL)
432     {
433         BnxeLogWarn(pUM, "Memory allocation for BAR %d at offset %d and size %d failed!",
434                     bar, offset, (int)regSize);
435         return NULL;
436     }
437 
438     if ((rc = ddi_regs_map_setup(pUM->pDev,
439                                  bar, // bar number
440                                  &pMem->pRegAddr,
441                                  offset, // region map offset,
442                                  size, // region memory window size (0=all)
443                                  &bnxeAccessAttribBAR,
444                                  pRegAccHandle)) != DDI_SUCCESS)
445     {
446         BnxeLogWarn(pUM, "Failed to memory map device (BAR=%d, offset=%d, size=%d) (%d)",
447                     bar, offset, size, rc);
448         kmem_free(pMem, sizeof(BnxeMemRegion));
449         return NULL;
450     }
451 
452     pMem->baseAddr  = physAddr;
453     pMem->regNumber = bar;
454     pMem->offset    = offset;
455     pMem->size      = size;
456     pMem->regAccess = *pRegAccHandle;
457 
458     BNXE_LOCK_ENTER_MEM(pUM);
459     d_list_push_head(&pUM->memRegionList, D_LINK_CAST(pMem));
460     BNXE_LOCK_EXIT_MEM(pUM);
461 
462     return pMem->pRegAddr;
463 }
464 
465 
466 void mm_unmap_io_space(lm_device_t * pLM,
467                        void *        pVirtAddr,
468                        u32_t         size)
469 {
470     um_device_t *   pUM = (um_device_t *)pLM;
471     BnxeMemRegion * pMemRegion;
472 
473     BNXE_LOCK_ENTER_MEM(pUM);
474 
475     pMemRegion = (BnxeMemRegion *)d_list_peek_head(&pUM->memRegionList);
476 
477     while (pMemRegion)
478     {
479         if ((pMemRegion->pRegAddr == pVirtAddr) &&
480             (pMemRegion->size == size))
481         {
482             d_list_remove_entry(&pUM->memRegionList, D_LINK_CAST(pMemRegion));
483             ddi_regs_map_free(&pMemRegion->regAccess);
484             kmem_free(pMemRegion, sizeof(BnxeMemRegion));
485             break;
486         }
487 
488         pMemRegion = (BnxeMemRegion *)d_list_next_entry(D_LINK_CAST(pMemRegion));
489     }
490 
491     BNXE_LOCK_EXIT_MEM(pUM);
492 }
493 
494 
495 void * mm_alloc_mem_imp(lm_device_t *       pLM,
496                         u32_t               memSize,
497                         const char *        sz_file,
498                         const unsigned long line,
499                         u8_t                cli_idx)
500 {
501     um_device_t *  pUM = (um_device_t *)pLM;
502     BnxeMemBlock * pMem;
503     void *         pBuf;
504     u32_t *        pTmp;
505     int i;
506 
507     (void)cli_idx;
508 
509     if ((pMem = kmem_zalloc(sizeof(BnxeMemBlock), KM_NOSLEEP)) == NULL)
510     {
511         return NULL;
512     }
513 
514     /* allocated space for header/trailer checks */
515     memSize += (BNXE_MEM_CHECK_LEN * 2);
516 
517     MEM_LOG(pUM, "*** MEM: %8u", memSize);
518 
519     if ((pBuf = kmem_zalloc(memSize, KM_NOSLEEP)) == NULL)
520     {
521         BnxeLogWarn(pUM, "Failed to allocate memory");
522         kmem_free(pMem, sizeof(BnxeMemBlock));
523         return NULL;
524     }
525 
526     /* fill in the header check */
527     for (i = 0, pTmp = (u32_t *)pBuf;
528          i < BNXE_MEM_CHECK_LEN;
529          i += 4, pTmp++)
530     {
531         *pTmp = BNXE_MAGIC;
532     }
533 
534     /* fill in the trailer check */
535     for (i = 0, pTmp = (u32_t *)((char *)pBuf + memSize - BNXE_MEM_CHECK_LEN);
536          i < BNXE_MEM_CHECK_LEN;
537          i += 4, pTmp++)
538     {
539         *pTmp = BNXE_MAGIC;
540     }
541 
542     pMem->size = memSize;
543     pMem->pBuf = pBuf;
544     snprintf(pMem->fileName, sizeof(pMem->fileName), "%s", sz_file);
545     pMem->fileLine = line;
546 
547     BNXE_LOCK_ENTER_MEM(pUM);
548     d_list_push_head(&pUM->memBlockList, D_LINK_CAST(pMem));
549     BNXE_LOCK_EXIT_MEM(pUM);
550 
551     MEM_LOG(pUM, "Allocated %d byte block virt:%p",
552             memSize, ((char *)pBuf + BNXE_MEM_CHECK_LEN));
553 
554     return ((char *)pBuf + BNXE_MEM_CHECK_LEN);
555 }
556 
557 
558 void * mm_alloc_phys_mem_align_imp(lm_device_t *       pLM,
559                                    u32_t               memSize,
560                                    lm_address_t *      pPhysAddr,
561                                    u32_t               alignment,
562                                    u8_t                memType,
563                                    const char *        sz_file,
564                                    const unsigned long line,
565                                    u8_t                cli_idx)
566 {
567     um_device_t * pUM = (um_device_t *)pLM;
568     int rc;
569     caddr_t pBuf;
570     size_t length;
571     unsigned int count;
572     ddi_dma_attr_t     dmaAttrib;
573     ddi_dma_handle_t * pDmaHandle;
574     ddi_acc_handle_t * pDmaAccHandle;
575     ddi_dma_cookie_t cookie;
576     BnxeMemDma * pMem;
577     size_t size;
578 
579     (void)memType;
580     (void)cli_idx;
581 
582     if (memSize == 0)
583     {
584         return NULL;
585     }
586 
587     if ((pMem = kmem_zalloc(sizeof(BnxeMemDma), KM_NOSLEEP)) == NULL)
588     {
589         return NULL;
590     }
591 
592     dmaAttrib                = bnxeDmaPageAttrib;
593     dmaAttrib.dma_attr_align = alignment;
594 
595     pDmaHandle    = &pMem->dmaHandle;
596     pDmaAccHandle = &pMem->dmaAccHandle;
597 
598     size  = memSize;
599     size += (alignment - 1);
600     size &= ~((u32_t)(alignment - 1));
601 
602     MEM_LOG(pUM, "*** DMA: %8u (%4d) - %8u", memSize, alignment, size);
603 
604     if ((rc = ddi_dma_alloc_handle(pUM->pDev,
605                                    &dmaAttrib,
606                                    DDI_DMA_DONTWAIT,
607                                    (void *)0,
608                                    pDmaHandle)) != DDI_SUCCESS)
609     {
610         BnxeLogWarn(pUM, "Failed to alloc DMA handle");
611         kmem_free(pMem, sizeof(BnxeMemDma));
612         return NULL;
613     }
614 
615     if ((rc = ddi_dma_mem_alloc(*pDmaHandle,
616                                 size,
617                                 &bnxeAccessAttribBUF,
618                                 DDI_DMA_CONSISTENT,
619                                 DDI_DMA_DONTWAIT,
620                                 (void *)0,
621                                 &pBuf,
622                                 &length,
623                                 pDmaAccHandle)) != DDI_SUCCESS)
624     {
625         BnxeLogWarn(pUM, "Failed to alloc DMA memory");
626         ddi_dma_free_handle(pDmaHandle);
627         kmem_free(pMem, sizeof(BnxeMemDma));
628         return NULL;
629     }
630 
631     if ((rc = ddi_dma_addr_bind_handle(*pDmaHandle,
632                                        (struct as *)0,
633                                        pBuf,
634                                        length,
635                                        DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
636                                        DDI_DMA_DONTWAIT,
637                                        (void *)0,
638                                        &cookie,
639                                        &count)) != DDI_DMA_MAPPED)
640     {
641         BnxeLogWarn(pUM, "Failed to bind DMA address");
642         ddi_dma_mem_free(pDmaAccHandle);
643         ddi_dma_free_handle(pDmaHandle);
644         kmem_free(pMem, sizeof(BnxeMemDma));
645         return NULL;
646     }
647 
648     pPhysAddr->as_u64 = cookie.dmac_laddress;
649 
650     /* save the virtual memory address so we can get the dma_handle later */
651     pMem->size     = memSize;
652     pMem->pDmaVirt = pBuf;
653     pMem->physAddr = *pPhysAddr;
654     snprintf(pMem->fileName, sizeof(pMem->fileName), "%s", sz_file);
655     pMem->fileLine = line;
656 
657 #if 0
658     MEM_LOG(pUM, "*** DMA: virt %p / phys 0x%0llx (%d/%d)",
659             pBuf, pPhysAddr->as_u64,
660             (!((u32_t)pBuf % (u32_t)alignment)) ? 1 : 0,
661             (!((u32_t)pPhysAddr->as_ptr % (u32_t)alignment) ? 1 : 0));
662 #endif
663 
664     BNXE_LOCK_ENTER_MEM(pUM);
665     d_list_push_head(&pUM->memDmaList, D_LINK_CAST(pMem));
666     BNXE_LOCK_EXIT_MEM(pUM);
667 
668     MEM_LOG(pUM, "Allocated %d sized DMA block phys:%p virt:%p",
669             memSize, pMem->physAddr.as_ptr, pMem->pDmaVirt);
670 
671     /* Zero memory! */
672     bzero(pBuf, length);
673 
674     /* make sure the new contents are flushed back to main memory */
675     ddi_dma_sync(*pDmaHandle, 0, length, DDI_DMA_SYNC_FORDEV);
676 
677     return pBuf;
678 }
679 
680 
681 void * mm_alloc_phys_mem_imp(lm_device_t *       pLM,
682                              u32_t               memSize,
683                              lm_address_t *      pPhysAddr,
684                              u8_t                memType,
685                              const char *        sz_file,
686                              const unsigned long line,
687                              u8_t                cli_idx)
688 {
689     return mm_alloc_phys_mem_align_imp(pLM, memSize, pPhysAddr,
690                                        BNXE_DMA_ALIGNMENT, memType,
691                                        sz_file, line, cli_idx);
692 }
693 
694 
695 void * mm_rt_alloc_mem_imp(lm_device_t *       pDev,
696                            u32_t               memSize,
697                            const char *        sz_file,
698                            const unsigned long line,
699                            u8_t                cli_idx)
700 {
701     return mm_alloc_mem_imp(pDev, memSize, sz_file, line, cli_idx);
702 }
703 
704 
705 void * mm_rt_alloc_phys_mem_imp(lm_device_t *       pDev,
706                                 u32_t               memSize,
707                                 lm_address_t *      pPhysAddr,
708                                 u8_t                flushType,
709                                 const char *        sz_file,
710                                 const unsigned long line,
711                                 u8_t                cli_idx)
712 {
713     return mm_alloc_phys_mem_imp(pDev, memSize, pPhysAddr, flushType,
714                                  sz_file, line, cli_idx);
715 }
716 
717 
718 u64_t mm_get_current_time(lm_device_t * pDev)
719 {
720     um_device_t * pUM = (um_device_t *)pDev;
721     BnxeDbgBreakMsg(pUM, "MM_GET_CURRENT_TIME");
722     return 0;
723 }
724 
725 
726 void mm_rt_free_mem(lm_device_t * pDev,
727                     void *        pBuf,
728                     u32_t         memSize,
729                     u8_t          cli_idx)
730 {
731     um_device_t *  pUM = (um_device_t *)pDev;
732     BnxeMemBlock * pMem;
733     u32_t *        pTmp;
734     int i;
735 
736     (void)cli_idx;
737 
738     BNXE_LOCK_ENTER_MEM(pUM);
739 
740     pMem = (BnxeMemBlock *)d_list_peek_head(&pUM->memBlockList);
741 
742     /* adjuest for header/trailer checks */
743     pBuf = ((char *)pBuf - BNXE_MEM_CHECK_LEN);
744     memSize += (BNXE_MEM_CHECK_LEN * 2);
745 
746     /* verify header check */
747     for (i = 0, pTmp = (u32_t *)pBuf;
748          i < BNXE_MEM_CHECK_LEN;
749          i += 4, pTmp++)
750     {
751         if (*pTmp != BNXE_MAGIC)
752         {
753             BnxeLogWarn(pUM, "Header overflow! (%p/%u)", pBuf, memSize);
754             BnxeDbgBreak(pUM);
755         }
756     }
757 
758     /* verify trailer check */
759     for (i = 0, pTmp = (u32_t *)((char *)pBuf + memSize - BNXE_MEM_CHECK_LEN);
760          i < BNXE_MEM_CHECK_LEN;
761          i += 4, pTmp++)
762     {
763         if (*pTmp != BNXE_MAGIC)
764         {
765             BnxeLogWarn(pUM, "Trailer overflow! (%p/%u)", pBuf, memSize);
766             BnxeDbgBreak(pUM);
767         }
768     }
769 
770     while (pMem)
771     {
772         if (pBuf == pMem->pBuf)
773         {
774             if (memSize != pMem->size)
775             {
776                 /* Uh-Oh! */
777                 BnxeLogWarn(pUM, "Attempt to free memory block with invalid size (%d/%d)",
778                             memSize, pMem->size);
779                 BnxeDbgBreak(pUM);
780 
781                 BNXE_LOCK_EXIT_MEM(pUM);
782                 return;
783             }
784 
785             d_list_remove_entry(&pUM->memBlockList, D_LINK_CAST(pMem));
786 
787             kmem_free(pBuf, memSize);
788             kmem_free(pMem, sizeof(BnxeMemBlock));
789 
790             BNXE_LOCK_EXIT_MEM(pUM);
791             return;
792         }
793 
794         pMem = (BnxeMemBlock *)d_list_next_entry(D_LINK_CAST(pMem));
795     }
796 
797     BNXE_LOCK_EXIT_MEM(pUM);
798 }
799 
800 
801 void mm_rt_free_phys_mem(lm_device_t * pDev,
802                          u32_t         memSize,
803                          void *        pBuf,
804                          lm_address_t  pPhysAddr,
805                          u8_t          cli_idx)
806 {
807     um_device_t * pUM = (um_device_t *)pDev;
808     BnxeMemDma * pMem;
809 
810     (void)pPhysAddr;
811     (void)cli_idx;
812 
813     BNXE_LOCK_ENTER_MEM(pUM);
814 
815     pMem = (BnxeMemDma *)d_list_peek_head(&pUM->memDmaList);
816 
817     while (pMem)
818     {
819         if (pBuf == pMem->pDmaVirt)
820         {
821             if (memSize != pMem->size)
822             {
823                 /* Uh-Oh! */
824                 BnxeLogWarn(pUM, "Attempt to free DMA memory with invalid size (%d/%d)",
825                             memSize, pMem->size);
826                 BnxeDbgBreak(pUM);
827 
828                 BNXE_LOCK_EXIT_MEM(pUM);
829                 return;
830             }
831 
832             d_list_remove_entry(&pUM->memDmaList, D_LINK_CAST(pMem));
833 
834             ddi_dma_unbind_handle(pMem->dmaHandle);
835             ddi_dma_mem_free(&pMem->dmaAccHandle);
836             ddi_dma_free_handle(&pMem->dmaHandle);
837             kmem_free(pMem, sizeof(BnxeMemDma));
838 
839             BNXE_LOCK_EXIT_MEM(pUM);
840             return;
841         }
842 
843         pMem = (BnxeMemDma *)d_list_next_entry(D_LINK_CAST(pMem));
844     }
845 
846     BNXE_LOCK_EXIT_MEM(pUM);
847 }
848 
849 
850 void mm_memset(void * pBuf,
851                u8_t   val,
852                u32_t  memSize)
853 {
854     memset(pBuf, val, memSize);
855 }
856 
857 
858 void mm_memcpy(void *       pDest,
859                const void * pSrc,
860                u32_t        memSize)
861 {
862     memcpy(pDest, pSrc, memSize);
863 }
864 
865 
866 u8_t mm_memcmp(void * pBuf1,
867                void * pBuf2,
868                u32_t  count)
869 {
870     return (memcmp(pBuf1, pBuf2, count) == 0) ? 1 : 0;
871 }
872 
873 
874 void mm_indicate_tx(lm_device_t * pLM,
875                     u32_t         idx,
876                     s_list_t *    packet_list)
877 {
878     BnxeTxPktsReclaim((um_device_t *)pLM, idx, packet_list);
879 }
880 
881 
882 void mm_set_done(lm_device_t * pDev,
883                  u32_t         cid,
884                  void *        cookie)
885 {
886 #if 0
887     um_device_t * pUM = (um_device_t *)pDev;
888     BnxeLogInfo(pUM, "RAMROD on cid %d cmd is done", cid);
889 #else
890     (void)pDev;
891     (void)cid;
892 #endif
893 }
894 
895 
896 void mm_return_sq_pending_command(lm_device_t *               pDev,
897                                   struct sq_pending_command * pPending)
898 {
899     /* XXX probably need a memory pool to pull from... */
900     mm_rt_free_mem(pDev, pPending, sizeof(struct sq_pending_command),
901                    LM_CLI_IDX_NDIS);
902 }
903 
904 
905 struct sq_pending_command * mm_get_sq_pending_command(lm_device_t * pDev)
906 {
907     /* XXX probably need a memory pool to pull from... */
908     return mm_rt_alloc_mem(pDev, sizeof(struct sq_pending_command),
909                            LM_CLI_IDX_NDIS);
910 }
911 
912 
913 u32_t mm_copy_packet_buf(lm_device_t * pDev,
914                          lm_packet_t * pLMPkt,
915                          u8_t *        pMemBuf,
916                          u32_t         size)
917 {
918     //um_device_t *   pUM = (um_device_t *)pDev;
919     um_txpacket_t * pTxPkt = (um_txpacket_t *)pLMPkt;
920     mblk_t *        pMblk;
921     u32_t           copied;
922     u32_t           mblkDataLen;
923     u32_t           toCopy;
924 
925     pMblk  = pTxPkt->pMblk;
926     copied = 0;
927 
928     while (size && pMblk)
929     {
930         mblkDataLen = (pMblk->b_wptr - pMblk->b_rptr);
931         toCopy = (mblkDataLen <= size) ? mblkDataLen : size;
932 
933         bcopy(pMblk->b_rptr, pMemBuf, toCopy);
934 
935         pMemBuf += toCopy;
936         copied  += toCopy;
937         size    -= toCopy;
938 
939         pMblk = pMblk->b_cont;
940     }
941 
942     return copied;
943 }
944 
945 
946 lm_status_t mm_fan_failure(lm_device_t * pDev)
947 {
948     um_device_t * pUM = (um_device_t *)pDev;
949     BnxeLogWarn(pUM, "FAN FAILURE!");
950     return LM_STATUS_SUCCESS;
951 }
952 
953 
954 static void BnxeLinkStatus(um_device_t * pUM,
955                            lm_status_t   link,
956                            lm_medium_t   medium)
957 {
958     #define TBUF_SIZE 64
959     char tbuf[TBUF_SIZE];
960     char * pDuplex;
961     char * pRxFlow;
962     char * pTxFlow;
963     char * pSpeed;
964 
965     if (link != LM_STATUS_LINK_ACTIVE)
966     {
967         /* reset the link status */
968         pUM->props.link_speed   = 0;
969         pUM->props.link_duplex  = B_FALSE;
970         pUM->props.link_txpause = B_FALSE;
971         pUM->props.link_rxpause = B_FALSE;
972         pUM->props.uptime       = 0;
973 
974         /* reset the link partner status */
975         pUM->remote.link_autoneg   = B_FALSE;
976         pUM->remote.param_20000fdx = B_FALSE;
977         pUM->remote.param_10000fdx = B_FALSE;
978         pUM->remote.param_2500fdx  = B_FALSE;
979         pUM->remote.param_1000fdx  = B_FALSE;
980         pUM->remote.param_100fdx   = B_FALSE;
981         pUM->remote.param_100hdx   = B_FALSE;
982         pUM->remote.param_10fdx    = B_FALSE;
983         pUM->remote.param_10hdx    = B_FALSE;
984         pUM->remote.param_txpause  = B_FALSE;
985         pUM->remote.param_rxpause  = B_FALSE;
986 
987         BnxeLogInfo(pUM, "Link Down");
988         return;
989     }
990 
991     pUM->props.uptime = ddi_get_time();
992 
993     if (GET_MEDIUM_DUPLEX(medium) == LM_MEDIUM_HALF_DUPLEX)
994     {
995         pDuplex = "Half";
996         pUM->props.link_duplex = B_FALSE;
997     }
998     else
999     {
1000         pDuplex = "Full";
1001         pUM->props.link_duplex = B_TRUE;
1002     }
1003 
1004     if (pUM->lm_dev.vars.flow_control & LM_FLOW_CONTROL_RECEIVE_PAUSE)
1005     {
1006         pRxFlow = "ON";
1007         pUM->props.link_rxpause = B_TRUE;
1008     }
1009     else
1010     {
1011         pRxFlow = "OFF";
1012         pUM->props.link_rxpause = B_FALSE;
1013     }
1014 
1015     if (pUM->lm_dev.vars.flow_control & LM_FLOW_CONTROL_TRANSMIT_PAUSE)
1016     {
1017         pTxFlow = "ON";
1018         pUM->props.link_txpause = B_TRUE;
1019     }
1020     else
1021     {
1022         pTxFlow = "OFF";
1023         pUM->props.link_txpause = B_FALSE;
1024     }
1025 
1026 #if 0
1027     if (pUM->curcfg.lnkcfg.link_autoneg == B_TRUE)
1028     {
1029         BnxeUpdateLpCap(pUM);
1030     }
1031 #endif
1032 
1033     switch (GET_MEDIUM_SPEED(medium))
1034     {
1035     case LM_MEDIUM_SPEED_10MBPS:
1036 
1037         pUM->props.link_speed = 10;
1038         pSpeed = "10Mb";
1039         break;
1040 
1041     case LM_MEDIUM_SPEED_100MBPS:
1042 
1043         pUM->props.link_speed = 100;
1044         pSpeed = "100Mb";
1045         break;
1046 
1047     case LM_MEDIUM_SPEED_1000MBPS:
1048 
1049         pUM->props.link_speed = 1000;
1050         pSpeed = "1Gb";
1051         break;
1052 
1053     case LM_MEDIUM_SPEED_2500MBPS:
1054 
1055         pUM->props.link_speed = 2500;
1056         pSpeed = "2.5Gb";
1057         break;
1058 
1059     case LM_MEDIUM_SPEED_10GBPS:
1060 
1061         pUM->props.link_speed = 10000;
1062         pSpeed = "10Gb";
1063         break;
1064 
1065     case LM_MEDIUM_SPEED_12GBPS:
1066 
1067         pUM->props.link_speed = 12000;
1068         pSpeed = "12Gb";
1069         break;
1070 
1071     case LM_MEDIUM_SPEED_12_5GBPS:
1072 
1073         pUM->props.link_speed = 12500;
1074         pSpeed = "12.5Gb";
1075         break;
1076 
1077     case LM_MEDIUM_SPEED_13GBPS:
1078 
1079         pUM->props.link_speed = 13000;
1080         pSpeed = "13Gb";
1081         break;
1082 
1083     case LM_MEDIUM_SPEED_15GBPS:
1084 
1085         pUM->props.link_speed = 15000;
1086         pSpeed = "15Gb";
1087         break;
1088 
1089     case LM_MEDIUM_SPEED_16GBPS:
1090 
1091         pUM->props.link_speed = 16000;
1092         pSpeed = "16Gb";
1093         break;
1094 
1095     case LM_MEDIUM_SPEED_20GBPS:
1096 
1097         pUM->props.link_speed = 20000;
1098         pSpeed = "20Gb";
1099         break;
1100 
1101     default:
1102 
1103         if ((GET_MEDIUM_SPEED(medium) >= LM_MEDIUM_SPEED_SEQ_START) &&
1104             (GET_MEDIUM_SPEED(medium) <= LM_MEDIUM_SPEED_SEQ_END))
1105         {
1106             pUM->props.link_speed = (((GET_MEDIUM_SPEED(medium) >> 8) -
1107                                       (LM_MEDIUM_SPEED_SEQ_START >> 8) +
1108                                       1) * 100);
1109             snprintf(tbuf, TBUF_SIZE, "%u", pUM->props.link_speed);
1110             pSpeed = tbuf;
1111             break;
1112         }
1113 
1114         pUM->props.link_speed = 0;
1115         pSpeed = "";
1116 
1117         break;
1118     }
1119 
1120     if (*pSpeed == 0)
1121     {
1122         BnxeLogInfo(pUM, "%s Duplex Rx Flow %s Tx Flow %s Link Up",
1123                     pDuplex, pRxFlow, pTxFlow);
1124     }
1125     else
1126     {
1127         BnxeLogInfo(pUM, "%s %s Duplex Rx Flow %s Tx Flow %s Link Up",
1128                     pSpeed, pDuplex, pRxFlow, pTxFlow);
1129     }
1130 }
1131 
1132 
1133 void mm_indicate_link(lm_device_t * pLM,
1134                       lm_status_t   link,
1135                       lm_medium_t   medium)
1136 {
1137     um_device_t * pUM = (um_device_t *)pLM;
1138 
1139     /* ignore link status if it has not changed since the last indicate */
1140     if ((pUM->devParams.lastIndLink == link) &&
1141         (pUM->devParams.lastIndMedium == medium))
1142     {
1143         return;
1144     }
1145 
1146     pUM->devParams.lastIndLink   = link;
1147     pUM->devParams.lastIndMedium = medium;
1148 
1149     BnxeLinkStatus(pUM, link, medium);
1150 
1151     if (CLIENT_BOUND(pUM, LM_CLI_IDX_NDIS))
1152     {
1153         BnxeGldLink(pUM, (link == LM_STATUS_LINK_ACTIVE) ?
1154                              LINK_STATE_UP : LINK_STATE_DOWN);
1155     }
1156 
1157     if (CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE))
1158     {
1159         if (pUM->fcoe.pDev == NULL)
1160         {
1161             BnxeLogWarn(pUM, "FCoE Client bound and pDev is NULL (LINK STATUS failed!) %s@%s",
1162                         BNXEF_NAME, ddi_get_name_addr(pUM->pDev));
1163         }
1164         else if (pUM->fcoe.bind.cliCtl == NULL)
1165         {
1166             BnxeLogWarn(pUM, "FCoE Client bound and cliCtl is NULL (LINK STATUS failed!) %s@%s",
1167                         BNXEF_NAME, ddi_get_name_addr(pUM->pDev));
1168         }
1169         else
1170         {
1171             pUM->fcoe.bind.cliCtl(pUM->fcoe.pDev,
1172                                   (link == LM_STATUS_LINK_ACTIVE) ?
1173                                       CLI_CTL_LINK_UP : CLI_CTL_LINK_DOWN,
1174                                   NULL,
1175                                   0);
1176         }
1177     }
1178 }
1179 
1180 
1181 lm_status_t mm_schedule_task(lm_device_t * pDev,
1182                              u32_t         delay_ms,
1183                              lm_task_cb_t  task,
1184                              void *        param)
1185 {
1186     um_device_t * pUM = (um_device_t *)pDev;
1187 
1188     BnxeWorkQueueAddDelayNoCopy(pUM, (void (*)(um_device_t *, void *))task, param, delay_ms);
1189 
1190     return LM_STATUS_SUCCESS;
1191 }
1192 
1193 
1194 lm_status_t mm_register_lpme(lm_device_t *                  pDev,
1195                              lm_generic_workitem_function * func,
1196                              u8_t                           b_fw_access,
1197                              u8_t                           b_queue_for_fw)
1198 {
1199     um_device_t * pUM = (um_device_t *)pDev;
1200 
1201     (void)b_fw_access;
1202     (void)b_queue_for_fw;
1203 
1204     BnxeWorkQueueAddGeneric(pUM, (void (*)(um_device_t *))func);
1205 
1206     return LM_STATUS_SUCCESS;
1207 }
1208 
1209 
1210 void MM_ACQUIRE_SPQ_LOCK_IMP(lm_device_t * pDev)
1211 {
1212     BNXE_LOCK_ENTER_SPQ((um_device_t *)pDev);
1213 }
1214 
1215 
1216 void MM_RELEASE_SPQ_LOCK_IMP(lm_device_t * pDev)
1217 {
1218     BNXE_LOCK_EXIT_SPQ((um_device_t *)pDev);
1219 }
1220 
1221 
1222 void MM_ACQUIRE_SPQ_LOCK_DPC_IMP(lm_device_t * pDev)
1223 {
1224     BNXE_LOCK_ENTER_SPQ((um_device_t *)pDev);
1225 }
1226 
1227 
1228 void MM_RELEASE_SPQ_LOCK_DPC_IMP(lm_device_t * pDev)
1229 {
1230     BNXE_LOCK_EXIT_SPQ((um_device_t *)pDev);
1231 }
1232 
1233 
1234 void MM_ACQUIRE_CID_LOCK_IMP(lm_device_t * pDev)
1235 {
1236     BNXE_LOCK_ENTER_CID((um_device_t *)pDev);
1237 }
1238 
1239 
1240 void MM_RELEASE_CID_LOCK_IMP(lm_device_t * pDev)
1241 {
1242     BNXE_LOCK_EXIT_CID((um_device_t *)pDev);
1243 }
1244 
1245 
1246 void MM_ACQUIRE_REQUEST_LOCK_IMP(lm_device_t * pDev)
1247 {
1248     BNXE_LOCK_ENTER_RRREQ((um_device_t *)pDev);
1249 }
1250 
1251 
1252 void MM_RELEASE_REQUEST_LOCK_IMP(lm_device_t * pDev)
1253 {
1254     BNXE_LOCK_EXIT_RRREQ((um_device_t *)pDev);
1255 }
1256 
1257 
1258 void MM_ACQUIRE_PHY_LOCK_IMP(lm_device_t * pDev)
1259 {
1260     BNXE_LOCK_ENTER_PHY((um_device_t *)pDev);
1261 }
1262 
1263 
1264 void MM_RELEASE_PHY_LOCK_IMP(lm_device_t * pDev)
1265 {
1266     BNXE_LOCK_EXIT_PHY((um_device_t *)pDev);
1267 }
1268 
1269 
1270 void MM_ACQUIRE_PHY_LOCK_DPC_IMP(lm_device_t * pDev)
1271 {
1272     BNXE_LOCK_ENTER_PHY((um_device_t *)pDev);
1273 }
1274 
1275 
1276 void MM_RELEASE_PHY_LOCK_DPC_IMP(lm_device_t * pDev)
1277 {
1278     BNXE_LOCK_EXIT_PHY((um_device_t *)pDev);
1279 }
1280 
1281 
1282 void mm_init_lock(lm_device_t *    pDev,
1283                   mm_spin_lock_t * spinlock)
1284 {
1285     um_device_t * pUM = (um_device_t *)pDev;
1286 
1287     mutex_init(spinlock, NULL,
1288                MUTEX_DRIVER, DDI_INTR_PRI(pUM->intrPriority));
1289 }
1290 
1291 
1292 lm_status_t mm_acquire_lock(mm_spin_lock_t * spinlock)
1293 {
1294     if (spinlock == NULL)
1295     {
1296         return LM_STATUS_INVALID_PARAMETER;
1297     }
1298 
1299     mutex_enter(spinlock);
1300 
1301     return LM_STATUS_SUCCESS;
1302 }
1303 
1304 
1305 lm_status_t mm_release_lock(mm_spin_lock_t * spinlock)
1306 {
1307     if (spinlock == NULL)
1308     {
1309         return LM_STATUS_INVALID_PARAMETER;
1310     }
1311 
1312     mutex_exit(spinlock);
1313 
1314     return LM_STATUS_SUCCESS;
1315 }
1316 
1317 
1318 void MM_ACQUIRE_MCP_LOCK_IMP(lm_device_t * pDev)
1319 {
1320     BNXE_LOCK_ENTER_MCP((um_device_t *)pDev);
1321 }
1322 
1323 
1324 void MM_RELEASE_MCP_LOCK_IMP(lm_device_t * pDev)
1325 {
1326     BNXE_LOCK_EXIT_MCP((um_device_t *)pDev);
1327 }
1328 
1329 
1330 void MM_ACQUIRE_ISLES_CONTROL_LOCK_IMP(lm_device_t * pDev)
1331 {
1332     BNXE_LOCK_ENTER_ISLES_CONTROL((um_device_t *)pDev);
1333 }
1334 
1335 
1336 void MM_RELEASE_ISLES_CONTROL_LOCK_IMP(lm_device_t * pDev)
1337 {
1338     BNXE_LOCK_EXIT_ISLES_CONTROL((um_device_t *)pDev);
1339 }
1340 
1341 
1342 void MM_ACQUIRE_ISLES_CONTROL_LOCK_DPC_IMP(lm_device_t * pDev)
1343 {
1344     BNXE_LOCK_ENTER_ISLES_CONTROL((um_device_t *)pDev);
1345 }
1346 
1347 
1348 void MM_RELEASE_ISLES_CONTROL_LOCK_DPC_IMP(lm_device_t * pDev)
1349 {
1350     BNXE_LOCK_EXIT_ISLES_CONTROL((um_device_t *)pDev);
1351 }
1352 
1353 
1354 void MM_ACQUIRE_IND_REG_LOCK_IMP(lm_device_t * pDev)
1355 {
1356     BNXE_LOCK_ENTER_IND((um_device_t *)pDev);
1357 }
1358 
1359 
1360 void MM_RELEASE_IND_REG_LOCK_IMP(lm_device_t * pDev)
1361 {
1362     BNXE_LOCK_EXIT_IND((um_device_t *)pDev);
1363 }
1364 
1365 
1366 void MM_ACQUIRE_LOADER_LOCK_IMP()
1367 {
1368     mutex_enter(&bnxeLoaderMutex);
1369 }
1370 
1371 
1372 void MM_RELEASE_LOADER_LOCK_IMP()
1373 {
1374     mutex_exit(&bnxeLoaderMutex);
1375 }
1376 
1377 
1378 void MM_ACQUIRE_SP_REQ_MGR_LOCK_IMP(lm_device_t * pDev)
1379 {
1380     BNXE_LOCK_ENTER_SPREQ((um_device_t *)pDev);
1381 }
1382 
1383 
1384 void MM_RELEASE_SP_REQ_MGR_LOCK_IMP(lm_device_t * pDev)
1385 {
1386     BNXE_LOCK_EXIT_SPREQ((um_device_t *)pDev);
1387 }
1388 
1389 
1390 void MM_ACQUIRE_SB_LOCK_IMP(lm_device_t * pDev, u8_t sb_idx)
1391 {
1392     BNXE_LOCK_ENTER_SB((um_device_t *)pDev, sb_idx);
1393 }
1394 
1395 
1396 void MM_RELEASE_SB_LOCK_IMP(lm_device_t * pDev, u8_t sb_idx)
1397 {
1398     BNXE_LOCK_EXIT_SB((um_device_t *)pDev, sb_idx);
1399 }
1400 
1401 
1402 void MM_ACQUIRE_ETH_CON_LOCK_IMP(lm_device_t * pDev)
1403 {
1404     BNXE_LOCK_ENTER_ETH_CON((um_device_t *)pDev);
1405 }
1406 
1407 
1408 void MM_RELEASE_ETH_CON_LOCK_IMP(lm_device_t * pDev)
1409 {
1410     BNXE_LOCK_EXIT_ETH_CON((um_device_t *)pDev);
1411 }
1412 
1413 
1414 unsigned int mm_crc32(unsigned char * address,
1415                       unsigned int    size,
1416                       unsigned int    crc)
1417 {
1418     return 0;
1419 }
1420 
1421 
1422 unsigned short mm_crc16(unsigned char * address,
1423                         unsigned int    size,
1424                         unsigned short  crc)
1425 {
1426     return 0;
1427 }
1428 
1429 
1430 lm_status_t mm_event_log_generic_arg_fwd(lm_device_t *     pDev,
1431                                          const lm_log_id_t lm_log_id,
1432                                          va_list           argp)
1433 {
1434     um_device_t * pUM = (um_device_t *)pDev;
1435     u8_t          port = 0 ;
1436     char *        sz_vendor_name = NULL;
1437     char *        sz_vendor_pn = NULL;
1438 
1439     switch (lm_log_id)
1440     {
1441     case LM_LOG_ID_FAN_FAILURE: // fan failure detected
1442 
1443         BnxeLogWarn(pUM, "FAN FAILURE!");
1444         break;
1445 
1446     case LM_LOG_ID_UNQUAL_IO_MODULE: // SFP+ unqualified io module
1447         /*
1448          * expected parameters:
1449          * u8 port, const char * vendor_name, const char * vendor_pn
1450          */
1451         port           = va_arg(argp, int);
1452         sz_vendor_name = va_arg(argp, char*);
1453         sz_vendor_pn   = va_arg(argp, char*);
1454 
1455         BnxeLogInfo(pUM, "Unqualified IO Module: %s %s (port=%d)",
1456                     sz_vendor_name, sz_vendor_pn, port);
1457         break;
1458 
1459     case LM_LOG_ID_OVER_CURRENT: // SFP+ over current power
1460         /*
1461          * expected parametrs:
1462          * u8 port
1463          */
1464         port = va_arg(argp, int);
1465 
1466         BnxeLogWarn(pUM, "SFP+ over current, power failure! (port=%d)", port);
1467         break;
1468 
1469     case LM_LOG_ID_NO_10G_SUPPORT: // 10g speed is requested but not supported
1470         /*
1471          * expected parametrs:
1472          * u8 port
1473          */
1474         port = va_arg(argp, int);
1475 
1476         BnxeLogWarn(pUM, "10Gb speed not supported! (port=%d)", port);
1477         break;
1478 
1479     case LM_LOG_ID_PHY_UNINITIALIZED:
1480         /*
1481          * expected parametrs:
1482          * u8 port
1483          */
1484         port = va_arg(argp, int);
1485 
1486         BnxeLogWarn(pUM, "PHY uninitialized! (port=%d)", port);
1487         break;
1488 
1489     case LM_LOG_ID_MDIO_ACCESS_TIMEOUT:
1490 
1491 #define MM_PORT_NUM(pdev)                               \
1492         (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4) ? \
1493             (PATH_ID(pdev) + (2 * PORT_ID(pdev)))     : \
1494             (PATH_ID(pdev) + PORT_ID(pdev))
1495 
1496         port = MM_PORT_NUM(&pUM->lm_dev);
1497 
1498         BnxeLogWarn(pUM, "MDIO access timeout! (port=%d)", port);
1499         break;
1500 
1501     default:
1502 
1503         BnxeLogWarn(pUM, "Unknown MM event log! (type=%d)", lm_log_id);
1504         break;
1505     }
1506 
1507     return LM_STATUS_SUCCESS;
1508 }
1509 
1510 
1511 lm_status_t mm_event_log_generic(lm_device_t *     pDev,
1512                                  const lm_log_id_t lm_log_id,
1513                                  ...)
1514 {
1515     lm_status_t lm_status = LM_STATUS_SUCCESS;
1516     va_list argp;
1517 
1518     va_start(argp, lm_log_id);
1519     lm_status = mm_event_log_generic_arg_fwd(pDev, lm_log_id, argp);
1520     va_end(argp);
1521 
1522     return lm_status;
1523 }
1524 
1525 
1526 u32_t mm_build_ver_string(lm_device_t * pDev)
1527 {
1528     um_device_t * pUM = (um_device_t *)pDev;
1529 
1530     snprintf((char *)pDev->ver_str,
1531              sizeof(pDev->ver_str),
1532              "%s",
1533              pUM->version);
1534 
1535     return min(strlen((char *)pDev->ver_str), strlen(pUM->version));
1536 }
1537 
1538 
1539 void mm_indicate_hw_failure(lm_device_t * pDev)
1540 {
1541     um_device_t * pUM = (um_device_t *)pDev;
1542 
1543     BnxeLogWarn(pUM, "HW failure indicated!");
1544 }
1545 
1546 
1547 void mm_bar_read_byte(struct _lm_device_t *pdev,
1548                       u8_t bar,
1549                       u32_t offset,
1550                       u8_t *ret)
1551 {
1552     mm_read_barrier();
1553     *ret = ddi_get8(pdev->vars.reg_handle[bar],
1554                     (uint8_t *)((caddr_t)pdev->vars.mapped_bar_addr[bar] +
1555                                 offset));
1556 }
1557 
1558 
1559 void mm_bar_read_word(struct _lm_device_t *pdev,
1560                       u8_t bar,
1561                       u32_t offset,
1562                       u16_t *ret)
1563 {
1564     mm_read_barrier();
1565     *ret = ddi_get16(pdev->vars.reg_handle[bar],
1566                      (uint16_t *)((caddr_t)pdev->vars.mapped_bar_addr[bar] +
1567                                   offset));
1568 }
1569 
1570 
1571 void mm_bar_read_dword(struct _lm_device_t *pdev,
1572                        u8_t bar,
1573                        u32_t offset,
1574                        u32_t *ret)
1575 {
1576     mm_read_barrier();
1577     *ret = ddi_get32(pdev->vars.reg_handle[bar],
1578                      (uint32_t *)((caddr_t)pdev->vars.mapped_bar_addr[bar] +
1579                                   offset));
1580 }
1581 
1582 
1583 void mm_bar_read_ddword(struct _lm_device_t *pdev,
1584                         u8_t bar,
1585                         u32_t offset,
1586                         u64_t *ret)
1587 {
1588     mm_read_barrier();
1589     *ret = ddi_get64(pdev->vars.reg_handle[bar],
1590                      (uint64_t *)((caddr_t)pdev->vars.mapped_bar_addr[bar] +
1591                                   offset));
1592 }
1593 
1594 
1595 void mm_bar_write_byte(struct _lm_device_t *pdev,
1596                        u8_t bar,
1597                        u32_t offset,
1598                        u8_t val)
1599 {
1600     ddi_put8(pdev->vars.reg_handle[bar],
1601              (uint8_t *)((caddr_t)pdev->vars.mapped_bar_addr[bar] + offset),
1602              val);
1603     mm_write_barrier();
1604 }
1605 
1606 
1607 void mm_bar_write_word(struct _lm_device_t *pdev,
1608                        u8_t bar,
1609                        u32_t offset,
1610                        u16_t val)
1611 {
1612     ddi_put16(pdev->vars.reg_handle[bar],
1613               (uint16_t *)((caddr_t)pdev->vars.mapped_bar_addr[bar] + offset),
1614               val);
1615     mm_write_barrier();
1616 }
1617 
1618 
1619 void mm_bar_write_dword(struct _lm_device_t *pdev,
1620                         u8_t bar,
1621                         u32_t offset,
1622                         u32_t val)
1623 {
1624     ddi_put32(pdev->vars.reg_handle[bar],
1625               (uint32_t *)((caddr_t)pdev->vars.mapped_bar_addr[bar] + offset),
1626               val);
1627     mm_write_barrier();
1628 }
1629 
1630 
1631 void mm_bar_write_ddword(struct _lm_device_t *pdev,
1632                          u8_t bar,
1633                          u32_t offset,
1634                          u64_t val)
1635 {
1636     ddi_put64(pdev->vars.reg_handle[bar],
1637               (uint64_t *)((caddr_t)pdev->vars.mapped_bar_addr[bar] + offset),
1638               val);
1639     mm_write_barrier();
1640 }
1641 
1642 
1643 void mm_bar_copy_buffer(struct _lm_device_t * pdev,
1644                         u8_t                  bar,
1645                         u32_t                 offset,
1646                         u32_t                 size,
1647                         u32_t                 *buf_ptr)
1648 {
1649     u32_t i;
1650 
1651     for (i = 0; i < size; i++)
1652     {
1653         ddi_put32(pdev->vars.reg_handle[bar],
1654                   (uint32_t *)((caddr_t)pdev->vars.mapped_bar_addr[bar] +
1655                                offset + (i * 4)),
1656                   *(buf_ptr + i));
1657     }
1658 }
1659 
1660 
1661 u32_t mm_get_cap_offset(struct _lm_device_t * pdev,
1662                         u32_t                 capabilityID)
1663 {
1664     u32_t cap_offset = PCI_CAPABILITY_LIST; //CapPtr ofset
1665     u8_t cap_id;
1666     u32_t reg_value = 0;
1667 
1668     lm_status_t lm_status = mm_read_pci(pdev, cap_offset, &reg_value);
1669     if ((lm_status == LM_STATUS_SUCCESS) && (reg_value != 0xFFFFFFFF)) {
1670         cap_offset = (u8_t)(reg_value & 0x000000FF);
1671         if ((cap_offset == 0) || (cap_offset >= 0x100)) {
1672             return 0xFFFFFFFF;
1673         }
1674     } else {
1675         return 0xFFFFFFFF;
1676     }
1677     do {
1678         reg_value = 0;
1679         lm_status = mm_read_pci(pdev, cap_offset, &reg_value);
1680         if ((lm_status == LM_STATUS_SUCCESS) && (reg_value != 0xFFFFFFFF)) {
1681             cap_id = (u8_t)(reg_value & 0x000000FF);
1682             if (cap_id == capabilityID) {
1683                 break;
1684             }
1685             cap_offset = (reg_value & 0x0000FF00) >> 8;
1686             if (cap_offset == 0) {
1687                 break;
1688             }
1689         } else {
1690             cap_offset = 0xFFFFFFFF;
1691             break;
1692         }
1693     } while ((lm_status == LM_STATUS_SUCCESS));
1694 
1695     return cap_offset;
1696 }
1697 
1698 u32_t mm_get_wol_flags(struct _lm_device_t * pdev)
1699 {
1700     return LM_WAKE_UP_MODE_NONE;
1701 }
1702 
1703 u32_t mm_get_feature_flags(struct _lm_device_t * pdev)
1704 {
1705     return 0;
1706 }
1707 
1708 u32_t mm_get_vmq_cnt(struct _lm_device_t * pdev)
1709 {
1710     return 0;
1711 }
1712 
1713 lm_status_t mm_i2c_update(struct _lm_device_t * pdev)
1714 {
1715     return LM_STATUS_SUCCESS;
1716 }
1717 
1718 u64_t mm_query_system_time(void)
1719 {
1720     return 0;
1721 }
1722 
1723