* <linux/slab.h>
* <linux/interrupt.h>
* <linux/pci.h>
+ * <linux/bitops.h>
* <asm/byteorder.h>
- * <asm/bitops.h>
* <asm/io.h>
* <linux/netdevice.h>
* <linux/etherdevice.h>
#include "h/skversion.h"
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
* Extern Function Prototypes
*
******************************************************************************/
-
-#ifdef CONFIG_PROC_FS
-static const char SK_Root_Dir_entry[] = "sk98lin";
+static const char SKRootName[] = "sk98lin";
static struct proc_dir_entry *pSkRootDir;
extern struct file_operations sk_proc_fops;
-#endif
+
+static inline void SkGeProcCreate(struct net_device *dev)
+{
+ struct proc_dir_entry *pe;
+
+ if (pSkRootDir &&
+ (pe = create_proc_entry(dev->name, S_IRUGO, pSkRootDir))) {
+ pe->proc_fops = &sk_proc_fops;
+ pe->data = dev;
+ pe->owner = THIS_MODULE;
+ }
+}
+
+static inline void SkGeProcRemove(struct net_device *dev)
+{
+ if (pSkRootDir)
+ remove_proc_entry(dev->name, pSkRootDir);
+}
extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);
extern void SkDimDisplayModerationSettings(SK_AC *pAC);
extern void SkDimStartModerationTimer(SK_AC *pAC);
extern void SkDimModerate(SK_AC *pAC);
+extern void SkGeBlinkTimer(unsigned long data);
#ifdef DEBUG
static void DumpMsg(struct sk_buff*, char*);
#endif
/* global variables *********************************************************/
-struct SK_NET_DEVICE *SkGeRootDev = NULL;
static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
+extern struct ethtool_ops SkGeEthtoolOps;
/* local variables **********************************************************/
static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
/*
* Remap the regs into kernel space.
*/
- pAC->IoBase = (char*)ioremap_nocache(dev->mem_start, 0x4000);
+ pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
if (!pAC->IoBase){
retval = 3;
DEV_NET *pNet;
SK_AC *pAC;
- if (dev->priv) {
- pNet = (DEV_NET*) dev->priv;
- pAC = pNet->pAC;
- AllocFlag = pAC->AllocFlag;
- if (pAC->PciDev) {
- pci_release_regions(pAC->PciDev);
- }
- if (AllocFlag & SK_ALLOC_IRQ) {
- free_irq(dev->irq, dev);
- }
- if (pAC->IoBase) {
- iounmap(pAC->IoBase);
- }
- if (pAC->pDescrMem) {
- BoardFreeMem(pAC);
- }
+ pNet = netdev_priv(dev);
+ pAC = pNet->pAC;
+ AllocFlag = pAC->AllocFlag;
+ if (pAC->PciDev) {
+ pci_release_regions(pAC->PciDev);
+ }
+ if (AllocFlag & SK_ALLOC_IRQ) {
+ free_irq(dev->irq, dev);
+ }
+ if (pAC->IoBase) {
+ iounmap(pAC->IoBase);
+ }
+ if (pAC->pDescrMem) {
+ BoardFreeMem(pAC);
}
} /* FreeResources */
MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
MODULE_LICENSE("GPL");
-MODULE_PARM(Speed_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Speed_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(AutoNeg_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(AutoNeg_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(DupCap_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(DupCap_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Role_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Role_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(ConType, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(PrefPort, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(RlmtMode, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-/* used for interrupt moderation */
-MODULE_PARM(IntsPerSec, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");
-MODULE_PARM(Moderation, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Stats, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(ModerationMask, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(AutoSizing, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-
#ifdef LINK_SPEED_A
static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
static char *AutoSizing[SK_MAX_CARD_PARAM];
static char *Stats[SK_MAX_CARD_PARAM];
+module_param_array(Speed_A, charp, NULL, 0);
+module_param_array(Speed_B, charp, NULL, 0);
+module_param_array(AutoNeg_A, charp, NULL, 0);
+module_param_array(AutoNeg_B, charp, NULL, 0);
+module_param_array(DupCap_A, charp, NULL, 0);
+module_param_array(DupCap_B, charp, NULL, 0);
+module_param_array(FlowCtrl_A, charp, NULL, 0);
+module_param_array(FlowCtrl_B, charp, NULL, 0);
+module_param_array(Role_A, charp, NULL, 0);
+module_param_array(Role_B, charp, NULL, 0);
+module_param_array(ConType, charp, NULL, 0);
+module_param_array(PrefPort, charp, NULL, 0);
+module_param_array(RlmtMode, charp, NULL, 0);
+/* used for interrupt moderation */
+module_param_array(IntsPerSec, int, NULL, 0);
+module_param_array(Moderation, charp, NULL, 0);
+module_param_array(Stats, charp, NULL, 0);
+module_param_array(ModerationMask, charp, NULL, 0);
+module_param_array(AutoSizing, charp, NULL, 0);
+
/*****************************************************************************
*
* SkGeBoardInit - do level 0 and 1 initialization
}
spin_lock_init(&pAC->SlowPathLock);
+ /* setup phy_id blink timer */
+ pAC->BlinkTimer.function = SkGeBlinkTimer;
+ pAC->BlinkTimer.data = (unsigned long) dev;
+ init_timer(&pAC->BlinkTimer);
+
/* level 0 init common modules here */
spin_lock_irqsave(&pAC->SlowPathLock, Flags);
return(-EAGAIN);
}
- /*
- * Register the device here
- */
- pAC->Next = SkGeRootDev;
- SkGeRootDev = dev;
-
return (0);
} /* SkGeBoardInit */
SK_AC *pAC;
SK_U32 IntSrc; /* interrupts source register contents */
- pNet = (DEV_NET*) dev->priv;
+ pNet = netdev_priv(dev);
pAC = pNet->pAC;
/*
SK_AC *pAC;
SK_U32 IntSrc; /* interrupts source register contents */
- pNet = (DEV_NET*) dev->priv;
+ pNet = netdev_priv(dev);
pAC = pNet->pAC;
/*
return SkIsrRetHandled;
} /* SkGeIsrOnePort */
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/****************************************************************************
+ *
+ * SkGePollController - polling receive, for netconsole
+ *
+ * Description:
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ *
+ * Returns: N/A
+ */
+static void SkGePollController(struct net_device *dev)
+{
+ disable_irq(dev->irq);
+ SkGeIsr(dev->irq, dev, NULL);
+ enable_irq(dev->irq);
+}
+#endif
/****************************************************************************
*
int i;
SK_EVPARA EvPara; /* an event parameter union */
- pNet = (DEV_NET*) dev->priv;
+ pNet = netdev_priv(dev);
pAC = pNet->pAC;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
}
#endif
- if (!try_module_get(THIS_MODULE)) {
- return (-1); /* increase of usage count not possible */
- }
-
/* Set blink mode */
if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
if (pAC->BoardLevel == SK_INIT_DATA) {
/* level 1 init common modules here */
if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
- module_put(THIS_MODULE); /* decrease usage count */
printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
return (-1);
}
if (pAC->BoardLevel != SK_INIT_RUN) {
/* tschilling: Level 2 init modules here, check return value. */
if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) {
- module_put(THIS_MODULE); /* decrease usage count */
printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
return (-1);
}
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
- pNet = (DEV_NET*) dev->priv;
+ pNet = netdev_priv(dev);
pAC = pNet->pAC;
#ifdef SK_DIAG_SUPPORT
if (pAC->DiagModeActive == DIAG_ACTIVE) {
if (pAC->DiagFlowCtrl == SK_FALSE) {
- module_put(THIS_MODULE);
/*
** notify that the interface which has been closed
** by operator interaction must not be started up
** again when the DIAG has finished.
*/
- newPtrNet = (DEV_NET *) pAC->dev[0]->priv;
+ newPtrNet = netdev_priv(pAC->dev[0]);
if (newPtrNet == pNet) {
pAC->WasIfUp[0] = SK_FALSE;
} else {
pAC->MaxPorts--;
pNet->Up = 0;
- module_put(THIS_MODULE);
return (0);
} /* SkGeClose */
SK_AC *pAC;
int Rc; /* return code of XmitFrame */
- pNet = (DEV_NET*) dev->priv;
+ pNet = netdev_priv(dev);
pAC = pNet->pAC;
if ((!skb_shinfo(skb)->nr_frags) ||
static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
{
-DEV_NET *pNet = (DEV_NET*) dev->priv;
+DEV_NET *pNet = netdev_priv(dev);
SK_AC *pAC = pNet->pAC;
struct sockaddr *addr = p;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeSetRxMode starts now... "));
- pNet = (DEV_NET*) dev->priv;
+ pNet = netdev_priv(dev);
pAC = pNet->pAC;
if (pAC->RlmtNets == 1)
PortIdx = pAC->ActivePort;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeChangeMtu starts now...\n"));
- pNet = (DEV_NET*) dev->priv;
+ pNet = netdev_priv(dev);
pAC = pNet->pAC;
if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
#endif
pNet->Mtu = NewMtu;
- pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
+ pOtherNet = netdev_priv(pAC->dev[1 - pNet->NetNr]);
if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
return(0);
}
*/
static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
{
-DEV_NET *pNet = (DEV_NET*) dev->priv;
+DEV_NET *pNet = netdev_priv(dev);
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_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeIoctl starts now...\n"));
- pNet = (DEV_NET*) dev->priv;
+ pNet = netdev_priv(dev);
pAC = pNet->pAC;
if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
int SkDrvEnterDiagMode(
SK_AC *pAc) /* pointer to adapter context */
{
- SK_AC *pAC = NULL;
- DEV_NET *pNet = NULL;
-
- pNet = (DEV_NET *) pAc->dev[0]->priv;
- pAC = pNet->pAC;
+ DEV_NET *pNet = netdev_priv(pAc->dev[0]);
+ SK_AC *pAC = pNet->pAC;
SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct),
sizeof(SK_PNMI_STRUCT_DATA));
} else {
pAC->WasIfUp[0] = SK_FALSE;
}
- if (pNet != (DEV_NET *) pAc->dev[1]->priv) {
- pNet = (DEV_NET *) pAc->dev[1]->priv;
+ if (pNet != netdev_priv(pAC->dev[1])) {
+ pNet = netdev_priv(pAC->dev[1]);
if (pNet->Up) {
pAC->WasIfUp[1] = SK_TRUE;
pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
dev = pAC->dev[devNbr];
- /*
- ** Function SkGeClose() uses MOD_DEC_USE_COUNT (2.2/2.4)
- ** or module_put() (2.6) to decrease the number of users for
- ** a device, but if a device is to be put under control of
- ** the DIAG, that count is OK already and does not need to
- ** be adapted! Hence the opposite MOD_INC_USE_COUNT or
- ** try_module_get() needs to be used again to correct that.
+ /* On Linux 2.6 the network driver does NOT mess with reference
+ ** counts. The driver MUST be able to be unloaded at any time
+ ** due to the possibility of hotplug.
*/
- if (!try_module_get(THIS_MODULE)) {
- return (-1);
- }
-
if (SkGeClose(dev) != 0) {
- module_put(THIS_MODULE);
return (-1);
}
return (0);
if (SkGeOpen(dev) != 0) {
return (-1);
- } else {
- /*
- ** Function SkGeOpen() uses MOD_INC_USE_COUNT (2.2/2.4)
- ** or try_module_get() (2.6) to increase the number of
- ** users for a device, but if a device was just under
- ** control of the DIAG, that count is OK already and
- ** does not need to be adapted! Hence the opposite
- ** MOD_DEC_USE_COUNT or module_put() needs to be used
- ** again to correct that.
- */
- module_put(THIS_MODULE);
}
/*
SK_AC *pAC;
DEV_NET *pNet = NULL;
struct net_device *dev = NULL;
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *pProcFile;
-#endif
static int boards_found = 0;
int error = -ENODEV;
goto out_disable_device;
}
- pNet = dev->priv;
+ pNet = netdev_priv(dev);
pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
if (!pNet->pAC) {
printk(KERN_ERR "Unable to allocate adapter "
dev->set_mac_address = &SkGeSetMacAddr;
dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ dev->poll_controller = &SkGePollController;
+#endif
dev->flags &= ~IFF_RUNNING;
SET_NETDEV_DEV(dev, &pdev->dev);
+ SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
#ifdef SK_ZEROCOPY
#ifdef USE_SK_TX_CHECKSUM
memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
-#ifdef CONFIG_PROC_FS
- pProcFile = create_proc_entry(dev->name, S_IRUGO, pSkRootDir);
- if (pProcFile) {
- pProcFile->proc_fops = &sk_proc_fops;
- pProcFile->data = dev;
- pProcFile->owner = THIS_MODULE;
- }
-#endif
+ SkGeProcCreate(dev);
pNet->PortNr = 0;
pNet->NetNr = 0;
}
pAC->dev[1] = dev;
- pNet = dev->priv;
+ pNet = netdev_priv(dev);
pNet->PortNr = 1;
pNet->NetNr = 1;
pNet->pAC = pAC;
dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu;
dev->flags &= ~IFF_RUNNING;
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
#ifdef SK_ZEROCOPY
#ifdef USE_SK_TX_CHECKSUM
free_netdev(dev);
pAC->dev[1] = pAC->dev[0];
} else {
-#ifdef CONFIG_PROC_FS
- pProcFile = create_proc_entry(dev->name, S_IRUGO,
- pSkRootDir);
- if (pProcFile) {
- pProcFile->proc_fops = &sk_proc_fops;
- pProcFile->data = dev;
- pProcFile->owner = THIS_MODULE;
- }
-#endif
-
+ SkGeProcCreate(dev);
memcpy(&dev->dev_addr,
&pAC->Addr.Net[1].CurrentMacAddress, 6);
static void __devexit skge_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
- DEV_NET *pNet = (DEV_NET *) dev->priv;
+ DEV_NET *pNet = netdev_priv(dev);
SK_AC *pAC = pNet->pAC;
- int have_second_mac = 0;
-
- if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2)
- have_second_mac = 1;
+ struct net_device *otherdev = pAC->dev[1];
- remove_proc_entry(dev->name, pSkRootDir);
+ SkGeProcRemove(dev);
unregister_netdev(dev);
- if (have_second_mac) {
- remove_proc_entry(pAC->dev[1]->name, pSkRootDir);
- unregister_netdev(pAC->dev[1]);
- }
+ if (otherdev != dev)
+ SkGeProcRemove(otherdev);
SkGeYellowLED(pAC, pAC->IoBase, 0);
FreeResources(dev);
free_netdev(dev);
- if (have_second_mac)
- free_netdev(pAC->dev[1]);
+ if (otherdev != dev)
+ free_netdev(otherdev);
kfree(pAC);
}
{
int error;
-#ifdef CONFIG_PROC_FS
- memcpy(&SK_Root_Dir_entry, BOOT_STRING, sizeof(SK_Root_Dir_entry) - 1);
-
- pSkRootDir = proc_mkdir(SK_Root_Dir_entry, proc_net);
- if (!pSkRootDir) {
- printk(KERN_WARNING "Unable to create /proc/net/%s",
- SK_Root_Dir_entry);
- return -ENOMEM;
- }
- pSkRootDir->owner = THIS_MODULE;
-#endif
-
- error = pci_module_init(&skge_driver);
- if (error) {
-#ifdef CONFIG_PROC_FS
- remove_proc_entry(pSkRootDir->name, proc_net);
-#endif
- }
-
+ pSkRootDir = proc_mkdir(SKRootName, proc_net);
+ if (pSkRootDir)
+ pSkRootDir->owner = THIS_MODULE;
+
+ error = pci_register_driver(&skge_driver);
+ if (error)
+ proc_net_remove(SKRootName);
return error;
}
static void __exit skge_exit(void)
{
- pci_unregister_driver(&skge_driver);
-#ifdef CONFIG_PROC_FS
- remove_proc_entry(pSkRootDir->name, proc_net);
-#endif
+ pci_unregister_driver(&skge_driver);
+ proc_net_remove(SKRootName);
+
}
module_init(skge_init);