diff --git a/.module-common.o b/.module-common.o index 50ee75b..b004a9a 100644 Binary files a/.module-common.o and b/.module-common.o differ diff --git a/src/ch397_driver.c b/src/ch397_driver.c index b4743bd..fd1973a 100644 --- a/src/ch397_driver.c +++ b/src/ch397_driver.c @@ -99,7 +99,6 @@ static void ch397_read_callback(struct urb *urb) struct ch397_device *dev = urb->context; struct net_device *netdev = dev->netdev; struct sk_buff *skb; - struct ethhdr *eth; int status = urb->status; switch (status) { @@ -230,11 +229,53 @@ static int ch397_net_stop(struct net_device *netdev) return 0; } +static void ch397_write_callback(struct urb *urb) +{ + struct sk_buff *skb = urb->context; + struct net_device *netdev = skb->dev; + + switch (urb->status) { + case 0: + netdev->stats.tx_packets++; + break; + default: + netdev->stats.tx_errors++; + break; + } + + dev_kfree_skb_any(skb); + usb_free_urb(urb); + netif_wake_queue(netdev); +} + static netdev_tx_t ch397_start_xmit(struct sk_buff *skb, struct net_device *netdev) { - // Pour l'instant, on drop juste les packets TX - dev_kfree_skb(skb); + struct ch397_device *dev = netdev_priv(netdev); + struct urb *urb; + int retval; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + goto drop; + + usb_fill_bulk_urb(urb, dev->udev, + usb_sndbulkpipe(dev->udev, + dev->bulk_out_endpointAddr), + skb->data, skb->len, ch397_write_callback, skb); + + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) { + usb_free_urb(urb); + goto drop; + } + + netdev->stats.tx_bytes += skb->len; + netif_stop_queue(netdev); + return NETDEV_TX_OK; + +drop: + dev_kfree_skb_any(skb); netdev->stats.tx_dropped++; return NETDEV_TX_OK; }