summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/bnxe/bnxe.h
blob: 3a707708b5852d39f6dd6149bd3f3827966ed9fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2014 QLogic Corporation
 * The contents of this file are subject to the terms of the
 * QLogic End User License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the License at
 * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
 * QLogic_End_User_Software_License.txt
 * See the License for the specific language governing permissions
 * and limitations under the License.
 */

/*
 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef BNXE_H
#define BNXE_H

#include <sys/types.h>
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/errno.h>
#include <sys/cred.h>
#include <sys/poll.h>
#include <sys/modctl.h>
#include <sys/mac.h>
#include <sys/mac_provider.h>
#include <sys/stat.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/sunndi.h>
#include <sys/ddifm.h>
#include <sys/fm/protocol.h>
#include <sys/fm/util.h>
#include <sys/fm/io/ddi.h>
#include <sys/pattr.h>
#include <sys/sysmacros.h>
#include <sys/ethernet.h>
//#include <sys/vlan.h>
#include <sys/strsun.h>
#include <sys/ksynch.h>
#include <sys/kstat.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <inet/common.h>
#include <inet/ip.h>
#include <inet/ip_if.h>
#include <sys/strsubr.h>
#include <sys/pci.h>
#include <sys/gld.h>

/*
 * This really ticks me off!  We use 'u' for naming unions
 * within structures.  Why is 'u' a reserved word!?!?!?
 * http://bugs.opensolaris.org/view_bug.do?bug_id=4340073
 * This undef has been moved to bnxe_debug.h.
 */
//#undef u

#include "version.h"
#include "debug.h"
#include "bcmtype.h"
#include "lm_defs.h"
#include "listq.h"
#include "lm5710.h"
#include "lm.h"
#include "bd_chain.h"
#if !defined(__SunOS_MDB)
#include "command.h"
#endif
#include "bnxe_binding.h"
#if !defined(DBG) && !defined(__SunOS_MDB)
#include "bnxe_debug.h" /* wasn't included by debug.h */
#endif

#ifndef VLAN_TAGSZ
#define VLAN_TAGSZ 4
#endif

#define BNXE_RINGS
#define RSS_ID_NONE -1

#define USER_OPTION_CKSUM_NONE     0x0
#define USER_OPTION_CKSUM_L3       0x1
#define USER_OPTION_CKSUM_L3_L4    0x2
#define USER_OPTION_CKSUM_DEFAULT  USER_OPTION_CKSUM_L3_L4

#define USER_OPTION_MTU_MIN      60
#define USER_OPTION_MTU_MAX      9216
#define USER_OPTION_MTU_DEFAULT  1500

#define USER_OPTION_NUM_RINGS_MIN         0
#define USER_OPTION_NUM_RINGS_MAX         MAX_RSS_CHAINS
#define USER_OPTION_NUM_RINGS_DEFAULT_MF  1
#define USER_OPTION_NUM_RINGS_DEFAULT_SF  4
#define USER_OPTION_NUM_RINGS_DEFAULT     0

#define USER_OPTION_RX_RING_GROUPS_MIN      1
#define USER_OPTION_RX_RING_GROUPS_MAX      1
#define USER_OPTION_RX_RING_GROUPS_DEFAULT  1

#define USER_OPTION_BDS_MIN         1
#define USER_OPTION_BDS_MAX         32767
#define USER_OPTION_RX_BDS_DEFAULT  1024
#define USER_OPTION_TX_BDS_DEFAULT  1024
#define USER_OPTION_MF_BDS_DIVISOR  4

#define USER_OPTION_INTR_COALESCE_MIN         10    /* usecs */
#define USER_OPTION_INTR_COALESCE_MAX         1000
#define USER_OPTION_INTR_COALESCE_RX_DEFAULT  20
#define USER_OPTION_INTR_COALESCE_TX_DEFAULT  40

#define USER_OPTION_TX_MAX_FREE_DEFAULT  32
#define USER_OPTION_RX_MAX_FREE_DEFAULT  32

//#define USER_OPTION_RX_DCOPY_THRESH_DEFAULT  0xffffffff
#define USER_OPTION_RX_DCOPY_THRESH_DEFAULT  128

//#define USER_OPTION_TX_DCOPY_THRESH_DEFAULT  0
#define USER_OPTION_TX_DCOPY_THRESH_DEFAULT  512

//#define BNXE_IP_MAXLEN   65535
#define BNXE_IP_MAXLEN   32768 /* 32768 = PAGESIZE * (BNXE_MAX_DMA_FRAGS_PER_PKT - 2 ) */
#define BNXE_OPTION_LEN  80    /* room for IP/TCP options (max 40 bytes each) */
#define BNXE_PKTHDR_LEN  (sizeof(struct ether_vlan_header) + sizeof(struct ip) + sizeof(struct tcphdr) + BNXE_OPTION_LEN)
#define BNXE_LSO_MAXLEN  (BNXE_IP_MAXLEN + sizeof(struct ether_vlan_header) - BNXE_PKTHDR_LEN) /* maximum payload */

#define BNXE_MAGIC          0x0feedead
#define BNXE_MEM_CHECK_LEN  16
#define BNXE_STR_SIZE       32

#define BNXEF_NAME "bnxef"

#define BNXE_FCOE(dev) ((um_device_t *)(dev))->do_fcoe

#ifdef __sparc
#define BNXE_DMA_ALIGNMENT  0x2000UL
#else
#define BNXE_DMA_ALIGNMENT  0x1000UL
#endif

/*
 * Adding a two byte offset to the receive buffer aligns the IP header on a
 * 16 byte boundary and it would put the TCP payload (assuming a 20 byte IP
 * header and 20 byte TCP header) on an 8 byte boundary.
 */
#define BNXE_DMA_RX_OFFSET 2

