netdev.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. * WUSB Wire Adapter: WLP interface
  3. * Driver for the Linux Network stack.
  4. *
  5. * Copyright (C) 2005-2006 Intel Corporation
  6. * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License version
  10. * 2 as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20. * 02110-1301, USA.
  21. *
  22. *
  23. * FIXME: docs
  24. *
  25. * Implementation of the netdevice linkage (except tx and rx related stuff).
  26. *
  27. * ROADMAP:
  28. *
  29. * ENTRY POINTS (Net device):
  30. *
  31. * i1480u_open(): Called when we ifconfig up the interface;
  32. * associates to a UWB host controller, reserves
  33. * bandwidth (MAS), sets up RX USB URB and starts
  34. * the queue.
  35. *
  36. * i1480u_stop(): Called when we ifconfig down a interface;
  37. * reverses _open().
  38. *
  39. * i1480u_set_config():
  40. */
  41. #include <linux/if_arp.h>
  42. #include <linux/etherdevice.h>
  43. #include "i1480u-wlp.h"
  44. struct i1480u_cmd_set_ip_mas {
  45. struct uwb_rccb rccb;
  46. struct uwb_dev_addr addr;
  47. u8 stream;
  48. u8 owner;
  49. u8 type; /* enum uwb_drp_type */
  50. u8 baMAS[32];
  51. } __attribute__((packed));
  52. static
  53. int i1480u_set_ip_mas(
  54. struct uwb_rc *rc,
  55. const struct uwb_dev_addr *dstaddr,
  56. u8 stream, u8 owner, u8 type, unsigned long *mas)
  57. {
  58. int result;
  59. struct i1480u_cmd_set_ip_mas *cmd;
  60. struct uwb_rc_evt_confirm reply;
  61. result = -ENOMEM;
  62. cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
  63. if (cmd == NULL)
  64. goto error_kzalloc;
  65. cmd->rccb.bCommandType = 0xfd;
  66. cmd->rccb.wCommand = cpu_to_le16(0x000e);
  67. cmd->addr = *dstaddr;
  68. cmd->stream = stream;
  69. cmd->owner = owner;
  70. cmd->type = type;
  71. if (mas == NULL)
  72. memset(cmd->baMAS, 0x00, sizeof(cmd->baMAS));
  73. else
  74. memcpy(cmd->baMAS, mas, sizeof(cmd->baMAS));
  75. reply.rceb.bEventType = 0xfd;
  76. reply.rceb.wEvent = cpu_to_le16(0x000e);
  77. result = uwb_rc_cmd(rc, "SET-IP-MAS", &cmd->rccb, sizeof(*cmd),
  78. &reply.rceb, sizeof(reply));
  79. if (result < 0)
  80. goto error_cmd;
  81. if (reply.bResultCode != UWB_RC_RES_FAIL) {
  82. dev_err(&rc->uwb_dev.dev,
  83. "SET-IP-MAS: command execution failed: %d\n",
  84. reply.bResultCode);
  85. result = -EIO;
  86. }
  87. error_cmd:
  88. kfree(cmd);
  89. error_kzalloc:
  90. return result;
  91. }
  92. /*
  93. * Inform a WLP interface of a MAS reservation
  94. *
  95. * @rc is assumed refcnted.
  96. */
  97. /* FIXME: detect if remote device is WLP capable? */
  98. static int i1480u_mas_set_dev(struct uwb_dev *uwb_dev, struct uwb_rc *rc,
  99. u8 stream, u8 owner, u8 type, unsigned long *mas)
  100. {
  101. int result = 0;
  102. struct device *dev = &rc->uwb_dev.dev;
  103. result = i1480u_set_ip_mas(rc, &uwb_dev->dev_addr, stream, owner,
  104. type, mas);
  105. if (result < 0) {
  106. char rcaddrbuf[UWB_ADDR_STRSIZE], devaddrbuf[UWB_ADDR_STRSIZE];
  107. uwb_dev_addr_print(rcaddrbuf, sizeof(rcaddrbuf),
  108. &rc->uwb_dev.dev_addr);
  109. uwb_dev_addr_print(devaddrbuf, sizeof(devaddrbuf),
  110. &uwb_dev->dev_addr);
  111. dev_err(dev, "Set IP MAS (%s to %s) failed: %d\n",
  112. rcaddrbuf, devaddrbuf, result);
  113. }
  114. return result;
  115. }
  116. /**
  117. * Called by bandwidth allocator when change occurs in reservation.
  118. *
  119. * @rsv: The reservation that is being established, modified, or
  120. * terminated.
  121. *
  122. * When a reservation is established, modified, or terminated the upper layer
  123. * (WLP here) needs set/update the currently available Media Access Slots
  124. * that can be use for IP traffic.
  125. *
  126. * Our action taken during failure depends on how the reservation is being
  127. * changed:
  128. * - if reservation is being established we do nothing if we cannot set the
  129. * new MAS to be used
  130. * - if reservation is being terminated we revert back to PCA whether the
  131. * SET IP MAS command succeeds or not.
  132. */
  133. void i1480u_bw_alloc_cb(struct uwb_rsv *rsv)
  134. {
  135. int result = 0;
  136. struct i1480u *i1480u = rsv->pal_priv;
  137. struct device *dev = &i1480u->usb_iface->dev;
  138. struct uwb_dev *target_dev = rsv->target.dev;
  139. struct uwb_rc *rc = i1480u->wlp.rc;
  140. u8 stream = rsv->stream;
  141. int type = rsv->type;
  142. int is_owner = rsv->owner == &rc->uwb_dev;
  143. unsigned long *bmp = rsv->mas.bm;
  144. dev_err(dev, "WLP callback called - sending set ip mas\n");
  145. /*user cannot change options while setting configuration*/
  146. mutex_lock(&i1480u->options.mutex);
  147. switch (rsv->state) {
  148. case UWB_RSV_STATE_T_ACCEPTED:
  149. case UWB_RSV_STATE_O_ESTABLISHED:
  150. result = i1480u_mas_set_dev(target_dev, rc, stream, is_owner,
  151. type, bmp);
  152. if (result < 0) {
  153. dev_err(dev, "MAS reservation failed: %d\n", result);
  154. goto out;
  155. }
  156. if (is_owner) {
  157. wlp_tx_hdr_set_delivery_id_type(&i1480u->options.def_tx_hdr,
  158. WLP_DRP | stream);
  159. wlp_tx_hdr_set_rts_cts(&i1480u->options.def_tx_hdr, 0);
  160. }
  161. break;
  162. case UWB_RSV_STATE_NONE:
  163. /* revert back to PCA */
  164. result = i1480u_mas_set_dev(target_dev, rc, stream, is_owner,
  165. type, bmp);
  166. if (result < 0)
  167. dev_err(dev, "MAS reservation failed: %d\n", result);
  168. /* Revert to PCA even though SET IP MAS failed. */
  169. wlp_tx_hdr_set_delivery_id_type(&i1480u->options.def_tx_hdr,
  170. i1480u->options.pca_base_priority);
  171. wlp_tx_hdr_set_rts_cts(&i1480u->options.def_tx_hdr, 1);
  172. break;
  173. default:
  174. dev_err(dev, "unexpected WLP reservation state: %s (%d).\n",
  175. uwb_rsv_state_str(rsv->state), rsv->state);
  176. break;
  177. }
  178. out:
  179. mutex_unlock(&i1480u->options.mutex);
  180. return;
  181. }
  182. /**
  183. *
  184. * Called on 'ifconfig up'
  185. */
  186. int i1480u_open(struct net_device *net_dev)
  187. {
  188. int result;
  189. struct i1480u *i1480u = netdev_priv(net_dev);
  190. struct wlp *wlp = &i1480u->wlp;
  191. struct uwb_rc *rc;
  192. struct device *dev = &i1480u->usb_iface->dev;
  193. rc = wlp->rc;
  194. result = i1480u_rx_setup(i1480u); /* Alloc RX stuff */
  195. if (result < 0)
  196. goto error_rx_setup;
  197. result = uwb_radio_start(&wlp->pal);
  198. if (result < 0)
  199. goto error_radio_start;
  200. netif_wake_queue(net_dev);
  201. #ifdef i1480u_FLOW_CONTROL
  202. result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);
  203. if (result < 0) {
  204. dev_err(dev, "Can't submit notification URB: %d\n", result);
  205. goto error_notif_urb_submit;
  206. }
  207. #endif
  208. /* Interface is up with an address, now we can create WSS */
  209. result = wlp_wss_setup(net_dev, &wlp->wss);
  210. if (result < 0) {
  211. dev_err(dev, "Can't create WSS: %d. \n", result);
  212. goto error_wss_setup;
  213. }
  214. return 0;
  215. error_wss_setup:
  216. #ifdef i1480u_FLOW_CONTROL
  217. usb_kill_urb(i1480u->notif_urb);
  218. error_notif_urb_submit:
  219. #endif
  220. uwb_radio_stop(&wlp->pal);
  221. error_radio_start:
  222. netif_stop_queue(net_dev);
  223. i1480u_rx_release(i1480u);
  224. error_rx_setup:
  225. return result;
  226. }
  227. /**
  228. * Called on 'ifconfig down'
  229. */
  230. int i1480u_stop(struct net_device *net_dev)
  231. {
  232. struct i1480u *i1480u = netdev_priv(net_dev);
  233. struct wlp *wlp = &i1480u->wlp;
  234. BUG_ON(wlp->rc == NULL);
  235. wlp_wss_remove(&wlp->wss);
  236. netif_carrier_off(net_dev);
  237. #ifdef i1480u_FLOW_CONTROL
  238. usb_kill_urb(i1480u->notif_urb);
  239. #endif
  240. netif_stop_queue(net_dev);
  241. uwb_radio_stop(&wlp->pal);
  242. i1480u_rx_release(i1480u);
  243. i1480u_tx_release(i1480u);
  244. return 0;
  245. }
  246. /**
  247. *
  248. * Change the interface config--we probably don't have to do anything.
  249. */
  250. int i1480u_set_config(struct net_device *net_dev, struct ifmap *map)
  251. {
  252. int result;
  253. struct i1480u *i1480u = netdev_priv(net_dev);
  254. BUG_ON(i1480u->wlp.rc == NULL);
  255. result = 0;
  256. return result;
  257. }
  258. /**
  259. * Change the MTU of the interface
  260. */
  261. int i1480u_change_mtu(struct net_device *net_dev, int mtu)
  262. {
  263. static union {
  264. struct wlp_tx_hdr tx;
  265. struct wlp_rx_hdr rx;
  266. } i1480u_all_hdrs;
  267. if (mtu < ETH_HLEN) /* We encap eth frames */
  268. return -ERANGE;
  269. if (mtu > 4000 - sizeof(i1480u_all_hdrs))
  270. return -ERANGE;
  271. net_dev->mtu = mtu;
  272. return 0;
  273. }
  274. /**
  275. * Stop the network queue
  276. *
  277. * Enable WLP substack to stop network queue. We also set the flow control
  278. * threshold at this time to prevent the flow control from restarting the
  279. * queue.
  280. *
  281. * we are loosing the current threshold value here ... FIXME?
  282. */
  283. void i1480u_stop_queue(struct wlp *wlp)
  284. {
  285. struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
  286. struct net_device *net_dev = i1480u->net_dev;
  287. i1480u->tx_inflight.threshold = 0;
  288. netif_stop_queue(net_dev);
  289. }
  290. /**
  291. * Start the network queue
  292. *
  293. * Enable WLP substack to start network queue. Also re-enable the flow
  294. * control to manage the queue again.
  295. *
  296. * We re-enable the flow control by storing the default threshold in the
  297. * flow control threshold. This means that if the user modified the
  298. * threshold before the queue was stopped and restarted that information
  299. * will be lost. FIXME?
  300. */
  301. void i1480u_start_queue(struct wlp *wlp)
  302. {
  303. struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
  304. struct net_device *net_dev = i1480u->net_dev;
  305. i1480u->tx_inflight.threshold = i1480u_TX_INFLIGHT_THRESHOLD;
  306. netif_start_queue(net_dev);
  307. }