/* * 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" #include #ifndef MAC_VERSION #include #endif #include /* * 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; mac_handle_t mh; 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 *); #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) 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__ */