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
|
/*
* usbgem.h: General USB to Ethernet MAC driver framework
* @(#)usbgem.h 1.4 12/02/09
* (C) Copyright 2003-2009 Masayuki Murayama KHF04453@nifty.ne.jp
*/
#ifndef __USBGEM_H__
#define __USBGEM_H__
#pragma ident "@(#)usbgem.h 1.4 12/02/09"
#ifdef USBGEM_CONFIG_GLDv3
#include <sys/mac.h>
#ifndef MAC_VERSION
#include <sys/mac_provider.h>
#endif
#include <sys/mac_ether.h>
#else
#include <sys/gld.h>
#endif /* GLDv3 */
/*
* Useful macros and typedefs
*/
#define USBGEM_NAME_LEN 32
#define USBGEM_TX_TIMEOUT (drv_usectohz(3*1000000))
#define USBGEM_TX_TIMEOUT_INTERVAL (drv_usectohz(1*1000000))
#define USBGEM_LINK_WATCH_INTERVAL (drv_usectohz(1*1000000))
/* general return code */
#define USBGEM_SUCCESS 0
#define USBGEM_FAILURE 1
/* return code of usbgem_tx_done */
#define INTR_RESTART_TX 0x80000000U
struct usbgem_stats {
uint32_t intr;
uint32_t crc;
uint32_t errrcv;
uint32_t overflow;
uint32_t frame;
uint32_t missed;
uint32_t runt;
uint32_t frame_too_long;
uint32_t norcvbuf;
uint32_t sqe;
uint32_t collisions;
uint32_t first_coll;
uint32_t multi_coll;
uint32_t excoll;
uint32_t xmit_internal_err;
uint32_t nocarrier;
uint32_t defer;
uint32_t errxmt;
uint32_t underflow;
uint32_t xmtlatecoll;
uint32_t noxmtbuf;
uint32_t jabber;
uint64_t rbytes;
uint64_t obytes;
uint64_t rpackets;
uint64_t opackets;
uint32_t rbcast;
uint32_t obcast;
uint32_t rmcast;
uint32_t omcast;
uint32_t rcv_internal_err;
};
struct mcast_addr {
struct ether_addr addr;
uint32_t hash;
};
#define USBGEM_MAXMC 64
#define USBGEM_MCALLOC (sizeof (struct mcast_addr) * USBGEM_MAXMC)
#define SLOT(dp, n) ((n) % (dp)->ugc.usbgc_tx_list_max)
/*
* mac soft state
*/
struct usbgem_dev {
dev_info_t *dip;
#ifdef USBGEM_CONFIG_GLDv3
mac_handle_t mh;
#else
void *macinfo; /* opaque handle for upper layer */
#endif
char name[USBGEM_NAME_LEN];
/* pointer to usb private data */
usb_client_dev_data_t *reg_data;
/* usb handles */
usb_pipe_handle_t default_pipe;
usb_pipe_handle_t bulkin_pipe;
usb_pipe_handle_t bulkout_pipe;
usb_pipe_handle_t intr_pipe;
/* usb endpoints */
usb_ep_descr_t *ep_default;
usb_ep_descr_t *ep_bulkin;
usb_ep_descr_t *ep_bulkout;
usb_ep_descr_t *ep_intr;
/* usb policies */
usb_pipe_policy_t policy_default;
usb_pipe_policy_t policy_bulkin;
usb_pipe_policy_t policy_bulkout;
usb_pipe_policy_t policy_interrupt;
/* MAC address information */
struct ether_addr cur_addr;
struct ether_addr dev_addr;
/* RX state and resource management */
kmutex_t rxlock;
int rx_busy_cnt;
boolean_t rx_active;
kcondvar_t rx_drain_cv;
/* RX buffer management */
int rx_buf_len;
/* TX state and resource management */
kmutex_t txlock;
int tx_busy_cnt;
usb_bulk_req_t *tx_free_list;
kcondvar_t tx_drain_cv;
clock_t tx_start_time;
int bulkout_timeout; /* in second */
int tx_max_packets;
int tx_seq_num;
int tx_intr_pended;
/* NIC state from OS view */
int nic_state;
#define NIC_STATE_UNKNOWN 0
#define NIC_STATE_STOPPED 1
#define NIC_STATE_INITIALIZED 2
#define NIC_STATE_ONLINE 3
/* MAC state from hardware view */
int mac_state;
#define MAC_STATE_DISCONNECTED 0 /* it includes suspended state too */
#define MAC_STATE_STOPPED 1 /* powered up / buf not initialized */
#define MAC_STATE_INITIALIZED 2 /* initialized */
#define MAC_STATE_ONLINE 3 /* working correctly */
#define MAC_STATE_ERROR 4 /* need to restart nic */
clock_t fatal_error;
/* robustness: timer and watchdog */
uint_t tx_watcher_stop;
kt_did_t tx_watcher_did;
kcondvar_t tx_watcher_cv;
kmutex_t tx_watcher_lock;
clock_t tx_watcher_timeout;
clock_t tx_watcher_interval;
/* MII mamagement */
boolean_t anadv_autoneg:1;
boolean_t anadv_1000fdx:1;
boolean_t anadv_1000hdx:1;
boolean_t anadv_100t4:1;
boolean_t anadv_100fdx:1;
boolean_t anadv_100hdx:1;
boolean_t anadv_10fdx:1;
boolean_t anadv_10hdx:1;
boolean_t anadv_1000t_ms:2;
boolean_t anadv_pause:1;
boolean_t anadv_asmpause:1;
boolean_t mii_advert_ro:1;
boolean_t full_duplex:1;
int speed:3;
#define USBGEM_SPD_10 0
#define USBGEM_SPD_100 1
#define USBGEM_SPD_1000 2
#define USBGEM_SPD_NUM 3
unsigned int flow_control:2;
#define FLOW_CONTROL_NONE 0
#define FLOW_CONTROL_SYMMETRIC 1
#define FLOW_CONTROL_TX_PAUSE 2
#define FLOW_CONTROL_RX_PAUSE 3
boolean_t mii_supress_msg:1;
uint32_t mii_phy_id;
uint16_t mii_status;
uint16_t mii_advert;
uint16_t mii_lpable;
uint16_t mii_exp;
uint16_t mii_ctl1000;
uint16_t mii_stat1000;
uint16_t mii_xstatus;
int8_t mii_phy_addr; /* must be signed */
uint16_t mii_status_ro;
uint16_t mii_xstatus_ro;
int mii_state;
#define MII_STATE_UNKNOWN 0
#define MII_STATE_RESETTING 1
#define MII_STATE_AUTONEGOTIATING 2
#define MII_STATE_AN_DONE 3
#define MII_STATE_MEDIA_SETUP 4
#define MII_STATE_LINKUP 5
#define MII_STATE_LINKDOWN 6
clock_t mii_last_check; /* in tick */
clock_t mii_timer; /* in tick */
#define MII_RESET_TIMEOUT drv_usectohz(1000*1000)
#define MII_AN_TIMEOUT drv_usectohz(5000*1000)
#define MII_LINKDOWN_TIMEOUT drv_usectohz(10000*1000)
clock_t mii_interval; /* in tick */
clock_t linkup_delay; /* in tick */
uint_t link_watcher_stop;
kt_did_t link_watcher_did;
kcondvar_t link_watcher_wait_cv;
kmutex_t link_watcher_lock;
krwlock_t dev_state_lock; /* mac_state and nic_state */
ksema_t hal_op_lock; /* serialize hw operations */
ksema_t drv_op_lock; /* hotplug op lock */
/* multcast list */
ksema_t rxfilter_lock;
int mc_count;
int mc_count_req;
struct mcast_addr *mc_list;
int rxmode;
#define RXMODE_PROMISC 0x01
#define RXMODE_ALLMULTI_REQ 0x02
#define RXMODE_MULTI_OVF 0x04
#define RXMODE_ENABLE 0x08
#define RXMODE_ALLMULTI (RXMODE_ALLMULTI_REQ | RXMODE_MULTI_OVF)
#define RXMODE_BITS \
"\020" \
"\004ENABLE" \
"\003MULTI_OVF" \
"\002ALLMULTI_REQ" \
"\001PROMISC"
/* statistcs */
struct usbgem_stats stats;
/* pointer to local structure */
void *private;
int priv_size;
/* configuration */
struct usbgem_conf {
/* name */
char usbgc_name[USBGEM_NAME_LEN];
int usbgc_ppa;
/* specification on usb */
int usbgc_ifnum; /* interface number */
int usbgc_alt; /* alternate */
/* specification on tx engine */
int usbgc_tx_list_max;
/* specification on rx engine */
int usbgc_rx_header_len;
int usbgc_rx_list_max;
/* time out parameters */
clock_t usbgc_tx_timeout;
clock_t usbgc_tx_timeout_interval;
/* flow control */
int usbgc_flow_control;
/* MII timeout parameters */
clock_t usbgc_mii_linkdown_timeout;
clock_t usbgc_mii_link_watch_interval;
clock_t usbgc_mii_reset_timeout;
clock_t usbgc_mii_an_watch_interval;
clock_t usbgc_mii_an_timeout;
clock_t usbgc_mii_an_wait;
clock_t usbgc_mii_an_delay;
/* MII configuration */
int usbgc_mii_addr_min;
int usbgc_mii_linkdown_action;
int usbgc_mii_linkdown_timeout_action;
#define MII_ACTION_NONE 0
#define MII_ACTION_RESET 1
#define MII_ACTION_RSA 2
boolean_t usbgc_mii_dont_reset:1;
boolean_t usbgc_mii_an_oneshot:1;
boolean_t usbgc_mii_hw_link_detection:1;
boolean_t usbgc_mii_stop_mac_on_linkdown:1;
uint16_t usbgc_mii_an_cmd;
/* I/O methods */
/* mac operation */
int (*usbgc_attach_chip)(struct usbgem_dev *dp);
int (*usbgc_reset_chip)(struct usbgem_dev *dp);
int (*usbgc_init_chip)(struct usbgem_dev *dp);
int (*usbgc_start_chip)(struct usbgem_dev *dp);
int (*usbgc_stop_chip)(struct usbgem_dev *dp);
uint32_t (*usbgc_multicast_hash)(struct usbgem_dev *dp,
const uint8_t *);
int (*usbgc_set_rx_filter)(struct usbgem_dev *dp);
int (*usbgc_set_media)(struct usbgem_dev *dp);
int (*usbgc_get_stats)(struct usbgem_dev *dp);
void (*usbgc_interrupt)(struct usbgem_dev *dp, mblk_t *mp);
/* packet manipulation */
mblk_t *(*usbgc_tx_make_packet)(struct usbgem_dev *dp,
mblk_t *mp);
mblk_t *(*usbgc_rx_make_packet)(struct usbgem_dev *dp,
mblk_t *mp);
/* mii operations */
int (*usbgc_mii_probe)(struct usbgem_dev *dp);
int (*usbgc_mii_init)(struct usbgem_dev *dp);
int (*usbgc_mii_config)(struct usbgem_dev *dp, int *errp);
uint16_t (*usbgc_mii_read)(struct usbgem_dev *dp, uint_t reg,
int *errp);
void (*usbgc_mii_write)(struct usbgem_dev *dp, uint_t reg,
uint16_t val, int *errp);
/* jumbo frame */
int usbgc_max_mtu;
int usbgc_default_mtu;
int usbgc_min_mtu;
} ugc;
int misc_flag;
#define USBGEM_VLAN 0x0001
timeout_id_t intr_watcher_id;
/* buffer size */
uint_t mtu;
/* performance tuning parameters */
uint_t txthr; /* tx fifo threshoold */
uint_t txmaxdma; /* tx max dma burst size */
uint_t rxthr; /* rx fifo threshoold */
uint_t rxmaxdma; /* tx max dma burst size */
/* kstat stuff */
kstat_t *ksp;
/* ndd stuff */
caddr_t nd_data_p;
caddr_t nd_arg_p;
#ifdef USBGEM_DEBUG_LEVEL
int tx_cnt;
#endif
};
/*
* Exported functions
*/
int usbgem_ctrl_out(struct usbgem_dev *dp,
uint8_t reqt, uint8_t req, uint16_t val, uint16_t ix, uint16_t len,
void *bp, int size);
int usbgem_ctrl_in(struct usbgem_dev *dp,
uint8_t reqt, uint8_t req, uint16_t val, uint16_t ix, uint16_t len,
void *bp, int size);
int usbgem_ctrl_out_val(struct usbgem_dev *dp,
uint8_t reqt, uint8_t req, uint16_t val, uint16_t ix, uint16_t len,
uint32_t v);
int usbgem_ctrl_in_val(struct usbgem_dev *dp,
uint8_t reqt, uint8_t req, uint16_t val, uint16_t ix, uint16_t len,
void *valp);
void usbgem_generate_macaddr(struct usbgem_dev *, uint8_t *);
boolean_t usbgem_get_mac_addr_conf(struct usbgem_dev *);
int usbgem_mii_probe_default(struct usbgem_dev *);
int usbgem_mii_init_default(struct usbgem_dev *);
int usbgem_mii_config_default(struct usbgem_dev *, int *errp);
void usbgem_mii_update_link(struct usbgem_dev *);
void usbgem_restart_tx(struct usbgem_dev *);
boolean_t usbgem_tx_done(struct usbgem_dev *, int);
void usbgem_receive(struct usbgem_dev *);
struct usbgem_dev *usbgem_do_attach(dev_info_t *,
struct usbgem_conf *, void *, int);
int usbgem_do_detach(dev_info_t *);
uint32_t usbgem_ether_crc_le(const uint8_t *addr);
uint32_t usbgem_ether_crc_be(const uint8_t *addr);
int usbgem_resume(dev_info_t *);
int usbgem_suspend(dev_info_t *);
int usbgem_quiesce(dev_info_t *);
#ifdef USBGEM_CONFIG_GLDv3
#if DEVO_REV < 4
#define USBGEM_STREAM_OPS(dev_ops, attach, detach) \
DDI_DEFINE_STREAM_OPS(dev_ops, nulldev, nulldev, attach, detach, \
nodev, NULL, D_MP, NULL)
#else
#define USBGEM_STREAM_OPS(dev_ops, attach, detach) \
DDI_DEFINE_STREAM_OPS(dev_ops, nulldev, nulldev, attach, detach, \
nodev, NULL, D_MP, NULL, usbgem_quiesce)
#endif
#else
#define usbgem_getinfo gld_getinfo
#define usbgem_open gld_open
#define usbgem_close gld_close
#define usbgem_wput gld_wput
#define usbgem_wsrv gld_wsrv
#define usbgem_rsrv gld_rsrv
#define usbgem_power NULL
#endif
int usbgem_mod_init(struct dev_ops *, char *);
void usbgem_mod_fini(struct dev_ops *);
#define USBGEM_GET_DEV(dip) \
((struct usbgem_dev *)(ddi_get_driver_private(dip)))
#endif /* __USBGEM_H__ */
|