i1480u-wlp.h 7.9 KB

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