/*
 * The following two defines are used for defining limits on Tx packets.
 * BNXE_MAX_DMA_HANDLES_PER_PKT is the maximum number of DMA handles that are
 * pre-allocated for every Tx buffer descriptor.  These DMA handles are used
 * for mapping each mblk in the chain when not double copying the packet data
 * into the copy buffer.  BNXE_MAX_DMA_FRAGS_PER_PKT is based on the hardware
 * and represents the maximum number of fragments an outgoing packet can have.
 * Note that a single DMA handle can be comprised of multiple fragments which
 * is very likely with LSO.
 *
 * As seen below BNXE_MAX_DMA_FRAGS_PER_PKT is set to 10.  The actual firmware
 * limit is 13 but 10 is chosen specifically for the case of LSO packets that
 * are broken up across a long mblk chain.  The firmware utilizes a sliding
 * window on a packet's assigned buffer descriptors for LSO.  The window is 10
 * bds and each window (i.e. bds 1-10, 2-11, 3-12, etc), except the window
 * containing the last bd, must contains at least MSS bytes.  There are 'rare'
 * cases where a packet sent down by the stack will not satisfy this window
 * size requirement.  Therefore, setting the frag limit to 10 results in any
 * long chained packet (i.e. greater than 10 mblks), the trailing mblks will
 * get double copied into a single copy buffer and will be pointed to by the
 * last bd.  This simple change will ensure the sliding window requirement is
 * always satisfied.  Note, LSO packets with long mblk chains are a rare
 * occurance (nicdrv test01 can trigger it).
 */
#define BNXE_MAX_DMA_HANDLES_PER_PKT 11 /* go easy on DMA resources */
#define BNXE_MAX_DMA_FRAGS_PER_PKT   10 /* set BNXE_IP_MAXLEN above accordingly */
#define BNXE_MAX_DMA_SGLLEN          20 /* for partial dma mapping */

#define BNXE_PDWM_THRESHOLD  8

#define BNXE_TX_RESOURCES_NO_CREDIT      0x01
#define BNXE_TX_RESOURCES_NO_DESC        0x02
#define BNXE_TX_RESOURCES_NO_DRV_DMA_RES 0x04 /* Out of Tx DMA handles */
#define BNXE_TX_RESOURCES_NO_OS_DMA_RES  0x08 /* Unable to allocate DMA resources. (e.g. bind error) */
#define BNXE_TX_RESOURCES_TOO_MANY_FRAGS 0x10

#define BNXE_TX_GOODXMIT  0
#define BNXE_TX_LINKDOWN  1
#define BNXE_TX_DEFERPKT  2
#define BNXE_TX_HDWRFULL  3
#define BNXE_TX_PKTERROR  4

#define BNXE_ROUTE_RING_NONE     0
#define BNXE_ROUTE_RING_TCPUDP   1
#define BNXE_ROUTE_RING_DEST_MAC 2
#define BNXE_ROUTE_RING_MSG_PRIO 3

#undef BNXE_DEBUG_DMA_LIST

extern ddi_device_acc_attr_t bnxeAccessAttribBAR;
extern ddi_device_acc_attr_t bnxeAccessAttribBUF;

typedef struct _BnxeDevParams
{
    u32_t        fw_ver;

    u32_t        mtu[LM_CLI_IDX_MAX];

    u32_t        routeTxRingPolicy;
    u32_t        numRings;   /* number of rings */
    u32_t        numRxDesc[LM_CLI_IDX_MAX]; /* number of RX descriptors */
    u32_t        numTxDesc[LM_CLI_IDX_MAX]; /* number of TX descriptors */
    u32_t        maxRxFree;  /* max free allowed before posting back */
    u32_t        maxTxFree;  /* max free allowed before posting back */

    boolean_t    intrCoalesce;
    u32_t        intrRxPerSec;
    u32_t        intrTxPerSec;
    boolean_t    disableMsix;

    boolean_t    l2_fw_flow_ctrl;
    boolean_t    autogreeenEnable;

    u32_t        rxCopyThreshold;
    u32_t        txCopyThreshold;

    lm_rx_mask_t rx_filter_mask[LM_CLI_IDX_MAX];

    int          checksum;
    lm_offload_t enabled_oflds;

    boolean_t    lsoEnable;

    boolean_t    logEnable;

    boolean_t    fcoeEnable;

    boolean_t    linkRemoteFaultDetect;

    lm_status_t  lastIndLink;
    lm_medium_t  lastIndMedium;

    uint32_t     debug_level;
} BnxeDevParams;


typedef struct _BnxeLinkCfg
{
    boolean_t link_autoneg;
    boolean_t param_20000fdx;
    boolean_t param_10000fdx;
    boolean_t param_2500fdx;
    boolean_t param_1000fdx;
    boolean_t param_100fdx;
    boolean_t param_100hdx;
    boolean_t param_10fdx;
    boolean_t param_10hdx;
    boolean_t param_txpause;
    boolean_t param_rxpause;
} BnxeLinkCfg;


typedef struct _BnxePhyCfg
{
    BnxeLinkCfg lnkcfg;
    boolean_t   flow_autoneg;
    u32_t       supported[ELINK_LINK_CONFIG_SIZE];
    u32_t       phy_cfg_size;
} BnxePhyCfg;


typedef struct _BnxeProps
{
    u32_t             link_speed;
    boolean_t         link_duplex;
    boolean_t         link_txpause;
    boolean_t         link_rxpause;
    time_t            uptime;
} BnxeProps;


typedef struct _BnxeMemBlock
{
    d_list_entry_t link;
    u32_t          size;
    void *         pBuf;
    char           fileName[128];
    u32_t          fileLine;
} BnxeMemBlock;


typedef struct _BnxeMemDma
{
    d_list_entry_t   link;
    u32_t            size;
    void *           pDmaVirt;
    ddi_dma_handle_t dmaHandle;
    ddi_acc_handle_t dmaAccHandle;
    lm_address_t     physAddr;
    char             fileName[128];
    u32_t            fileLine;
} BnxeMemDma;


