1*0035018cSRaymond Chen /* 2*0035018cSRaymond Chen * CDDL HEADER START 3*0035018cSRaymond Chen * 4*0035018cSRaymond Chen * The contents of this file are subject to the terms of the 5*0035018cSRaymond Chen * Common Development and Distribution License (the "License"). 6*0035018cSRaymond Chen * You may not use this file except in compliance with the License. 7*0035018cSRaymond Chen * 8*0035018cSRaymond Chen * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*0035018cSRaymond Chen * or http://www.opensolaris.org/os/licensing. 10*0035018cSRaymond Chen * See the License for the specific language governing permissions 11*0035018cSRaymond Chen * and limitations under the License. 12*0035018cSRaymond Chen * 13*0035018cSRaymond Chen * When distributing Covered Code, include this CDDL HEADER in each 14*0035018cSRaymond Chen * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*0035018cSRaymond Chen * If applicable, add the following below this CDDL HEADER, with the 16*0035018cSRaymond Chen * fields enclosed by brackets "[]" replaced with your own identifying 17*0035018cSRaymond Chen * information: Portions Copyright [yyyy] [name of copyright owner] 18*0035018cSRaymond Chen * 19*0035018cSRaymond Chen * CDDL HEADER END 20*0035018cSRaymond Chen */ 21*0035018cSRaymond Chen /* 22*0035018cSRaymond Chen * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23*0035018cSRaymond Chen * Use is subject to license terms. 24*0035018cSRaymond Chen */ 25*0035018cSRaymond Chen 26*0035018cSRaymond Chen #ifndef _SYS_USB_USBETH_H 27*0035018cSRaymond Chen #define _SYS_USB_USBETH_H 28*0035018cSRaymond Chen 29*0035018cSRaymond Chen 30*0035018cSRaymond Chen #include <sys/types.h> 31*0035018cSRaymond Chen #include <sys/dditypes.h> 32*0035018cSRaymond Chen #include <sys/mac.h> 33*0035018cSRaymond Chen #include <sys/note.h> 34*0035018cSRaymond Chen 35*0035018cSRaymond Chen #ifdef __cplusplus 36*0035018cSRaymond Chen extern "C" { 37*0035018cSRaymond Chen #endif 38*0035018cSRaymond Chen 39*0035018cSRaymond Chen typedef struct usbecm_state usbecm_state_t; 40*0035018cSRaymond Chen 41*0035018cSRaymond Chen 42*0035018cSRaymond Chen /* 43*0035018cSRaymond Chen * PM support 44*0035018cSRaymond Chen */ 45*0035018cSRaymond Chen typedef struct usbecm_power { 46*0035018cSRaymond Chen uint8_t pm_wakeup_enabled; /* remote wakeup enabled */ 47*0035018cSRaymond Chen uint8_t pm_pwr_states; /* bit mask of power states */ 48*0035018cSRaymond Chen boolean_t pm_raise_power; /* driver is about to raise power */ 49*0035018cSRaymond Chen uint8_t pm_cur_power; /* current power level */ 50*0035018cSRaymond Chen uint_t pm_busy_cnt; /* number of set_busy requests */ 51*0035018cSRaymond Chen } usbecm_pm_t; 52*0035018cSRaymond Chen 53*0035018cSRaymond Chen struct usbecm_statistics { 54*0035018cSRaymond Chen uint32_t es_upspeed; /* Upstream bit rate, bps */ 55*0035018cSRaymond Chen uint32_t es_downspeed; /* Downstream bit rate, bps */ 56*0035018cSRaymond Chen int es_linkstate; /* link state */ 57*0035018cSRaymond Chen uint64_t es_ipackets; 58*0035018cSRaymond Chen uint64_t es_opackets; 59*0035018cSRaymond Chen uint64_t es_ibytes; 60*0035018cSRaymond Chen uint64_t es_obytes; 61*0035018cSRaymond Chen uint64_t es_ierrors; /* received frames with errors */ 62*0035018cSRaymond Chen uint64_t es_oerrors; /* transmitted frames with errors */ 63*0035018cSRaymond Chen uint64_t es_multircv; /* received multicast frames */ 64*0035018cSRaymond Chen uint64_t es_multixmt; /* transmitted multicast frames */ 65*0035018cSRaymond Chen uint64_t es_brdcstrcv; 66*0035018cSRaymond Chen uint64_t es_brdcstxmt; 67*0035018cSRaymond Chen uint64_t es_macxmt_err; 68*0035018cSRaymond Chen }; 69*0035018cSRaymond Chen 70*0035018cSRaymond Chen struct usbecm_ds_ops { 71*0035018cSRaymond Chen /* Device specific initialization and deinitialization */ 72*0035018cSRaymond Chen int (*ecm_ds_init)(usbecm_state_t *); 73*0035018cSRaymond Chen int (*ecm_ds_fini)(usbecm_state_t *); 74*0035018cSRaymond Chen 75*0035018cSRaymond Chen int (*ecm_ds_start)(usbecm_state_t *); 76*0035018cSRaymond Chen int (*ecm_ds_stop)(usbecm_state_t *); 77*0035018cSRaymond Chen int (*ecm_ds_unicst)(usbecm_state_t *); 78*0035018cSRaymond Chen int (*ecm_ds_promisc)(usbecm_state_t *); 79*0035018cSRaymond Chen int (*ecm_ds_multicst)(usbecm_state_t *); 80*0035018cSRaymond Chen mblk_t *(*ecm_ds_tx)(usbecm_state_t *, mblk_t *); 81*0035018cSRaymond Chen 82*0035018cSRaymond Chen int (*ecm_ds_intr_cb)(usbecm_state_t *, mblk_t *); 83*0035018cSRaymond Chen int (*ecm_ds_bulkin_cb)(usbecm_state_t *, mblk_t *); 84*0035018cSRaymond Chen int (*ecm_ds_bulkout_cb)(usbecm_state_t *, mblk_t *); 85*0035018cSRaymond Chen }; 86*0035018cSRaymond Chen 87*0035018cSRaymond Chen /* 88*0035018cSRaymond Chen * per bulk in/out structure 89*0035018cSRaymond Chen */ 90*0035018cSRaymond Chen struct usbecm_state { 91*0035018cSRaymond Chen kmutex_t ecm_mutex; /* structure lock */ 92*0035018cSRaymond Chen dev_info_t *ecm_dip; /* device info */ 93*0035018cSRaymond Chen usb_client_dev_data_t *ecm_dev_data; /* registration data */ 94*0035018cSRaymond Chen usb_pipe_handle_t ecm_def_ph; /* default pipe hdl */ 95*0035018cSRaymond Chen usb_log_handle_t ecm_lh; /* USBA log handle */ 96*0035018cSRaymond Chen int ecm_dev_state; /* USB device state */ 97*0035018cSRaymond Chen size_t ecm_xfer_sz; /* bulk xfer size */ 98*0035018cSRaymond Chen size_t ecm_bulkin_sz; 99*0035018cSRaymond Chen usbecm_pm_t *ecm_pm; /* PM support */ 100*0035018cSRaymond Chen mac_handle_t ecm_mh; /* mac handle */ 101*0035018cSRaymond Chen usb_serialization_t ecm_ser_acc; /* serialization object */ 102*0035018cSRaymond Chen 103*0035018cSRaymond Chen uint_t ecm_cfg_index; /* config contains ECM ifc */ 104*0035018cSRaymond Chen uint16_t ecm_ctrl_if_no; 105*0035018cSRaymond Chen uint16_t ecm_data_if_no; 106*0035018cSRaymond Chen uint16_t ecm_data_if_alt; /* non-compatible device */ 107*0035018cSRaymond Chen 108*0035018cSRaymond Chen usb_ep_data_t *ecm_intr_ep; 109*0035018cSRaymond Chen usb_ep_data_t *ecm_bulk_in_ep; 110*0035018cSRaymond Chen usb_ep_data_t *ecm_bulk_out_ep; 111*0035018cSRaymond Chen 112*0035018cSRaymond Chen boolean_t ecm_compatibility; /* if conform to spec */ 113*0035018cSRaymond Chen usb_cdc_ecm_descr_t ecm_desc; /* if conform to spec */ 114*0035018cSRaymond Chen 115*0035018cSRaymond Chen uint8_t ecm_srcaddr[6]; /* source MAC addr */ 116*0035018cSRaymond Chen uint16_t ecm_pkt_flt; /* pkt flt bitmap ECM1.2 T.8 */ 117*0035018cSRaymond Chen 118*0035018cSRaymond Chen usb_pipe_handle_t ecm_bulkout_ph; 119*0035018cSRaymond Chen int ecm_bulkout_state; 120*0035018cSRaymond Chen usb_pipe_handle_t ecm_bulkin_ph; 121*0035018cSRaymond Chen int ecm_bulkin_state; 122*0035018cSRaymond Chen usb_pipe_handle_t ecm_intr_ph; 123*0035018cSRaymond Chen int ecm_intr_state; 124*0035018cSRaymond Chen struct usbecm_statistics ecm_stat; 125*0035018cSRaymond Chen uint32_t ecm_init_flags; 126*0035018cSRaymond Chen int ecm_mac_state; 127*0035018cSRaymond Chen mblk_t *ecm_rcv_queue; /* receive queue */ 128*0035018cSRaymond Chen int ecm_tx_cnt; 129*0035018cSRaymond Chen 130*0035018cSRaymond Chen void *ecm_priv; /* device private data */ 131*0035018cSRaymond Chen struct usbecm_ds_ops *ecm_ds_ops; 132*0035018cSRaymond Chen }; 133*0035018cSRaymond Chen 134*0035018cSRaymond Chen 135*0035018cSRaymond Chen _NOTE(MUTEX_PROTECTS_DATA(usbecm_state::ecm_mutex, usbecm_state)) 136*0035018cSRaymond Chen _NOTE(MUTEX_PROTECTS_DATA(usbecm_state::ecm_mutex, usbecm_statistics)) 137*0035018cSRaymond Chen 138*0035018cSRaymond Chen _NOTE(DATA_READABLE_WITHOUT_LOCK(usbecm_state::{ 139*0035018cSRaymond Chen ecm_dip 140*0035018cSRaymond Chen ecm_dev_data 141*0035018cSRaymond Chen ecm_def_ph 142*0035018cSRaymond Chen ecm_lh 143*0035018cSRaymond Chen ecm_dev_state 144*0035018cSRaymond Chen ecm_xfer_sz 145*0035018cSRaymond Chen ecm_compatibility 146*0035018cSRaymond Chen ecm_pm 147*0035018cSRaymond Chen ecm_mh 148*0035018cSRaymond Chen ecm_bulkin_ph 149*0035018cSRaymond Chen ecm_bulkout_ph 150*0035018cSRaymond Chen ecm_intr_ph 151*0035018cSRaymond Chen ecm_ser_acc 152*0035018cSRaymond Chen ecm_ctrl_if_no 153*0035018cSRaymond Chen ecm_data_if_no 154*0035018cSRaymond Chen ecm_data_if_alt 155*0035018cSRaymond Chen ecm_desc 156*0035018cSRaymond Chen ecm_bulk_in_ep 157*0035018cSRaymond Chen ecm_intr_ep 158*0035018cSRaymond Chen ecm_bulk_out_ep 159*0035018cSRaymond Chen ecm_bulkin_sz 160*0035018cSRaymond Chen ecm_priv 161*0035018cSRaymond Chen ecm_ds_ops 162*0035018cSRaymond Chen })) 163*0035018cSRaymond Chen 164*0035018cSRaymond Chen _NOTE(SCHEME_PROTECTS_DATA("unshared data", mblk_t iocblk)) 165*0035018cSRaymond Chen _NOTE(SCHEME_PROTECTS_DATA("unshared data", usb_bulk_req_t usb_intr_req_t)) 166*0035018cSRaymond Chen 167*0035018cSRaymond Chen /* pipe state */ 168*0035018cSRaymond Chen enum { 169*0035018cSRaymond Chen USBECM_PIPE_CLOSED, /* pipe is closed */ 170*0035018cSRaymond Chen USBECM_PIPE_IDLE, /* open but no requests */ 171*0035018cSRaymond Chen USBECM_PIPE_BUSY, /* servicing request */ 172*0035018cSRaymond Chen USBECM_PIPE_CLOSING /* pipe is closing */ 173*0035018cSRaymond Chen }; 174*0035018cSRaymond Chen 175*0035018cSRaymond Chen enum { 176*0035018cSRaymond Chen USBECM_MAC_STOPPED = 0, 177*0035018cSRaymond Chen USBECM_MAC_STARTED, 178*0035018cSRaymond Chen }; 179*0035018cSRaymond Chen 180*0035018cSRaymond Chen /* various tunables */ 181*0035018cSRaymond Chen enum { 182*0035018cSRaymond Chen USBECM_BULKOUT_TIMEOUT = 15, /* bulkout timeout */ 183*0035018cSRaymond Chen USBECM_BULKIN_TIMEOUT = 0 /* bulkin timeout */ 184*0035018cSRaymond Chen }; 185*0035018cSRaymond Chen 186*0035018cSRaymond Chen /* hardware definitions */ 187*0035018cSRaymond Chen enum { 188*0035018cSRaymond Chen USBSACM_REQ_OUT = USB_DEV_REQ_TYPE_CLASS| USB_DEV_REQ_HOST_TO_DEV, 189*0035018cSRaymond Chen USBSACM_REQ_IN = USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_DEV_TO_HOST, 190*0035018cSRaymond Chen USBSACM_REQ_WRITE_IF = USBSACM_REQ_OUT | USB_DEV_REQ_RCPT_IF, 191*0035018cSRaymond Chen USBSACM_REQ_READ_IF = USBSACM_REQ_IN | USB_DEV_REQ_RCPT_IF 192*0035018cSRaymond Chen }; 193*0035018cSRaymond Chen 194*0035018cSRaymond Chen #define USBECM_INIT_EVENTS (0x01 << 0) 195*0035018cSRaymond Chen #define USBECM_INIT_SER (0x01 << 1) 196*0035018cSRaymond Chen #define USBECM_INIT_MAC (0x01 << 2) 197*0035018cSRaymond Chen 198*0035018cSRaymond Chen /* Bit offset for ECM statistics capabilities, CDC ECM Rev 1.2, Table 4 */ 199*0035018cSRaymond Chen #define ECM_XMIT_OK 0 200*0035018cSRaymond Chen #define ECM_RCV_OK 1 201*0035018cSRaymond Chen #define ECM_XMIT_ERROR 2 202*0035018cSRaymond Chen #define ECM_RCV_ERROR 3 203*0035018cSRaymond Chen #define ECM_RCV_NO_BUFFER 4 204*0035018cSRaymond Chen #define ECM_DIRECTED_BYTES_XMIT 5 205*0035018cSRaymond Chen #define ECM_DIRECTED_FRAMES_XMIT 6 206*0035018cSRaymond Chen #define ECM_MULTICAST_BYTES_XMIT 7 207*0035018cSRaymond Chen #define ECM_MULTICAST_FRAMES_XMIT 8 208*0035018cSRaymond Chen #define ECM_BROADCAST_BYTES_XMIT 9 209*0035018cSRaymond Chen #define ECM_BROADCAST_FRAMES_XMIT 10 210*0035018cSRaymond Chen #define ECM_DIRECTED_BYTES_RCV 11 211*0035018cSRaymond Chen #define ECM_DIRECTED_FRAMES_RCV 12 212*0035018cSRaymond Chen #define ECM_MULTICAST_BYTES_RCV 13 213*0035018cSRaymond Chen #define ECM_MULTICAST_FRAMES_RCV 14 214*0035018cSRaymond Chen #define ECM_BROADCAST_BYTES_RCV 15 215*0035018cSRaymond Chen #define ECM_BROADCAST_FRAMES_RCV 16 216*0035018cSRaymond Chen #define ECM_RCV_CRC_ERROR 17 217*0035018cSRaymond Chen #define ECM_TRANSMIT_QUEUE_LENGTH 18 218*0035018cSRaymond Chen #define ECM_RCV_ERROR_ALIGNMENT 19 219*0035018cSRaymond Chen #define ECM_XMIT_ONE_COLLISION 20 220*0035018cSRaymond Chen #define ECM_XMIT_MORE_COLLISIONS 21 221*0035018cSRaymond Chen #define ECM_XMIT_DEFERRED 22 222*0035018cSRaymond Chen #define ECM_XMIT_MAX_COLLISIONS 23 223*0035018cSRaymond Chen #define ECM_RCV_OVERRUN 24 224*0035018cSRaymond Chen #define ECM_XMIT_UNDERRUN 25 225*0035018cSRaymond Chen #define ECM_XMIT_HEARTBEAT_FAILURE 26 226*0035018cSRaymond Chen #define ECM_XMIT_TIMES_CRS_LOST 27 227*0035018cSRaymond Chen #define ECM_XMIT_LATE_COLLISIONS 28 228*0035018cSRaymond Chen 229*0035018cSRaymond Chen #define ECM_STAT_CAP_MASK(x) (1UL << (x)) /* Table 4 */ 230*0035018cSRaymond Chen #define ECM_STAT_SELECTOR(x) ((x) + 1) /* Table 9 */ 231*0035018cSRaymond Chen 232*0035018cSRaymond Chen /* ECM class-specific request codes, Table 6 */ 233*0035018cSRaymond Chen #define CDC_ECM_SET_ETH_MCAST_FLT 0x40 234*0035018cSRaymond Chen #define CDC_ECM_SET_ETH_PM_FLT 0x41 235*0035018cSRaymond Chen #define CDC_ECM_GET_ETH_PM_FLT 0x42 236*0035018cSRaymond Chen #define CDC_ECM_SET_ETH_PKT_FLT 0x43 237*0035018cSRaymond Chen #define CDC_ECM_GET_ETH_STAT 0x44 238*0035018cSRaymond Chen 239*0035018cSRaymond Chen /* ECM Ethernet Pakcet Filter Bitmap, Table 8 */ 240*0035018cSRaymond Chen #define CDC_ECM_PKT_TYPE_PROMISC (1<<0) 241*0035018cSRaymond Chen #define CDC_ECM_PKT_TYPE_ALL_MCAST (1<<1) /* all multicast */ 242*0035018cSRaymond Chen #define CDC_ECM_PKT_TYPE_DIRECTED (1<<2) 243*0035018cSRaymond Chen #define CDC_ECM_PKT_TYPE_BCAST (1<<3) /* broadcast */ 244*0035018cSRaymond Chen #define CDC_ECM_PKT_TYPE_MCAST (1<<4) /* multicast */ 245*0035018cSRaymond Chen 246*0035018cSRaymond Chen #define PRINT_MASK_ATTA 0x00000001 247*0035018cSRaymond Chen #define PRINT_MASK_CLOSE 0x00000002 248*0035018cSRaymond Chen #define PRINT_MASK_OPEN 0x00000004 249*0035018cSRaymond Chen #define PRINT_MASK_EVENTS 0x00000008 250*0035018cSRaymond Chen #define PRINT_MASK_PM 0x00000010 251*0035018cSRaymond Chen #define PRINT_MASK_CB 0x00000020 252*0035018cSRaymond Chen #define PRINT_MASK_OPS 0x00000040 253*0035018cSRaymond Chen #define PRINT_MASK_ALL 0xFFFFFFFF 254*0035018cSRaymond Chen 255*0035018cSRaymond Chen /* Turn a little endian byte array to a uint32_t */ 256*0035018cSRaymond Chen #define LE_TO_UINT32(src, des) { \ 257*0035018cSRaymond Chen uint32_t tmp; \ 258*0035018cSRaymond Chen des = src[3]; \ 259*0035018cSRaymond Chen des = des << 24; \ 260*0035018cSRaymond Chen tmp = src[2]; \ 261*0035018cSRaymond Chen des |= tmp << 16; \ 262*0035018cSRaymond Chen tmp = src[1]; \ 263*0035018cSRaymond Chen des |= tmp << 8; \ 264*0035018cSRaymond Chen des |= src[0]; \ 265*0035018cSRaymond Chen } 266*0035018cSRaymond Chen 267*0035018cSRaymond Chen #define isdigit(c) ((c) >= '0' && c <= '9') 268*0035018cSRaymond Chen #define toupper(C) (((C) >= 'a' && (C) <= 'z')? ((C) - 'a' + 'A'): (C)) 269*0035018cSRaymond Chen 270*0035018cSRaymond Chen /* #define NELEM(a) (sizeof (a) / sizeof (*(a))) */ 271*0035018cSRaymond Chen 272*0035018cSRaymond Chen 273*0035018cSRaymond Chen #ifdef __cplusplus 274*0035018cSRaymond Chen } 275*0035018cSRaymond Chen #endif 276*0035018cSRaymond Chen 277*0035018cSRaymond Chen #endif /* _SYS_USB_USBETH_H */ 278