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
|
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_NGE_H
#define _SYS_NGE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/strsun.h>
#include <sys/strsubr.h>
#include <sys/stat.h>
#include <sys/pci.h>
#include <sys/note.h>
#include <sys/modctl.h>
#include <sys/kstat.h>
#include <sys/ethernet.h>
#include <sys/pattr.h>
#include <sys/errno.h>
#include <sys/dlpi.h>
#include <sys/devops.h>
#include <sys/debug.h>
#include <sys/conf.h>
#include <sys/callb.h>
#include <netinet/ip6.h>
#include <inet/common.h>
#include <inet/ip.h>
#include <netinet/udp.h>
#include <inet/mi.h>
#include <inet/nd.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/mac_provider.h>
#include <sys/mac_ether.h>
/*
* Reconfiguring the network devices requires the net_config privilege
* in Solaris 10+.
*/
extern int secpolicy_net_config(const cred_t *, boolean_t);
#include <sys/netlb.h>
#include <sys/miiregs.h>
#include "nge_chip.h"
#define PIO_ADDR(ngep, offset) ((void *)((caddr_t)(ngep)->io_regs+(offset)))
/*
* Copy an ethernet address
*/
#define ethaddr_copy(src, dst) bcopy((src), (dst), ETHERADDRL)
#define ether_eq(a, b) (bcmp((caddr_t)(a), (caddr_t)(b), (ETHERADDRL)) == 0)
#define BIS(w, b) (((w) & (b)) ? B_TRUE : B_FALSE)
#define BIC(w, b) (((w) & (b)) ? B_FALSE : B_TRUE)
#define UPORDOWN(x) ((x) ? "up" : "down")
#define NGE_DRIVER_NAME "nge"
/*
* 'Progress' bit flags ...
*/
#define PROGRESS_CFG 0x0001 /* config space mapped */
#define PROGRESS_REGS 0x0002 /* registers mapped */
#define PROGRESS_BUFS 0x0004 /* registers mapped */
#define PROGRESS_RESCHED 0x0008 /* resched softint registered */
#define PROGRESS_FACTOTUM 0x0010 /* factotum softint registered */
#define PROGRESS_SWINT 0x0020 /* s/w interrupt registered */
#define PROGRESS_INTR 0x0040 /* h/w interrupt registered */
/* and mutexen initialised */
#define PROGRESS_HWINT 0x0080
#define PROGRESS_PHY 0x0100 /* PHY initialised */
#define PROGRESS_NDD 0x0200 /* NDD parameters set up */
#define PROGRESS_KSTATS 0x0400 /* kstats created */
#define PROGRESS_READY 0x0800 /* ready for work */
#define NGE_HW_ERR 0x00
#define NGE_HW_LINK 0x01
#define NGE_HW_BM 0x02
#define NGE_HW_RCHAN 0x03
#define NGE_HW_TCHAN 0x04
#define NGE_HW_ROM 0x05
#define NGE_SW_PROBLEM_ID 0x06
/*
* NOTES:
*
* #defines:
*
* NGE_PCI_CONFIG_RNUMBER and NGE_PCI_OPREGS_RNUMBER are the
* register-set numbers to use for the config space registers
* and the operating registers respectively. On an OBP-based
* machine, regset 0 refers to CONFIG space, and regset 1 will
* be the operating registers in MEMORY space. If an expansion
* ROM is fitted, it may appear as a further register set.
*
* NGE_DMA_MODE defines the mode (STREAMING/CONSISTENT) used
* for the data buffers. The descriptors are always set up
* in CONSISTENT mode.
*
* NGE_HEADROOM defines how much space we'll leave in allocated
* mblks before the first valid data byte. This should be chosen
* to be 2 modulo 4, so that once the ethernet header (14 bytes)
* has been stripped off, the packet data will be 4-byte aligned.
* The remaining space can be used by upstream modules to prepend
* any headers required.
*/
#define NGE_PCI_OPREGS_RNUMBER 1
#define NGE_DMA_MODE DDI_DMA_STREAMING
#define NGE_HEADROOM 6
#define ETHER_HEAD_LEN 14
#ifndef VTAG_SIZE
#define VTAG_SIZE 4
#endif
#define NGE_CYCLIC_PERIOD (1000000000)
#define NGE_DEFAULT_MTU 1500
#define NGE_DEFAULT_SDU 1518
#define NGE_MTU_2500 2500
#define NGE_MTU_4500 4500
#define NGE_MAX_MTU 9000
#define NGE_MAX_SDU 9018
#define NGE_DESC_MIN 0x200
#define NGE_STD_BUFSZ 1792
#define NGE_JB2500_BUFSZ (3*1024)
#define NGE_JB4500_BUFSZ (5*1024)
#define NGE_JB9000_BUFSZ (9*1024)
#define NGE_SEND_SLOTS_DESC_1024 1024
#define NGE_SEND_SLOTS_DESC_3072 3072
#define NGE_SEND_JB2500_SLOTS_DESC 3072
#define NGE_SEND_JB4500_SLOTS_DESC 2048
#define NGE_SEND_JB9000_SLOTS_DESC 1024
#define NGE_SEND_LOWMEM_SLOTS_DESC 1024
#define NGE_SEND_SLOTS_BUF 3072
#define NGE_RECV_SLOTS_DESC_1024 1024
#define NGE_RECV_SLOTS_DESC_3072 3072
#define NGE_RECV_JB2500_SLOTS_DESC 3072
#define NGE_RECV_JB4500_SLOTS_DESC 2048
#define NGE_RECV_JB9000_SLOTS_DESC 1024
#define NGE_RECV_LOWMEM_SLOTS_DESC 1024
#define NGE_RECV_SLOTS_BUF 6144
#define NGE_SPLIT_32 32
#define NGE_SPLIT_96 96
#define NGE_SPLIT_256 256
#define NGE_RX_COPY_SIZE 512
#define NGE_TX_COPY_SIZE 512
#define NGE_MAP_FRAGS 3
#define NGE_MAX_COOKIES 3
#define NGE_MAX_DMA_HDR (4*1024)
/* Used by interrupt moderation */
#define NGE_TFINT_DEFAULT 32
#define NGE_POLL_TUNE 80000
#define NGE_POLL_ENTER 10000
#define NGE_POLL_MAX 1280000
#define NGE_POLL_QUIET_TIME 100
#define NGE_POLL_BUSY_TIME 2
/*
* NGE-specific ioctls ...
*/
#define NGE_IOC ((((('N' << 8) + 'G') << 8) + 'E') << 8)
/*
* PHY register read/write ioctls, used by cable test software
*/
#define NGE_MII_READ (NGE_IOC|1)
#define NGE_MII_WRITE (NGE_IOC|2)
/*
* SEEPROM read/write ioctls, for use by SEEPROM upgrade utility
*
* Note: SEEPROMs can only be accessed as 32-bit words, so <see_addr>
* must be a multiple of 4. Not all systems have a SEEPROM fitted!
*/
#define NGE_SEE_READ (NGE_IOC|3)
#define NGE_SEE_WRITE (NGE_IOC|4)
/*
* These diagnostic IOCTLS are enabled only in DEBUG drivers
*/
#define NGE_DIAG (NGE_IOC|5) /* currently a no-op */
#define NGE_PEEK (NGE_IOC|6)
#define NGE_POKE (NGE_IOC|7)
#define NGE_PHY_RESET (NGE_IOC|8)
#define NGE_SOFT_RESET (NGE_IOC|9)
#define NGE_HARD_RESET (NGE_IOC|10)
enum NGE_HW_OP {
NGE_CLEAR = 0,
NGE_SET
};
/*
* Required state according to GLD
*/
enum nge_mac_state {
NGE_MAC_UNKNOWN,
NGE_MAC_RESET,
NGE_MAC_STOPPED,
NGE_MAC_STARTED,
NGE_MAC_UNATTACH
};
enum loop_type {
NGE_LOOP_NONE = 0,
NGE_LOOP_EXTERNAL_100,
NGE_LOOP_EXTERNAL_10,
NGE_LOOP_INTERNAL_PHY,
};
/*
* (Internal) return values from send_msg subroutines
*/
enum send_status {
SEND_COPY_FAIL = -1, /* => GLD_NORESOURCES */
SEND_MAP_FAIL, /* => GLD_NORESOURCES */
SEND_COPY_SUCESS, /* OK, msg queued */
SEND_MAP_SUCCESS /* OK, free msg */
};
/*
* (Internal) 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 */
};
enum nge_pp_type {
NGE_PP_SPACE_CFG = 0,
NGE_PP_SPACE_REG,
NGE_PP_SPACE_NIC,
NGE_PP_SPACE_MII,
NGE_PP_SPACE_NGE,
NGE_PP_SPACE_TXDESC,
NGE_PP_SPACE_TXBUFF,
NGE_PP_SPACE_RXDESC,
NGE_PP_SPACE_RXBUFF,
NGE_PP_SPACE_STATISTICS,
NGE_PP_SPACE_SEEPROM,
NGE_PP_SPACE_FLASH
};
/*
* Flag to kstat type
*/
enum nge_kstat_type {
NGE_KSTAT_RAW = 0,
NGE_KSTAT_STATS,
NGE_KSTAT_CHIPID,
NGE_KSTAT_DEBUG,
NGE_KSTAT_COUNT
};
/*
* Actual state of the nvidia's chip
*/
enum nge_chip_state {
NGE_CHIP_FAULT = -2, /* fault, need reset */
NGE_CHIP_ERROR, /* error, want reset */
NGE_CHIP_INITIAL, /* Initial state only */
NGE_CHIP_RESET, /* reset, need init */
NGE_CHIP_STOPPED, /* Tx/Rx stopped */
NGE_CHIP_RUNNING /* with interrupts */
};
enum nge_eeprom_size {
EEPROM_1K = 0,
EEPROM_2K,
EEPROM_4K,
EEPROM_8K,
EEPROM_16K,
EEPROM_32K,
EEPROM_64K
};
enum nge_eeprom_access_wid {
ACCESS_8BIT = 0,
ACCESS_16BIT
};
/*
* MDIO operation
*/
enum nge_mdio_operation {
NGE_MDIO_READ = 0,
NGE_MDIO_WRITE
};
/*
* Speed selection
*/
enum nge_speed {
UNKOWN_SPEED = 0,
NGE_10M,
NGE_100M,
NGE_1000M
};
/*
* Duplex selection
*/
enum nge_duplex {
UNKOWN_DUPLEX = 0,
NGE_HD,
NGE_FD
};
typedef struct {
ether_addr_t addr; /* in canonical form */
uint8_t spare;
uint8_t set; /* nonzero => valid */
} nge_mac_addr_t;
struct nge;
#define CHIP_FLAG_COPPER 0x40
/*
* Collection of physical-layer functions to:
* (re)initialise the physical layer
* update it to match software settings
* check for link status change
*/
typedef struct {
boolean_t (*phys_restart)(struct nge *);
void (*phys_update)(struct nge *);
boolean_t (*phys_check)(struct nge *);
} phys_ops_t;
struct nge_see_rw {
uint32_t see_addr; /* Byte offset within SEEPROM */
uint32_t see_data; /* Data read/data to write */
};
typedef struct {
uint64_t pp_acc_size; /* in bytes: 1,2,4,8 */
uint64_t pp_acc_space; /* See #defines below */
uint64_t pp_acc_offset;
uint64_t pp_acc_data; /* output for peek */
/* input for poke */
} nge_peekpoke_t;
typedef uintptr_t nge_regno_t; /* register # (offset) */
typedef struct _mul_list {
struct _mul_list *next;
uint32_t ref_cnt;
ether_addr_t mul_addr;
}mul_item, *pmul_item;
/*
* Describes one chunk of allocated DMA-able memory
*
* In some cases, this is a single chunk as allocated from the system;
* but we also use this structure to represent slices carved off such
* a chunk. Even when we don't really need all the information, we
* use this structure as a convenient way of correlating the various
* ways of looking at a piece of memory (kernel VA, IO space DVMA,
* handle+offset, etc).
*/
typedef struct dma_area
{
caddr_t private; /* pointer to nge */
frtn_t rx_recycle; /* recycle function */
mblk_t *mp;
ddi_acc_handle_t acc_hdl; /* handle for memory */
void *mem_va; /* CPU VA of memory */
uint32_t nslots; /* number of slots */
uint32_t size; /* size per slot */
size_t alength; /* allocated size */
/* >= product of above */
ddi_dma_handle_t dma_hdl; /* DMA handle */
offset_t offset; /* relative to handle */
ddi_dma_cookie_t cookie; /* associated cookie */
uint32_t ncookies;
uint32_t signature; /* buffer signature */
/* for deciding to free */
/* or to reuse buffers */
boolean_t rx_delivered; /* hold by upper layer */
struct dma_area *next;
} dma_area_t;
#define HOST_OWN 0x00000000
#define CONTROLER_OWN 0x00000001
#define NGE_END_PACKET 0x00000002
typedef struct nge_dmah_node
{
struct nge_dmah_node *next;
ddi_dma_handle_t hndl;
} nge_dmah_node_t;
typedef struct nge_dmah_list
{
nge_dmah_node_t *head;
nge_dmah_node_t *tail;
} nge_dmah_list_t;
/*
* Software version of the Recv Descriptor
* There's one of these for each recv buffer (up to 512 per ring)
*/
typedef struct sw_rx_sbd {
dma_area_t desc; /* (const) related h/w */
/* descriptor area */
dma_area_t *bufp; /* (const) related */
/* buffer area */
uint8_t flags;
} sw_rx_sbd_t;
/*
* Software version of the send Buffer Descriptor
* There's one of these for each send buffer (up to 512 per ring)
*/
typedef struct sw_tx_sbd {
dma_area_t desc; /* (const) related h/w */
/* descriptor area */
dma_area_t pbuf; /* (const) related */
/* buffer area */
void (*tx_recycle)(struct sw_tx_sbd *);
uint32_t flags;
mblk_t *mp; /* related mblk, if any */
nge_dmah_list_t mp_hndl;
uint32_t frags;
uint32_t ncookies; /* dma cookie number */
} sw_tx_sbd_t;
/*
* Software Receive Buffer (Producer) Ring Control Block
* There's one of these for each receiver producer ring (up to 3),
* but each holds buffers of a different size.
*/
typedef struct buff_ring {
uint64_t nslots; /* descriptor area */
struct nge *ngep; /* (const) containing */
/* driver soft state */
/* initialise same */
uint64_t rx_hold;
sw_rx_sbd_t *sw_rbds; /* software descriptors */
sw_rx_sbd_t *free_rbds; /* free ring */
dma_area_t *free_list; /* available buffer queue */
dma_area_t *recycle_list; /* recycling buffer queue */
kmutex_t recycle_lock[1];
uint32_t buf_sign; /* buffer ring signature */
/* for deciding to free */
/* or to reuse buffers */
boolean_t rx_bcopy;
} buff_ring_t;
/*
* Software Receive (Return) Ring Control Block
* There's one of these for each receiver return ring (up to 16).
*/
typedef struct recv_ring {
/*
* The elements flagged (const) in the comments below are
* set up once during initialiation and thereafter unchanged.
*/
dma_area_t desc; /* (const) related h/w */
/* descriptor area */
struct nge *ngep; /* (const) containing */
/* driver soft state */
uint16_t prod_index; /* (const) ptr to h/w */
/* "producer index" */
mac_resource_handle_t handle;
} recv_ring_t;
/*
* Software Send Ring Control Block
* There's one of these for each of (up to) 1 send rings
*/
typedef struct send_ring {
/*
* The elements flagged (const) in the comments below are
* set up once during initialiation and thereafter unchanged.
*/
dma_area_t desc; /* (const) related h/w */
/* descriptor area */
dma_area_t buf[NGE_SEND_SLOTS_BUF];
/* buffer area(s) */
struct nge *ngep; /* (const) containing */
/* driver soft state */
uint32_t tx_hwmark;
uint32_t tx_lwmark;
/*
* The tx_lock must be held when updating
* the s/w producer index
* (tx_next)
*/
kmutex_t tx_lock[1]; /* serialize h/w update */
uint32_t tx_next; /* next slot to use */
uint32_t tx_flow;
/*
* These counters/indexes are manipulated in the transmit
* path using atomics rather than mutexes for speed
*/
uint32_t tx_free; /* # of slots available */
/*
* index (tc_next).
*/
kmutex_t tc_lock[1];
uint32_t tc_next; /* next slot to recycle */
/* ("consumer index") */
sw_tx_sbd_t *sw_sbds; /* software descriptors */
kmutex_t dmah_lock;
nge_dmah_list_t dmah_free;
nge_dmah_node_t dmahndl[NGE_MAX_DMA_HDR];
} send_ring_t;
typedef struct {
uint32_t businfo; /* from private reg */
uint16_t command; /* saved during attach */
uint16_t vendor; /* vendor-id */
uint16_t device; /* device-id */
uint16_t subven; /* subsystem-vendor-id */
uint16_t subdev; /* subsystem-id */
uint8_t class_code;
uint8_t revision; /* revision-id */
uint8_t clsize; /* cache-line-size */
uint8_t latency; /* latency-timer */
uint8_t flags;
uint16_t phy_type; /* Fiber module type */
uint64_t hw_mac_addr; /* from chip register */
nge_mac_addr_t vendor_addr; /* transform of same */
} chip_info_t;
typedef struct {
offset_t index;
char *name;
} nge_ksindex_t;
typedef struct {
uint64_t tso_err_mss;
uint64_t tso_dis;
uint64_t tso_err_nosum;
uint64_t tso_err_hov;
uint64_t tso_err_huf;
uint64_t tso_err_l2;
uint64_t tso_err_ip;
uint64_t tso_err_l4;
uint64_t tso_err_tcp;
uint64_t hsum_err_ip;
uint64_t hsum_err_l4;
}fe_statistics_t;
/*
* statistics parameters to tune the driver
*/
typedef struct {
uint64_t intr_count;
uint64_t intr_lval;
uint64_t recv_realloc;
uint64_t poll_time;
uint64_t recy_free;
uint64_t recv_count;
uint64_t xmit_count;
uint64_t obytes;
uint64_t rbytes;
uint64_t mp_alloc_err;
uint64_t dma_alloc_err;
uint64_t kmem_alloc_err;
uint64_t load_context;
uint64_t ip_hwsum_err;
uint64_t tcp_hwsum_err;
uint64_t rx_nobuffer;
uint64_t rx_err;
uint64_t tx_stop_err;
uint64_t tx_stall;
uint64_t tx_rsrv_fail;
uint64_t tx_resched;
fe_statistics_t fe_err;
}nge_sw_statistics_t;
typedef struct {
nge_hw_statistics_t hw_statistics;
nge_sw_statistics_t sw_statistics;
}nge_statistics_t;
struct nge_desc_attr {
size_t rxd_size;
size_t txd_size;
ddi_dma_attr_t *dma_attr;
ddi_dma_attr_t *tx_dma_attr;
void (*rxd_fill)(void *, const ddi_dma_cookie_t *, size_t);
uint32_t (*rxd_check)(const void *, size_t *);
void (*txd_fill)(void *, const ddi_dma_cookie_t *, size_t,
uint32_t, boolean_t, boolean_t);
uint32_t (*txd_check)(const void *);
};
typedef struct nge_desc_attr nge_desc_attr_t;
/*
* Structure used to hold the device-specific config parameters.
* The setting of such parameters may not consistent with the
* hardware feature of the device. It's used for software purpose.
*/
typedef struct nge_dev_spec_param {
boolean_t msi; /* specifies msi support */
boolean_t msi_x; /* specifies msi_x support */
boolean_t vlan; /* specifies vlan support */
boolean_t advanced_pm; /* advanced power management support */
boolean_t mac_addr_order; /* mac address order */
boolean_t tx_pause_frame; /* specifies tx pause frame support */
boolean_t rx_pause_frame; /* specifies rx pause frame support */
boolean_t jumbo; /* jumbo frame support */
boolean_t tx_rx_64byte; /* set the max tx/rx prd fetch size */
boolean_t rx_hw_checksum; /* specifies tx hw checksum feature */
uint32_t tx_hw_checksum; /* specifies rx hw checksum feature */
uint32_t desc_type; /* specifies descriptor type */
uint32_t rx_desc_num; /* specifies rx descriptor number */
uint32_t tx_desc_num; /* specifies tx descriptor number */
uint32_t nge_split; /* specifies the split number */
} nge_dev_spec_param_t;
typedef struct nge {
/*
* These fields are set by attach() and unchanged thereafter ...
*/
dev_info_t *devinfo; /* device instance */
mac_handle_t mh; /* mac module handle */
chip_info_t chipinfo;
ddi_acc_handle_t cfg_handle; /* DDI I/O handle */
ddi_acc_handle_t io_handle; /* DDI I/O handle */
void *io_regs; /* mapped registers */
ddi_periodic_t periodic_id; /* periodical callback */
uint32_t factotum_flag;
ddi_softint_handle_t factotum_hdl; /* factotum callback */
ddi_softint_handle_t resched_hdl; /* reschedule callback */
uint_t soft_pri;
ddi_intr_handle_t *htable; /* for array of interrupts */
int intr_type; /* type of interrupt */
int intr_actual_cnt; /* alloc intrs count */
int intr_req_cnt; /* request intrs count */
uint_t intr_pri; /* interrupt priority */
int intr_cap; /* interrupt capabilities */
uint32_t progress; /* attach tracking */
uint32_t debug; /* flag to debug function */
char ifname[8]; /* "nge0" ... "nge999" */
enum nge_mac_state nge_mac_state; /* definitions above */
enum nge_chip_state nge_chip_state; /* definitions above */
boolean_t promisc;
boolean_t record_promisc;
boolean_t suspended;
int resched_needed;
uint32_t default_mtu;
uint32_t max_sdu;
uint32_t buf_size;
uint32_t rx_desc;
uint32_t tx_desc;
uint32_t rx_buf;
uint32_t nge_split;
uint32_t watchdog;
uint32_t lowmem_mode;
/*
* Runtime read-write data starts here ...
* 1 Receive Rings
* 1 Send Rings
*
* Note: they're not necessarily all used.
*/
struct buff_ring buff[1];
struct recv_ring recv[1];
struct send_ring send[1];
kmutex_t genlock[1];
krwlock_t rwlock[1];
kmutex_t softlock[1];
uint32_t intr_masks;
boolean_t poll;
boolean_t ch_intr_mode;
boolean_t intr_moderation;
uint32_t recv_count;
uint32_t quiet_time;
uint32_t busy_time;
uint64_t tpkts_last;
uint32_t tfint_threshold;
uint32_t sw_intr_intv;
nge_mac_addr_t cur_uni_addr;
uint32_t rx_datahwm;
uint32_t rx_prdlwm;
uint32_t rx_prdhwm;
uint32_t rx_def;
uint32_t desc_mode;
mul_item *pcur_mulist;
nge_mac_addr_t cur_mul_addr;
nge_mac_addr_t cur_mul_mask;
nge_desc_attr_t desc_attr;
/*
* Link state data (protected by genlock)
*/
int32_t link_state; /* See GLD #defines */
uint32_t stall_cknum; /* Stall check number */
uint32_t phy_xmii_addr;
uint32_t phy_id;
uint32_t phy_mode;
const phys_ops_t *physops;
uint16_t phy_gen_status;
uint32_t param_loop_mode;
kstat_t *nge_kstats[NGE_KSTAT_COUNT];
nge_statistics_t statistics;
nge_dev_spec_param_t dev_spec_param;
uint32_t param_en_pause:1,
param_en_asym_pause:1,
param_en_1000hdx:1,
param_en_1000fdx:1,
param_en_100fdx:1,
param_en_100hdx:1,
param_en_10fdx:1,
param_en_10hdx:1,
param_adv_autoneg:1,
param_adv_pause:1,
param_adv_asym_pause:1,
param_adv_1000fdx:1,
param_adv_1000hdx:1,
param_adv_100fdx:1,
param_adv_100hdx:1,
param_adv_10fdx:1,
param_adv_10hdx:1,
param_lp_autoneg:1,
param_lp_pause:1,
param_lp_asym_pause:1,
param_lp_1000fdx:1,
param_lp_1000hdx:1,
param_lp_100fdx:1,
param_lp_100hdx:1,
param_lp_10fdx:1,
param_lp_10hdx:1,
param_link_up:1,
param_link_autoneg:1,
param_link_rx_pause:1,
param_link_tx_pause:1,
param_pad_to_32:2;
uint64_t param_link_speed;
link_duplex_t param_link_duplex;
int param_txbcopy_threshold;
int param_rxbcopy_threshold;
int param_recv_max_packet;
int param_poll_quiet_time;
int param_poll_busy_time;
int param_rx_intr_hwater;
int param_rx_intr_lwater;
} nge_t;
extern const nge_ksindex_t nge_statistics[];
/*
* Sync a DMA area described by a dma_area_t
*/
#define DMA_SYNC(area, flag) ((void) ddi_dma_sync((area).dma_hdl, \
(area).offset, (area).alength, (flag)))
/*
* Find the (kernel virtual) address of block of memory
* described by a dma_area_t
*/
#define DMA_VPTR(area) ((area).mem_va)
/*
* Zero a block of memory described by a dma_area_t
*/
#define DMA_ZERO(area) bzero(DMA_VPTR(area), (area).alength)
/*
* Next/Prev value of a cyclic index
*/
#define NEXT(index, limit) ((index) + 1 < (limit) ? (index) + 1 : 0)
#define PREV(index, limit) (0 == (index) ? (limit - 1) : (index) - 1)
#define NEXT_INDEX(ndx, num, lim)\
(((ndx) + (num) < (lim)) ? ((ndx) + (num)) : ((ndx) + (num) - (lim)))
/*
* Property lookups
*/
#define NGE_PROP_EXISTS(d, n) ddi_prop_exists(DDI_DEV_T_ANY, (d), \
DDI_PROP_DONTPASS, (n))
#define NGE_PROP_GET_INT(d, n) ddi_prop_get_int(DDI_DEV_T_ANY, (d), \
DDI_PROP_DONTPASS, (n), -1)
/*
* Debugging ...
*/
#ifdef DEBUG
#define NGE_DEBUGGING 1
#else
#define NGE_DEBUGGING 0
#endif /* DEBUG */
/*
* Bit flags in the 'debug' word ...
*/
#define NGE_DBG_STOP 0x00000001 /* early debug_enter() */
#define NGE_DBG_TRACE 0x00000002 /* general flow tracing */
#define NGE_DBG_MII 0x00000010 /* low-level MII access */
#define NGE_DBG_CHIP 0x00000020 /* low(ish)-level code */
#define NGE_DBG_RECV 0x00000100 /* receive-side code */
#define NGE_DBG_SEND 0x00000200 /* packet-send code */
#define NGE_DBG_INIT 0x00100000 /* initialisation */
#define NGE_DBG_NEMO 0x00200000 /* MAC layer entry points */
#define NGE_DBG_STATS 0x00400000 /* statistics */
#define NGE_DBG_BADIOC 0x01000000 /* unknown ioctls */
#define NGE_DBG_NDD 0x10000000 /* NDD operations */
/*
* 'Do-if-debugging' macro. The parameter <command> should be one or more
* C statements (but without the *final* semicolon), which will either be
* compiled inline or completely ignored, depending on the NGE_DEBUGGING
* compile-time flag.
*
* You should get a compile-time error (at least on a DEBUG build) if
* your statement isn't actually a statement, rather than unexpected
* run-time behaviour caused by unintended matching of if-then-elses etc.
*
* Note that the NGE_DDB() macro itself can only be used as a statement,
* not an expression, and should always be followed by a semicolon.
*/
#if NGE_DEBUGGING
#define NGE_DDB(command) do { \
{ command; } \
_NOTE(CONSTANTCONDITION) \
} while (0)
#else /* NGE_DEBUGGING */
#define NGE_DDB(command)
/*
* Old way of debugging. This is a poor way, as it leeaves empty
* statements that cause lint to croak.
* #define NGE_DDB(command) do { \
* { _NOTE(EMPTY); } \
* _NOTE(CONSTANTCONDITION) \
* } while (0)
*/
#endif /* NGE_DEBUGGING */
/*
* 'Internal' macros used to construct the TRACE/DEBUG macros below.
* These provide the primitive conditional-call capability required.
* Note: the parameter <args> is a parenthesised list of the actual
* printf-style arguments to be passed to the debug function ...
*/
#define NGE_XDB(b, w, f, args) NGE_DDB(if ((b) & (w)) f args)
#define NGE_GDB(b, args) NGE_XDB(b, nge_debug, (*nge_gdb()), args)
#define NGE_LDB(b, args) NGE_XDB(b, ngep->debug, \
(*nge_db(ngep)), args)
#define NGE_CDB(f, args) NGE_XDB(NGE_DBG, ngep->debug, f, args)
/*
* Conditional-print macros.
*
* Define NGE_DBG to be the relevant member of the set of NGE_DBG_* values
* above before using the NGE_GDEBUG() or NGE_DEBUG() macros. The 'G'
* versions look at the Global debug flag word (nge_debug); the non-G
* versions look in the per-instance data (ngep->debug) and so require a
* variable called 'ngep' to be in scope (and initialised!) before use.
*
* You could redefine NGE_TRC too if you really need two different
* flavours of debugging output in the same area of code, but I don't
* really recommend it.
*
* Note: the parameter <args> is a parenthesised list of the actual
* arguments to be passed to the debug function, usually a printf-style
* format string and corresponding values to be formatted.
*/
#define NGE_TRC NGE_DBG_TRACE
#define NGE_GTRACE(args) NGE_GDB(NGE_TRC, args)
#define NGE_GDEBUG(args) NGE_GDB(NGE_DBG, args)
#define NGE_TRACE(args) NGE_LDB(NGE_TRC, args)
#define NGE_DEBUG(args) NGE_LDB(NGE_DBG, args)
/*
* Debug-only action macros
*/
#define NGE_REPORT(args) NGE_DDB(nge_log args)
boolean_t nge_atomic_decrease(uint64_t *count_p, uint64_t n);
void nge_atomic_increase(uint64_t *count_p, uint64_t n);
int nge_alloc_dma_mem(nge_t *ngep, size_t memsize,
ddi_device_acc_attr_t *attr_p, uint_t dma_flags, dma_area_t *dma_p);
void nge_free_dma_mem(dma_area_t *dma_p);
int nge_restart(nge_t *ngep);
void nge_wake_factotum(nge_t *ngep);
uint8_t nge_reg_get8(nge_t *ngep, nge_regno_t regno);
void nge_reg_put8(nge_t *ngep, nge_regno_t regno, uint8_t data);
uint16_t nge_reg_get16(nge_t *ngep, nge_regno_t regno);
void nge_reg_put16(nge_t *ngep, nge_regno_t regno, uint16_t data);
uint32_t nge_reg_get32(nge_t *ngep, nge_regno_t regno);
void nge_reg_put32(nge_t *ngep, nge_regno_t regno, uint32_t data);
uint_t nge_chip_factotum(caddr_t args1, caddr_t args2);
void nge_chip_cfg_init(nge_t *ngep, chip_info_t *infop, boolean_t reset);
void nge_init_dev_spec_param(nge_t *ngep);
int nge_chip_stop(nge_t *ngep, boolean_t fault);
void nge_restore_mac_addr(nge_t *ngep);
int nge_chip_reset(nge_t *ngep);
int nge_chip_start(nge_t *ngep);
void nge_chip_sync(nge_t *ngep);
uint_t nge_chip_intr(caddr_t arg1, caddr_t arg2);
enum ioc_reply nge_chip_ioctl(nge_t *ngep, mblk_t *mp, struct iocblk *iocp);
void nge_phys_init(nge_t *ngep);
boolean_t nge_phy_reset(nge_t *ngep);
uint16_t nge_mii_get16(nge_t *ngep, nge_regno_t regno);
void nge_mii_put16(nge_t *ngep, nge_regno_t regno, uint16_t data);
void nge_recv_recycle(caddr_t arg);
void nge_receive(nge_t *ngep);
uint_t nge_reschedule(caddr_t args1, caddr_t args2);
mblk_t *nge_m_tx(void *arg, mblk_t *mp);
void nge_tx_recycle(nge_t *ngep, boolean_t is_intr);
void nge_tx_recycle_all(nge_t *ngep);
int nge_nd_init(nge_t *ngep);
void nge_nd_cleanup(nge_t *ngep);
void nge_init_kstats(nge_t *ngep, int instance);
void nge_fini_kstats(nge_t *ngep);
int nge_m_stat(void *arg, uint_t stat, uint64_t *val);
uint32_t nge_atomic_shl32(uint32_t *sp, uint_t count);
void nge_log(nge_t *ngep, const char *fmt, ...);
void nge_problem(nge_t *ngep, const char *fmt, ...);
void nge_error(nge_t *ngep, const char *fmt, ...);
void
nge_report(nge_t *ngep, uint8_t error_id);
void (*nge_db(nge_t *ngep))(const char *fmt, ...);
void (*nge_gdb(void))(const char *fmt, ...);
extern uint32_t nge_debug;
/*
* DESC MODE 2
*/
extern void nge_sum_rxd_fill(void *, const ddi_dma_cookie_t *, size_t);
extern uint32_t nge_sum_rxd_check(const void *, size_t *);
extern void nge_sum_txd_fill(void *, const ddi_dma_cookie_t *,
size_t, uint32_t, boolean_t, boolean_t);
extern uint32_t nge_sum_txd_check(const void *);
/*
* DESC MODE 3
*/
extern void nge_hot_rxd_fill(void *, const ddi_dma_cookie_t *, size_t);
extern uint32_t nge_hot_rxd_check(const void *, size_t *);
extern void nge_hot_txd_fill(void *, const ddi_dma_cookie_t *,
size_t, uint32_t, boolean_t, boolean_t);
extern uint32_t nge_hot_txd_check(const void *);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_NGE_H */
|