typedef struct _BnxeMemRegion
{
    d_list_entry_t   link;
    lm_address_t     baseAddr;
    u32_t            regNumber;
    offset_t         offset;
    u32_t            size;
    ddi_acc_handle_t regAccess;
    caddr_t          pRegAddr;
} BnxeMemRegion;


typedef struct _um_txpacket_t
{
    lm_packet_t      lm_pkt; /* must be the first entry */
    lm_pkt_tx_info_t tx_info;

    mblk_t *         pMblk;

    ddi_dma_handle_t cbDmaHandle;    /* cb = copy buffer */
    ddi_acc_handle_t cbDmaAccHandle;
    caddr_t          pCbBuf;
    lm_address_t     cbPhysAddr;

    u32_t            cbLength;
    u32_t            num_handles; /* number of handles used for pkt */
    ddi_dma_handle_t dmaHandles[BNXE_MAX_DMA_HANDLES_PER_PKT];

    lm_frag_list_t   frag_list;
    lm_frag_t        frag_list_buffer[BNXE_MAX_DMA_FRAGS_PER_PKT];
} um_txpacket_t;


typedef struct _TxQueue
{
    void *            pUM; /* backpointer to um_device_t */
    u32_t             idx; /* this ring's index */

    mac_ring_handle_t ringHandle;

    u32_t             desc_cnt;     /* number of Tx descriptors */

    u32_t             txFailed;
    u32_t             txDiscards;
    u32_t             txRecycle;
    u32_t             txCopied;
    u32_t             txBlocked;
    u32_t             txWait;
    u32_t             txLowWater;

    u32_t             thresh_pdwm;  /* low resource water marks */

    kmutex_t          txMutex;

    s_list_t          sentTxQ;      /* bds that have been sent and are ready to be freed */

    kmutex_t          freeTxDescMutex;
    s_list_t          freeTxDescQ;  /* bds that are free for use */

    s_list_t          waitTxDescQ;  /* bds that are setup and waiting for tx (lock w/ tx mutex) */

    u32_t             noTxCredits;
} TxQueue;


typedef struct _um_rxpacket_t
{
    lm_packet_t      lm_pkt; /* must be first entry */
    lm_pkt_rx_info_t rx_info;    
    u32_t            hash_value;

    frtn_t           freeRtn;
    void *           pUM; /* backpointer to um_device_t for free routine */
    int              idx; /* chain index used by the free routine */

    u32_t            signature;

    ddi_dma_handle_t dmaHandle;
    ddi_acc_handle_t dmaAccHandle;
} um_rxpacket_t;


typedef struct _RxQueue
{
    void *            pUM; /* backpointer to um_device_t */
    u32_t             idx; /* this ring's index */

    mac_ring_handle_t ringHandle;
    uint64_t          genNumber; /* set by mac and passed up in mac_ring_rx */

    volatile u32_t    inPollMode;
    u8_t              intrDisableCnt;
    u8_t              intrEnableCnt;
    u8_t              pollCnt;

    u32_t             rxDiscards;
    u32_t             rxCopied;
    u32_t             rxLowWater;
    u32_t             rxBufUpInStack;

    kmutex_t          rxMutex;

    kmutex_t          doneRxMutex;
    s_list_t          doneRxQ;  /* free bds that are ready to be posted */

    s_list_t          waitRxQ; /* packet waiting to be sent up */
} RxQueue;


typedef struct _RxQueueGroup
{
    void *             pUM; /* backpointer to um_device_t */
    u32_t              idx; /* this group's index */
    mac_group_handle_t groupHandle;
} RxQueueGroup;


typedef struct _KstatRingMap
{
    u32_t  idx;  /* ring index */
    void * pUM;  /* reference back to um_device_t */
} KstatRingMap;


typedef struct _BnxeFcoeState
{
    lm_fcoe_state_t lm_fcoe;
} BnxeFcoeState;


typedef struct _BnxeClientStats
{
    u32_t initWqeTx;
    u32_t initWqeTxErr;
    u32_t initCqeRx;
    u32_t initCqeRxErr;
    u32_t offloadConnWqeTx;
    u32_t offloadConnWqeTxErr;
    u32_t offloadConnCqeRx;
    u32_t offloadConnCqeRxErr;
    u32_t enableConnWqeTx;
    u32_t enableConnWqeTxErr;
    u32_t enableConnCqeRx;
    u32_t enableConnCqeRxErr;
    u32_t disableConnWqeTx;
    u32_t disableConnWqeTxErr;
    u32_t disableConnCqeRx;
    u32_t disableConnCqeRxErr;
    u32_t destroyConnWqeTx;
    u32_t destroyConnWqeTxErr;
    u32_t destroyConnCqeRx;
    u32_t destroyConnCqeRxErr;
    u32_t destroyWqeTx;
    u32_t destroyWqeTxErr;
    u32_t destroyCqeRx;
    u32_t destroyCqeRxErr;
    u32_t compRequestCqeRx;
    u32_t compRequestCqeRxErr;
    u32_t statWqeTx;
    u32_t statWqeTxErr;
    u32_t statCqeRx;
    u32_t statCqeRxErr;
} BnxeClientStats;


typedef struct _BnxeFcoeData
{
    dev_info_t *    pDev;
    BnxeBinding     bind;
    BnxeClientStats stats;
    BnxeWwnInfo     wwn;
} BnxeFcoeData;


typedef struct _BnxeIntrBlock
{
    int                 intrCount;
    int                 intrCapability;
    u32_t               intrPriority;
    u32_t               intrHandleBlockSize;
    ddi_intr_handle_t * pIntrHandleBlockAlloc;
    ddi_intr_handle_t * pIntrHandleBlock;
} BnxeIntrBlock;


typedef struct _BnxeWorkQueueInstance
{
    void *        pUM;

    char          taskqName[BNXE_STR_SIZE];
    ddi_taskq_t * pTaskq;
    kmutex_t      workQueueMutex;
    s_list_t      workQueue;

    u32_t         workItemQueued;
    u32_t         workItemError;
    u32_t         workItemComplete;
    u32_t         highWater;
} BnxeWorkQueueInstance;


