patch-2.4.7 linux/drivers/net/sk98lin/skge.c
Next file: linux/drivers/net/sk98lin/skgehwt.c
Previous file: linux/drivers/net/sk98lin/skcsum.c
Back to the patch index
Back to the overall index
- Lines: 1907
- Date:
Wed Jul 4 11:50:39 2001
- Orig file:
v2.4.6/linux/drivers/net/sk98lin/skge.c
- Orig date:
Wed Apr 18 14:40:05 2001
diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
@@ -1,20 +1,21 @@
-;/******************************************************************************
+/******************************************************************************
*
- * Name: skge.c
+ * Name: skge.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.29 $
- * Date: $Date: 2000/02/21 13:31:56 $
+ * Version: $Revision: 1.29.2.6 $
+ * Date: $Date: 2001/05/21 07:59:29 $
* Purpose: The main driver source module
*
******************************************************************************/
/******************************************************************************
*
- * (C)Copyright 1998,1999 SysKonnect,
- * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ * (C)Copyright 1998-2001 SysKonnect GmbH.
*
* Driver for SysKonnect Gigabit Ethernet Server Adapters:
*
+ * SK-9861 (single link 1000Base-SX, VF45 Volition Plug)
+ * SK-9862 (dual link 1000Base-SX, VF45 Volition Plug)
* SK-9841 (single link 1000Base-LX)
* SK-9842 (dual link 1000Base-LX)
* SK-9843 (single link 1000Base-SX)
@@ -25,6 +26,7 @@
* Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
* SysKonnects GEnesis Solaris driver
* Author: Christoph Goos (cgoos@syskonnect.de)
+ * Mirko Lindner (mlindner@syskonnect.de)
*
* Address all question to: linux@syskonnect.de
*
@@ -46,6 +48,27 @@
* History:
*
* $Log: skge.c,v $
+ * Revision 1.29.2.6 2001/05/21 07:59:29 mlindner
+ * fix: MTU init problems
+ *
+ * Revision 1.29.2.5 2001/05/08 11:25:08 mlindner
+ * fix: removed VLAN error message
+ *
+ * Revision 1.29.2.4 2001/05/04 13:31:43 gklug
+ * fix: do not handle eth_copy on bad fragments received.
+ *
+ * Revision 1.29.2.3 2001/04/23 08:06:43 mlindner
+ * Fix: error handling
+ *
+ * Revision 1.29.2.2 2001/03/15 12:04:54 mlindner
+ * Fixed memory problem
+ *
+ * Revision 1.29.2.1 2001/03/12 16:41:44 mlindner
+ * add: procfs function
+ * add: dual-net function
+ * add: RLMT networks
+ * add: extended PNMI features
+ *
* Kernel 2.4.x specific:
* Revision 1.xx 2000/09/12 13:31:56 cgoos
* Fixed missign "dev=NULL in skge_probe.
@@ -109,7 +132,7 @@
* Transmit descriptor polling was not reenabled after SkGePortInit.
*
* Revision 1.16 1999/07/27 15:17:29 cgoos
- * Added some "\n" in output strings (removed while debugging...).
+ * Added some "\n" in output strings (removed while debuging...).
*
* Revision 1.15 1999/07/23 12:09:30 cgoos
* Performance optimization, rx checksumming, large frame support.
@@ -242,25 +265,17 @@
*
******************************************************************************/
-static const char SysKonnectFileId[] = "@(#)" __FILE__ " (C) SysKonnect.";
-static const char SysKonnectBuildNumber[] =
- "@(#)SK-BUILD: 3.05 (20000907) PL: 01";
+#include "h/skversion.h"
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/proc_fs.h>
#include "h/skdrv1st.h"
#include "h/skdrv2nd.h"
/* defines ******************************************************************/
-
-#define BOOT_STRING "sk98lin: Network Device Driver v3.05\n" \
- "Copyright (C) 1999-2000 SysKonnect"
-
-#define VER_STRING "3.05"
-
-
-/* for debugging on x86 only */
+/* for debuging on x86 only */
/* #define BREAKPOINT() asm(" int $3"); */
/* use of a transmit complete interrupt */
@@ -292,8 +307,7 @@
// #define ROLE_A {"Auto", }
// #define ROLE_B {"Auto", }
// #define PREF_PORT {"A", }
-// #define RLMT_MODE {"CheckLink", }
-
+// #define RLMT_MODE {"CheckLinkState", }
#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
@@ -333,7 +347,18 @@
static void SetQueueSizes(SK_AC *pAC);
static int SkGeChangeMtu(struct net_device *dev, int new_mtu);
static void PortReInitBmu(SK_AC*, int);
-static int SkGeIocMib(SK_AC*, unsigned int, int);
+static int SkGeIocMib(DEV_NET*, unsigned int, int);
+
+
+/*Extern */
+
+extern struct proc_dir_entry *pSkRootDir;
+
+//extern struct proc_dir_entry Our_Proc_Dir;
+extern int proc_read(char *buffer, char **buffer_location,
+ off_t offset, int buffer_length, int *eof, void *data);
+
+
#ifdef DEBUG
static void DumpMsg(struct sk_buff*, char*);
static void DumpData(char*, int);
@@ -343,13 +368,27 @@
/* global variables *********************************************************/
static const char *BootString = BOOT_STRING;
-static struct net_device *root_dev;
+static struct net_device *root_dev = NULL;
static int probed __initdata = 0;
+struct inode_operations SkInodeOps;
+//static struct file_operations SkFileOps; /* with open/relase */
/* local variables **********************************************************/
static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
+
+
+void proc_fill_inode(struct inode *inode, int fill)
+{
+ if (fill)
+ MOD_INC_USE_COUNT;
+ else
+ MOD_DEC_USE_COUNT;
+}
+
+
+
/*****************************************************************************
*
* skge_probe - find all SK-98xx adapters
@@ -365,12 +404,14 @@
*/
static int __init skge_probe (void)
{
- int boards_found = 0;
- int version_disp = 0;
+ int boards_found = 0;
+ int version_disp = 0;
SK_AC *pAC;
- struct pci_dev *pdev = NULL;
- unsigned long base_address;
+ DEV_NET *pNet = NULL;
+ struct pci_dev *pdev = NULL;
+ unsigned long base_address;
struct net_device *dev = NULL;
+ struct proc_dir_entry *pProcFile;
if (probed)
return -ENODEV;
@@ -388,27 +429,46 @@
if (!pci_present()) /* is PCI support present? */
return -ENODEV;
+ pSkRootDir = create_proc_entry("sk98lin",
+ S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net);
+
+ pSkRootDir->owner = THIS_MODULE;
+
while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT,
PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
- if (pci_enable_device(pdev))
- continue;
dev = NULL;
- dev = init_etherdev(dev, sizeof(SK_AC));
+ pNet = NULL;
+
+ if (pci_enable_device(pdev))
+ continue;
- if (dev == NULL) {
+ if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == 0) {
printk(KERN_ERR "Unable to allocate etherdev "
"structure!\n");
break;
}
- pAC = dev->priv;
+ pNet = dev->priv;
+ pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
+ if (pNet->pAC == NULL){
+ kfree(dev->priv);
+ printk(KERN_ERR "Unable to allocate adapter "
+ "structure!\n");
+ break;
+ }
+
+ memset(pNet->pAC, 0, sizeof(SK_AC));
+ pAC = pNet->pAC;
pAC->PciDev = *pdev;
pAC->PciDevId = pdev->device;
- pAC->dev = dev;
+ pAC->dev[0] = dev;
+ pAC->dev[1] = dev;
sprintf(pAC->Name, "SysKonnect SK-98xx");
pAC->CheckQueue = SK_FALSE;
-
+
+ pNet->Mtu = 1500;
+ pNet->Up = 0;
dev->irq = pdev->irq;
dev->open = &SkGeOpen;
@@ -419,14 +479,20 @@
dev->set_mac_address = &SkGeSetMacAddr;
dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu;
-
+
+ pProcFile = create_proc_entry(dev->name,
+ S_IFREG | 0444, pSkRootDir);
+ pProcFile->read_proc = proc_read;
+ pProcFile->write_proc = NULL;
+ pProcFile->nlink = 1;
+ pProcFile->size = sizeof(dev->name+1);
+ pProcFile->data = (void*)pProcFile;
+
/*
* Dummy value.
*/
dev->base_addr = 42;
-
pci_set_master(pdev);
-
base_address = pci_resource_start (pdev, 0);
#ifdef SK_BIG_ENDIAN
@@ -446,24 +512,28 @@
* Remap the regs into kernel space.
*/
-
pAC->IoBase = (char*)ioremap(base_address, 0x4000);
if (!pAC->IoBase){
printk(KERN_ERR "%s: Unable to map I/O register, "
"SK 98xx No. %i will be disabled.\n",
dev->name, boards_found);
+ kfree(dev);
break;
}
pAC->Index = boards_found;
if (SkGeBoardInit(dev, pAC)) {
FreeResources(dev);
+ kfree(dev);
continue;
}
- memcpy((caddr_t) &dev->dev_addr,
- (caddr_t) &pAC->Addr.CurrentMacAddress, 6);
-
+ memcpy((caddr_t) &dev->dev_addr,
+ (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
+
+ pNet->PortNr = 0;
+ pNet->NetNr = 0;
+
boards_found++;
/*
@@ -499,10 +569,12 @@
static void FreeResources(struct net_device *dev)
{
SK_U32 AllocFlag;
-SK_AC *pAC;
+DEV_NET *pNet;
+SK_AC *pAC;
if (dev->priv) {
- pAC = (SK_AC*) dev->priv;
+ pNet = (DEV_NET*) dev->priv;
+ pAC = pNet->pAC;
AllocFlag = pAC->AllocFlag;
if (AllocFlag & SK_ALLOC_IRQ) {
free_irq(dev->irq, dev);
@@ -517,13 +589,6 @@
} /* FreeResources */
-
-static struct pci_device_id skge_pci_tbl[] __initdata = {
- { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE, PCI_ANY_ID, PCI_ANY_ID, },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
-
MODULE_AUTHOR("Christoph Goos <cgoos@syskonnect.de>");
MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
MODULE_PARM(AutoNeg_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
@@ -602,8 +667,8 @@
#endif
-static int debug; /* not used */
-static int options[SK_MAX_CARD_PARAM]; /* not used */
+static int debug = 0; /* not used */
+static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */
/*****************************************************************************
@@ -620,7 +685,6 @@
static int __init skge_init_module(void)
{
int cards;
-
root_dev = NULL;
/* just to avoid warnings ... */
@@ -647,21 +711,28 @@
*/
static void __exit skge_cleanup_module(void)
{
-SK_AC *pAC;
+DEV_NET *pNet;
+SK_AC *pAC;
struct net_device *next;
unsigned long Flags;
SK_EVPARA EvPara;
while (root_dev) {
- pAC = (SK_AC*)root_dev->priv;
+ pNet = (DEV_NET*) root_dev->priv;
+ pAC = pNet->pAC;
next = pAC->Next;
netif_stop_queue(root_dev);
SkGeYellowLED(pAC, pAC->IoBase, 0);
-
+
if(pAC->BoardLevel == 2) {
/* board is still alive */
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ EvPara.Para32[0] = 0;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ EvPara.Para32[0] = 1;
+ EvPara.Para32[1] = -1;
SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
SkEventDispatcher(pAC, pAC->IoBase);
/* disable interrupts */
@@ -671,15 +742,20 @@
pAC->BoardLevel = 0;
/* We do NOT check here, if IRQ was pending, of course*/
}
-
+
if(pAC->BoardLevel == 1) {
/* board is still alive */
SkGeDeInit(pAC, pAC->IoBase);
pAC->BoardLevel = 0;
}
-
+
+ if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
+ unregister_netdev(pAC->dev[1]);
+ kfree(pAC->dev[1]);
+ }
+
FreeResources(root_dev);
-
+
root_dev->get_stats = NULL;
/*
* otherwise unregister_netdev calls get_stats with
@@ -687,9 +763,13 @@
*/
unregister_netdev(root_dev);
kfree(root_dev);
-
+ kfree(pAC);
root_dev = next;
}
+
+ /* clear proc-dir */
+ remove_proc_entry(pSkRootDir->name, proc_net);
+
} /* skge_cleanup_module */
module_init(skge_init_module);
@@ -757,8 +837,6 @@
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- GetConfiguration(pAC);
-
/* level 1 init common modules here (HW init) */
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
if (SkGeInit(pAC, pAC->IoBase, 1) != 0) {
@@ -773,6 +851,12 @@
SkRlmtInit( pAC, pAC->IoBase, 1);
SkTimerInit(pAC, pAC->IoBase, 1);
+ GetConfiguration(pAC);
+ if (pAC->RlmtNets == 2) {
+ pAC->GIni.GIPortUsage = SK_MUL_LINK;
+ }
+
+
pAC->BoardLevel = 1;
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
@@ -801,7 +885,7 @@
SkCsSetReceiveFlags(pAC,
SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
- &pAC->CsOfs1, &pAC->CsOfs2);
+ &pAC->CsOfs1, &pAC->CsOfs2, 0);
pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
BoardInitMem(pAC);
@@ -814,11 +898,13 @@
/* Print configuration settings */
printk(" PrefPort:%c RlmtMode:%s\n",
- 'A' + pAC->Rlmt.PrefPort,
- (pAC->RlmtMode==0) ? "ChkLink" :
- ((pAC->RlmtMode==1) ? "ChkLink" :
- ((pAC->RlmtMode==3) ? "ChkOth" :
- ((pAC->RlmtMode==7) ? "ChkSeg" : "Error"))));
+ 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
+ (pAC->RlmtMode==0) ? "Check Link State" :
+ ((pAC->RlmtMode==1) ? "Check Link State" :
+ ((pAC->RlmtMode==3) ? "Check Local Port" :
+ ((pAC->RlmtMode==7) ? "Check Segmentation" :
+ ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
+
SkGeYellowLED(pAC, pAC->IoBase, 1);
@@ -1103,10 +1189,13 @@
static void SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
{
struct net_device *dev = (struct net_device *)dev_id;
+
+DEV_NET *pNet;
SK_AC *pAC;
SK_U32 IntSrc; /* interrupts source register contents */
- pAC = (SK_AC*) dev->priv;
+ pNet = (DEV_NET*) dev->priv;
+ pAC = pNet->pAC;
/*
* Check and process if its our interrupt
@@ -1129,21 +1218,21 @@
SK_DBGCAT_DRV_INT_SRC,
("EOF RX1 IRQ\n"));
ReceiveIrq(pAC, &pAC->RxPort[0]);
- SK_PNMI_CNT_RX_INTR(pAC);
+ SK_PNMI_CNT_RX_INTR(pAC,0);
}
if (IntSrc & IRQ_EOF_RX2) {
SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
SK_DBGCAT_DRV_INT_SRC,
("EOF RX2 IRQ\n"));
ReceiveIrq(pAC, &pAC->RxPort[1]);
- SK_PNMI_CNT_RX_INTR(pAC);
+ SK_PNMI_CNT_RX_INTR(pAC,1);
}
#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
if (IntSrc & IRQ_EOF_AS_TX1) {
SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
SK_DBGCAT_DRV_INT_SRC,
("EOF AS TX1 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC);
+ SK_PNMI_CNT_TX_INTR(pAC,0);
spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
@@ -1152,7 +1241,7 @@
SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
SK_DBGCAT_DRV_INT_SRC,
("EOF AS TX2 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC);
+ SK_PNMI_CNT_TX_INTR(pAC,1);
spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
@@ -1162,7 +1251,7 @@
SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
SK_DBGCAT_DRV_INT_SRC,
("EOF SY TX1 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC);
+ SK_PNMI_CNT_TX_INTR(pAC,0);
spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
@@ -1172,7 +1261,7 @@
SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
SK_DBGCAT_DRV_INT_SRC,
("EOF SY TX2 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC);
+ SK_PNMI_CNT_TX_INTR(pAC,1);
spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
@@ -1210,8 +1299,12 @@
* came in after handling the ring (OUTs may be delayed
* in hardware buffers, but are through after IN)
*/
- ReceiveIrq(pAC, &pAC->RxPort[pAC->ActivePort]);
-// ReceiveIrq(pAC, &pAC->RxPort[1]);
+ // ReceiveIrq(pAC, &pAC->RxPort[pAC->ActivePort]);
+ ReceiveIrq(pAC, &pAC->RxPort[0]);
+ ReceiveIrq(pAC, &pAC->RxPort[1]);
+
+
+
#if 0
// #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
@@ -1257,10 +1350,12 @@
static void SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
{
struct net_device *dev = (struct net_device *)dev_id;
+DEV_NET *pNet;
SK_AC *pAC;
SK_U32 IntSrc; /* interrupts source register contents */
- pAC = (SK_AC*) dev->priv;
+ pNet = (DEV_NET*) dev->priv;
+ pAC = pNet->pAC;
/*
* Check and process if its our interrupt
@@ -1283,14 +1378,14 @@
SK_DBGCAT_DRV_INT_SRC,
("EOF RX1 IRQ\n"));
ReceiveIrq(pAC, &pAC->RxPort[0]);
- SK_PNMI_CNT_RX_INTR(pAC);
+ SK_PNMI_CNT_RX_INTR(pAC,0);
}
#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
if (IntSrc & IRQ_EOF_AS_TX1) {
SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
SK_DBGCAT_DRV_INT_SRC,
("EOF AS TX1 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC);
+ SK_PNMI_CNT_TX_INTR(pAC,0);
spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
@@ -1300,7 +1395,7 @@
SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
SK_DBGCAT_DRV_INT_SRC,
("EOF SY TX1 IRQ\n"));
- SK_PNMI_CNT_TX_INTR(pAC);
+ SK_PNMI_CNT_TX_INTR(pAC,1);
spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
@@ -1376,12 +1471,14 @@
static int SkGeOpen(
struct net_device *dev)
{
-SK_AC *pAC; /* pointer to adapter context struct */
+DEV_NET *pNet;
+SK_AC *pAC;
unsigned int Flags; /* for spin lock */
int i;
-SK_EVPARA EvPara; /* an event parameter union */
+SK_EVPARA EvPara; /* an event parameter union */
- pAC = (SK_AC*) dev->priv;
+ pNet = (DEV_NET*) dev->priv;
+ pAC = pNet->pAC;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
@@ -1389,7 +1486,7 @@
if (pAC->BoardLevel == 0) {
/* level 1 init common modules here */
if (SkGeInit(pAC, pAC->IoBase, 1) != 0) {
- printk("%s: HWInit(1) failed\n", pAC->dev->name);
+ printk("%s: HWInit(1) failed\n", pAC->dev[pNet->PortNr]->name);
return (-1);
}
SkI2cInit (pAC, pAC->IoBase, 1);
@@ -1400,26 +1497,27 @@
SkTimerInit (pAC, pAC->IoBase, 1);
pAC->BoardLevel = 1;
}
-
- /* level 2 init modules here */
- SkGeInit (pAC, pAC->IoBase, 2);
- SkI2cInit (pAC, pAC->IoBase, 2);
- SkEventInit (pAC, pAC->IoBase, 2);
- SkPnmiInit (pAC, pAC->IoBase, 2);
- SkAddrInit (pAC, pAC->IoBase, 2);
- SkRlmtInit (pAC, pAC->IoBase, 2);
- SkTimerInit (pAC, pAC->IoBase, 2);
- pAC->BoardLevel = 2;
-
+
+ if (pAC->BoardLevel != 2) {
+ /* level 2 init modules here */
+ SkGeInit (pAC, pAC->IoBase, 2);
+ SkI2cInit (pAC, pAC->IoBase, 2);
+ SkEventInit (pAC, pAC->IoBase, 2);
+ SkPnmiInit (pAC, pAC->IoBase, 2);
+ SkAddrInit (pAC, pAC->IoBase, 2);
+ SkRlmtInit (pAC, pAC->IoBase, 2);
+ SkTimerInit (pAC, pAC->IoBase, 2);
+ pAC->BoardLevel = 2;
+ }
for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- // Enable transmit descriptor polling.
+ /* Enable transmit descriptor polling. */
SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
FillRxRing(pAC, &pAC->RxPort[i]);
}
SkGeYellowLED(pAC, pAC->IoBase, 1);
#ifdef USE_INT_MOD
-// moderate only TX complete interrupts (these are not time critical)
+/* moderate only TX complete interrupts (these are not time critical) */
#define IRQ_MOD_MASK (IRQ_EOF_AS_TX1 | IRQ_EOF_AS_TX2)
{
unsigned long ModBase;
@@ -1435,17 +1533,29 @@
SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
- if (pAC->RlmtMode != 0) {
+
+ if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
+ EvPara.Para32[0] = pAC->RlmtNets;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
+ EvPara);
EvPara.Para32[0] = pAC->RlmtMode;
+ EvPara.Para32[1] = 0;
SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
EvPara);
}
+
+ EvPara.Para32[0] = pNet->NetNr;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
SkEventDispatcher(pAC, pAC->IoBase);
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
+
+ pAC->MaxPorts++;
+ pNet->Up = 1;
+
MOD_INC_USE_COUNT;
-
+
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeOpen suceeded\n"));
@@ -1467,48 +1577,84 @@
static int SkGeClose(
struct net_device *dev)
{
+DEV_NET *pNet;
SK_AC *pAC;
+
unsigned int Flags; /* for spin lock */
-int i;
-SK_EVPARA EvPara;
+int i;
+int PortIdx;
+SK_EVPARA EvPara;
netif_stop_queue(dev);
- pAC = (SK_AC*) dev->priv;
-
+ pNet = (DEV_NET*) dev->priv;
+ pAC = pNet->pAC;
+
+ if (pAC->RlmtNets == 1)
+ PortIdx = pAC->ActivePort;
+ else
+ PortIdx = pNet->NetNr;
+
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
/*
* Clear multicast table, promiscuous mode ....
*/
- SkAddrMcClear(pAC, pAC->IoBase, pAC->ActivePort, 0);
- SkAddrPromiscuousChange(pAC, pAC->IoBase, pAC->ActivePort,
+
+ SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
+ SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
SK_PROM_MODE_NONE);
+ if (pAC->MaxPorts == 1) {
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ /* disable interrupts */
+ SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+ EvPara.Para32[0] = pNet->NetNr;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ SkEventDispatcher(pAC, pAC->IoBase);
+ SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+ /* stop the hardware */
+ SkGeDeInit(pAC, pAC->IoBase);
+ pAC->BoardLevel = 0;
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+ } else {
- spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- /* disable interrupts */
- SK_OUT32(pAC->IoBase, B0_IMSK, 0);
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
- SkEventDispatcher(pAC, pAC->IoBase);
- SK_OUT32(pAC->IoBase, B0_IMSK, 0);
- /* stop the hardware */
- SkGeDeInit(pAC, pAC->IoBase);
- pAC->BoardLevel = 0;
-
- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-
- for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ EvPara.Para32[0] = pNet->NetNr;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ SkEventDispatcher(pAC, pAC->IoBase);
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+ /* Stop port */
+ spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
+ [TX_PRIO_LOW].TxDesRingLock, Flags);
+ SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
+ SK_STOP_ALL, SK_HARD_RST);
+ spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
+ [TX_PRIO_LOW].TxDesRingLock, Flags);
+ }
+ if (pAC->RlmtNets == 1) {
/* clear all descriptor rings */
- ReceiveIrq(pAC, &pAC->RxPort[i]);
- ClearRxRing(pAC, &pAC->RxPort[i]);
- ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ ReceiveIrq(pAC, &pAC->RxPort[i]);
+ ClearRxRing(pAC, &pAC->RxPort[i]);
+ ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
+ }
+ } else {
+ /* clear port descriptor rings */
+ ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr]);
+ ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
+ ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
}
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeClose: done "));
+ pAC->MaxPorts--;
+ pNet->Up = 0;
MOD_DEC_USE_COUNT;
return (0);
@@ -1531,12 +1677,17 @@
*/
static int SkGeXmit(struct sk_buff *skb, struct net_device *dev)
{
+DEV_NET *pNet;
SK_AC *pAC;
-int Rc; /* return code of XmitFrame */
+int Rc; /* return code of XmitFrame */
- pAC = (SK_AC*) dev->priv;
+ pNet = (DEV_NET*) dev->priv;
+ pAC = pNet->pAC;
- Rc = XmitFrame(pAC, &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], skb);
+ if (pAC->RlmtNets == 2)
+ Rc = XmitFrame(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW], skb);
+ else
+ Rc = XmitFrame(pAC, &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], skb);
/* Transmitter out of resources? */
if (Rc <= 0)
@@ -1551,7 +1702,7 @@
dev->trans_start = jiffies;
return (0);
} /* SkGeXmit */
-
+
/*****************************************************************************
*
@@ -1570,10 +1721,10 @@
* if necessary.
*
* Returns:
- * > 0 - on succes: the number of bytes in the message
- * = 0 - on resource shortage: this frame sent or dropped, now
+ * > 0 - on succes: the number of bytes in the message
+ * = 0 - on resource shortage: this frame sent or dropped, now
* the ring is full ( -> set tbusy)
- * < 0 - on failure: other problems ( -> return failure to upper layers)
+ * < 0 - on failure: other problems ( -> return failure to upper layers)
*/
static int XmitFrame(
SK_AC *pAC, /* pointer to adapter context */
@@ -1595,7 +1746,7 @@
FreeTxDescriptors(pAC, pTxPort);
if (pTxPort->TxdRingFree == 0) {
spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
- SK_PNMI_CNT_NO_TX_BUF(pAC);
+ SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
SK_DBGCAT_DRV_TX_PROGRESS,
("XmitFrame failed\n"));
@@ -1699,13 +1850,13 @@
* freed ( -> ring completely free now).
*/
pTxPort->pTxdRingTail = pTxd;
- netif_start_queue(pAC->dev);
+ netif_start_queue(pAC->dev[pTxPort->PortIndex]);
return;
}
if (Control & TX_CTRL_OWN_BMU) {
pTxPort->pTxdRingTail = pTxd;
if (pTxPort->TxdRingFree > 0) {
- netif_start_queue(pAC->dev);
+ netif_start_queue(pAC->dev[pTxPort->PortIndex]);
}
return;
}
@@ -1784,8 +1935,8 @@
SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
SK_DBGCAT_DRV_ENTRY,
("%s: Allocation of rx buffer failed !\n",
- pAC->dev->name));
- SK_PNMI_CNT_NO_RX_BUF(pAC);
+ pAC->dev[pRxPort->PortIndex]->name));
+ SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
return(SK_FALSE);
}
skb_reserve(pMsgBlock, 2); /* to align IP frames */
@@ -1877,64 +2028,110 @@
int Result;
SK_U64 PhysAddr;
-
rx_start:
/* do forever; exit if RX_CTRL_OWN_BMU found */
- while (pRxPort->RxdRingFree < pAC->RxDescrPerRing) {
- pRxd = pRxPort->pRxdRingHead;
-
+ for ( pRxd = pRxPort->pRxdRingHead ;
+ pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
+ pRxd = pRxd->pNextRxd,
+ pRxPort->pRxdRingHead = pRxd,
+ pRxPort->RxdRingFree ++) {
+
+ /*
+ * For a better understanding of this loop
+ * Go through every descriptor beginning at the head
+ * Please note: the ring might be completely received so the OWN bit
+ * set is not a good crirteria to leave that loop.
+ * Therefore the RingFree counter is used.
+ * On entry of this loop pRxd is a pointer to the Rxd that needs
+ * to be checked next.
+ */
+
Control = pRxd->RBControl;
-
+
/* check if this descriptor is ready */
if ((Control & RX_CTRL_OWN_BMU) != 0) {
/* this descriptor is not yet ready */
+ /* This is the usual end of the loop */
+ /* We don't need to start the ring again */
FillRxRing(pAC, pRxPort);
return;
}
-
+
/* get length of frame and check it */
FrameLength = Control & RX_CTRL_LEN_MASK;
- if (FrameLength > pAC->RxBufSize)
+ if (FrameLength > pAC->RxBufSize) {
goto rx_failed;
+ }
/* check for STF and EOF */
if ((Control & (RX_CTRL_STF | RX_CTRL_EOF)) !=
- (RX_CTRL_STF | RX_CTRL_EOF))
+ (RX_CTRL_STF | RX_CTRL_EOF)) {
goto rx_failed;
+ }
/* here we have a complete frame in the ring */
pMsg = pRxd->pMBuf;
+
+ FrameStat = pRxd->FrameStat;
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
+ ("Received frame of length %d on port %d\n",
+ FrameLength, PortIndex));
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
+ ("Number of free rx descriptors: %d\n",
+ pRxPort->RxdRingFree));
+ /*DumpMsg(pMsg, "Rx"); */
+ if ((Control & RX_CTRL_STAT_VALID) != RX_CTRL_STAT_VALID ||
+ (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
+ /* there is a receive error in this frame */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_RX_PROGRESS,
+ ("skge: Error in received frame, dropped!\n"
+ "Control: %x\nRxStat: %x\n",
+ Control, FrameStat));
+ PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+ PhysAddr |= (SK_U64) pRxd->VDataLow;
+ pci_dma_sync_single(&pAC->PciDev,
+ (dma_addr_t) PhysAddr,
+ FrameLength,
+ PCI_DMA_FROMDEVICE);
+ ReQueueRxBuffer(pAC, pRxPort, pMsg,
+ pRxd->VDataHigh, pRxd->VDataLow);
+
+ continue;
+ }
+
/*
* if short frame then copy data to reduce memory waste
*/
- pNewMsg = NULL;
- if (FrameLength < SK_COPY_THRESHOLD) {
- pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC);
- if (pNewMsg != NULL) {
- PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
- PhysAddr |= (SK_U64) pRxd->VDataLow;
-
- /* use new skb and copy data */
- skb_reserve(pNewMsg, 2);
- skb_put(pNewMsg, FrameLength);
- pci_dma_sync_single(&pAC->PciDev,
- (dma_addr_t) PhysAddr,
- FrameLength,
- PCI_DMA_FROMDEVICE);
- eth_copy_and_sum(pNewMsg, pMsg->data,
- FrameLength, 0);
- ReQueueRxBuffer(pAC, pRxPort, pMsg,
- pRxd->VDataHigh, pRxd->VDataLow);
- pMsg = pNewMsg;
- }
+ if ((FrameLength < SK_COPY_THRESHOLD) &&
+ ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
+ /*
+ * Short frame detected and allocation successfull
+ */
+ PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+ PhysAddr |= (SK_U64) pRxd->VDataLow;
+
+ /* use new skb and copy data */
+ skb_reserve(pNewMsg, 2);
+ skb_put(pNewMsg, FrameLength);
+ pci_dma_sync_single(&pAC->PciDev,
+ (dma_addr_t) PhysAddr,
+ FrameLength,
+ PCI_DMA_FROMDEVICE);
+ eth_copy_and_sum(pNewMsg, pMsg->data,
+ FrameLength, 0);
+ ReQueueRxBuffer(pAC, pRxPort, pMsg,
+ pRxd->VDataHigh, pRxd->VDataLow);
+ pMsg = pNewMsg;
+
}
+ else {
+ /*
+ * if large frame, or SKB allocation failed, pass
+ * the SKB directly to the networking
+ */
- /*
- * if large frame, or SKB allocation failed, pass
- * the SKB directly to the networking
- */
- if (pNewMsg == NULL) {
PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
PhysAddr |= (SK_U64) pRxd->VDataLow;
@@ -1954,7 +2151,7 @@
if ((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) {
Result = SkCsGetReceiveInfo(pAC,
&pMsg->data[14],
- Csum1, Csum2);
+ Csum1, Csum2, pRxPort->PortIndex);
if (Result ==
SKCS_STATUS_IP_FRAGMENT ||
Result ==
@@ -1970,123 +2167,85 @@
} /* IP frame */
} /* frame > SK_COPY_TRESHOLD */
- FrameStat = pRxd->FrameStat;
- if ((FrameStat & XMR_FS_LNG_ERR) != 0) {
- /* jumbo frame, count to correct statistic */
- SK_PNMI_CNT_RX_LONGFRAMES(pAC, pRxPort->PortIndex);
- }
- pRxd = pRxd->pNextRxd;
- pRxPort->pRxdRingHead = pRxd;
- pRxPort->RxdRingFree ++;
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
- ("Received frame of length %d on port %d\n",
- FrameLength, PortIndex));
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS,
- ("Number of free rx descriptors: %d\n",
- pRxPort->RxdRingFree));
-
- if ((Control & RX_CTRL_STAT_VALID) == RX_CTRL_STAT_VALID &&
- (FrameStat & XMR_FS_ANY_ERR) == 0) {
- // was the following, changed to allow VLAN support
- // (XMR_FS_ANY_ERR | XMR_FS_1L_VLAN | XMR_FS_2L_VLAN)
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS,("V"));
- ForRlmt = SK_RLMT_RX_PROTOCOL;
- IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
- SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
- IsBc, &Offset, &NumBytes);
- if (NumBytes != 0) {
- IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
- SK_RLMT_LOOKAHEAD(pAC, PortIndex,
- &pMsg->data[Offset],
- IsBc, IsMc, &ForRlmt);
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
+ ForRlmt = SK_RLMT_RX_PROTOCOL;
+ IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
+ SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
+ IsBc, &Offset, &NumBytes);
+ if (NumBytes != 0) {
+ IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
+ SK_RLMT_LOOKAHEAD(pAC, PortIndex,
+ &pMsg->data[Offset],
+ IsBc, IsMc, &ForRlmt);
+ }
+ if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
+ /* send up only frames from active port */
+ if ((PortIndex == pAC->ActivePort) ||
+ (pAC->RlmtNets == 2)) {
+ /* frame for upper layer */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
+#ifdef xDEBUG
+ DumpMsg(pMsg, "Rx");
+#endif
+ SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
+ FrameLength, pRxPort->PortIndex);
+
+ pMsg->dev = pAC->dev[pRxPort->PortIndex];
+ pMsg->protocol = eth_type_trans(pMsg,
+ pAC->dev[pRxPort->PortIndex]);
+ netif_rx(pMsg);
+ pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
}
- if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
- /* send up only frames from active port */
- if (PortIndex == pAC->ActivePort) {
- /* frame for upper layer */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS,
- ("U"));
-#ifdef DUMP_RX
- DumpMsg(pMsg, "Rx");
-#endif
- pMsg->dev = pAC->dev;
- pMsg->protocol = eth_type_trans(pMsg,
- pAC->dev);
- SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
- FrameLength);
- netif_rx(pMsg);
- pAC->dev->last_rx = jiffies;
- }
- else {
- /* drop frame */
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS,
- ("D"));
- DEV_KFREE_SKB_IRQ(pMsg);
- }
- } /* if not for rlmt */
else {
- /* packet for rlmt */
+ /* drop frame */
SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
- pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
- pAC->IoBase, FrameLength);
- if (pRlmtMbuf != NULL) {
- pRlmtMbuf->pNext = NULL;
- pRlmtMbuf->Length = FrameLength;
- pRlmtMbuf->PortIdx = PortIndex;
- EvPara.pParaPtr = pRlmtMbuf;
- memcpy((char*)(pRlmtMbuf->pData),
- (char*)(pMsg->data),
- FrameLength);
- SkEventQueue(pAC, SKGE_RLMT,
- SK_RLMT_PACKET_RECEIVED,
- EvPara);
- pAC->CheckQueue = SK_TRUE;
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS,
- ("Q"));
- }
- if ((pAC->dev->flags &
- (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
- (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
- SK_RLMT_RX_PROTOCOL) {
- pMsg->dev = pAC->dev;
- pMsg->protocol = eth_type_trans(pMsg,
- pAC->dev);
- netif_rx(pMsg);
- pAC->dev->last_rx = jiffies;
- }
- else {
- DEV_KFREE_SKB_IRQ(pMsg);
- }
-
- } /* if packet for rlmt */
- } /* if valid frame */
+ SK_DBGCAT_DRV_RX_PROGRESS,
+ ("D"));
+ DEV_KFREE_SKB(pMsg);
+ }
+
+ } /* if not for rlmt */
else {
- /* there is a receive error in this frame */
- if ((FrameStat & XMR_FS_1L_VLAN) != 0) {
- printk("%s: Received frame"
- " with VLAN Level 1 header, check"
- " switch configuration\n",
- pAC->dev->name);
+ /* packet for rlmt */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
+ pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
+ pAC->IoBase, FrameLength);
+ if (pRlmtMbuf != NULL) {
+ pRlmtMbuf->pNext = NULL;
+ pRlmtMbuf->Length = FrameLength;
+ pRlmtMbuf->PortIdx = PortIndex;
+ EvPara.pParaPtr = pRlmtMbuf;
+ memcpy((char*)(pRlmtMbuf->pData),
+ (char*)(pMsg->data),
+ FrameLength);
+ SkEventQueue(pAC, SKGE_RLMT,
+ SK_RLMT_PACKET_RECEIVED,
+ EvPara);
+ pAC->CheckQueue = SK_TRUE;
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_RX_PROGRESS,
+ ("Q"));
}
- if ((FrameStat & XMR_FS_2L_VLAN) != 0) {
- printk("%s: Received frame"
- " with VLAN Level 2 header, check"
- " switch configuration\n",
- pAC->dev->name);
+ if ((pAC->dev[pRxPort->PortIndex]->flags &
+ (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
+ (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
+ SK_RLMT_RX_PROTOCOL) {
+ pMsg->dev = pAC->dev[pRxPort->PortIndex];
+ pMsg->protocol = eth_type_trans(pMsg,
+ pAC->dev[pRxPort->PortIndex]);
+ netif_rx(pMsg);
+ pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
}
- SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
- SK_DBGCAT_DRV_RX_PROGRESS,
- ("skge: Error in received frame, dropped!\n"
- "Control: %x\nRxStat: %x\n",
- Control, FrameStat));
- DEV_KFREE_SKB_IRQ(pMsg);
- }
- } /* while */
+ else {
+ DEV_KFREE_SKB(pMsg);
+ }
+
+ } /* if packet for rlmt */
+ } /* for ... scanning the RXD ring */
+
+ /* RXD ring is empty -> fill and restart */
FillRxRing(pAC, pRxPort);
/* do not start if called from Close */
if (pAC->BoardLevel > 0) {
@@ -2254,6 +2413,7 @@
int RxRam; /* RAM used for the active port receive queue */
int i; /* loop counter */
+if (pAC->RlmtNets == 1) {
StandbyRam = SK_RLMT_STANDBY_QRXSIZE + SK_RLMT_STANDBY_QXASIZE +
SK_RLMT_STANDBY_QXSSIZE;
RemainingRam = pAC->GIni.GIRamSize -
@@ -2274,21 +2434,40 @@
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("queue sizes settings - rx:%d txA:%d txS:%d\n",
pAC->RxQueueSize,pAC->TxAQueueSize, pAC->TxSQueueSize));
+} else {
+ RemainingRam = pAC->GIni.GIRamSize/pAC->GIni.GIMacsFound;
+ RxRam = (RemainingRam * 8 / 10) & ~7;
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ pAC->GIni.GP[i].PRxQSize = RxRam;
+ pAC->GIni.GP[i].PXSQSize = 0;
+ pAC->GIni.GP[i].PXAQSize = (RemainingRam - RxRam) & ~7;
+ }
+ pAC->RxQueueSize = RxRam;
+ pAC->TxSQueueSize = 0;
+ pAC->TxAQueueSize = (RemainingRam - RxRam) & ~7;
+}
for (i=0; i<SK_MAX_MACS; i++) {
pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing;
}
- for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
+
+ if (pAC->RlmtNets == 2) {
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
+ }
+ } else {
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - 100;
+ }
+ /*
+ * Do not set the Limit to 0, because this could cause
+ * wrap around with ReQueue'ed buffers (a buffer could
+ * be requeued in the same position, made accessable to
+ * the hardware, and the hardware could change its
+ * contents!
+ */
+ pAC->RxPort[pAC->ActivePort].RxFillLimit = 1;
}
- /*
- * Do not set the Limit to 0, because this could cause
- * wrap around with ReQueue'ed buffers (a buffer could
- * be requeued in the same position, made accessable to
- * the hardware, and the hardware could change its
- * contents!
- */
- pAC->RxPort[pAC->ActivePort].RxFillLimit = 1;
#ifdef DEBUG
for (i=0; i<pAC->GIni.GIMacsFound; i++) {
@@ -2316,7 +2495,10 @@
*/
static int SkGeSetMacAddr(struct net_device *dev, void *p)
{
-SK_AC *pAC = (SK_AC*) dev->priv;
+
+DEV_NET *pNet = (DEV_NET*) dev->priv;
+SK_AC *pAC = pNet->pAC;
+
struct sockaddr *addr = p;
unsigned int Flags;
@@ -2328,8 +2510,15 @@
memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
- (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+
+ if (pAC->RlmtNets == 2)
+ SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
+ (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+ else
+ SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
+ (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+
+
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
return 0;
@@ -2352,37 +2541,47 @@
*/
static void SkGeSetRxMode(struct net_device *dev)
{
-SK_AC *pAC;
+
+DEV_NET *pNet;
+SK_AC *pAC;
+
struct dev_mc_list *pMcList;
int i;
+int PortIdx;
unsigned int Flags;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeSetRxMode starts now... "));
- pAC = (SK_AC*) dev->priv;
-
+
+ pNet = (DEV_NET*) dev->priv;
+ pAC = pNet->pAC;
+ if (pAC->RlmtNets == 1)
+ PortIdx = pAC->ActivePort;
+ else
+ PortIdx = pNet->NetNr;
+
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
if (dev->flags & IFF_PROMISC) {
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("PROMISCUOUS mode\n"));
- SkAddrPromiscuousChange(pAC, pAC->IoBase, pAC->ActivePort,
+ SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
SK_PROM_MODE_LLC);
} else if (dev->flags & IFF_ALLMULTI) {
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("ALLMULTI mode\n"));
- SkAddrPromiscuousChange(pAC, pAC->IoBase, pAC->ActivePort,
+ SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
SK_PROM_MODE_ALL_MC);
} else {
- SkAddrPromiscuousChange(pAC, pAC->IoBase, pAC->ActivePort,
+ SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
SK_PROM_MODE_NONE);
- SkAddrMcClear(pAC, pAC->IoBase, pAC->ActivePort, 0);
+ SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("Number of MC entries: %d ", dev->mc_count));
pMcList = dev->mc_list;
for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
- SkAddrMcAdd(pAC, pAC->IoBase, pAC->ActivePort,
+ SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
(SK_MAC_ADDR*)pMcList->dmi_addr, 0);
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
("%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -2393,7 +2592,7 @@
pMcList->dmi_addr[4],
pMcList->dmi_addr[5]));
}
- SkAddrMcUpdate(pAC, pAC->IoBase, pAC->ActivePort);
+ SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
}
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
@@ -2417,6 +2616,8 @@
*/
static int SkGeChangeMtu(struct net_device *dev, int NewMtu)
{
+DEV_NET *pNet;
+DEV_NET *pOtherNet;
SK_AC *pAC;
unsigned int Flags;
int i;
@@ -2424,30 +2625,58 @@
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeChangeMtu starts now...\n"));
-
- pAC = (SK_AC*) dev->priv;
+
+ pNet = (DEV_NET*) dev->priv;
+ pAC = pNet->pAC;
+
if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
return -EINVAL;
}
+ pNet->Mtu = NewMtu;
+ pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
+ if ((pOtherNet->Mtu > 1500) && (NewMtu <= 1500) && (pOtherNet->Up==1)) {
+ return(0);
+ }
+
+ EvPara.Para32[0] = pNet->NetNr;
+ EvPara.Para32[1] = -1;
+
pAC->RxBufSize = NewMtu + 32;
dev->mtu = NewMtu;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("New MTU: %d\n", NewMtu));
+ if(pAC->BoardLevel != 2) {
+ return 0;
+ }
+
/* prevent reconfiguration while changing the MTU */
/* disable interrupts */
SK_OUT32(pAC->IoBase, B0_IMSK, 0);
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+
+ /* Found more than one port */
+ if ((pAC->GIni.GIMacsFound == 2 ) &&
+ (pAC->RlmtNets == 2)) {
+ /* Stop both ports */
+ EvPara.Para32[0] = 0;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ EvPara.Para32[0] = 1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ } else {
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ }
+
SkEventDispatcher(pAC, pAC->IoBase);
for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
+ spin_lock_irqsave(
+ &pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags);
+ netif_stop_queue(pAC->dev[i]);
}
- netif_stop_queue(pAC->dev);
/*
* adjust number of rx buffers allocated
@@ -2455,23 +2684,35 @@
if (NewMtu > 1500) {
/* use less rx buffers */
for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- if (i == pAC->ActivePort)
- pAC->RxPort[i].RxFillLimit =
- pAC->RxDescrPerRing - 100;
- else
- pAC->RxPort[i].RxFillLimit =
- pAC->RxDescrPerRing - 10;
-
+ /* Found more than one port */
+ if ((pAC->GIni.GIMacsFound == 2 ) &&
+ (pAC->RlmtNets == 2)) {
+ pAC->RxPort[i].RxFillLimit =
+ pAC->RxDescrPerRing - 100;
+ } else {
+ if (i == pAC->ActivePort)
+ pAC->RxPort[i].RxFillLimit =
+ pAC->RxDescrPerRing - 100;
+ else
+ pAC->RxPort[i].RxFillLimit =
+ pAC->RxDescrPerRing - 10;
+ }
}
}
else {
/* use normal anoumt of rx buffers */
for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- if (i == pAC->ActivePort)
- pAC->RxPort[i].RxFillLimit = 1;
- else
- pAC->RxPort[i].RxFillLimit =
- pAC->RxDescrPerRing - 100;
+ /* Found more than one port */
+ if ((pAC->GIni.GIMacsFound == 2 ) &&
+ (pAC->RlmtNets == 2)) {
+ pAC->RxPort[i].RxFillLimit = 1;
+ } else {
+ if (i == pAC->ActivePort)
+ pAC->RxPort[i].RxFillLimit = 1;
+ else
+ pAC->RxPort[i].RxFillLimit =
+ pAC->RxDescrPerRing - 100;
+ }
}
}
@@ -2481,6 +2722,7 @@
* enable/disable hardware support for long frames
*/
if (NewMtu > 1500) {
+// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
for (i=0; i<pAC->GIni.GIMacsFound; i++) {
pAC->GIni.GP[i].PRxCmd =
@@ -2488,10 +2730,14 @@
}
}
else {
- pAC->GIni.GIPortUsage = SK_RED_LINK;
+ if ((pAC->GIni.GIMacsFound == 2 ) &&
+ (pAC->RlmtNets == 2)) {
+ pAC->GIni.GIPortUsage = SK_MUL_LINK;
+ } else {
+ pAC->GIni.GIPortUsage = SK_RED_LINK;
+ }
for (i=0; i<pAC->GIni.GIMacsFound; i++) {
- pAC->GIni.GP[i].PRxCmd =
- XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
+ pAC->GIni.GP[i].PRxCmd = XM_RX_STRIP_FCS;
}
}
@@ -2519,7 +2765,7 @@
ClearRxRing(pAC, &pAC->RxPort[i]);
FillRxRing(pAC, &pAC->RxPort[i]);
- // Enable transmit descriptor polling.
+ /* Enable transmit descriptor polling. */
SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
FillRxRing(pAC, &pAC->RxPort[i]);
};
@@ -2536,7 +2782,7 @@
}
#endif
- netif_start_queue(pAC->dev);
+ netif_start_queue(pAC->dev[pNet->PortNr]);
for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
}
@@ -2548,7 +2794,30 @@
SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
SkEventDispatcher(pAC, pAC->IoBase);
+ /* Found more than one port */
+ if ((pAC->GIni.GIMacsFound == 2 ) &&
+ (pAC->RlmtNets == 2)) {
+ /* Start both ports */
+ EvPara.Para32[0] = pAC->RlmtNets;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
+ EvPara);
+
+
+ EvPara.Para32[1] = -1;
+ EvPara.Para32[0] = pNet->PortNr;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+
+ if (pOtherNet->Up) {
+ EvPara.Para32[0] = pOtherNet->PortNr;
+ SkEventQueue(pAC, SKGE_RLMT,
+ SK_RLMT_START, EvPara);
+ }
+ } else {
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+ }
+ SkEventDispatcher(pAC, pAC->IoBase);
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
return 0;
@@ -2568,7 +2837,8 @@
*/
static struct net_device_stats *SkGeStats(struct net_device *dev)
{
-SK_AC *pAC = (SK_AC*) dev->priv;
+DEV_NET *pNet = (DEV_NET*) dev->priv;
+SK_AC *pAC = pNet->pAC;
SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */
SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */
unsigned int Size; /* size of pnmi struct */
@@ -2580,7 +2850,7 @@
memset(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
Size = SK_PNMI_STRUCT_SIZE;
- SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size);
+ SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
pPnmiStat = &pPnmiStruct->Stat[0];
pPnmiConf = &pPnmiStruct->Conf[0];
@@ -2622,7 +2892,7 @@
* Description:
* This function is called if an ioctl is issued on the device.
* There are three subfunction for reading, writing and test-writing
- * the private MIB data structure (useful for SysKonnect-internal tools).
+ * the private MIB data structure (usefull for SysKonnect-internal tools).
*
* Returns:
* 0, if everything is ok
@@ -2630,14 +2900,18 @@
*/
static int SkGeIoctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
+DEV_NET *pNet;
SK_AC *pAC;
+
SK_GE_IOCTL Ioctl;
unsigned int Err = 0;
int Size;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeIoctl starts now...\n"));
- pAC = (SK_AC*) dev->priv;
+
+ pNet = (DEV_NET*) dev->priv;
+ pAC = pNet->pAC;
if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
return -EFAULT;
@@ -2653,7 +2927,7 @@
Ioctl.Len : sizeof(pAC->PnmiStruct))) {
return -EFAULT;
}
- Size = SkGeIocMib(pAC, Ioctl.Len, cmd);
+ Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
Ioctl.Len<Size? Ioctl.Len : Size)) {
return -EFAULT;
@@ -2688,25 +2962,30 @@
* returned size from PNMI call
*/
static int SkGeIocMib(
-SK_AC *pAC, /* pointer to the adapter context */
+DEV_NET *pNet, /* pointer to the adapter context */
unsigned int Size, /* length of ioctl data */
int mode) /* flag for set/preset */
{
unsigned int Flags; /* for spin lock */
-
+SK_AC *pAC;
+
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeIocMib starts now...\n"));
+ pAC = pNet->pAC;
/* access MIB */
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
switch(mode) {
case SK_IOCTL_GETMIB:
- SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size);
+ SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+ pNet->NetNr);
break;
case SK_IOCTL_PRESETMIB:
- SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size);
+ SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+ pNet->NetNr);
break;
case SK_IOCTL_SETMIB:
- SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size);
+ SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+ pNet->NetNr);
break;
default:
break;
@@ -2780,7 +3059,7 @@
AutoNeg = AN_SENS;
}
else printk("%s: Illegal value for AutoNeg_A\n",
- pAC->dev->name);
+ pAC->dev[0]->name);
}
DuplexCap = DC_BOTH;
@@ -2801,18 +3080,18 @@
DuplexCap = DC_HALF;
}
else printk("%s: Illegal value for DupCap_A\n",
- pAC->dev->name);
+ pAC->dev[0]->name);
}
/* check for illegal combinations */
if (AutoSet && AutoNeg==AN_SENS && DupSet) {
printk("%s, Port A: DuplexCapabilities"
- " ignored using Sense mode\n", pAC->dev->name);
+ " ignored using Sense mode\n", pAC->dev[0]->name);
}
if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
printk("%s, Port A: Illegal combination"
" of values AutoNeg. and DuplexCap.\n Using "
- "Full Duplex\n", pAC->dev->name);
+ "Full Duplex\n", pAC->dev[0]->name);
DuplexCap = DC_FULL;
}
@@ -2824,7 +3103,7 @@
printk("%s, Port A: Duplex setting not"
" possible in\n default AutoNegotiation mode"
" (Sense).\n Using AutoNegotiation On\n",
- pAC->dev->name);
+ pAC->dev[0]->name);
AutoNeg = AN_ON;
}
@@ -2859,7 +3138,7 @@
SK_FLOW_MODE_NONE) {
printk("%s, Port A: FlowControl"
" impossible without AutoNegotiation,"
- " disabled\n", pAC->dev->name);
+ " disabled\n", pAC->dev[0]->name);
pAC->GIni.GP[0].PFlowCtrlMode = SK_FLOW_MODE_NONE;
}
@@ -2878,7 +3157,7 @@
MSMode = SK_MS_MODE_SLAVE;
}
else printk("%s: Illegal value for Role_A\n",
- pAC->dev->name);
+ pAC->dev[0]->name);
}
pAC->GIni.GP[0].PMSMode = MSMode;
@@ -2927,12 +3206,12 @@
/* check for illegal combinations */
if (AutoSet && AutoNeg==AN_SENS && DupSet) {
printk("%s, Port B: DuplexCapabilities"
- " ignored using Sense mode\n", pAC->dev->name);
+ " ignored using Sense mode\n", pAC->dev[1]->name);
}
if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
printk("%s, Port B: Illegal combination"
" of values AutoNeg. and DuplexCap.\n Using "
- "Full Duplex\n", pAC->dev->name);
+ "Full Duplex\n", pAC->dev[1]->name);
DuplexCap = DC_FULL;
}
@@ -2944,14 +3223,14 @@
printk("%s, Port B: Duplex setting not"
" possible in\n default AutoNegotiation mode"
" (Sense).\n Using AutoNegotiation On\n",
- pAC->dev->name);
+ pAC->dev[1]->name);
AutoNeg = AN_ON;
}
-
+
/* set the desired mode */
pAC->GIni.GP[1].PLinkModeConf =
Capabilities[AutoNeg][DuplexCap];
-
+
pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
FlowCtrl_B[pAC->Index] != NULL) {
@@ -2979,7 +3258,7 @@
SK_FLOW_MODE_NONE) {
printk("%s, Port B: FlowControl"
" impossible without AutoNegotiation,"
- " disabled\n", pAC->dev->name);
+ " disabled\n", pAC->dev[1]->name);
pAC->GIni.GP[1].PFlowCtrlMode = SK_FLOW_MODE_NONE;
}
@@ -2998,7 +3277,7 @@
MSMode = SK_MS_MODE_SLAVE;
}
else printk("%s: Illegal value for Role_B\n",
- pAC->dev->name);
+ pAC->dev[1]->name);
}
pAC->GIni.GP[1].PMSMode = MSMode;
@@ -3009,8 +3288,8 @@
PrefPort[pAC->Index] != NULL) {
if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
pAC->ActivePort = 0;
- pAC->Rlmt.MacPreferred = -1; /* auto */
- pAC->Rlmt.PrefPort = 0;
+ pAC->Rlmt.Net[0].Preference = -1; /* auto */
+ pAC->Rlmt.Net[0].PrefPort = 0;
}
else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
/*
@@ -3018,8 +3297,8 @@
* switch is issued after net up.
*/
Port = 0;
- pAC->Rlmt.MacPreferred = Port;
- pAC->Rlmt.PrefPort = Port;
+ pAC->Rlmt.Net[0].Preference = Port;
+ pAC->Rlmt.Net[0].PrefPort = Port;
}
else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
/*
@@ -3027,12 +3306,14 @@
* switch is issued after net up.
*/
Port = 1;
- pAC->Rlmt.MacPreferred = Port;
- pAC->Rlmt.PrefPort = Port;
+ pAC->Rlmt.Net[0].Preference = Port;
+ pAC->Rlmt.Net[0].PrefPort = Port;
}
else printk("%s: Illegal value for PrefPort\n",
- pAC->dev->name);
+ pAC->dev[0]->name);
}
+
+ pAC->RlmtNets = 1;
if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
RlmtMode[pAC->Index] != NULL) {
@@ -3051,9 +3332,18 @@
SK_RLMT_CHECK_LOC_LINK |
SK_RLMT_CHECK_SEG;
}
+ else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
+ (pAC->GIni.GIMacsFound == 2)) {
+ pAC->RlmtMode = SK_RLMT_CHECK_LINK;
+ pAC->RlmtNets = 2;
+ }
else {
printk("%s: Illegal value for"
- " RlmtMode, using default\n", pAC->dev->name);
+ " RlmtMode, using default\n", pAC->dev[0]->name);
+
+printk("MacFound = %d\nRlmtMode = %s", pAC->GIni.GIMacsFound, RlmtMode[pAC->Index]);
+
+
pAC->RlmtMode = 0;
}
}
@@ -3355,7 +3645,7 @@
case SK_DRV_ADAP_FAIL:
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
("ADAPTER FAIL EVENT\n"));
- printk("%s: Adapter failed.\n", pAC->dev->name);
+ printk("%s: Adapter failed.\n", pAC->dev[0]->name);
/* disable interrupts */
SK_OUT32(pAC->IoBase, B0_IMSK, 0);
/* cgoos */
@@ -3365,9 +3655,9 @@
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
("PORT FAIL EVENT, Port: %d\n", FromPort));
if (FromPort == 0) {
- printk("%s: Port A failed.\n", pAC->dev->name);
+ printk("%s: Port A failed.\n", pAC->dev[0]->name);
} else {
- printk("%s: Port B failed.\n", pAC->dev->name);
+ printk("%s: Port B failed.\n", pAC->dev[1]->name);
}
/* cgoos */
break;
@@ -3408,7 +3698,7 @@
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
("NET UP EVENT, Port: %d ", Param.Para32[0]));
printk("%s: network connection up using"
- " port %c\n", pAC->dev->name, 'A'+Param.Para32[0]);
+ " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
printk(" speed: 1000\n");
Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
if (Stat == SK_LMODE_STAT_AUTOHALF ||
@@ -3451,7 +3741,8 @@
}
}
- if (Param.Para32[0] != pAC->ActivePort) {
+ if ((Param.Para32[0] != pAC->ActivePort) &&
+ (pAC->RlmtNets == 1)) {
NewPara.Para32[0] = pAC->ActivePort;
NewPara.Para32[1] = Param.Para32[0];
SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
@@ -3462,21 +3753,21 @@
/* action list 7 */
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
("NET DOWN EVENT "));
- printk("%s: network connection down\n", pAC->dev->name);
+ printk("%s: network connection down\n", pAC->dev[Param.Para32[1]]->name);
break;
case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
("PORT SWITCH HARD "));
case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
/* action list 6 */
- printk("%s: switching to port %c\n", pAC->dev->name,
+ printk("%s: switching to port %c\n", pAC->dev[0]->name,
'A'+Param.Para32[1]);
case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
FromPort = Param.Para32[0];
ToPort = Param.Para32[1];
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
("PORT SWITCH EVENT, From: %d To: %d (Pref %d) ",
- FromPort, ToPort, pAC->Rlmt.PrefPort));
+ FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
NewPara.Para64 = FromPort;
SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
NewPara.Para64 = ToPort;
@@ -3591,7 +3882,7 @@
break;
}
printk(KERN_INFO "%s: -- ERROR --\n Class: %s\n"
- " Nr: 0x%x\n Msg: %s\n", pAC->dev->name,
+ " Nr: 0x%x\n Msg: %s\n", pAC->dev[0]->name,
ClassStr, ErrNum, pErrorMsg);
} /* SkErrorLog */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)