patch-1.3.31 linux/drivers/net/ne.c
Next file: linux/drivers/net/plip.c
Previous file: linux/drivers/net/loopback.c
Back to the patch index
Back to the overall index
- Lines: 148
- Date:
Sun Oct 1 19:18:58 1995
- Orig file:
v1.3.30/linux/drivers/net/ne.c
- Orig date:
Tue Aug 15 20:39:03 1995
diff -u --recursive --new-file v1.3.30/linux/drivers/net/ne.c linux/drivers/net/ne.c
@@ -73,6 +73,7 @@
{"NE1000","NE2000-invalid", {0x00, 0x00, 0xd8}}, /* Ancient real NE1000. */
{"NN1000", "NN2000", {0x08, 0x03, 0x08}}, /* Outlaw no-name clone. */
{"4-DIM8","4-DIM16", {0x00,0x00,0x4d,}}, /* Outlaw 4-Dimension cards. */
+ {"Con-Intl_8", "Con-Intl_16", {0x00, 0x00, 0x24}}, /* Connect Int'nl */
{0,}
};
#endif
@@ -92,8 +93,10 @@
static int ne_probe1(struct device *dev, int ioaddr);
static void ne_reset_8390(struct device *dev);
-static int ne_block_input(struct device *dev, int count,
- char *buf, int ring_offset);
+static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
+ int ring_page);
+static void ne_block_input(struct device *dev, int count,
+ struct sk_buff *skb, int ring_offset);
static void ne_block_output(struct device *dev, const int count,
const unsigned char *buf, const int start_page);
@@ -181,14 +184,12 @@
/* DON'T change these to inb_p/outb_p or reset will fail on clones. */
outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
- /* wait 20 ms for the dust to settle. */
- while (jiffies - reset_start_time < 2*HZ/100)
- barrier();
-
- if ((inb_p(ioaddr+EN0_ISR) & ENISR_RESET) == 0) {
- printk(" not found (no reset ack).\n");
- return ENODEV;
- }
+ while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0)
+ if (jiffies - reset_start_time > 2*HZ/100) {
+ printk(" not found (no reset ack).\n");
+ return ENODEV;
+ }
+
outb_p(0xff, ioaddr + EN0_ISR); /* Ack all intr. */
}
@@ -338,6 +339,7 @@
ei_status.reset_8390 = &ne_reset_8390;
ei_status.block_input = &ne_block_input;
ei_status.block_output = &ne_block_output;
+ ei_status.get_8390_hdr = &ne_get_8390_hdr;
NS8390_init(dev, 0);
return 0;
}
@@ -366,27 +368,63 @@
outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */
}
+/* Grab the 8390 specific header. Similar to the block_input routine, but
+ we don't need to be concerned with ring wrap as the header will be at
+ the start of a page, so we optimize accordingly. */
+
+static void
+ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
+{
+
+ int nic_base = dev->base_addr;
+
+ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+ if (ei_status.dmaing) {
+ printk("%s: DMAing conflict in ne_get_8390_hdr "
+ "[DMAstat:%d][irqlock:%d][intr:%d].\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock,
+ dev->interrupt);
+ return;
+ }
+
+ ei_status.dmaing |= 0x01;
+ outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+ outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
+ outb_p(0, nic_base + EN0_RCNTHI);
+ outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */
+ outb_p(ring_page, nic_base + EN0_RSARHI);
+ outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+ if (ei_status.word16)
+ insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
+ else
+ insb(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
+
+ outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
+ ei_status.dmaing &= ~0x01;
+}
+
/* Block input and output, similar to the Crynwr packet driver. If you
are porting to a new ethercard, look at the packet driver source for hints.
- The NEx000 doesn't share it on-board packet memory -- you have to put
+ The NEx000 doesn't share the on-board packet memory -- you have to put
the packet out through the "remote DMA" dataport using outb. */
-static int
-ne_block_input(struct device *dev, int count, char *buf, int ring_offset)
+static void
+ne_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
{
- int nic_base = dev->base_addr;
#ifdef CONFIG_NE_SANITY
int xfer_count = count;
#endif
+ int nic_base = dev->base_addr;
+ char *buf = skb->data;
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
- if (ei_debug > 0)
- printk("%s: DMAing conflict in ne_block_input "
- "[DMAstat:%d][irqlock:%d][intr:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
- return 0;
+ printk("%s: DMAing conflict in ne_block_input "
+ "[DMAstat:%d][irqlock:%d][intr:%d].\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock,
+ dev->interrupt);
+ return;
}
ei_status.dmaing |= 0x01;
outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
@@ -431,7 +469,6 @@
#endif
outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
ei_status.dmaing &= ~0x01;
- return ring_offset + count;
}
static void
@@ -452,11 +489,10 @@
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
- if (ei_debug > 0)
- printk("%s: DMAing conflict in ne_block_output."
- "[DMAstat:%d][irqlock:%d][intr:%d]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
+ printk("%s: DMAing conflict in ne_block_output."
+ "[DMAstat:%d][irqlock:%d][intr:%d]\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock,
+ dev->interrupt);
return;
}
ei_status.dmaing |= 0x01;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this