typedef struct _BnxeWorkQueues
{
    BnxeWorkQueueInstance instq;  /* instant, single thread serialized */
    BnxeWorkQueueInstance delayq; /* delayed, multi thread not serialized */
} BnxeWorkQueues;


/* the following are used against the clientState variable in um_device_t */

#define CLIENT_FLG_DEVI  0x001
#define CLIENT_FLG_BIND  0x002
#define CLIENT_FLG_HW    0x004

#define CLIENT_DEVI(pUM, client) \
    ((pUM)->clientState[(client)] & CLIENT_FLG_DEVI)

#define CLIENT_HW(pUM, client) \
    ((pUM)->clientState[(client)] & CLIENT_FLG_HW)

#define CLIENT_BOUND(pUM, client) \
    (((client) == LM_CLI_IDX_NDIS)                      ? \
         ((pUM)->clientState[(client)] & CLIENT_FLG_HW) : \
         ((pUM)->clientState[(client)] & CLIENT_FLG_BIND))

#define CLIENT_DEVI_SET(pUM, client) \
    ((pUM)->clientState[(client)] |= CLIENT_FLG_DEVI)

#define CLIENT_DEVI_RESET(pUM, client) \
    ((pUM)->clientState[(client)] &= ~CLIENT_FLG_DEVI)

#define CLIENT_BIND_SET(pUM, client) \
    ((pUM)->clientState[(client)] |= CLIENT_FLG_BIND)

#define CLIENT_BIND_RESET(pUM, client) \
    ((pUM)->clientState[(client)] &= ~CLIENT_FLG_BIND)

#define CLIENT_HW_SET(pUM, client) \
    ((pUM)->clientState[(client)] |= CLIENT_FLG_HW)

#define CLIENT_HW_RESET(pUM, client) \
    ((pUM)->clientState[(client)] &= ~CLIENT_FLG_HW)


typedef struct _um_device
{
    lm_device_t           lm_dev;  /* must be the first element */

    u32_t                 magic;
    dev_info_t *          pDev;

    u32_t                 hwInitDone;
    u32_t                 chipStarted;
    u32_t                 clientState[LM_CLI_IDX_MAX];

    d_list_t              memBlockList;
    d_list_t              memDmaList;
    d_list_t              memRegionList;
#ifdef BNXE_DEBUG_DMA_LIST
    d_list_t              memDmaListSaved;
#endif

    int                   instance;
    char                  devName[BNXE_STR_SIZE];
    char                  version[BNXE_STR_SIZE];
    char                  versionLM[BNXE_STR_SIZE];
    char                  versionFW[BNXE_STR_SIZE];
    char                  versionBC[BNXE_STR_SIZE];
    char                  chipName[BNXE_STR_SIZE];
    char                  chipID[BNXE_STR_SIZE];
    char                  intrAlloc[BNXE_STR_SIZE];
    char                  bus_dev_func[BNXE_STR_SIZE];
    char                  vendor_device[BNXE_STR_SIZE];

    volatile u32_t        plumbed;

    ddi_acc_handle_t      pPciCfg;

    kmutex_t              intrMutex[MAX_RSS_CHAINS + 1];
    kmutex_t              intrFlipMutex[MAX_RSS_CHAINS + 1];
    kmutex_t              sbMutex[MAX_RSS_CHAINS + 1];
    kmutex_t              ethConMutex;
    kmutex_t              mcpMutex;
    kmutex_t              phyMutex;
    kmutex_t              indMutex;
    kmutex_t              cidMutex;
    kmutex_t              spqMutex;   /* slow path queue lock */
    kmutex_t              spReqMutex; /* slow path request manager lock */
    kmutex_t              rrReqMutex; /* ramrod request */
    kmutex_t              islesCtrlMutex;
    kmutex_t              toeMutex;
    kmutex_t              memMutex;
    kmutex_t              offloadMutex;
    kmutex_t              hwInitMutex;
    kmutex_t              gldMutex;
    krwlock_t             gldTxMutex;

    kmutex_t              timerMutex;
    volatile u32_t        timerEnabled;
    timeout_id_t          timerID;

    BnxeWorkQueues        workqs;

    BnxeMemDma *          statusBlocks[MAX_RSS_CHAINS + 1];
    volatile u32_t        intrEnabled;
    u64_t                 intrFired;
                          /* the arrays below = LM_SB_CNT() + 1 = 17 */
    u64_t                 intrSbCnt[MAX_RSS_CHAINS + 1];
    u64_t                 intrSbNoChangeCnt[MAX_RSS_CHAINS + 1];
    u64_t                 intrSbPollCnt[MAX_RSS_CHAINS + 1];
    u64_t                 intrSbPollNoChangeCnt[MAX_RSS_CHAINS + 1];

    int                   intrType;
    u32_t                 intrPriority;
    BnxeIntrBlock         defIntr;
    BnxeIntrBlock         rssIntr;
    BnxeIntrBlock         fcoeIntr;

    BnxeDevParams         devParams;
    mac_handle_t          pMac;
    mac_resource_handle_t macRxResourceHandles[MAX_ETH_REG_CONS];
    u8_t                  gldMac[ETHERNET_ADDRESS_SIZE];

    d_list_t              mcast_l2;
    d_list_t              mcast_fcoe;

    u32_t                 ucastTableLen; /* number of ucast addrs in the table */
#ifndef LM_MAX_UC_TABLE_SIZE
#define LM_MAX_UC_TABLE_SIZE 1 /* for now, fix needed to support multiple ucast addr */
#endif

    TxQueue               txq[MAX_ETH_CONS];
    RxQueue               rxq[MAX_ETH_CONS];
    RxQueueGroup          rxqGroup[USER_OPTION_RX_RING_GROUPS_MAX];
    u32_t                 rxBufSignature[LM_CLI_IDX_MAX];
    u32_t                 txMsgPullUp;

    BnxeProps             props;
    BnxePhyCfg            hwinit; /* gathered by BnxeCfgInit */
    BnxePhyCfg            curcfg; /* initialized from hwinit by BnxeCfgReset */
    BnxeLinkCfg           remote;
    u32_t                 phyInitialized;

    kstat_t *             kstats;
    kstat_t *             kstatsLink;
    kstat_t *             kstatsIntr;
    kstat_t *             kstatsL2Chip;
    kstat_t *             kstatsL2Driver;
    kstat_t *             kstatsL2Stats;
    kstat_t *             kstatsFcoe;
    kstat_t *             kstatsDcbx;
    kstat_t *             kstats_rxq[MAX_ETH_CONS];
    KstatRingMap          kstats_rxq_map[MAX_ETH_CONS];
    kstat_t *             kstats_txq[MAX_ETH_CONS];
    KstatRingMap          kstats_txq_map[MAX_ETH_CONS];
    kmutex_t              kstatMutex;

    int                   fmCapabilities; /* FMA capabilities */

    boolean_t              do_fcoe;
    BnxeFcoeData           fcoe;
    iscsi_info_block_hdr_t iscsiInfo;

} um_device_t;


/* mioc[ack|nak] return values from ioctl subroutines */
enum ioc_reply
{
    IOC_INVAL = -1,   /* bad, NAK with EINVAL */
    IOC_DONE,         /* OK, reply sent       */
    IOC_ACK,          /* OK, just send ACK    */
    IOC_REPLY,        /* OK, just send reply  */
    IOC_RESTART_ACK,  /* OK, restart & ACK    */
    IOC_RESTART_REPLY /* OK, restart & reply  */
};


#define BNXE_IOC_BASE ('X' << 8)
/* IOCTLs for get/set lldp and dcbx params */
#define GIOCBNXELLDP  (BNXE_IOC_BASE + 0)
#define GIOCBNXEDCBX  (BNXE_IOC_BASE + 1)
#define SIOCBNXEDCBX  (BNXE_IOC_BASE + 2)
/* IOCTLs for edebug and firmware upgrade */
#define GIOCBNXEREG   (BNXE_IOC_BASE + 3)
#define SIOCBNXEREG   (BNXE_IOC_BASE + 4)
#define GIOCBNXENVRM  (BNXE_IOC_BASE + 5)
#define SIOCBNXENVRM  (BNXE_IOC_BASE + 6)
#define GIOCBNXEPCI   (BNXE_IOC_BASE + 7)
#define GIOCBNXESTATS (BNXE_IOC_BASE + 8)

struct bnxe_reg_data
{
    u32_t offset;
    u32_t value;
};

struct bnxe_nvram_data
{
    u32_t offset;
    u32_t num_of_u32;
    u32_t value[1]; /* variable */
};


/* bnxe_cfg.c */
void BnxeCfgInit(um_device_t * pUM);
void BnxeCfgReset(um_device_t * pUM);

/* bnxe_mm.c */
void BnxeInitBdCnts(um_device_t * pUM,
                    int           cli_idx);

/* bnxe_gld.c */
boolean_t BnxeGldInit(um_device_t * pUM);
boolean_t BnxeGldFini(um_device_t * pUM);
void      BnxeGldLink(um_device_t * pUM,
                      link_state_t  state);

/* bnxe_hw.c */
boolean_t BnxeEstablishHwConn(um_device_t * pUM,
                              int           cid);
int       BnxeHwStartFCOE(um_device_t * pUM);
int       BnxeHwStartL2(um_device_t * pUM);
int       BnxeHwStartCore(um_device_t * pUM);
void      BnxeHwStopFCOE(um_device_t * pUM);
void      BnxeHwStopL2(um_device_t * pUM);
void      BnxeHwStopCore(um_device_t * pUM);
void      BnxeUpdatePhy(um_device_t * pUM);
int       BnxeMacAddress(um_device_t *   pUM,
                         int             cliIdx,
                         boolean_t       flag,
                         const uint8_t * pMacAddr);
int       BnxeMulticast(um_device_t *   pUM,
                        int             cliIdx,
                        boolean_t       flag,
                        const uint8_t * pMcastAddr,
                        boolean_t       hwSet);
int       BnxeRxMask(um_device_t * pUM,
                     int           cliIdx,
                     lm_rx_mask_t  mask);
int       BnxeHwResume(um_device_t * pUM);
int       BnxeHwSuspend(um_device_t * pUM);
#if (DEVO_REV > 3)
int       BnxeHwQuiesce(um_device_t * pUM);
#endif

/* bnxe_intr.c */
void      BnxeIntrIguSbEnable(um_device_t * pUM,
                              u32_t         idx,
                              boolean_t     fromISR);
void      BnxeIntrIguSbDisable(um_device_t * pUM,
                               u32_t         idx,
                               boolean_t     fromISR);
void      BnxePollRxRing(um_device_t * pUM,
                         u32_t         idx,
                         boolean_t *   pPktsRxed,
                         boolean_t *   pPktsTxed);
void      BnxePollRxRingFCOE(um_device_t * pUM);
int       BnxeIntrEnable(um_device_t * pUM);
void      BnxeIntrDisable(um_device_t * pUM);
boolean_t BnxeIntrInit(um_device_t * pUM);
void      BnxeIntrFini(um_device_t * pUM);

/* bnxe_kstat.c */
boolean_t BnxeKstatInit(um_device_t * pUM);
void      BnxeKstatFini(um_device_t * pUM);

/* bnxe_rr.c */
int BnxeRouteTxRing(um_device_t * pUM,
                    mblk_t *      pMblk);

/* bnxe_rx.c */
boolean_t BnxeWaitForPacketsFromClient(um_device_t * pUM,
                                      int            cliIdx);
mblk_t *  BnxeRxRingProcess(um_device_t * pUM,
                            int           idx,
                            boolean_t     polling,
                            int           numBytes);
void      BnxeRxPktsAbort(um_device_t * pUM,
                          int           cliIdx);
