162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * USB Networking Link Interface 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net> 662306a36Sopenharmony_ci * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef __LINUX_USB_USBNET_H 1062306a36Sopenharmony_ci#define __LINUX_USB_USBNET_H 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/mii.h> 1362306a36Sopenharmony_ci#include <linux/netdevice.h> 1462306a36Sopenharmony_ci#include <linux/skbuff.h> 1562306a36Sopenharmony_ci#include <linux/types.h> 1662306a36Sopenharmony_ci#include <linux/usb.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* interface from usbnet core to each USB networking link we handle */ 1962306a36Sopenharmony_cistruct usbnet { 2062306a36Sopenharmony_ci /* housekeeping */ 2162306a36Sopenharmony_ci struct usb_device *udev; 2262306a36Sopenharmony_ci struct usb_interface *intf; 2362306a36Sopenharmony_ci const struct driver_info *driver_info; 2462306a36Sopenharmony_ci const char *driver_name; 2562306a36Sopenharmony_ci void *driver_priv; 2662306a36Sopenharmony_ci wait_queue_head_t wait; 2762306a36Sopenharmony_ci struct mutex phy_mutex; 2862306a36Sopenharmony_ci unsigned char suspend_count; 2962306a36Sopenharmony_ci unsigned char pkt_cnt, pkt_err; 3062306a36Sopenharmony_ci unsigned short rx_qlen, tx_qlen; 3162306a36Sopenharmony_ci unsigned can_dma_sg:1; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci /* i/o info: pipes etc */ 3462306a36Sopenharmony_ci unsigned in, out; 3562306a36Sopenharmony_ci struct usb_host_endpoint *status; 3662306a36Sopenharmony_ci unsigned maxpacket; 3762306a36Sopenharmony_ci struct timer_list delay; 3862306a36Sopenharmony_ci const char *padding_pkt; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci /* protocol/interface state */ 4162306a36Sopenharmony_ci struct net_device *net; 4262306a36Sopenharmony_ci int msg_enable; 4362306a36Sopenharmony_ci unsigned long data[5]; 4462306a36Sopenharmony_ci u32 xid; 4562306a36Sopenharmony_ci u32 hard_mtu; /* count any extra framing */ 4662306a36Sopenharmony_ci size_t rx_urb_size; /* size for rx urbs */ 4762306a36Sopenharmony_ci struct mii_if_info mii; 4862306a36Sopenharmony_ci long rx_speed; /* If MII not used */ 4962306a36Sopenharmony_ci long tx_speed; /* If MII not used */ 5062306a36Sopenharmony_ci# define SPEED_UNSET -1 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci /* various kinds of pending driver work */ 5362306a36Sopenharmony_ci struct sk_buff_head rxq; 5462306a36Sopenharmony_ci struct sk_buff_head txq; 5562306a36Sopenharmony_ci struct sk_buff_head done; 5662306a36Sopenharmony_ci struct sk_buff_head rxq_pause; 5762306a36Sopenharmony_ci struct urb *interrupt; 5862306a36Sopenharmony_ci unsigned interrupt_count; 5962306a36Sopenharmony_ci struct mutex interrupt_mutex; 6062306a36Sopenharmony_ci struct usb_anchor deferred; 6162306a36Sopenharmony_ci struct tasklet_struct bh; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci struct work_struct kevent; 6462306a36Sopenharmony_ci unsigned long flags; 6562306a36Sopenharmony_ci# define EVENT_TX_HALT 0 6662306a36Sopenharmony_ci# define EVENT_RX_HALT 1 6762306a36Sopenharmony_ci# define EVENT_RX_MEMORY 2 6862306a36Sopenharmony_ci# define EVENT_STS_SPLIT 3 6962306a36Sopenharmony_ci# define EVENT_LINK_RESET 4 7062306a36Sopenharmony_ci# define EVENT_RX_PAUSED 5 7162306a36Sopenharmony_ci# define EVENT_DEV_ASLEEP 6 7262306a36Sopenharmony_ci# define EVENT_DEV_OPEN 7 7362306a36Sopenharmony_ci# define EVENT_DEVICE_REPORT_IDLE 8 7462306a36Sopenharmony_ci# define EVENT_NO_RUNTIME_PM 9 7562306a36Sopenharmony_ci# define EVENT_RX_KILL 10 7662306a36Sopenharmony_ci# define EVENT_LINK_CHANGE 11 7762306a36Sopenharmony_ci# define EVENT_SET_RX_MODE 12 7862306a36Sopenharmony_ci# define EVENT_NO_IP_ALIGN 13 7962306a36Sopenharmony_ci}; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistatic inline struct usb_driver *driver_of(struct usb_interface *intf) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci return to_usb_driver(intf->dev.driver); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* interface from the device/framing level "minidriver" to core */ 8762306a36Sopenharmony_cistruct driver_info { 8862306a36Sopenharmony_ci char *description; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci int flags; 9162306a36Sopenharmony_ci/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */ 9262306a36Sopenharmony_ci#define FLAG_FRAMING_NC 0x0001 /* guard against device dropouts */ 9362306a36Sopenharmony_ci#define FLAG_FRAMING_GL 0x0002 /* genelink batches packets */ 9462306a36Sopenharmony_ci#define FLAG_FRAMING_Z 0x0004 /* zaurus adds a trailer */ 9562306a36Sopenharmony_ci#define FLAG_FRAMING_RN 0x0008 /* RNDIS batches, plus huge header */ 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */ 9862306a36Sopenharmony_ci#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */ 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ 10162306a36Sopenharmony_ci#define FLAG_WLAN 0x0080 /* use "wlan%d" names */ 10262306a36Sopenharmony_ci#define FLAG_AVOID_UNLINK_URBS 0x0100 /* don't unlink urbs at usbnet_stop() */ 10362306a36Sopenharmony_ci#define FLAG_SEND_ZLP 0x0200 /* hw requires ZLPs are sent */ 10462306a36Sopenharmony_ci#define FLAG_WWAN 0x0400 /* use "wwan%d" names */ 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci#define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */ 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci#define FLAG_POINTTOPOINT 0x1000 /* possibly use "usb%d" names */ 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/* 11162306a36Sopenharmony_ci * Indicates to usbnet, that USB driver accumulates multiple IP packets. 11262306a36Sopenharmony_ci * Affects statistic (counters) and short packet handling. 11362306a36Sopenharmony_ci */ 11462306a36Sopenharmony_ci#define FLAG_MULTI_PACKET 0x2000 11562306a36Sopenharmony_ci#define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */ 11662306a36Sopenharmony_ci#define FLAG_NOARP 0x8000 /* device can't do ARP */ 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci /* init device ... can sleep, or cause probe() failure */ 11962306a36Sopenharmony_ci int (*bind)(struct usbnet *, struct usb_interface *); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci /* cleanup device ... can sleep, but can't fail */ 12262306a36Sopenharmony_ci void (*unbind)(struct usbnet *, struct usb_interface *); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci /* reset device ... can sleep */ 12562306a36Sopenharmony_ci int (*reset)(struct usbnet *); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci /* stop device ... can sleep */ 12862306a36Sopenharmony_ci int (*stop)(struct usbnet *); 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci /* see if peer is connected ... can sleep */ 13162306a36Sopenharmony_ci int (*check_connect)(struct usbnet *); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci /* (dis)activate runtime power management */ 13462306a36Sopenharmony_ci int (*manage_power)(struct usbnet *, int); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci /* for status polling */ 13762306a36Sopenharmony_ci void (*status)(struct usbnet *, struct urb *); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci /* link reset handling, called from defer_kevent */ 14062306a36Sopenharmony_ci int (*link_reset)(struct usbnet *); 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci /* fixup rx packet (strip framing) */ 14362306a36Sopenharmony_ci int (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci /* fixup tx packet (add framing) */ 14662306a36Sopenharmony_ci struct sk_buff *(*tx_fixup)(struct usbnet *dev, 14762306a36Sopenharmony_ci struct sk_buff *skb, gfp_t flags); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci /* recover from timeout */ 15062306a36Sopenharmony_ci void (*recover)(struct usbnet *dev); 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci /* early initialization code, can sleep. This is for minidrivers 15362306a36Sopenharmony_ci * having 'subminidrivers' that need to do extra initialization 15462306a36Sopenharmony_ci * right after minidriver have initialized hardware. */ 15562306a36Sopenharmony_ci int (*early_init)(struct usbnet *dev); 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci /* called by minidriver when receiving indication */ 15862306a36Sopenharmony_ci void (*indication)(struct usbnet *dev, void *ind, int indlen); 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci /* rx mode change (device changes address list filtering) */ 16162306a36Sopenharmony_ci void (*set_rx_mode)(struct usbnet *dev); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci /* for new devices, use the descriptor-reading code instead */ 16462306a36Sopenharmony_ci int in; /* rx endpoint */ 16562306a36Sopenharmony_ci int out; /* tx endpoint */ 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci unsigned long data; /* Misc driver specific data */ 16862306a36Sopenharmony_ci}; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci/* Minidrivers are just drivers using the "usbnet" core as a powerful 17162306a36Sopenharmony_ci * network-specific subroutine library ... that happens to do pretty 17262306a36Sopenharmony_ci * much everything except custom framing and chip-specific stuff. 17362306a36Sopenharmony_ci */ 17462306a36Sopenharmony_ciextern int usbnet_probe(struct usb_interface *, const struct usb_device_id *); 17562306a36Sopenharmony_ciextern int usbnet_suspend(struct usb_interface *, pm_message_t); 17662306a36Sopenharmony_ciextern int usbnet_resume(struct usb_interface *); 17762306a36Sopenharmony_ciextern void usbnet_disconnect(struct usb_interface *); 17862306a36Sopenharmony_ciextern void usbnet_device_suggests_idle(struct usbnet *dev); 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ciextern int usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype, 18162306a36Sopenharmony_ci u16 value, u16 index, void *data, u16 size); 18262306a36Sopenharmony_ciextern int usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype, 18362306a36Sopenharmony_ci u16 value, u16 index, const void *data, u16 size); 18462306a36Sopenharmony_ciextern int usbnet_read_cmd_nopm(struct usbnet *dev, u8 cmd, u8 reqtype, 18562306a36Sopenharmony_ci u16 value, u16 index, void *data, u16 size); 18662306a36Sopenharmony_ciextern int usbnet_write_cmd_nopm(struct usbnet *dev, u8 cmd, u8 reqtype, 18762306a36Sopenharmony_ci u16 value, u16 index, const void *data, u16 size); 18862306a36Sopenharmony_ciextern int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype, 18962306a36Sopenharmony_ci u16 value, u16 index, const void *data, u16 size); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci/* Drivers that reuse some of the standard USB CDC infrastructure 19262306a36Sopenharmony_ci * (notably, using multiple interfaces according to the CDC 19362306a36Sopenharmony_ci * union descriptor) get some helper code. 19462306a36Sopenharmony_ci */ 19562306a36Sopenharmony_cistruct cdc_state { 19662306a36Sopenharmony_ci struct usb_cdc_header_desc *header; 19762306a36Sopenharmony_ci struct usb_cdc_union_desc *u; 19862306a36Sopenharmony_ci struct usb_cdc_ether_desc *ether; 19962306a36Sopenharmony_ci struct usb_interface *control; 20062306a36Sopenharmony_ci struct usb_interface *data; 20162306a36Sopenharmony_ci}; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ciextern void usbnet_cdc_update_filter(struct usbnet *dev); 20462306a36Sopenharmony_ciextern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *); 20562306a36Sopenharmony_ciextern int usbnet_ether_cdc_bind(struct usbnet *dev, struct usb_interface *intf); 20662306a36Sopenharmony_ciextern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *); 20762306a36Sopenharmony_ciextern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *); 20862306a36Sopenharmony_ciextern void usbnet_cdc_status(struct usbnet *, struct urb *); 20962306a36Sopenharmony_ciextern int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb); 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */ 21262306a36Sopenharmony_ci#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ 21362306a36Sopenharmony_ci |USB_CDC_PACKET_TYPE_ALL_MULTICAST \ 21462306a36Sopenharmony_ci |USB_CDC_PACKET_TYPE_PROMISCUOUS \ 21562306a36Sopenharmony_ci |USB_CDC_PACKET_TYPE_DIRECTED) 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci/* we record the state for each of our queued skbs */ 21962306a36Sopenharmony_cienum skb_state { 22062306a36Sopenharmony_ci illegal = 0, 22162306a36Sopenharmony_ci tx_start, tx_done, 22262306a36Sopenharmony_ci rx_start, rx_done, rx_cleanup, 22362306a36Sopenharmony_ci unlink_start 22462306a36Sopenharmony_ci}; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_cistruct skb_data { /* skb->cb is one of these */ 22762306a36Sopenharmony_ci struct urb *urb; 22862306a36Sopenharmony_ci struct usbnet *dev; 22962306a36Sopenharmony_ci enum skb_state state; 23062306a36Sopenharmony_ci long length; 23162306a36Sopenharmony_ci unsigned long packets; 23262306a36Sopenharmony_ci}; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci/* Drivers that set FLAG_MULTI_PACKET must call this in their 23562306a36Sopenharmony_ci * tx_fixup method before returning an skb. 23662306a36Sopenharmony_ci */ 23762306a36Sopenharmony_cistatic inline void 23862306a36Sopenharmony_ciusbnet_set_skb_tx_stats(struct sk_buff *skb, 23962306a36Sopenharmony_ci unsigned long packets, long bytes_delta) 24062306a36Sopenharmony_ci{ 24162306a36Sopenharmony_ci struct skb_data *entry = (struct skb_data *) skb->cb; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci entry->packets = packets; 24462306a36Sopenharmony_ci entry->length = bytes_delta; 24562306a36Sopenharmony_ci} 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ciextern int usbnet_open(struct net_device *net); 24862306a36Sopenharmony_ciextern int usbnet_stop(struct net_device *net); 24962306a36Sopenharmony_ciextern netdev_tx_t usbnet_start_xmit(struct sk_buff *skb, 25062306a36Sopenharmony_ci struct net_device *net); 25162306a36Sopenharmony_ciextern void usbnet_tx_timeout(struct net_device *net, unsigned int txqueue); 25262306a36Sopenharmony_ciextern int usbnet_change_mtu(struct net_device *net, int new_mtu); 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ciextern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *); 25562306a36Sopenharmony_ciextern int usbnet_get_ethernet_addr(struct usbnet *, int); 25662306a36Sopenharmony_ciextern void usbnet_defer_kevent(struct usbnet *, int); 25762306a36Sopenharmony_ciextern void usbnet_skb_return(struct usbnet *, struct sk_buff *); 25862306a36Sopenharmony_ciextern void usbnet_unlink_rx_urbs(struct usbnet *); 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ciextern void usbnet_pause_rx(struct usbnet *); 26162306a36Sopenharmony_ciextern void usbnet_resume_rx(struct usbnet *); 26262306a36Sopenharmony_ciextern void usbnet_purge_paused_rxq(struct usbnet *); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ciextern int usbnet_get_link_ksettings_mii(struct net_device *net, 26562306a36Sopenharmony_ci struct ethtool_link_ksettings *cmd); 26662306a36Sopenharmony_ciextern int usbnet_set_link_ksettings_mii(struct net_device *net, 26762306a36Sopenharmony_ci const struct ethtool_link_ksettings *cmd); 26862306a36Sopenharmony_ciextern int usbnet_get_link_ksettings_internal(struct net_device *net, 26962306a36Sopenharmony_ci struct ethtool_link_ksettings *cmd); 27062306a36Sopenharmony_ciextern u32 usbnet_get_link(struct net_device *net); 27162306a36Sopenharmony_ciextern u32 usbnet_get_msglevel(struct net_device *); 27262306a36Sopenharmony_ciextern void usbnet_set_msglevel(struct net_device *, u32); 27362306a36Sopenharmony_ciextern void usbnet_set_rx_mode(struct net_device *net); 27462306a36Sopenharmony_ciextern void usbnet_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); 27562306a36Sopenharmony_ciextern int usbnet_nway_reset(struct net_device *net); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ciextern int usbnet_manage_power(struct usbnet *, int); 27862306a36Sopenharmony_ciextern void usbnet_link_change(struct usbnet *, bool, bool); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ciextern int usbnet_status_start(struct usbnet *dev, gfp_t mem_flags); 28162306a36Sopenharmony_ciextern void usbnet_status_stop(struct usbnet *dev); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ciextern void usbnet_update_max_qlen(struct usbnet *dev); 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci#endif /* __LINUX_USB_USBNET_H */ 286