/* * Setup the RX context * * Each URB is provided with a transfer_buffer that is the data field * of a new socket buffer. */ int i1480u_rx_setup(struct i1480u *i1480u) { int result, cnt; struct device *dev = &i1480u->usb_iface->dev; struct net_device *net_dev = i1480u->net_dev; struct usb_endpoint_descriptor *epd; struct sk_buff *skb; /* Alloc RX stuff */ i1480u->rx_skb = NULL; /* not in process of receiving packet */ result = -ENOMEM; epd = &i1480u->usb_iface->cur_altsetting->endpoint[1].desc; for (cnt = 0; cnt < i1480u_RX_BUFS; cnt++) { struct i1480u_rx_buf *rx_buf = &i1480u->rx_buf[cnt]; rx_buf->i1480u = i1480u; skb = dev_alloc_skb(i1480u_MAX_RX_PKT_SIZE); if (!skb) { dev_err(dev, "RX: cannot allocate RX buffer %d\n", cnt); result = -ENOMEM; goto error; } skb->dev = net_dev; skb->ip_summed = CHECKSUM_NONE; skb_reserve(skb, 2); rx_buf->data = skb; rx_buf->urb = usb_alloc_urb(0, GFP_KERNEL); if (unlikely(rx_buf->urb == NULL)) { dev_err(dev, "RX: cannot allocate URB %d\n", cnt); result = -ENOMEM; goto error; } usb_fill_bulk_urb(rx_buf->urb, i1480u->usb_dev, usb_rcvbulkpipe(i1480u->usb_dev, epd->bEndpointAddress), rx_buf->data->data, i1480u_MAX_RX_PKT_SIZE - 2, i1480u_rx_cb, rx_buf); result = usb_submit_urb(rx_buf->urb, GFP_NOIO); if (unlikely(result < 0)) { dev_err(dev, "RX: cannot submit URB %d: %d\n", cnt, result); goto error; } } return 0; error: i1480u_rx_release(i1480u); return result; }
int i1480u_stop(struct net_device *net_dev) { struct i1480u *i1480u = netdev_priv(net_dev); struct wlp *wlp = &i1480u->wlp; BUG_ON(wlp->rc == NULL); wlp_wss_remove(&wlp->wss); netif_carrier_off(net_dev); #ifdef i1480u_FLOW_CONTROL usb_kill_urb(i1480u->notif_urb); #endif netif_stop_queue(net_dev); uwb_radio_stop(&wlp->pal); i1480u_rx_release(i1480u); i1480u_tx_release(i1480u); return 0; }
int i1480u_open(struct net_device *net_dev) { int result; struct i1480u *i1480u = netdev_priv(net_dev); struct wlp *wlp = &i1480u->wlp; struct uwb_rc *rc; struct device *dev = &i1480u->usb_iface->dev; rc = wlp->rc; result = i1480u_rx_setup(i1480u); if (result < 0) goto error_rx_setup; result = uwb_radio_start(&wlp->pal); if (result < 0) goto error_radio_start; netif_wake_queue(net_dev); #ifdef i1480u_FLOW_CONTROL result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL); if (result < 0) { dev_err(dev, "Can't submit notification URB: %d\n", result); goto error_notif_urb_submit; } #endif result = wlp_wss_setup(net_dev, &wlp->wss); if (result < 0) { dev_err(dev, "Can't create WSS: %d. \n", result); goto error_wss_setup; } return 0; error_wss_setup: #ifdef i1480u_FLOW_CONTROL usb_kill_urb(i1480u->notif_urb); error_notif_urb_submit: #endif uwb_radio_stop(&wlp->pal); error_radio_start: netif_stop_queue(net_dev); i1480u_rx_release(i1480u); error_rx_setup: return result; }