xref: /titanic_52/usr/src/uts/common/io/hme/hme.h (revision 34841cc2abc43146ada78560d5f179be666acbda)
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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_SYS_HME_H
27 #define	_SYS_HME_H
28 
29 #ifdef	__cplusplus
30 extern "C" {
31 #endif
32 
33 /* mode */
34 #define	HME_AUTO_SPEED	0
35 #define	HME_FORCE_SPEED	1
36 
37 /* speed */
38 #define	HME_SPEED_10	10
39 #define	HME_SPEED_100	100
40 
41 /* half-duplex or full-duplex mode */
42 
43 #define	HME_HALF_DUPLEX	0
44 #define	HME_FULL_DUPLEX	1
45 
46 #ifdef _KERNEL
47 
48 /* Named Dispatch Parameter Management Structure */
49 typedef struct	hmeparam_s {
50 	uint32_t hme_param_min;
51 	uint32_t hme_param_max;
52 	uint32_t hme_param_val;
53 	char	*hme_param_name;
54 } hmeparam_t;
55 
56 
57 static hmeparam_t	hme_param_arr[] = {
58 	/* min		max		value		name */
59 	{  0,		1,		1,		"transceiver_inuse"},
60 	{  0,		1,		0,		"link_status"},
61 	{  0,		1,		0,		"link_speed"},
62 	{  0,		1,		0,		"link_mode"},
63 	{  0,		255,		8,		"ipg1"},
64 	{  0,		255,		4,		"ipg2"},
65 	{  0,		1,		0,		"use_int_xcvr"},
66 	{  0,		255,		0,		"pace_size"},
67 	{  0,		1,		1,		"adv_autoneg_cap"},
68 	{  0,		1,		1,		"adv_100T4_cap"},
69 	{  0,		1,		1,		"adv_100fdx_cap"},
70 	{  0,		1,		1,		"adv_100hdx_cap"},
71 	{  0,		1,		1,		"adv_10fdx_cap"},
72 	{  0,		1,		1,		"adv_10hdx_cap"},
73 	{  0,		1,		1,		"autoneg_cap"},
74 	{  0,		1,		1,		"100T4_cap"},
75 	{  0,		1,		1,		"100fdx_cap"},
76 	{  0,		1,		1,		"100hdx_cap"},
77 	{  0,		1,		1,		"10fdx_cap"},
78 	{  0,		1,		1,		"10hdx_cap"},
79 	{  0,		1,		0,		"lp_autoneg_cap"},
80 	{  0,		1,		0,		"lp_100T4_cap"},
81 	{  0,		1,		0,		"lp_100fdx_cap"},
82 	{  0,		1,		0,		"lp_100hdx_cap"},
83 	{  0,		1,		0,		"lp_10fdx_cap"},
84 	{  0,		1,		0,		"lp_10hdx_cap"},
85 	{  0,		1,		1,		"lance_mode"},
86 	{  0,		31,		16,		"ipg0"},
87 };
88 
89 
90 #define	hme_param_transceiver	(hmep->hme_param_arr[0].hme_param_val)
91 #define	hme_param_linkup	(hmep->hme_param_arr[1].hme_param_val)
92 #define	hme_param_speed		(hmep->hme_param_arr[2].hme_param_val)
93 #define	hme_param_mode		(hmep->hme_param_arr[3].hme_param_val)
94 #define	hme_param_ipg1		(hmep->hme_param_arr[4].hme_param_val)
95 #define	hme_param_ipg2		(hmep->hme_param_arr[5].hme_param_val)
96 #define	hme_param_use_intphy	(hmep->hme_param_arr[6].hme_param_val)
97 #define	hme_param_pace_count	(hmep->hme_param_arr[7].hme_param_val)
98 #define	hme_param_autoneg	(hmep->hme_param_arr[8].hme_param_val)
99 #define	hme_param_anar_100T4	(hmep->hme_param_arr[9].hme_param_val)
100 #define	hme_param_anar_100fdx	(hmep->hme_param_arr[10].hme_param_val)
101 #define	hme_param_anar_100hdx	(hmep->hme_param_arr[11].hme_param_val)
102 #define	hme_param_anar_10fdx	(hmep->hme_param_arr[12].hme_param_val)
103 #define	hme_param_anar_10hdx	(hmep->hme_param_arr[13].hme_param_val)
104 #define	hme_param_bmsr_ancap	(hmep->hme_param_arr[14].hme_param_val)
105 #define	hme_param_bmsr_100T4	(hmep->hme_param_arr[15].hme_param_val)
106 #define	hme_param_bmsr_100fdx	(hmep->hme_param_arr[16].hme_param_val)
107 #define	hme_param_bmsr_100hdx	(hmep->hme_param_arr[17].hme_param_val)
108 #define	hme_param_bmsr_10fdx	(hmep->hme_param_arr[18].hme_param_val)
109 #define	hme_param_bmsr_10hdx	(hmep->hme_param_arr[19].hme_param_val)
110 #define	hme_param_aner_lpancap	(hmep->hme_param_arr[20].hme_param_val)
111 #define	hme_param_anlpar_100T4	(hmep->hme_param_arr[21].hme_param_val)
112 #define	hme_param_anlpar_100fdx	(hmep->hme_param_arr[22].hme_param_val)
113 #define	hme_param_anlpar_100hdx	(hmep->hme_param_arr[23].hme_param_val)
114 #define	hme_param_anlpar_10fdx	(hmep->hme_param_arr[24].hme_param_val)
115 #define	hme_param_anlpar_10hdx	(hmep->hme_param_arr[25].hme_param_val)
116 #define	hme_param_lance_mode	(hmep->hme_param_arr[26].hme_param_val)
117 #define	hme_param_ipg0		(hmep->hme_param_arr[27].hme_param_val)
118 
119 #define	HME_PARAM_CNT	29
120 
121 
122 /* command */
123 
124 #define	HME_ND_GET	ND_GET
125 #define	HME_ND_SET	ND_SET
126 
127 /* default IPG settings */
128 #define	IPG1	8
129 #define	IPG2	4
130 
131 /*
132  * Declarations and definitions specific to the
133  * FEPS 10/100 Mbps Ethernet (hme) device.
134  */
135 
136 /*
137  * Per-Stream instance state information.
138  *
139  * Each instance is dynamically allocated at open() and free'd
140  * at close().  Each per-Stream instance points to at most one
141  * per-device structure using the sb_hmep field.  All instances
142  * are threaded together into one list of active instances
143  * ordered on minor device number.
144  */
145 
146 #define	MSECOND(t)	t
147 #define	SECOND(t)	t*1000
148 #define	HME_TICKS	MSECOND(100)
149 
150 #define	HME_LINKCHECK_TIMER	SECOND(30)
151 
152 #define	HME_2P0_REVID		0xa0 /* hme - feps. */
153 #define	HME_2P1_REVID		0x20
154 #define	HME_2P1_REVID_OBP	0x21
155 #define	HME_1C0_REVID		0xc0 /* cheerio 1.0, hme 2.0 equiv. */
156 #define	HME_2C0_REVID		0xc1 /* cheerio 2.0, hme 2.2 equiv. */
157 #define	HME_REV_VERS_MASK	0x0f /* Mask to retain bits for cheerio ver */
158 
159 #define	HME_NTRIES_LOW		(SECOND(5)/HME_TICKS)	/* 5 Seconds */
160 #define	HME_NTRIES_HIGH		(SECOND(5)/HME_TICKS)	/* 5 Seconds */
161 #define	HME_NTRIES_LOW_10	(SECOND(2)/HME_TICKS)	/* 2 Seconds */
162 #define	HME_LINKDOWN_TIME	(SECOND(2)/HME_TICKS)	/* 2 Seconds */
163 
164 #define	HME_LINKDOWN_OK		0
165 #define	HME_FORCE_LINKDOWN	1
166 #define	HME_LINKDOWN_STARTED	2
167 #define	HME_LINKDOWN_DONE	3
168 
169 #define	P1_0    0x100
170 
171 #define	HME_EXTERNAL_TRANSCEIVER	0
172 #define	HME_INTERNAL_TRANSCEIVER	1
173 #define	HME_NO_TRANSCEIVER		2
174 
175 #define	HME_HWAN_TRY		0 /* Try Hardware autonegotiation */
176 #define	HME_HWAN_INPROGRESS	1 /* Hardware autonegotiation in progress */
177 #define	HME_HWAN_SUCCESFUL	2 /* Hardware autonegotiation succesful */
178 #define	HME_HWAN_FAILED		3 /* Hardware autonegotiation failed */
179 
180 #define	RESET_TO_BE_ISSUED	0 /* Reset command to be issued to the PHY */
181 #define	RESET_ISSUED		1 /* Reset command has been issued */
182 #define	ISOLATE_ISSUED		2 /* Isolate-remove command has been issued */
183 #define	POWER_OFF_ISSUED	3 /* The QSI Phy may have problems with */
184 					/* Power rampup. Issue powerdown in   */
185 					/* the driver to insure good reset.   */
186 struct	hmesave {
187 	ulong_t		hme_starts;
188 	uint32_t	hme_opackets;
189 };
190 
191 typedef struct {
192 	ddi_dma_handle_t	dmah;
193 	ddi_acc_handle_t	acch;
194 	caddr_t			kaddr;
195 	uint32_t		paddr;
196 } hmebuf_t;
197 
198 /*
199  * HME Device Channel instance state information.
200  *
201  * Each instance is dynamically allocated on first attach.
202  */
203 struct	hme {
204 	mac_handle_t		hme_mh;		/* GLDv3 handle */
205 	dev_info_t		*dip;		/* associated dev_info */
206 	int			instance;	/* instance */
207 	ulong_t			pagesize;	/* btop(9F) */
208 
209 	/*
210 	 * xcvr information
211 	 */
212 	uint16_t		hme_idr1;	/* PHY IDR1 register */
213 	uint16_t		hme_idr2;	/* PHY IDR2 register */
214 	uint16_t		hme_anar;	/* PHY ANAR register */
215 	uint16_t		hme_anlpar;	/* PHY ANLPAR register */
216 	uint16_t		hme_aner;	/* PHY ANER register */
217 
218 	int			hme_mifpoll_enable;
219 	int			hme_frame_enable;
220 	int			hme_lance_mode_enable;
221 	int			hme_rxcv_enable;
222 
223 	uint_t			hme_burstsizes; /* binary encoded val */
224 	uint32_t		hme_config;	/* Config reg store */
225 
226 	int			hme_phy_retries; /* phy reset failures */
227 	int			hme_phy_failure; /* phy failure type */
228 
229 	int			hme_64bit_xfer;	/* 64-bit Sbus xfers */
230 	int			hme_phyad;
231 	int			hme_autoneg;
232 
233 	caddr_t			hme_g_nd;	/* head of the */
234 						/* named dispatch table */
235 	hmeparam_t		hme_param_arr[HME_PARAM_CNT];
236 	int			hme_transceiver;  /* current PHY in use */
237 	int			hme_link_pulse_disabled;
238 	uint16_t		hme_bmcr;	/* PHY control register */
239 	uint16_t		hme_bmsr;	/* PHY status register */
240 	int			hme_mode;	/* auto/forced mode */
241 	int			hme_linkup;	/* link status */
242 	int			hme_xcvr_state; /* transceiver status */
243 	int			hme_forcespeed; /* speed in forced mode */
244 	int			hme_tryspeed;	/* speed in auto mode */
245 	int			hme_fdx;	/* full-duplex mode */
246 	int			hme_pace_count;	/* pacing pkt count */
247 
248 	int			hme_macfdx;
249 	int			hme_linkcheck;
250 	int			hme_force_linkdown;
251 	int			hme_nlasttries;
252 	int			hme_ntries;
253 	int			hme_delay;
254 	int			hme_linkup_10;
255 	int			hme_linkup_cnt;
256 	timeout_id_t		hme_timerid;
257 	int			hme_cheerio_mode;
258 	int			hme_polling_on;
259 	int			hme_mifpoll_data;
260 	int			hme_mifpoll_flag;
261 
262 	/*
263 	 * This is part of the hardening of the hme driver
264 	 * (following x fields)
265 	 */
266 	ushort_t		hme_disabled;
267 
268 	struct	ether_addr	hme_factaddr;	/* factory mac address */
269 	struct	ether_addr	hme_ouraddr;	/* individual address */
270 	uint32_t		hme_addrflags;	/* address flags */
271 	uint32_t		hme_flags;	/* misc. flags */
272 	boolean_t		hme_wantw;	/* xmit: out of resources */
273 	boolean_t		hme_started;	/* mac layer started */
274 
275 	uint8_t			hme_devno;
276 
277 	uint16_t		hme_ladrf[4];	/* 64 bit multicast filter */
278 	uint32_t		hme_ladrf_refcnt[64];
279 	boolean_t		hme_promisc;
280 	uint32_t		hme_multi;	/* refcount on mcast addrs */
281 
282 	struct	hme_global	*hme_globregp;	/* HME global regs */
283 	struct	hme_etx		*hme_etxregp;	/* HME ETX regs */
284 	struct	hme_erx		*hme_erxregp;	/* HME ERX regs */
285 	struct	hme_bmac	*hme_bmacregp;	/* BigMAC registers */
286 	struct	hme_mif		*hme_mifregp;	/* HME transceiver */
287 	unsigned char		*hme_romp;	/* fcode rom pointer */
288 
289 	kmutex_t	hme_xmitlock;		/* protect xmit-side fields */
290 	kmutex_t	hme_intrlock;		/* protect intr-side fields */
291 	kmutex_t	hme_linklock;		/* protect link-side fields */
292 	ddi_iblock_cookie_t	hme_cookie;	/* interrupt cookie */
293 
294 	struct	hme_rmd	*hme_rmdp;	/* receive descriptor ring start */
295 	struct	hme_tmd	*hme_tmdp;	/* transmit descriptor ring start */
296 
297 	ddi_dma_handle_t	hme_rmd_dmah;
298 	ddi_acc_handle_t	hme_rmd_acch;
299 	caddr_t			hme_rmd_kaddr;
300 	uint32_t		hme_rmd_paddr;
301 
302 	ddi_dma_handle_t	hme_tmd_dmah;
303 	ddi_acc_handle_t	hme_tmd_acch;
304 	caddr_t			hme_tmd_kaddr;
305 	uint32_t		hme_tmd_paddr;
306 
307 	uint64_t		hme_rxindex;
308 	uint64_t		hme_txindex;
309 	uint64_t		hme_txreclaim;
310 
311 	hmebuf_t		*hme_tbuf;	/* hmebuf associated with TMD */
312 	hmebuf_t		*hme_rbuf;	/* hmebuf associated with RMD */
313 
314 	ddi_device_acc_attr_t	hme_dev_attr;
315 	ddi_acc_handle_t	hme_globregh;   /* HME global regs */
316 	ddi_acc_handle_t	hme_etxregh;    /* HME ETX regs */
317 	ddi_acc_handle_t	hme_erxregh;    /* HME ERX regs */
318 	ddi_acc_handle_t	hme_bmacregh;   /* BigMAC registers */
319 	ddi_acc_handle_t	hme_mifregh;    /* HME transceiver */
320 	ddi_acc_handle_t	hme_romh;	/* rom handle */
321 
322 	ddi_acc_handle_t	pci_config_handle; /* HME PCI config */
323 
324 	/*
325 	 * DDI dma handle, kernel virtual base,
326 	 * and io virtual base of IOPB area.
327 	 */
328 	ddi_dma_handle_t	hme_iopbhandle;
329 	ulong_t			hme_iopbkbase;
330 	uint32_t		hme_iopbiobase;
331 
332 	kstat_t	*hme_ksp;	/* kstat pointer */
333 	kstat_t	*hme_intrstats;	/* kstat interrupt counter */
334 	uint64_t hme_iipackets;	/* Used to store the Count of packets */
335 				/* recieved at the start of 'hme_check_link' */
336 				/* watch dog interval. */
337 
338 	uint64_t hme_ifspeed;		/* ifspeed is now in bits/sec	*/
339 	uint64_t hme_ipackets;
340 	uint64_t hme_rbytes;
341 	uint64_t hme_ierrors;
342 	uint64_t hme_opackets;
343 	uint64_t hme_obytes;
344 	uint64_t hme_oerrors;
345 	uint64_t hme_multircv;		/* # multicast packets received */
346 	uint64_t hme_multixmt;		/* # multicast packets for xmit */
347 	uint64_t hme_brdcstrcv;		/* # broadcast packets received */
348 	uint64_t hme_brdcstxmt;		/* # broadcast packets for xmit */
349 	uint64_t hme_oflo;
350 	uint64_t hme_uflo;
351 	uint64_t hme_norcvbuf;		/* # rcv packets discarded */
352 	uint64_t hme_noxmtbuf;		/* # xmit packets discarded */
353 	uint64_t hme_duplex;
354 	uint64_t hme_align_errors;
355 	uint64_t hme_coll;
356 	uint64_t hme_fcs_errors;
357 	uint64_t hme_defer_xmts;
358 	uint64_t hme_sqe_errors;
359 	uint64_t hme_excol;
360 	uint64_t hme_fstcol;
361 	uint64_t hme_tlcol;
362 	uint64_t hme_toolong_errors;
363 	uint64_t hme_runt;
364 	uint64_t hme_carrier_errors;
365 	uint64_t hme_jab;
366 
367 	uint32_t hme_cvc;
368 	uint32_t hme_lenerr;
369 	uint32_t hme_buff;
370 	uint32_t hme_missed;
371 	uint32_t hme_nocanput;
372 	uint32_t hme_allocbfail;
373 	uint32_t hme_babl;
374 	uint32_t hme_tmder;
375 	uint32_t hme_txlaterr;
376 	uint32_t hme_rxlaterr;
377 	uint32_t hme_slvparerr;
378 	uint32_t hme_txparerr;
379 	uint32_t hme_rxparerr;
380 	uint32_t hme_slverrack;
381 	uint32_t hme_txerrack;
382 	uint32_t hme_rxerrack;
383 	uint32_t hme_txtagerr;
384 	uint32_t hme_rxtagerr;
385 	uint32_t hme_eoperr;
386 	uint32_t hme_notmds;
387 	uint32_t hme_notbufs;
388 	uint32_t hme_norbufs;
389 
390 	/*
391 	 * check if transmitter is hung
392 	 */
393 	uint32_t hme_starts;
394 	uint32_t hme_txhung;
395 	time_t hme_msg_time;
396 	struct hmesave hmesave;
397 
398 	/*
399 	 * Debuging kstats
400 	 */
401 	uint32_t inits;
402 	uint32_t phyfail;
403 	uint32_t asic_rev;
404 };
405 
406 /* flags */
407 #define	HMERUNNING	0x01	/* chip is initialized */
408 #define	HMESUSPENDED	0x08	/* suspended interface */
409 #define	HMEINITIALIZED	0x10	/* interface initialized */
410 
411 /* Mac address flags */
412 
413 #define	HME_FACTADDR_PRESENT	0x01	/* factory MAC id present */
414 #define	HME_FACTADDR_USE	0x02	/* use factory MAC id */
415 
416 struct	hmekstat {
417 	struct kstat_named	hk_cvc;		/* code violation  errors */
418 	struct kstat_named	hk_lenerr;	/* rx len errors */
419 	struct kstat_named	hk_buff;	/* buff errors */
420 	struct kstat_named	hk_missed;	/* missed/dropped packets */
421 	struct kstat_named	hk_nocanput;	/* nocanput errors */
422 	struct kstat_named	hk_allocbfail;	/* allocb failures */
423 	struct kstat_named	hk_babl;	/* runt errors */
424 	struct kstat_named	hk_tmder;	/* tmd errors */
425 	struct kstat_named	hk_txlaterr;	/* tx late errors */
426 	struct kstat_named	hk_rxlaterr;	/* rx late errors */
427 	struct kstat_named	hk_slvparerr;	/* slave parity errors */
428 	struct kstat_named	hk_txparerr;	/* tx parity errors */
429 	struct kstat_named	hk_rxparerr;	/* rx parity errors */
430 	struct kstat_named	hk_slverrack;	/* slave error acks */
431 	struct kstat_named	hk_txerrack;	/* tx error acks */
432 	struct kstat_named	hk_rxerrack;	/* rx error acks */
433 	struct kstat_named	hk_txtagerr;	/* tx tag error */
434 	struct kstat_named	hk_rxtagerr;	/* rx tag error */
435 	struct kstat_named	hk_eoperr;	/* eop error */
436 	struct kstat_named	hk_notmds;	/* tmd errors */
437 	struct kstat_named	hk_notbufs;	/* tx buf errors */
438 	struct kstat_named	hk_norbufs;	/* rx buf errors */
439 
440 	struct kstat_named	hk_inits;		/* global inits */
441 	struct	kstat_named	hk_phyfail;		/* phy failures */
442 
443 	struct	kstat_named	hk_asic_rev;		/* asic_rev */
444 };
445 
446 #define	HMEDRAINTIME	(400000)	/* # microseconds xmit drain */
447 
448 #define	ROUNDUP(a, n)	(((a) + ((n) - 1)) & ~((n) - 1))
449 #define	ROUNDUP2(a, n)	(uchar_t *)((((uintptr_t)(a)) + ((n) - 1)) & ~((n) - 1))
450 
451 /*
452  * Xmit/receive buffer structure.
453  * This structure is organized to meet the following requirements:
454  * - bb_buf starts on an HMEBURSTSIZE boundary.
455  * - hmebuf is an even multiple of HMEBURSTSIZE
456  * - bb_buf[] is large enough to contain max VLAN frame (1522) plus
457  *   (3 x HMEBURSTSIZE) rounded up to the next HMEBURSTSIZE
458  * XXX What about another 128 bytes (HMEC requirement).
459  * Fast aligned copy requires both the source and destination
460  * addresses have the same offset from some N-byte boundary.
461  */
462 #define		HMEBURSTSIZE	(64)
463 #define		HMEBURSTMASK	(HMEBURSTSIZE - 1)
464 #define		HMEBUFSIZE	(1728)
465 
466 /*
467  * Define offset from start of bb_buf[] to point receive descriptor.
468  * Requirements:
469  * - must be 14 bytes back of a 4-byte boundary so the start of
470  *   the network packet is 4-byte aligned.
471  * - leave some headroom for others
472  */
473 #define		HMEHEADROOM	(34)
474 
475 /* Offset for the first byte in the receive buffer */
476 #define	HME_FSTBYTE_OFFSET	2
477 
478 #endif	/* _KERNEL */
479 
480 #ifdef	__cplusplus
481 }
482 #endif
483 
484 #endif	/* _SYS_HME_H */
485