int       BnxeRxPktsInitPostBuffers(um_device_t * pUM,
                                    int           cliIdx);
int       BnxeRxPktsInit(um_device_t * pUM,
                         int           cliIdx);
void      BnxeRxPktsFini(um_device_t * pUM,
                         int           cliIdx);

/* bnxe_tx.c */
void BnxeTxPktsReclaim(um_device_t * pUM,
                       int           idx,
                       s_list_t *    pPktList);
void BnxeTxRingProcess(um_device_t * pUM,
                       int           idx);
int  BnxeTxSendMblk(um_device_t * pUM,
                    int           idx,
                    mblk_t *      pMblk,
                    u32_t         flags,
                    u16_t         vlan_tag);
void BnxeTxPktsAbort(um_device_t * pUM,
                     int           cliIdx);
int  BnxeTxPktsInit(um_device_t * pUM,
                    int           cliIdx);
void BnxeTxPktsFini(um_device_t * pUM,
                    int           cliIdx);

/* bnxe_timer.c */
void BnxeTimerStart(um_device_t * pUM);
void BnxeTimerStop(um_device_t * pUM);

/* bnxe_workq.c */
boolean_t BnxeWorkQueueInit(um_device_t * pUM);
void      BnxeWorkQueueWaitAndDestroy(um_device_t * pUM);
void      BnxeWorkQueueStartPending(um_device_t * pUM);
boolean_t BnxeWorkQueueAdd(um_device_t * pUM,
                           void (*pWorkCbk)(um_device_t *, void *, u32_t),
                           void * pWorkData,
                           u32_t  workDataLen);
boolean_t BnxeWorkQueueAddNoCopy(um_device_t * pUM,
                                 void (*pWorkCbk)(um_device_t *, void *),
                                 void * pWorkData);
boolean_t BnxeWorkQueueAddGeneric(um_device_t * pUM,
                                  void (*pWorkCbkGeneric)(um_device_t *));
boolean_t BnxeWorkQueueAddDelay(um_device_t * pUM,
                                void (*pWorkCbk)(um_device_t *, void *, u32_t),
                                void * pWorkData,
                                u32_t  workDataLen,
                                u32_t  delayMs);
boolean_t BnxeWorkQueueAddDelayNoCopy(um_device_t * pUM,
                                      void (*pWorkCbk)(um_device_t *, void *),
                                      void * pWorkData,
                                      u32_t  delayMs);
boolean_t BnxeWorkQueueAddDelayGeneric(um_device_t * pUM,
                                       void (*pWorkCbkGeneric)(um_device_t *),
                                       u32_t delayMs);

/* bnxe_fcoe.c */
boolean_t BnxeFcoeInitCqe(um_device_t *      pUM,
                          struct fcoe_kcqe * kcqe);
boolean_t BnxeFcoeOffloadConnCqe(um_device_t *      pUM,
                                 BnxeFcoeState *    pFcoeState,
                                 struct fcoe_kcqe * kcqe);
boolean_t BnxeFcoeEnableConnCqe(um_device_t *      pUM,
                                BnxeFcoeState *    pFcoeState,
                                struct fcoe_kcqe * kcqe);
boolean_t BnxeFcoeDisableConnCqe(um_device_t *      pUM,
                                 BnxeFcoeState *    pFcoeState,
                                 struct fcoe_kcqe * kcqe);
boolean_t BnxeFcoeDestroyConnCqe(um_device_t *      pUM,
                                 BnxeFcoeState *    pFcoeState,
                                 struct fcoe_kcqe * kcqe);
boolean_t BnxeFcoeDestroyCqe(um_device_t *      pUM,
                             struct fcoe_kcqe * kcqe);
boolean_t BnxeFcoeStatCqe(um_device_t *      pUM,
                          struct fcoe_kcqe * kcqe);
boolean_t BnxeFcoeCompRequestCqe(um_device_t *      pUM,
                                 struct fcoe_kcqe * kcqes,
                                 u32_t              num_kcqes);
boolean_t BnxeFcoePrvCtl(dev_info_t * pDev,
                         int          cmd,
                         void *       pData,
                         int          dataLen);
mblk_t *  BnxeFcoePrvTx(dev_info_t * pDev,
                        mblk_t *     pMblk,
                        u32_t        flags,
                        u16_t        vlan_tag);
boolean_t BnxeFcoePrvPoll(dev_info_t * pDev);
boolean_t BnxeFcoePrvSendWqes(dev_info_t * pDev,
                              void *       wqes[],
                              int          wqeCnt);
boolean_t BnxeFcoePrvMapMailboxq(dev_info_t *       pDev,
                                 u32_t              cid,
                                 void **            ppMap,
                                 ddi_acc_handle_t * pAccHandle);
boolean_t BnxeFcoePrvUnmapMailboxq(dev_info_t *     pDev,
                                   u32_t            cid,
                                   void *           pMap,
                                   ddi_acc_handle_t accHandle);
int       BnxeFcoeInit(um_device_t * pUM);
int       BnxeFcoeFini(um_device_t * pUM);
void      BnxeFcoeStartStop(um_device_t * pUM);

/* bnxe_main.c */
u8_t      BnxeInstance(void * pDev);
char *    BnxeDevName(void * pDev);
boolean_t BnxeProtoSupport(um_device_t * pUM, int proto);
boolean_t BnxeProtoFcoeAfex(um_device_t * pUM);
int       BnxeCheckAccHandle(ddi_acc_handle_t handle);
int       BnxeCheckDmaHandle(ddi_dma_handle_t handle);
void      BnxeFmErrorReport(um_device_t * pUM, char * detail);

/* bnxe_illumos.c */
extern boolean_t bnxe_fill_transceiver(um_device_t *, void *);

extern kmutex_t bnxeLoaderMutex;
extern u32_t    bnxeNumPlumbed;

extern BnxeLinkCfg bnxeLinkCfg;

/* undefine this to help with dtrace analysis */
#define BNXE_LOCKS_INLINE

