mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-14 12:49:08 +00:00
m68k: Mac89x0 Ethernet netif updates
Macintosh CS89x0 Ethernet: Netif updates Addition of netif_stop_queue() before transmission by Michael Schmitz skb_copy_{from,to}_linear_data() conversion by Geert Uytterhoeven Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
ec0203e753
commit
39ad2cb352
@ -311,7 +311,7 @@ config MAC8390
|
|||||||
|
|
||||||
config MAC89x0
|
config MAC89x0
|
||||||
tristate "Macintosh CS89x0 based ethernet cards"
|
tristate "Macintosh CS89x0 based ethernet cards"
|
||||||
depends on NET_ETHERNET && MAC && BROKEN
|
depends on NET_ETHERNET && MAC
|
||||||
---help---
|
---help---
|
||||||
Support for CS89x0 chipset based Ethernet cards. If you have a
|
Support for CS89x0 chipset based Ethernet cards. If you have a
|
||||||
Nubus or LC-PDS network (Ethernet) card of this type, say Y and
|
Nubus or LC-PDS network (Ethernet) card of this type, say Y and
|
||||||
|
@ -128,7 +128,7 @@ struct net_local {
|
|||||||
extern void reset_chip(struct net_device *dev);
|
extern void reset_chip(struct net_device *dev);
|
||||||
#endif
|
#endif
|
||||||
static int net_open(struct net_device *dev);
|
static int net_open(struct net_device *dev);
|
||||||
static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
|
static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
|
||||||
static irqreturn_t net_interrupt(int irq, void *dev_id);
|
static irqreturn_t net_interrupt(int irq, void *dev_id);
|
||||||
static void set_multicast_list(struct net_device *dev);
|
static void set_multicast_list(struct net_device *dev);
|
||||||
static void net_rx(struct net_device *dev);
|
static void net_rx(struct net_device *dev);
|
||||||
@ -374,56 +374,39 @@ net_open(struct net_device *dev)
|
|||||||
static int
|
static int
|
||||||
net_send_packet(struct sk_buff *skb, struct net_device *dev)
|
net_send_packet(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
if (dev->tbusy) {
|
struct net_local *lp = netdev_priv(dev);
|
||||||
/* If we get here, some higher level has decided we are broken.
|
unsigned long flags;
|
||||||
There should really be a "kick me" function call instead. */
|
|
||||||
int tickssofar = jiffies - dev->trans_start;
|
|
||||||
if (tickssofar < 5)
|
|
||||||
return 1;
|
|
||||||
if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
|
|
||||||
tx_done(dev) ? "IRQ conflict" : "network cable problem");
|
|
||||||
/* Try to restart the adaptor. */
|
|
||||||
dev->tbusy=0;
|
|
||||||
dev->trans_start = jiffies;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Block a timer-based transmit from overlapping. This could better be
|
if (net_debug > 3)
|
||||||
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
|
printk("%s: sent %d byte packet of type %x\n",
|
||||||
if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
|
dev->name, skb->len,
|
||||||
printk("%s: Transmitter access conflict.\n", dev->name);
|
(skb->data[ETH_ALEN+ETH_ALEN] << 8)
|
||||||
else {
|
| skb->data[ETH_ALEN+ETH_ALEN+1]);
|
||||||
struct net_local *lp = netdev_priv(dev);
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (net_debug > 3)
|
/* keep the upload from being interrupted, since we
|
||||||
printk("%s: sent %d byte packet of type %x\n",
|
ask the chip to start transmitting before the
|
||||||
dev->name, skb->len,
|
whole packet has been completely uploaded. */
|
||||||
(skb->data[ETH_ALEN+ETH_ALEN] << 8)
|
local_irq_save(flags);
|
||||||
| skb->data[ETH_ALEN+ETH_ALEN+1]);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
/* keep the upload from being interrupted, since we
|
/* initiate a transmit sequence */
|
||||||
ask the chip to start transmitting before the
|
writereg(dev, PP_TxCMD, lp->send_cmd);
|
||||||
whole packet has been completely uploaded. */
|
writereg(dev, PP_TxLength, skb->len);
|
||||||
local_irq_save(flags);
|
|
||||||
|
|
||||||
/* initiate a transmit sequence */
|
|
||||||
writereg(dev, PP_TxCMD, lp->send_cmd);
|
|
||||||
writereg(dev, PP_TxLength, skb->len);
|
|
||||||
|
|
||||||
/* Test to see if the chip has allocated memory for the packet */
|
|
||||||
if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
|
|
||||||
/* Gasp! It hasn't. But that shouldn't happen since
|
|
||||||
we're waiting for TxOk, so return 1 and requeue this packet. */
|
|
||||||
local_irq_restore(flags);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the contents of the packet */
|
|
||||||
memcpy_toio(dev->mem_start + PP_TxFrame, skb->data, skb->len+1);
|
|
||||||
|
|
||||||
|
/* Test to see if the chip has allocated memory for the packet */
|
||||||
|
if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
|
||||||
|
/* Gasp! It hasn't. But that shouldn't happen since
|
||||||
|
we're waiting for TxOk, so return 1 and requeue this packet. */
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
dev->trans_start = jiffies;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write the contents of the packet */
|
||||||
|
skb_copy_from_linear_data(skb, (void *)(dev->mem_start + PP_TxFrame),
|
||||||
|
skb->len+1);
|
||||||
|
|
||||||
|
local_irq_restore(flags);
|
||||||
|
dev->trans_start = jiffies;
|
||||||
dev_kfree_skb (skb);
|
dev_kfree_skb (skb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -441,9 +424,6 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
|
|||||||
printk ("net_interrupt(): irq %d for unknown device.\n", irq);
|
printk ("net_interrupt(): irq %d for unknown device.\n", irq);
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
if (dev->interrupt)
|
|
||||||
printk("%s: Re-entering the interrupt handler.\n", dev->name);
|
|
||||||
dev->interrupt = 1;
|
|
||||||
|
|
||||||
ioaddr = dev->base_addr;
|
ioaddr = dev->base_addr;
|
||||||
lp = netdev_priv(dev);
|
lp = netdev_priv(dev);
|
||||||
@ -464,8 +444,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
|
|||||||
break;
|
break;
|
||||||
case ISQ_TRANSMITTER_EVENT:
|
case ISQ_TRANSMITTER_EVENT:
|
||||||
lp->stats.tx_packets++;
|
lp->stats.tx_packets++;
|
||||||
dev->tbusy = 0;
|
netif_wake_queue(dev);
|
||||||
mark_bh(NET_BH); /* Inform upper layers. */
|
|
||||||
if ((status & TX_OK) == 0) lp->stats.tx_errors++;
|
if ((status & TX_OK) == 0) lp->stats.tx_errors++;
|
||||||
if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++;
|
if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++;
|
||||||
if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++;
|
if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++;
|
||||||
@ -479,8 +458,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
|
|||||||
That shouldn't happen since we only ever
|
That shouldn't happen since we only ever
|
||||||
load one packet. Shrug. Do the right
|
load one packet. Shrug. Do the right
|
||||||
thing anyway. */
|
thing anyway. */
|
||||||
dev->tbusy = 0;
|
netif_wake_queue(dev);
|
||||||
mark_bh(NET_BH); /* Inform upper layers. */
|
|
||||||
}
|
}
|
||||||
if (status & TX_UNDERRUN) {
|
if (status & TX_UNDERRUN) {
|
||||||
if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
|
if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
|
||||||
@ -497,7 +475,6 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dev->interrupt = 0;
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,7 +508,8 @@ net_rx(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
skb_put(skb, length);
|
skb_put(skb, length);
|
||||||
|
|
||||||
memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length);
|
skb_copy_to_linear_data(skb, (void *)(dev->mem_start + PP_RxFrame),
|
||||||
|
length);
|
||||||
|
|
||||||
if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
|
if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
|
||||||
dev->name, length,
|
dev->name, length,
|
||||||
@ -610,8 +588,6 @@ static void set_multicast_list(struct net_device *dev)
|
|||||||
static int set_mac_address(struct net_device *dev, void *addr)
|
static int set_mac_address(struct net_device *dev, void *addr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (dev->start)
|
|
||||||
return -EBUSY;
|
|
||||||
printk("%s: Setting MAC address to ", dev->name);
|
printk("%s: Setting MAC address to ", dev->name);
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]);
|
printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]);
|
||||||
|
Loading…
Reference in New Issue
Block a user