lkml.org 
[lkml]   [1999]   [Sep]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch] working syskonnect driver for 2.2.13pre10

Attached is a patch to get the SysKonnect token ring driver working in
2.2.13pre10, based on Christoph's fixes and a few minor additions of my
own (Compaq detection mainly). Alan, can you please include this in
2.2.13final? [The Compaq detection does add the PCI Device ID for the
board in include/linux/pci.h]

I changed sktr_wait() to use udelay() only. I'm not sure what it is, but
my card gets suicidal if the timing is not as "accurate" as a udelay(). It
waits indefinitly (same thing happens with the sktr_wait() from
2.3.18ac8). udelay is the only thing that works for me without getting a
hanging ifconfig.

Christoph, how precise does the timing need to be? The problem seems to
be with the waits in the bring-up diagnostics (where it hangs
indefinitly). I couldn't find any exact times in the TI information I
have. Do the waits really need to be that long? Half-second is quite a
span of time, especially several times in a row.

Patch also includes the multicast_list code that Jochen suggested.

Finally, this driver seems quite slow. An (ISA) 3com tokenlink with the
ibmtr driver can easily beat this (PCI) board. Latency is nearly double
and transfer times are around 10% less. I was expecting a PCI board to
get _higher_ throughput than an ISA board! Now that the driver actually
works, I guess its time to look for more speed.

mid

PS: A larger patch for 2.3.18ac8 will follow in a day or two.

---
Adam Fritzler
{ mid@auk.cx, afritz@iname.com}
http://www.auk.cx/~mid/

Only in 2.2.13pre10.clean/arch/i386: vmlinux.lds
diff -u --recursive 2.2.13pre10.clean/drivers/net/sktr.c 2.2.13pre10/drivers/net/sktr.c
--- 2.2.13pre10.clean/drivers/net/sktr.c Thu Jan 7 16:46:59 1999
+++ 2.2.13pre10/drivers/net/sktr.c Tue Sep 21 20:18:26 1999
@@ -24,7 +24,8 @@
*
* Maintainer(s):
* JS Jay Schulist jschlst@samba.anu.edu.au
- * CG Christoph Goos cgoos@syskonnect.de
+ * CG Christoph Goos cgoos@syskonnect.de
+ * AF Adam Fritzler mid@auk.cx
*
* Modification History:
* 29-Aug-97 CG Created
@@ -33,10 +34,14 @@
* 27-May-98 JS Formated to Linux Kernel Format
* 31-May-98 JS Hacked in PCI support
* 16-Jun-98 JS Modulized for multiple cards with one driver
+ * 21-Sep-99 CG Fixed source routing issues for 2.2 kernels
+ * 21-Sep-99 AF Added multicast changes recommended by
+ * Jochen Friedrich <jochen@nwe.de> (untested)
+ * Added detection of compatible Compaq PCI card
*
* To do:
* 1. Selectable 16 Mbps or 4Mbps
- * 2. Multi/Broadcast packet handling
+ * 2. Multi/Broadcast packet handling (might be done)
*
*/

@@ -135,7 +140,6 @@
static void sktr_exec_cmd(struct device *dev, unsigned short Command);
static void sktr_exec_sifcmd(struct device *dev, unsigned int WriteValue);
/* "F" */
-static unsigned char *sktr_fix_srouting(unsigned char *buf, short *FrameLen);
/* "G" */
static struct enet_statistics *sktr_get_stats(struct device *dev);
/* "H" */
@@ -254,10 +258,17 @@
/* Remove I/O space marker in bit 0. */
pci_ioaddr &= ~3;

- if(vendor != PCI_VENDOR_ID_SK)
+ if((vendor != PCI_VENDOR_ID_SK) &&
+ (vendor != PCI_VENDOR_ID_COMPAQ))
continue;
- if(device != PCI_DEVICE_ID_SK_TR)
+
+ if((vendor == PCI_VENDOR_ID_SK) &&
+ (device != PCI_DEVICE_ID_SK_TR))
+ continue;
+ else if((vendor == PCI_VENDOR_ID_COMPAQ) &&
+ (device != PCI_DEVICE_ID_COMPAQ_TOKENRING))
continue;
+
if(check_region(pci_ioaddr, SKTR_IO_EXTENT))
continue;
request_region(pci_ioaddr, SKTR_IO_EXTENT, pci_cardname);
@@ -390,6 +401,7 @@
{
static unsigned version_printed = 0;
struct net_local *tp;
+ int DeviceType = SK_PCI;
int err;

if(sktr_debug && version_printed++ == 0)
@@ -407,6 +419,7 @@
err = sktr_isa_chk_card(dev, ioaddr);
if(err < 0)
return (-ENODEV);
+ DeviceType = SK_ISA;
}