#ifdef BNXE_LOCKS_INLINE

#define BNXE_LOCK_ENTER_INTR(pUM, idx)      mutex_enter(&(pUM)->intrMutex[(idx)])
#define BNXE_LOCK_EXIT_INTR(pUM, idx)       mutex_exit(&(pUM)->intrMutex[(idx)])
#define BNXE_LOCK_ENTER_INTR_FLIP(pUM, idx) mutex_enter(&(pUM)->intrFlipMutex[(idx)])
#define BNXE_LOCK_EXIT_INTR_FLIP(pUM, idx)  mutex_exit(&(pUM)->intrFlipMutex[(idx)])
#define BNXE_LOCK_ENTER_TX(pUM, idx)        mutex_enter(&(pUM)->txq[(idx)].txMutex)
#define BNXE_LOCK_EXIT_TX(pUM, idx)         mutex_exit(&(pUM)->txq[(idx)].txMutex)
#define BNXE_LOCK_ENTER_FREETX(pUM, idx)    mutex_enter(&(pUM)->txq[(idx)].freeTxDescMutex)
#define BNXE_LOCK_EXIT_FREETX(pUM, idx)     mutex_exit(&(pUM)->txq[(idx)].freeTxDescMutex)
#define BNXE_LOCK_ENTER_RX(pUM, idx)        mutex_enter(&(pUM)->rxq[(idx)].rxMutex)
#define BNXE_LOCK_EXIT_RX(pUM, idx)         mutex_exit(&(pUM)->rxq[(idx)].rxMutex)
#define BNXE_LOCK_ENTER_DONERX(pUM, idx)    mutex_enter(&(pUM)->rxq[(idx)].doneRxMutex)
#define BNXE_LOCK_EXIT_DONERX(pUM, idx)     mutex_exit(&(pUM)->rxq[(idx)].doneRxMutex)
#define BNXE_LOCK_ENTER_SB(pUM, idx)        mutex_enter(&(pUM)->sbMutex[(idx)])
#define BNXE_LOCK_EXIT_SB(pUM, idx)         mutex_exit(&(pUM)->sbMutex[(idx)])
#define BNXE_LOCK_ENTER_ETH_CON(pUM)        mutex_enter(&(pUM)->ethConMutex)
#define BNXE_LOCK_EXIT_ETH_CON(pUM)         mutex_exit(&(pUM)->ethConMutex)
#define BNXE_LOCK_ENTER_MCP(pUM)            mutex_enter(&(pUM)->mcpMutex)
#define BNXE_LOCK_EXIT_MCP(pUM)             mutex_exit(&(pUM)->mcpMutex)
#define BNXE_LOCK_ENTER_PHY(pUM)            mutex_enter(&(pUM)->phyMutex)
#define BNXE_LOCK_EXIT_PHY(pUM)             mutex_exit(&(pUM)->phyMutex)
#define BNXE_LOCK_ENTER_IND(pUM)            mutex_enter(&(pUM)->indMutex)
#define BNXE_LOCK_EXIT_IND(pUM)             mutex_exit(&(pUM)->indMutex)
#define BNXE_LOCK_ENTER_CID(pUM)            mutex_enter(&(pUM)->cidMutex)
#define BNXE_LOCK_EXIT_CID(pUM)             mutex_exit(&(pUM)->cidMutex)
#define BNXE_LOCK_ENTER_SPQ(pUM)            mutex_enter(&(pUM)->spqMutex)
#define BNXE_LOCK_EXIT_SPQ(pUM)             mutex_exit(&(pUM)->spqMutex)
#define BNXE_LOCK_ENTER_SPREQ(pUM)          mutex_enter(&(pUM)->spReqMutex)
#define BNXE_LOCK_EXIT_SPREQ(pUM)           mutex_exit(&(pUM)->spReqMutex)
#define BNXE_LOCK_ENTER_RRREQ(pUM)          mutex_enter(&(pUM)->rrReqMutex)
#define BNXE_LOCK_EXIT_RRREQ(pUM)           mutex_exit(&(pUM)->rrReqMutex)
#define BNXE_LOCK_ENTER_ISLES_CONTROL(pUM)  mutex_enter(&(pUM)->islesCtrlMutex)
#define BNXE_LOCK_EXIT_ISLES_CONTROL(pUM)   mutex_exit(&(pUM)->islesCtrlMutex)
#define BNXE_LOCK_ENTER_TOE(pUM)            mutex_enter(&(pUM)->toeMutex)
#define BNXE_LOCK_EXIT_TOE(pUM)             mutex_exit(&(pUM)->toeMutex)
#define BNXE_LOCK_ENTER_MEM(pUM)            mutex_enter(&(pUM)->memMutex)
#define BNXE_LOCK_EXIT_MEM(pUM)             mutex_exit(&(pUM)->memMutex)
#define BNXE_LOCK_ENTER_OFFLOAD(pUM)        mutex_enter(&(pUM)->offloadMutex)
#define BNXE_LOCK_EXIT_OFFLOAD(pUM)         mutex_exit(&(pUM)->offloadMutex)
#define BNXE_LOCK_ENTER_HWINIT(pUM)         mutex_enter(&(pUM)->hwInitMutex)
#define BNXE_LOCK_EXIT_HWINIT(pUM)          mutex_exit(&(pUM)->hwInitMutex)
#define BNXE_LOCK_ENTER_GLD(pUM)            mutex_enter(&(pUM)->gldMutex)
#define BNXE_LOCK_EXIT_GLD(pUM)             mutex_exit(&(pUM)->gldMutex)
#define BNXE_LOCK_ENTER_GLDTX(pUM, rw)      rw_enter(&(pUM)->gldTxMutex, (rw))
#define BNXE_LOCK_EXIT_GLDTX(pUM)           rw_exit(&(pUM)->gldTxMutex)
#define BNXE_LOCK_ENTER_TIMER(pUM)          mutex_enter(&(pUM)->timerMutex)
#define BNXE_LOCK_EXIT_TIMER(pUM)           mutex_exit(&(pUM)->timerMutex)
#define BNXE_LOCK_ENTER_STATS(pUM)          mutex_enter(&(pUM)->kstatMutex)
#define BNXE_LOCK_EXIT_STATS(pUM)           mutex_exit(&(pUM)->kstatMutex)

