1 2 3#ifndef __i1480u_wlp_h__ 4#define __i1480u_wlp_h__ 5 6#include <linux/usb.h> 7#include <linux/netdevice.h> 8#include <linux/uwb.h> /* struct uwb_rc, struct uwb_notifs_handler */ 9#include <linux/wlp.h> 10#include "../i1480-wlp.h" 11 12#undef i1480u_FLOW_CONTROL /* Enable flow control code */ 13 14/** 15 * Basic flow control 16 */ 17enum { 18 i1480u_TX_INFLIGHT_MAX = 1000, 19 i1480u_TX_INFLIGHT_THRESHOLD = 100, 20}; 21 22/** Maximum size of a transaction that we can tx/rx */ 23enum { 24 /* Maximum packet size computed as follows: max UNTD header (8) + 25 * i1480 RX header (8) + max Ethernet header and payload (4096) + 26 * Padding added by skb_reserve (2) to make post Ethernet payload 27 * start on 16 byte boundary*/ 28 i1480u_MAX_RX_PKT_SIZE = 4114, 29 i1480u_MAX_FRG_SIZE = 512, 30 i1480u_RX_BUFS = 9, 31}; 32 33 34/** 35 * UNTD packet type 36 * 37 * We need to fragment any payload whose UNTD packet is going to be 38 * bigger than i1480u_MAX_FRG_SIZE. 39 */ 40enum i1480u_pkt_type { 41 i1480u_PKT_FRAG_1ST = 0x1, 42 i1480u_PKT_FRAG_NXT = 0x0, 43 i1480u_PKT_FRAG_LST = 0x2, 44 i1480u_PKT_FRAG_CMP = 0x3 45}; 46enum { 47 i1480u_PKT_NONE = 0x4, 48}; 49 50/** USB Network Transfer Descriptor - common */ 51struct untd_hdr { 52 u8 type; 53 __le16 len; 54} __attribute__((packed)); 55 56static inline enum i1480u_pkt_type untd_hdr_type(const struct untd_hdr *hdr) 57{ 58 return hdr->type & 0x03; 59} 60 61static inline int untd_hdr_rx_tx(const struct untd_hdr *hdr) 62{ 63 return (hdr->type >> 2) & 0x01; 64} 65 66static inline void untd_hdr_set_type(struct untd_hdr *hdr, enum i1480u_pkt_type type) 67{ 68 hdr->type = (hdr->type & ~0x03) | type; 69} 70 71static inline void untd_hdr_set_rx_tx(struct untd_hdr *hdr, int rx_tx) 72{ 73 hdr->type = (hdr->type & ~0x04) | (rx_tx << 2); 74} 75 76 77/** 78 * USB Network Transfer Descriptor - Complete Packet 79 * 80 * This is for a packet that is smaller (header + payload) than 81 * i1480u_MAX_FRG_SIZE. 82 * 83 * @hdr.total_len is the size of the payload; the payload doesn't 84 * count this header nor the padding, but includes the size of i1480 85 * header. 86 */ 87struct untd_hdr_cmp { 88 struct untd_hdr hdr; 89 u8 padding; 90} __attribute__((packed)); 91 92 93/** 94 * USB Network Transfer Descriptor - First fragment 95 * 96 * @hdr.len is the size of the *whole packet* (excluding UNTD 97 * headers); @fragment_len is the size of the payload (excluding UNTD 98 * headers, but including i1480 headers). 99 */ 100struct untd_hdr_1st { 101 struct untd_hdr hdr; 102 __le16 fragment_len; 103 u8 padding[3]; 104} __attribute__((packed)); 105 106 107/** 108 * USB Network Transfer Descriptor - Next / Last [Rest] 109 * 110 * @hdr.len is the size of the payload, not including headrs. 111 */ 112struct untd_hdr_rst { 113 struct untd_hdr hdr; 114 u8 padding; 115} __attribute__((packed)); 116 117 118/** 119 * Transmission context 120 * 121 * Wraps all the stuff needed to track a pending/active tx 122 * operation. 123 */ 124struct i1480u_tx { 125 struct list_head list_node; 126 struct i1480u *i1480u; 127 struct urb *urb; 128 129 struct sk_buff *skb; 130 struct wlp_tx_hdr *wlp_tx_hdr; 131 132 void *buf; /* if NULL, no new buf was used */ 133 size_t buf_size; 134}; 135 136/** 137 * Basic flow control 138 * 139 * We maintain a basic flow control counter. "count" how many TX URBs are 140 * outstanding. Only allow "max" 141 * TX URBs to be outstanding. If this value is reached the queue will be 142 * stopped. The queue will be restarted when there are 143 * "threshold" URBs outstanding. 144 * Maintain a counter of how many time the TX queue needed to be restarted 145 * due to the "max" being exceeded and the "threshold" reached again. The 146 * timestamp "restart_ts" is to keep track from when the counter was last 147 * queried (see sysfs handling of file wlp_tx_inflight). 148 */ 149struct i1480u_tx_inflight { 150 atomic_t count; 151 unsigned long max; 152 unsigned long threshold; 153 unsigned long restart_ts; 154 atomic_t restart_count; 155}; 156 157/** 158 * Instance of a i1480u WLP interface 159 * 160 * Keeps references to the USB device that wraps it, as well as it's 161 * interface and associated UWB host controller. As well, it also 162 * keeps a link to the netdevice for integration into the networking 163 * stack. 164 * We maintian separate error history for the tx and rx endpoints because 165 * the implementation does not rely on locking - having one shared 166 * structure between endpoints may cause problems. Adding locking to the 167 * implementation will have higher cost than adding a separate structure. 168 */ 169struct i1480u { 170 struct usb_device *usb_dev; 171 struct usb_interface *usb_iface; 172 struct net_device *net_dev; 173 174 spinlock_t lock; 175 176 /* RX context handling */ 177 struct sk_buff *rx_skb; 178 struct uwb_dev_addr rx_srcaddr; 179 size_t rx_untd_pkt_size; 180 struct i1480u_rx_buf { 181 struct i1480u *i1480u; /* back pointer */ 182 struct urb *urb; 183 struct sk_buff *data; /* i1480u_MAX_RX_PKT_SIZE each */ 184 } rx_buf[i1480u_RX_BUFS]; /* N bufs */ 185 186 spinlock_t tx_list_lock; /* TX context */ 187 struct list_head tx_list; 188 u8 tx_stream; 189 190 struct stats lqe_stats, rssi_stats; /* radio statistics */ 191 192 /* Options we can set from sysfs */ 193 struct wlp_options options; 194 struct uwb_notifs_handler uwb_notifs_handler; 195 struct edc tx_errors; 196 struct edc rx_errors; 197 struct wlp wlp; 198#ifdef i1480u_FLOW_CONTROL 199 struct urb *notif_urb; 200 struct edc notif_edc; /* error density counter */ 201 u8 notif_buffer[1]; 202#endif 203 struct i1480u_tx_inflight tx_inflight; 204}; 205 206/* Internal interfaces */ 207extern void i1480u_rx_cb(struct urb *urb); 208extern int i1480u_rx_setup(struct i1480u *); 209extern void i1480u_rx_release(struct i1480u *); 210extern void i1480u_tx_release(struct i1480u *); 211extern int i1480u_xmit_frame(struct wlp *, struct sk_buff *, 212 struct uwb_dev_addr *); 213extern void i1480u_stop_queue(struct wlp *); 214extern void i1480u_start_queue(struct wlp *); 215extern int i1480u_sysfs_setup(struct i1480u *); 216extern void i1480u_sysfs_release(struct i1480u *); 217 218/* netdev interface */ 219extern int i1480u_open(struct net_device *); 220extern int i1480u_stop(struct net_device *); 221extern netdev_tx_t i1480u_hard_start_xmit(struct sk_buff *, 222 struct net_device *); 223extern void i1480u_tx_timeout(struct net_device *); 224extern int i1480u_set_config(struct net_device *, struct ifmap *); 225extern int i1480u_change_mtu(struct net_device *, int); 226extern void i1480u_uwb_notifs_cb(void *, struct uwb_dev *, enum uwb_notifs); 227 228/* bandwidth allocation callback */ 229extern void i1480u_bw_alloc_cb(struct uwb_rsv *); 230 231/* Sys FS */ 232extern struct attribute_group i1480u_wlp_attr_group; 233 234#endif /* #ifndef __i1480u_wlp_h__ */ 235