/* Setup this devices private information structure */
@@ -414,6 +427,7 @@
if(tp == NULL)
return (-ENOMEM);
memset(tp, 0, sizeof(struct net_local));
+ tp->DeviceType = DeviceType;

dev->priv = tp;
dev->init = sktr_init_card;
@@ -690,7 +704,9 @@
skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize);

/* data unreachable for DMA ? then use local buffer */
- if(virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > ISA_MAX_ADDRESS)
+ if(tp->DeviceType == SK_ISA &&
+ virt_to_bus(tp->Rpl[i].Skb->data) +
+ tp->MaxPacketSize > ISA_MAX_ADDRESS)
{
tp->Rpl[i].SkbStat = SKB_DATA_COPY;
tp->Rpl[i].FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[i]));
@@ -748,7 +764,7 @@

tp->ocpl.OPENOptions = 0;
tp->ocpl.OPENOptions |= ENABLE_FULL_DUPLEX_SELECTION;
- tp->ocpl.OPENOptions |= PAD_ROUTING_FIELD;
+/* tp->ocpl.OPENOptions |= PAD_ROUTING_FIELD; no more needed */
tp->ocpl.FullDuplex = 0;
tp->ocpl.FullDuplex |= OPEN_FULL_DUPLEX_OFF;

@@ -826,32 +842,6 @@
}

/*
- * Linux always gives 18 byte of source routing information in the frame header.
- * But the length field can indicate shorter length. Then cut header
- * appropriate.
- */
-static unsigned char *sktr_fix_srouting(unsigned char *buf, short *FrameLen)
-{
- struct trh_hdr *trh = (struct trh_hdr *)buf;
- int len;
-
- if(buf[8] & TR_RII)
- {
- trh->rcf &= ~SWAPB((unsigned short) TR_RCF_LONGEST_FRAME_MASK);
- trh->rcf |= SWAPB((unsigned short) TR_RCF_FRAME4K);
- len = (SWAPB(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
- if(len < 18)
- {
- memcpy(&buf[18-len],buf,sizeof(struct trh_hdr)-18+len);
- *FrameLen -= (18 - len);
- }
- return (&buf[18-len]);
- }
-
- return (buf);
-}
-
-/*
* Gets skb from system, queues it and checks if it can be sent
*/
static int sktr_send_packet(struct sk_buff *skb, struct device *dev)
@@ -933,7 +923,8 @@

tp->QueueSkb++;
/* Is buffer reachable for Busmaster-DMA? */
- if(virt_to_bus((void*)(((long) skb->data) + skb->len))
+ if(tp->DeviceType == SK_ISA &&
+ virt_to_bus((void*)(((long) skb->data) + skb->len))
> ISA_MAX_ADDRESS)
{
/* Copy frame to local buffer */
@@ -941,13 +932,13 @@
length = skb->len;
buf = tp->LocalTxBuffers[i];
memcpy(buf, skb->data, length);
- newbuf = sktr_fix_srouting(buf, &length);
+ newbuf = buf;
}
else
{
/* Send direct from skb->data */
length = skb->len;
- newbuf = sktr_fix_srouting(skb->data, &length);
+ newbuf = skb->data;
}

/* Source address in packet? */
@@ -1485,53 +1476,64 @@
static void sktr_set_multicast_list(struct device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
- unsigned int OpenOptions;
-
- OpenOptions = tp->ocpl.OPENOptions &
- ~(PASS_ADAPTER_MAC_FRAMES
- | PASS_ATTENTION_FRAMES
- | PASS_BEACON_MAC_FRAMES
- | COPY_ALL_MAC_FRAMES
- | COPY_ALL_NON_MAC_FRAMES);
-
- if(dev->flags & IFF_PROMISC)
- /* Enable promiscuous mode */
- OpenOptions |= COPY_ALL_NON_MAC_FRAMES | COPY_ALL_MAC_FRAMES;
- else
- {
- if(dev->flags & IFF_ALLMULTI)
- /* || dev->mc_count > HW_MAX_ADDRS) */
- {
- /* Disable promiscuous mode, use normal mode. */
- }
- else
- {
- if(dev->mc_count)
- {
- /* Walk the address list, and load the filter */
- }
- }
- }
-
- tp->ocpl.OPENOptions = OpenOptions;
- sktr_exec_cmd(dev, OC_MODIFY_OPEN_PARMS);
-
- return;
+ unsigned int OpenOptions;
+
+ OpenOptions = tp->ocpl.OPENOptions &
+ ~(PASS_ADAPTER_MAC_FRAMES
+ | PASS_ATTENTION_FRAMES
+ | PASS_BEACON_MAC_FRAMES
+ | COPY_ALL_MAC_FRAMES
+ | COPY_ALL_NON_MAC_FRAMES);
+
+ tp->ocpl.FunctAddr = 0;
+
+ if(dev->flags & IFF_PROMISC)
+ /* Enable promiscuous mode */
+ OpenOptions |= COPY_ALL_NON_MAC_FRAMES |
+ COPY_ALL_MAC_FRAMES;
+ else
+ {
+ if(dev->flags & IFF_ALLMULTI)
+ {
+ /* Disable promiscuous mode, use normal mode. */
+ tp->ocpl.FunctAddr = 0xFFFFFFFF;
+
+ }
+ else
+ {
+ int i;
+ struct dev_mc_list *mclist = dev->mc_list;
+ for (i=0; i< dev->mc_count; i++)
+ {
+ ((char *)(&tp->ocpl.FunctAddr))[0] |=
+ mclist->dmi_addr[2];
+ ((char *)(&tp->ocpl.FunctAddr))[1] |=
+ mclist->dmi_addr[3];
+ ((char *)(&tp->ocpl.FunctAddr))[2] |=
+ mclist->dmi_addr[4];
+ ((char *)(&tp->ocpl.FunctAddr))[3] |=
+ mclist->dmi_addr[5];
+ mclist = mclist->next;
+ }
+ }
+ sktr_exec_cmd(dev, OC_SET_FUNCT_ADDR);
+ }
+
+ tp->ocpl.OPENOptions = OpenOptions;
+ sktr_exec_cmd(dev, OC_MODIFY_OPEN_PARMS);
+ return;
}

/*
* Wait for some time (microseconds)
+ *
+ * udelay() is a bit harsh, but using a looser timer causes
+ * the bring-up-diags to stall indefinitly.
+ *
*/
static void sktr_wait(unsigned long time)
{
- long tmp;
-
- tmp = jiffies + time/(1000000/HZ);
- do {
- current->state = TASK_INTERRUPTIBLE;
- tmp = schedule_timeout(tmp);
- } while(time_after(tmp, jiffies));
-
+ udelay(time);
return;
}

@@ -2450,8 +2452,6 @@
/* Drop frames sent by myself */
if(sktr_chk_frame(dev, rpl->MData))
{
- printk(KERN_INFO "%s: Received my own frame\n",
- dev->name);
if(rpl->Skb != NULL)
dev_kfree_skb(rpl->Skb);
}
@@ -2463,9 +2463,10 @@
printk("%s: Packet Length %04X (%d)\n",
dev->name, Length, Length);

- /* Indicate the received frame to system the
- * adapter does the Source-Routing padding for
- * us. See: OpenOptions in sktr_init_opb()
+ /* Indicate the received frame to system.
+ * The source routing padding is no more
+ * necessary with 2.2.x kernel.
+ * See: OpenOptions in sktr_init_opb()
*/
skb = rpl->Skb;
if(rpl->SkbStat == SKB_UNAVAILABLE)
@@ -2528,7 +2529,8 @@
skb_put(rpl->Skb, tp->MaxPacketSize);

/* Data unreachable for DMA ? then use local buffer */
- if(virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize
+ if(tp->DeviceType == SK_ISA &&
+ virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize
> ISA_MAX_ADDRESS)
{
rpl->SkbStat = SKB_DATA_COPY;
diff -u --recursive 2.2.13pre10.clean/drivers/net/sktr.h 2.2.13pre10/drivers/net/sktr.h
--- 2.2.13pre10.clean/drivers/net/sktr.h Wed Jun 24 21:26:13 1998
+++ 2.2.13pre10/drivers/net/sktr.h Tue Sep 21 11:03:58 1999
@@ -16,6 +16,9 @@
#define TR_RCF_LONGEST_FRAME_MASK 0x0070
#define TR_RCF_FRAME4K 0x0030

+#define SK_ISA 0
+#define SK_PCI 1
+
/*------------------------------------------------------------------*/
/* Bit order for adapter communication with DMA */
/* -------------------------------------------------------------- */
@@ -1062,6 +1065,8 @@
int DataRate;
unsigned char ScbInUse;
unsigned short CMDqueue;
+
+ unsigned int DeviceType;

unsigned long AdapterOpenFlag:1;
unsigned long AdapterVirtOpenFlag:1;
diff -u --recursive 2.2.13pre10.clean/include/linux/pci.h 2.2.13pre10/include/linux/pci.h
--- 2.2.13pre10.clean/include/linux/pci.h Tue Sep 21 20:11:43 1999
+++ 2.2.13pre10/include/linux/pci.h Tue Sep 21 20:17:21 1999
@@ -283,6 +283,7 @@
* <linux-pcisupport@cck.uni-kl.de>.
*/
#define PCI_VENDOR_ID_COMPAQ 0x0e11
+#define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508
#define PCI_DEVICE_ID_COMPAQ_1280 0x3033
#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000
#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10
\
 
 \ /
  Last update: 2005-03-22 13:54    [W:0.400 / U:0.044 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site