#else /* not BNXE_LOCKS_INLINE */

void BNXE_LOCK_ENTER_INTR(um_device_t * pUM, int idx);
void BNXE_LOCK_EXIT_INTR(um_device_t * pUM, int idx);
void BNXE_LOCK_ENTER_INTR_FLIP(um_device_t * pUM, int idx);
void BNXE_LOCK_EXIT_INTR_FLIP(um_device_t * pUM, int idx);
void BNXE_LOCK_ENTER_TX(um_device_t * pUM, int idx);
void BNXE_LOCK_EXIT_TX(um_device_t * pUM, int idx);
void BNXE_LOCK_ENTER_FREETX(um_device_t * pUM, int idx);
void BNXE_LOCK_EXIT_FREETX(um_device_t * pUM, int idx);
void BNXE_LOCK_ENTER_RX(um_device_t * pUM, int idx);
void BNXE_LOCK_EXIT_RX(um_device_t * pUM, int idx);
void BNXE_LOCK_ENTER_DONERX(um_device_t * pUM, int idx);
void BNXE_LOCK_EXIT_DONERX(um_device_t * pUM, int idx);
void BNXE_LOCK_ENTER_SB(um_device_t * pUM, int idx);            
void BNXE_LOCK_EXIT_SB(um_device_t * pUM, int idx);
void BNXE_LOCK_ENTER_ETH_CON(um_device_t * pUM);            
void BNXE_LOCK_EXIT_ETH_CON(um_device_t * pUM);
void BNXE_LOCK_ENTER_MCP(um_device_t * pUM);
void BNXE_LOCK_EXIT_MCP(um_device_t * pUM);
void BNXE_LOCK_ENTER_PHY(um_device_t * pUM);
void BNXE_LOCK_EXIT_PHY(um_device_t * pUM);
void BNXE_LOCK_ENTER_IND(um_device_t * pUM);
void BNXE_LOCK_EXIT_IND(um_device_t * pUM);
void BNXE_LOCK_ENTER_CID(um_device_t * pUM);
void BNXE_LOCK_EXIT_CID(um_device_t * pUM);
void BNXE_LOCK_ENTER_SPQ(um_device_t * pUM);
void BNXE_LOCK_EXIT_SPQ(um_device_t * pUM);
void BNXE_LOCK_ENTER_SPREQ(um_device_t * pUM);
void BNXE_LOCK_EXIT_SPREQ(um_device_t * pUM);
void BNXE_LOCK_ENTER_RRREQ(um_device_t * pUM);
void BNXE_LOCK_EXIT_RRREQ(um_device_t * pUM);
void BNXE_LOCK_ENTER_ISLES_CONTROL(um_device_t * pUM);
void BNXE_LOCK_EXIT_ISLES_CONTROL(um_device_t * pUM);
void BNXE_LOCK_ENTER_MEM(um_device_t * pUM);
void BNXE_LOCK_EXIT_MEM(um_device_t * pUM);
void BNXE_LOCK_ENTER_GLD(um_device_t * pUM);
void BNXE_LOCK_EXIT_GLD(um_device_t * pUM);
void BNXE_LOCK_ENTER_GLDTX(um_device_t * pUM, krw_t rw);
void BNXE_LOCK_EXIT_GLDTX(um_device_t * pUM);
void BNXE_LOCK_ENTER_TIMER(um_device_t * pUM);
void BNXE_LOCK_EXIT_TIMER(um_device_t * pUM);
void BNXE_LOCK_ENTER_STATS(um_device_t * pUM);
void BNXE_LOCK_EXIT_STATS(um_device_t * pUM);

#endif /* BNXE_LOCKS_INLINE */

#define CATC_TRIGGER(lmdev, data) {            \
              REG_WR((lmdev), 0x2000, (data)); \
        }
#define CATC_TRIGGER_START(lmdev) CATC_TRIGGER((lmdev), 0xcafecafe)

void BnxeDumpMem(um_device_t * pUM,
                 char *        pTag,
                 u8_t *        pMem,
                 u32_t         len);
void BnxeDumpPkt(um_device_t * pUM,
                 char *        pTag,
                 mblk_t *      pMblk,
                 boolean_t     contents);

/* XXX yuck (beware return strings lengths with kstat and mdb) */

inline boolean_t BnxeIsClientBound(um_device_t * pUM)
{
    return (CLIENT_HW(pUM, LM_CLI_IDX_NDIS) ||
            CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE));
}

inline char * BnxeClientsHw(um_device_t * pUM)
{
    if (CLIENT_HW(pUM, LM_CLI_IDX_NDIS) &&
        CLIENT_HW(pUM, LM_CLI_IDX_FCOE))      { return "L2,FCoE"; }
    else if (CLIENT_HW(pUM, LM_CLI_IDX_NDIS)) { return "L2"; }
    else if (CLIENT_HW(pUM, LM_CLI_IDX_FCOE)) { return "FCoE"; }
    else                                      { return "None"; }
}

inline char * BnxeClientsDevi(um_device_t * pUM)
{
    if (CLIENT_DEVI(pUM, LM_CLI_IDX_FCOE)) { return "FCoE"; }
    else                                   { return "None"; }
}

inline char * BnxeClientsBound(um_device_t * pUM)
{
    if (CLIENT_HW(pUM, LM_CLI_IDX_NDIS) &&
        CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE))      { return "L2,FCoE"; }
    else if (CLIENT_HW(pUM, LM_CLI_IDX_NDIS))    { return "L2"; }
    else if (CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE)) { return "FCoE"; }
    else                                         { return "None"; }
}

#endif /* BNXE_H */