Commit f7462f7b authored by Petko Manolov's avatar Petko Manolov Committed by Greg Kroah-Hartman

USB pegasus and rtl8150

Rx tasklet cleanups for both pegasus and rtl8150
parent 4f1aadaa
...@@ -469,20 +469,11 @@ static inline int reset_mac(pegasus_t * pegasus) ...@@ -469,20 +469,11 @@ static inline int reset_mac(pegasus_t * pegasus)
static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
{ {
__u16 linkpart, bmsr; __u16 linkpart;
__u8 data[4]; __u8 data[4];
pegasus_t *pegasus = dev->priv; pegasus_t *pegasus = dev->priv;
read_mii_word(pegasus, pegasus->phy, MII_BMSR, &bmsr); read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart);
read_mii_word(pegasus, pegasus->phy, MII_BMSR, &bmsr);
if (!(bmsr & BMSR_LSTATUS) && !loopback)
warn("%s: link NOT established (%04x) - check the cable.",
dev->name, bmsr);
if (read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart))
return 2;
if (!(linkpart & 1))
warn("link partner stat %x", linkpart);
data[0] = 0xc9; data[0] = 0xc9;
data[1] = 0; data[1] = 0;
if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL)) if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL))
...@@ -529,6 +520,8 @@ static void read_bulk_callback(struct urb *urb) ...@@ -529,6 +520,8 @@ static void read_bulk_callback(struct urb *urb)
dbg("reset MAC"); dbg("reset MAC");
pegasus->flags &= ~PEGASUS_RX_BUSY; pegasus->flags &= ~PEGASUS_RX_BUSY;
break; break;
case -ENOENT:
return;
default: default:
dbg("%s: RX status %d", net->name, urb->status); dbg("%s: RX status %d", net->name, urb->status);
goto goon; goto goon;
...@@ -551,10 +544,8 @@ static void read_bulk_callback(struct urb *urb) ...@@ -551,10 +544,8 @@ static void read_bulk_callback(struct urb *urb)
} }
pkt_len = (rx_status & 0xfff) - 8; pkt_len = (rx_status & 0xfff) - 8;
tasklet_schedule(&pegasus->rx_tl);
if (!pegasus->rx_skb) if (!pegasus->rx_skb)
return; goto tl_sched;
skb_put(pegasus->rx_skb, pkt_len); skb_put(pegasus->rx_skb, pkt_len);
pegasus->rx_skb->protocol = eth_type_trans(pegasus->rx_skb, net); pegasus->rx_skb->protocol = eth_type_trans(pegasus->rx_skb, net);
...@@ -562,7 +553,7 @@ static void read_bulk_callback(struct urb *urb) ...@@ -562,7 +553,7 @@ static void read_bulk_callback(struct urb *urb)
if (!(skb = dev_alloc_skb(PEGASUS_MTU + 2))) { if (!(skb = dev_alloc_skb(PEGASUS_MTU + 2))) {
pegasus->rx_skb = NULL; pegasus->rx_skb = NULL;
return; goto tl_sched;
} }
skb->dev = net; skb->dev = net;
...@@ -575,10 +566,17 @@ static void read_bulk_callback(struct urb *urb) ...@@ -575,10 +566,17 @@ static void read_bulk_callback(struct urb *urb)
usb_rcvbulkpipe(pegasus->usb, 1), usb_rcvbulkpipe(pegasus->usb, 1),
pegasus->rx_skb->data, PEGASUS_MTU + 8, pegasus->rx_skb->data, PEGASUS_MTU + 8,
read_bulk_callback, pegasus); read_bulk_callback, pegasus);
if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) {
pegasus->flags |= PEGASUS_RX_URB_FAIL; pegasus->flags |= PEGASUS_RX_URB_FAIL;
else goto tl_sched;
} else {
pegasus->flags &= ~PEGASUS_RX_URB_FAIL; pegasus->flags &= ~PEGASUS_RX_URB_FAIL;
}
return;
tl_sched:
tasklet_schedule(&pegasus->rx_tl);
} }
static void rx_fixup(unsigned long data) static void rx_fixup(unsigned long data)
...@@ -587,11 +585,10 @@ static void rx_fixup(unsigned long data) ...@@ -587,11 +585,10 @@ static void rx_fixup(unsigned long data)
pegasus = (pegasus_t *)data; pegasus = (pegasus_t *)data;
if (pegasus->flags & PEGASUS_RX_URB_FAIL) { if (pegasus->flags & PEGASUS_RX_URB_FAIL)
goto try_again;
}
if (pegasus->rx_skb) if (pegasus->rx_skb)
return; goto try_again;
if (!(pegasus->rx_skb = dev_alloc_skb(PEGASUS_MTU + 2))) { if (!(pegasus->rx_skb = dev_alloc_skb(PEGASUS_MTU + 2))) {
tasklet_schedule(&pegasus->rx_tl); tasklet_schedule(&pegasus->rx_tl);
return; return;
...@@ -655,8 +652,12 @@ static void intr_callback(struct urb *urb) ...@@ -655,8 +652,12 @@ static void intr_callback(struct urb *urb)
pegasus->stats.tx_aborted_errors++; pegasus->stats.tx_aborted_errors++;
if (d[0] & LATE_COL) if (d[0] & LATE_COL)
pegasus->stats.tx_window_errors++; pegasus->stats.tx_window_errors++;
if (d[0] & (NO_CARRIER | LOSS_CARRIER)) if (d[0] & (NO_CARRIER | LOSS_CARRIER)) {
pegasus->stats.tx_carrier_errors++; pegasus->stats.tx_carrier_errors++;
netif_carrier_off(net);
} else {
netif_carrier_on(net);
}
} }
} }
#endif #endif
......
...@@ -309,7 +309,7 @@ static void read_bulk_callback(struct urb *urb) ...@@ -309,7 +309,7 @@ static void read_bulk_callback(struct urb *urb)
case 0: case 0:
break; break;
case -ENOENT: case -ENOENT:
return; /* urb's in unlink state */ return; /* the urb is in unlink state */
case -ETIMEDOUT: case -ETIMEDOUT:
warn("reset needed may be?.."); warn("reset needed may be?..");
goto goon; goto goon;
...@@ -318,12 +318,8 @@ static void read_bulk_callback(struct urb *urb) ...@@ -318,12 +318,8 @@ static void read_bulk_callback(struct urb *urb)
goto goon; goto goon;
} }
tasklet_schedule(&dev->tl); if (!dev->rx_skb)
goto resched;
if (!dev->rx_skb) {
/* lost packets++ */
return;
}
res = urb->actual_length; res = urb->actual_length;
rx_stat = le16_to_cpu(*(short *)(urb->transfer_buffer + res - 4)); rx_stat = le16_to_cpu(*(short *)(urb->transfer_buffer + res - 4));
...@@ -336,10 +332,8 @@ static void read_bulk_callback(struct urb *urb) ...@@ -336,10 +332,8 @@ static void read_bulk_callback(struct urb *urb)
dev->stats.rx_bytes += pkt_len; dev->stats.rx_bytes += pkt_len;
skb = pull_skb(dev); skb = pull_skb(dev);
if (!skb) { if (!skb)
dev->rx_skb = NULL; goto resched;
return;
}
skb->dev = netdev; skb->dev = netdev;
skb_reserve(skb, 2); skb_reserve(skb, 2);
...@@ -347,10 +341,16 @@ static void read_bulk_callback(struct urb *urb) ...@@ -347,10 +341,16 @@ static void read_bulk_callback(struct urb *urb)
goon: goon:
FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) {
set_bit(RX_URB_FAIL, &dev->flags); set_bit(RX_URB_FAIL, &dev->flags);
else goto resched;
} else {
clear_bit(RX_URB_FAIL, &dev->flags); clear_bit(RX_URB_FAIL, &dev->flags);
}
return;
resched:
tasklet_schedule(&dev->tl);
} }
static void rx_fixup(unsigned long data) static void rx_fixup(unsigned long data)
...@@ -362,22 +362,24 @@ static void rx_fixup(unsigned long data) ...@@ -362,22 +362,24 @@ static void rx_fixup(unsigned long data)
fill_skb_pool(dev); fill_skb_pool(dev);
if (test_bit(RX_URB_FAIL, &dev->flags)) if (test_bit(RX_URB_FAIL, &dev->flags))
goto try_again;
if (dev->rx_skb) if (dev->rx_skb)
return; goto try_again;
if (!(skb = pull_skb(dev))) { if (!(skb = pull_skb(dev)))
tasklet_schedule(&dev->tl); goto tlsched;
return;
}
dev->rx_skb = skb; dev->rx_skb = skb;
FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
try_again: try_again:
if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) {
set_bit(RX_URB_FAIL, &dev->flags); set_bit(RX_URB_FAIL, &dev->flags);
tasklet_schedule(&dev->tl); goto tlsched;
} else } else {
clear_bit(RX_URB_FAIL, &dev->flags); clear_bit(RX_URB_FAIL, &dev->flags);
}
return;
tlsched:
tasklet_schedule(&dev->tl);
} }
static void write_bulk_callback(struct urb *urb) static void write_bulk_callback(struct urb *urb)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment