Commit 05c5f695 authored by Jeff Garzik's avatar Jeff Garzik

Merge pobox.com:/garz/repo/netdev-2.6/sk98lin

into pobox.com:/garz/repo/net-drivers-2.6
parents 87475e1f 82cd9a70
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
obj-$(CONFIG_SK98LIN) += sk98lin.o obj-$(CONFIG_SK98LIN) += sk98lin.o
sk98lin-objs := \ sk98lin-objs := \
skge.o \ skge.o \
skethtool.o \
skdim.o \ skdim.o \
skaddr.o \ skaddr.o \
skgehwt.o \ skgehwt.o \
......
...@@ -266,7 +266,6 @@ struct s_TxD { ...@@ -266,7 +266,6 @@ struct s_TxD {
typedef struct s_DevNet DEV_NET; typedef struct s_DevNet DEV_NET;
struct s_DevNet { struct s_DevNet {
struct proc_dir_entry *proc;
int PortNr; int PortNr;
int NetNr; int NetNr;
int Mtu; int Mtu;
...@@ -383,6 +382,8 @@ struct s_AC { ...@@ -383,6 +382,8 @@ struct s_AC {
SK_CSUM Csum; /* for checksum module */ SK_CSUM Csum; /* for checksum module */
SK_RLMT Rlmt; /* for rlmt module */ SK_RLMT Rlmt; /* for rlmt module */
spinlock_t SlowPathLock; /* Normal IRQ lock */ spinlock_t SlowPathLock; /* Normal IRQ lock */
struct timer_list BlinkTimer; /* for LED blinking */
int LedsOn;
SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */ SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
int RlmtMode; /* link check mode to set */ int RlmtMode; /* link check mode to set */
int RlmtNets; /* Number of nets */ int RlmtNets; /* Number of nets */
...@@ -395,7 +396,7 @@ struct s_AC { ...@@ -395,7 +396,7 @@ struct s_AC {
SK_U32 PciDevId; /* pci device id */ SK_U32 PciDevId; /* pci device id */
struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */ struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */
char Name[30]; /* driver name */ char Name[30]; /* driver name */
struct SK_NET_DEVICE *Next; /* link all devices (for clearing) */
int RxBufSize; /* length of receive buffers */ int RxBufSize; /* length of receive buffers */
struct net_device_stats stats; /* linux 'netstat -i' statistics */ struct net_device_stats stats; /* linux 'netstat -i' statistics */
int Index; /* internal board index number */ int Index; /* internal board index number */
......
...@@ -79,7 +79,7 @@ extern "C" { ...@@ -79,7 +79,7 @@ extern "C" {
/* 64-bit hash values with all bits set. */ /* 64-bit hash values with all bits set. */
SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
/* local variables ************************************************************/ /* local variables ************************************************************/
......
/******************************************************************************
*
* Name: skethtool.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.7 $
* Date: $Date: 2004/09/29 13:32:07 $
* Purpose: All functions regarding ethtool handling
*
******************************************************************************/
/******************************************************************************
*
* (C)Copyright 1998-2002 SysKonnect GmbH.
* (C)Copyright 2002-2004 Marvell.
*
* Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet
* Server Adapters.
*
* Author: Ralph Roesler (rroesler@syskonnect.de)
* Mirko Lindner (mlindner@syskonnect.de)
*
* Address all question to: linux@syskonnect.de
*
* The technical manual for the adapters is available from SysKonnect's
* web pages: www.syskonnect.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The information in this file is provided "AS IS" without warranty.
*
*****************************************************************************/
#include "h/skdrv1st.h"
#include "h/skdrv2nd.h"
#include "h/skversion.h"
#include <linux/ethtool.h>
#include <linux/timer.h>
#include <linux/delay.h>
/******************************************************************************
*
* Defines
*
*****************************************************************************/
#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \
SUPPORTED_TP)
#define ADV_COPPER_ALL (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \
ADVERTISED_TP)
#define SUPP_FIBRE_ALL (SUPPORTED_1000baseT_Full | \
SUPPORTED_FIBRE | \
SUPPORTED_Autoneg)
#define ADV_FIBRE_ALL (ADVERTISED_1000baseT_Full | \
ADVERTISED_FIBRE | \
ADVERTISED_Autoneg)
/******************************************************************************
*
* Local Functions
*
*****************************************************************************/
/*****************************************************************************
*
* getSettings - retrieves the current settings of the selected adapter
*
* Description:
* The current configuration of the selected adapter is returned.
* This configuration involves a)speed, b)duplex and c)autoneg plus
* a number of other variables.
*
* Returns: always 0
*
*/
static int getSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
const DEV_NET *pNet = netdev_priv(dev);
int port = pNet->PortNr;
const SK_AC *pAC = pNet->pAC;
const SK_GEPORT *pPort = &pAC->GIni.GP[port];
static int DuplexAutoNegConfMap[9][3]= {
{ -1 , -1 , -1 },
{ 0 , -1 , -1 },
{ SK_LMODE_HALF , DUPLEX_HALF, AUTONEG_DISABLE },
{ SK_LMODE_FULL , DUPLEX_FULL, AUTONEG_DISABLE },
{ SK_LMODE_AUTOHALF , DUPLEX_HALF, AUTONEG_ENABLE },
{ SK_LMODE_AUTOFULL , DUPLEX_FULL, AUTONEG_ENABLE },
{ SK_LMODE_AUTOBOTH , DUPLEX_FULL, AUTONEG_ENABLE },
{ SK_LMODE_AUTOSENSE , -1 , -1 },
{ SK_LMODE_INDETERMINATED, -1 , -1 }
};
static int SpeedConfMap[6][2] = {
{ 0 , -1 },
{ SK_LSPEED_AUTO , -1 },
{ SK_LSPEED_10MBPS , SPEED_10 },
{ SK_LSPEED_100MBPS , SPEED_100 },
{ SK_LSPEED_1000MBPS , SPEED_1000 },
{ SK_LSPEED_INDETERMINATED, -1 }
};
static int AdvSpeedMap[6][2] = {
{ 0 , -1 },
{ SK_LSPEED_AUTO , -1 },
{ SK_LSPEED_10MBPS , ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full },
{ SK_LSPEED_100MBPS , ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full },
{ SK_LSPEED_1000MBPS , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full},
{ SK_LSPEED_INDETERMINATED, -1 }
};
ecmd->phy_address = port;
ecmd->speed = SpeedConfMap[pPort->PLinkSpeedUsed][1];
ecmd->duplex = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1];
ecmd->autoneg = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2];
ecmd->transceiver = XCVR_INTERNAL;
if (pAC->GIni.GICopperType) {
ecmd->port = PORT_TP;
ecmd->supported = (SUPP_COPPER_ALL|SUPPORTED_Autoneg);
if (pAC->GIni.GIGenesis) {
ecmd->supported &= ~(SUPPORTED_10baseT_Half);
ecmd->supported &= ~(SUPPORTED_10baseT_Full);
ecmd->supported &= ~(SUPPORTED_100baseT_Half);
ecmd->supported &= ~(SUPPORTED_100baseT_Full);
} else {
if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
}
#ifdef CHIP_ID_YUKON_FE
if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
ecmd->supported &= ~(SUPPORTED_1000baseT_Full);
}
#endif
}
if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) {
ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1];
if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
ecmd->advertising &= ~(SUPPORTED_1000baseT_Half);
}
} else {
ecmd->advertising = ecmd->supported;
}
if (ecmd->autoneg == AUTONEG_ENABLE)
ecmd->advertising |= ADVERTISED_Autoneg;
} else {
ecmd->port = PORT_FIBRE;
ecmd->supported = SUPP_FIBRE_ALL;
ecmd->advertising = ADV_FIBRE_ALL;
}
return 0;
}
/*
* MIB infrastructure uses instance value starting at 1
* based on board and port.
*/
static inline u32 pnmiInstance(const DEV_NET *pNet)
{
return 1 + (pNet->pAC->RlmtNets == 2) + pNet->PortNr;
}
/*****************************************************************************
*
* setSettings - configures the settings of a selected adapter
*
* Description:
* Possible settings that may be altered are a)speed, b)duplex or
* c)autonegotiation.
*
* Returns:
* 0: everything fine, no error
* <0: the return value is the error code of the failure
*/
static int setSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
DEV_NET *pNet = netdev_priv(dev);
SK_AC *pAC = pNet->pAC;
u32 instance;
char buf[4];
int len = 1;
if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100
&& ecmd->speed != SPEED_1000)
return -EINVAL;
if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
return -EINVAL;
if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
return -EINVAL;
if (ecmd->autoneg == AUTONEG_DISABLE)
*buf = (ecmd->duplex == DUPLEX_FULL)
? SK_LMODE_FULL : SK_LMODE_HALF;
else
*buf = (ecmd->duplex == DUPLEX_FULL)
? SK_LMODE_AUTOFULL : SK_LMODE_AUTOHALF;
instance = pnmiInstance(pNet);
if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE,
&buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
return -EINVAL;
switch(ecmd->speed) {
case SPEED_1000:
*buf = SK_LSPEED_1000MBPS;
break;
case SPEED_100:
*buf = SK_LSPEED_100MBPS;
break;
case SPEED_10:
*buf = SK_LSPEED_10MBPS;
}
if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
&buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
return -EINVAL;
return 0;
}
/*****************************************************************************
*
* getDriverInfo - returns generic driver and adapter information
*
* Description:
* Generic driver information is returned via this function, such as
* the name of the driver, its version and and firmware version.
* In addition to this, the location of the selected adapter is
* returned as a bus info string (e.g. '01:05.0').
*
* Returns: N/A
*
*/
static void getDriverInfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
const DEV_NET *pNet = netdev_priv(dev);
const SK_AC *pAC = pNet->pAC;
char vers[32];
snprintf(vers, sizeof(vers)-1, VER_STRING "(v%d.%d)",
(pAC->GIni.GIPciHwRev >> 4) & 0xf, pAC->GIni.GIPciHwRev & 0xf);
strlcpy(info->driver, DRIVER_FILE_NAME, sizeof(info->driver));
strcpy(info->version, vers);
strcpy(info->fw_version, "N/A");
strlcpy(info->bus_info, pAC->PciDev->slot_name, ETHTOOL_BUSINFO_LEN);
}
/*
* Ethtool statistics support.
*/
static const char StringsStats[][ETH_GSTRING_LEN] = {
"rx_packets", "tx_packets",
"rx_bytes", "tx_bytes",
"rx_errors", "tx_errors",
"rx_dropped", "tx_dropped",
"multicasts", "collisions",
"rx_length_errors", "rx_buffer_overflow_errors",
"rx_crc_errors", "rx_frame_errors",
"rx_too_short_errors", "rx_too_long_errors",
"rx_carrier_extension_errors", "rx_symbol_errors",
"rx_llc_mac_size_errors", "rx_carrier_errors",
"rx_jabber_errors", "rx_missed_errors",
"tx_abort_collision_errors", "tx_carrier_errors",
"tx_buffer_underrun_errors", "tx_heartbeat_errors",
"tx_window_errors",
};
static int getStatsCount(struct net_device *dev)
{
return ARRAY_SIZE(StringsStats);
}
static void getStrings(struct net_device *dev, u32 stringset, u8 *data)
{
switch(stringset) {
case ETH_SS_STATS:
memcpy(data, *StringsStats, sizeof(StringsStats));
break;
}
}
static void getEthtoolStats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
const DEV_NET *pNet = netdev_priv(dev);
const SK_AC *pAC = pNet->pAC;
const SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
*data++ = pPnmiStruct->Stat[0].StatRxOkCts;
*data++ = pPnmiStruct->Stat[0].StatTxOkCts;
*data++ = pPnmiStruct->Stat[0].StatRxOctetsOkCts;
*data++ = pPnmiStruct->Stat[0].StatTxOctetsOkCts;
*data++ = pPnmiStruct->InErrorsCts;
*data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
*data++ = pPnmiStruct->RxNoBufCts;
*data++ = pPnmiStruct->TxNoBufCts;
*data++ = pPnmiStruct->Stat[0].StatRxMulticastOkCts;
*data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
*data++ = pPnmiStruct->Stat[0].StatRxRuntCts;
*data++ = pPnmiStruct->Stat[0].StatRxFifoOverflowCts;
*data++ = pPnmiStruct->Stat[0].StatRxFcsCts;
*data++ = pPnmiStruct->Stat[0].StatRxFramingCts;
*data++ = pPnmiStruct->Stat[0].StatRxShortsCts;
*data++ = pPnmiStruct->Stat[0].StatRxTooLongCts;
*data++ = pPnmiStruct->Stat[0].StatRxCextCts;
*data++ = pPnmiStruct->Stat[0].StatRxSymbolCts;
*data++ = pPnmiStruct->Stat[0].StatRxIRLengthCts;
*data++ = pPnmiStruct->Stat[0].StatRxCarrierCts;
*data++ = pPnmiStruct->Stat[0].StatRxJabberCts;
*data++ = pPnmiStruct->Stat[0].StatRxMissedCts;
*data++ = pAC->stats.tx_aborted_errors;
*data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
*data++ = pPnmiStruct->Stat[0].StatTxFifoUnderrunCts;
*data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
*data++ = pAC->stats.tx_window_errors;
}
/*****************************************************************************
*
* toggleLeds - Changes the LED state of an adapter
*
* Description:
* This function changes the current state of all LEDs of an adapter so
* that it can be located by a user.
*
* Returns: N/A
*
*/
static void toggleLeds(DEV_NET *pNet, int on)
{
SK_AC *pAC = pNet->pAC;
int port = pNet->PortNr;
void __iomem *io = pAC->IoBase;
if (pAC->GIni.GIGenesis) {
SK_OUT8(io, MR_ADDR(port,LNK_LED_REG),
on ? SK_LNK_ON : SK_LNK_OFF);
SkGeYellowLED(pAC, io,
on ? (LED_ON >> 1) : (LED_OFF >> 1));
SkGeXmitLED(pAC, io, MR_ADDR(port,RX_LED_INI),
on ? SK_LED_TST : SK_LED_DIS);
if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM)
SkXmPhyWrite(pAC, io, port, PHY_BCOM_P_EXT_CTRL,
on ? PHY_B_PEC_LED_ON : PHY_B_PEC_LED_OFF);
else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE)
SkXmPhyWrite(pAC, io, port, PHY_LONE_LED_CFG,
on ? 0x0800 : PHY_L_LC_LEDT);
else
SkGeXmitLED(pAC, io, MR_ADDR(port,TX_LED_INI),
on ? SK_LED_TST : SK_LED_DIS);
} else {
const u16 YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON) |
PHY_M_LED_MO_10(MO_LED_ON) |
PHY_M_LED_MO_100(MO_LED_ON) |
PHY_M_LED_MO_1000(MO_LED_ON) |
PHY_M_LED_MO_RX(MO_LED_ON));
const u16 YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF) |
PHY_M_LED_MO_10(MO_LED_OFF) |
PHY_M_LED_MO_100(MO_LED_OFF) |
PHY_M_LED_MO_1000(MO_LED_OFF) |
PHY_M_LED_MO_RX(MO_LED_OFF));
SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_CTRL,0);
SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_OVER,
on ? YukLedOn : YukLedOff);
}
}
/*****************************************************************************
*
* skGeBlinkTimer - Changes the LED state of an adapter
*
* Description:
* This function changes the current state of all LEDs of an adapter so
* that it can be located by a user. If the requested time interval for
* this test has elapsed, this function cleans up everything that was
* temporarily setup during the locate NIC test. This involves of course
* also closing or opening any adapter so that the initial board state
* is recovered.
*
* Returns: N/A
*
*/
void SkGeBlinkTimer(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
DEV_NET *pNet = netdev_priv(dev);
SK_AC *pAC = pNet->pAC;
toggleLeds(pNet, pAC->LedsOn);
pAC->LedsOn = !pAC->LedsOn;
mod_timer(&pAC->BlinkTimer, jiffies + HZ/4);
}
/*****************************************************************************
*
* locateDevice - start the locate NIC feature of the elected adapter
*
* Description:
* This function is used if the user want to locate a particular NIC.
* All LEDs are regularly switched on and off, so the NIC can easily
* be identified.
*
* Returns:
* ==0: everything fine, no error, locateNIC test was started
* !=0: one locateNIC test runs already
*
*/
static int locateDevice(struct net_device *dev, u32 data)
{
DEV_NET *pNet = netdev_priv(dev);
SK_AC *pAC = pNet->pAC;
if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
/* start blinking */
pAC->LedsOn = 0;
mod_timer(&pAC->BlinkTimer, jiffies);
msleep_interruptible(data * 1000);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(data * HZ);
del_timer_sync(&pAC->BlinkTimer);
toggleLeds(pNet, 0);
return 0;
}
/*****************************************************************************
*
* getPauseParams - retrieves the pause parameters
*
* Description:
* All current pause parameters of a selected adapter are placed
* in the passed ethtool_pauseparam structure and are returned.
*
* Returns: N/A
*
*/
static void getPauseParams(struct net_device *dev, struct ethtool_pauseparam *epause)
{
DEV_NET *pNet = netdev_priv(dev);
SK_AC *pAC = pNet->pAC;
SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
epause->rx_pause = (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) ||
(pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM);
epause->tx_pause = epause->rx_pause || (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND);
epause->autoneg = epause->rx_pause || epause->tx_pause;
}
/*****************************************************************************
*
* setPauseParams - configures the pause parameters of an adapter
*
* Description:
* This function sets the Rx or Tx pause parameters
*
* Returns:
* ==0: everything fine, no error
* !=0: the return value is the error code of the failure
*/
static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *epause)
{
DEV_NET *pNet = netdev_priv(dev);
SK_AC *pAC = pNet->pAC;
SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
u32 instance = pnmiInstance(pNet);
struct ethtool_pauseparam old;
u8 oldspeed = pPort->PLinkSpeedUsed;
char buf[4];
int len = 1;
int ret;
/*
** we have to determine the current settings to see if
** the operator requested any modification of the flow
** control parameters...
*/
getPauseParams(dev, &old);
/*
** perform modifications regarding the changes
** requested by the operator
*/
if (epause->autoneg != old.autoneg)
*buf = epause->autoneg ? SK_FLOW_MODE_NONE : SK_FLOW_MODE_SYMMETRIC;
else {
if (epause->rx_pause && epause->tx_pause)
*buf = SK_FLOW_MODE_SYMMETRIC;
else if (epause->rx_pause && !epause->tx_pause)
*buf = SK_FLOW_MODE_SYM_OR_REM;
else if (!epause->rx_pause && epause->tx_pause)
*buf = SK_FLOW_MODE_LOC_SEND;
else
*buf = SK_FLOW_MODE_NONE;
}
ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE,
&buf, &len, instance, pNet->NetNr);
if (ret != SK_PNMI_ERR_OK) {
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
("ethtool (sk98lin): error changing rx/tx pause (%i)\n", ret));
goto err;
}
/*
** It may be that autoneg has been disabled! Therefore
** set the speed to the previously used value...
*/
if (!epause->autoneg) {
len = 1;
ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
&oldspeed, &len, instance, pNet->NetNr);
if (ret != SK_PNMI_ERR_OK)
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
("ethtool (sk98lin): error setting speed (%i)\n", ret));
}
err:
return ret ? -EIO : 0;
}
struct ethtool_ops SkGeEthtoolOps = {
.get_settings = getSettings,
.set_settings = setSettings,
.get_drvinfo = getDriverInfo,
.get_strings = getStrings,
.get_stats_count = getStatsCount,
.get_ethtool_stats = getEthtoolStats,
.phys_id = locateDevice,
.get_pauseparam = getPauseParams,
.set_pauseparam = setPauseParams,
};
...@@ -109,6 +109,7 @@ ...@@ -109,6 +109,7 @@
#include "h/skversion.h" #include "h/skversion.h"
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
...@@ -233,17 +234,33 @@ static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr); ...@@ -233,17 +234,33 @@ static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
* Extern Function Prototypes * Extern Function Prototypes
* *
******************************************************************************/ ******************************************************************************/
static const char SKRootName[] = "sk98lin";
#ifdef CONFIG_PROC_FS
static const char SK_Root_Dir_entry[] = "sk98lin";
static struct proc_dir_entry *pSkRootDir; static struct proc_dir_entry *pSkRootDir;
extern struct file_operations sk_proc_fops; 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 SkDimEnableModerationIfNeeded(SK_AC *pAC);
extern void SkDimDisplayModerationSettings(SK_AC *pAC); extern void SkDimDisplayModerationSettings(SK_AC *pAC);
extern void SkDimStartModerationTimer(SK_AC *pAC); extern void SkDimStartModerationTimer(SK_AC *pAC);
extern void SkDimModerate(SK_AC *pAC); extern void SkDimModerate(SK_AC *pAC);
extern void SkGeBlinkTimer(unsigned long data);
#ifdef DEBUG #ifdef DEBUG
static void DumpMsg(struct sk_buff*, char*); static void DumpMsg(struct sk_buff*, char*);
...@@ -252,8 +269,8 @@ static void DumpLong(char*, int); ...@@ -252,8 +269,8 @@ static void DumpLong(char*, int);
#endif #endif
/* global variables *********************************************************/ /* global variables *********************************************************/
struct SK_NET_DEVICE *SkGeRootDev = NULL;
static SK_BOOL DoPrintInterfaceChange = SK_TRUE; static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
extern struct ethtool_ops SkGeEthtoolOps;
/* local variables **********************************************************/ /* local variables **********************************************************/
static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
...@@ -337,22 +354,20 @@ SK_U32 AllocFlag; ...@@ -337,22 +354,20 @@ SK_U32 AllocFlag;
DEV_NET *pNet; DEV_NET *pNet;
SK_AC *pAC; SK_AC *pAC;
if (dev->priv) { pNet = netdev_priv(dev);
pNet = (DEV_NET*) dev->priv; pAC = pNet->pAC;
pAC = pNet->pAC; AllocFlag = pAC->AllocFlag;
AllocFlag = pAC->AllocFlag; if (pAC->PciDev) {
if (pAC->PciDev) { pci_release_regions(pAC->PciDev);
pci_release_regions(pAC->PciDev); }
} if (AllocFlag & SK_ALLOC_IRQ) {
if (AllocFlag & SK_ALLOC_IRQ) { free_irq(dev->irq, dev);
free_irq(dev->irq, dev); }
} if (pAC->IoBase) {
if (pAC->IoBase) { iounmap(pAC->IoBase);
iounmap(pAC->IoBase); }
} if (pAC->pDescrMem) {
if (pAC->pDescrMem) { BoardFreeMem(pAC);
BoardFreeMem(pAC);
}
} }
} /* FreeResources */ } /* FreeResources */
...@@ -360,26 +375,6 @@ SK_AC *pAC; ...@@ -360,26 +375,6 @@ SK_AC *pAC;
MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>"); MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver"); MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
MODULE_LICENSE("GPL"); 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 #ifdef LINK_SPEED_A
static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED; static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
...@@ -465,6 +460,26 @@ static char *ModerationMask[SK_MAX_CARD_PARAM]; ...@@ -465,6 +460,26 @@ static char *ModerationMask[SK_MAX_CARD_PARAM];
static char *AutoSizing[SK_MAX_CARD_PARAM]; static char *AutoSizing[SK_MAX_CARD_PARAM];
static char *Stats[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 * SkGeBoardInit - do level 0 and 1 initialization
...@@ -503,6 +518,11 @@ SK_BOOL DualNet; ...@@ -503,6 +518,11 @@ SK_BOOL DualNet;
} }
spin_lock_init(&pAC->SlowPathLock); 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 */ /* level 0 init common modules here */
spin_lock_irqsave(&pAC->SlowPathLock, Flags); spin_lock_irqsave(&pAC->SlowPathLock, Flags);
...@@ -601,12 +621,6 @@ SK_BOOL DualNet; ...@@ -601,12 +621,6 @@ SK_BOOL DualNet;
return(-EAGAIN); return(-EAGAIN);
} }
/*
* Register the device here
*/
pAC->Next = SkGeRootDev;
SkGeRootDev = dev;
return (0); return (0);
} /* SkGeBoardInit */ } /* SkGeBoardInit */
...@@ -887,7 +901,7 @@ DEV_NET *pNet; ...@@ -887,7 +901,7 @@ DEV_NET *pNet;
SK_AC *pAC; SK_AC *pAC;
SK_U32 IntSrc; /* interrupts source register contents */ SK_U32 IntSrc; /* interrupts source register contents */
pNet = (DEV_NET*) dev->priv; pNet = netdev_priv(dev);
pAC = pNet->pAC; pAC = pNet->pAC;
/* /*
...@@ -1036,7 +1050,7 @@ DEV_NET *pNet; ...@@ -1036,7 +1050,7 @@ DEV_NET *pNet;
SK_AC *pAC; SK_AC *pAC;
SK_U32 IntSrc; /* interrupts source register contents */ SK_U32 IntSrc; /* interrupts source register contents */
pNet = (DEV_NET*) dev->priv; pNet = netdev_priv(dev);
pAC = pNet->pAC; pAC = pNet->pAC;
/* /*
...@@ -1126,6 +1140,24 @@ SK_U32 IntSrc; /* interrupts source register contents */ ...@@ -1126,6 +1140,24 @@ SK_U32 IntSrc; /* interrupts source register contents */
return SkIsrRetHandled; return SkIsrRetHandled;
} /* SkGeIsrOnePort */ } /* 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
/**************************************************************************** /****************************************************************************
* *
...@@ -1152,7 +1184,7 @@ struct SK_NET_DEVICE *dev) ...@@ -1152,7 +1184,7 @@ struct SK_NET_DEVICE *dev)
int i; int i;
SK_EVPARA EvPara; /* an event parameter union */ SK_EVPARA EvPara; /* an event parameter union */
pNet = (DEV_NET*) dev->priv; pNet = netdev_priv(dev);
pAC = pNet->pAC; pAC = pNet->pAC;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
...@@ -1166,10 +1198,6 @@ struct SK_NET_DEVICE *dev) ...@@ -1166,10 +1198,6 @@ struct SK_NET_DEVICE *dev)
} }
#endif #endif
if (!try_module_get(THIS_MODULE)) {
return (-1); /* increase of usage count not possible */
}
/* Set blink mode */ /* Set blink mode */
if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab )) if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE; pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
...@@ -1177,7 +1205,6 @@ struct SK_NET_DEVICE *dev) ...@@ -1177,7 +1205,6 @@ struct SK_NET_DEVICE *dev)
if (pAC->BoardLevel == SK_INIT_DATA) { if (pAC->BoardLevel == SK_INIT_DATA) {
/* level 1 init common modules here */ /* level 1 init common modules here */
if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { 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); printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
return (-1); return (-1);
} }
...@@ -1193,7 +1220,6 @@ struct SK_NET_DEVICE *dev) ...@@ -1193,7 +1220,6 @@ struct SK_NET_DEVICE *dev)
if (pAC->BoardLevel != SK_INIT_RUN) { if (pAC->BoardLevel != SK_INIT_RUN) {
/* tschilling: Level 2 init modules here, check return value. */ /* tschilling: Level 2 init modules here, check return value. */
if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) { 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); printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
return (-1); return (-1);
} }
...@@ -1279,19 +1305,18 @@ struct SK_NET_DEVICE *dev) ...@@ -1279,19 +1305,18 @@ struct SK_NET_DEVICE *dev)
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeClose: pAC=0x%lX ", (unsigned long)pAC)); ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
pNet = (DEV_NET*) dev->priv; pNet = netdev_priv(dev);
pAC = pNet->pAC; pAC = pNet->pAC;
#ifdef SK_DIAG_SUPPORT #ifdef SK_DIAG_SUPPORT
if (pAC->DiagModeActive == DIAG_ACTIVE) { if (pAC->DiagModeActive == DIAG_ACTIVE) {
if (pAC->DiagFlowCtrl == SK_FALSE) { if (pAC->DiagFlowCtrl == SK_FALSE) {
module_put(THIS_MODULE);
/* /*
** notify that the interface which has been closed ** notify that the interface which has been closed
** by operator interaction must not be started up ** by operator interaction must not be started up
** again when the DIAG has finished. ** again when the DIAG has finished.
*/ */
newPtrNet = (DEV_NET *) pAC->dev[0]->priv; newPtrNet = netdev_priv(pAC->dev[0]);
if (newPtrNet == pNet) { if (newPtrNet == pNet) {
pAC->WasIfUp[0] = SK_FALSE; pAC->WasIfUp[0] = SK_FALSE;
} else { } else {
...@@ -1376,7 +1401,6 @@ struct SK_NET_DEVICE *dev) ...@@ -1376,7 +1401,6 @@ struct SK_NET_DEVICE *dev)
pAC->MaxPorts--; pAC->MaxPorts--;
pNet->Up = 0; pNet->Up = 0;
module_put(THIS_MODULE);
return (0); return (0);
} /* SkGeClose */ } /* SkGeClose */
...@@ -1402,7 +1426,7 @@ DEV_NET *pNet; ...@@ -1402,7 +1426,7 @@ DEV_NET *pNet;
SK_AC *pAC; SK_AC *pAC;
int Rc; /* return code of XmitFrame */ int Rc; /* return code of XmitFrame */
pNet = (DEV_NET*) dev->priv; pNet = netdev_priv(dev);
pAC = pNet->pAC; pAC = pNet->pAC;
if ((!skb_shinfo(skb)->nr_frags) || if ((!skb_shinfo(skb)->nr_frags) ||
...@@ -2498,7 +2522,7 @@ unsigned long Flags; ...@@ -2498,7 +2522,7 @@ unsigned long Flags;
static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p) 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; SK_AC *pAC = pNet->pAC;
struct sockaddr *addr = p; struct sockaddr *addr = p;
...@@ -2555,7 +2579,7 @@ unsigned long Flags; ...@@ -2555,7 +2579,7 @@ unsigned long Flags;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeSetRxMode starts now... ")); ("SkGeSetRxMode starts now... "));
pNet = (DEV_NET*) dev->priv; pNet = netdev_priv(dev);
pAC = pNet->pAC; pAC = pNet->pAC;
if (pAC->RlmtNets == 1) if (pAC->RlmtNets == 1)
PortIdx = pAC->ActivePort; PortIdx = pAC->ActivePort;
...@@ -2627,7 +2651,7 @@ SK_EVPARA EvPara; ...@@ -2627,7 +2651,7 @@ SK_EVPARA EvPara;
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeChangeMtu starts now...\n")); ("SkGeChangeMtu starts now...\n"));
pNet = (DEV_NET*) dev->priv; pNet = netdev_priv(dev);
pAC = pNet->pAC; pAC = pNet->pAC;
if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) { if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
...@@ -2649,7 +2673,7 @@ SK_EVPARA EvPara; ...@@ -2649,7 +2673,7 @@ SK_EVPARA EvPara;
#endif #endif
pNet->Mtu = NewMtu; 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)) { if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
return(0); return(0);
} }
...@@ -2855,7 +2879,7 @@ SK_EVPARA EvPara; ...@@ -2855,7 +2879,7 @@ SK_EVPARA EvPara;
*/ */
static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev) 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_AC *pAC = pNet->pAC;
SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */ SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */
SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */ SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */
...@@ -2953,7 +2977,7 @@ int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32); ...@@ -2953,7 +2977,7 @@ int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
("SkGeIoctl starts now...\n")); ("SkGeIoctl starts now...\n"));
pNet = (DEV_NET*) dev->priv; pNet = netdev_priv(dev);
pAC = pNet->pAC; pAC = pNet->pAC;
if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) { if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
...@@ -4539,11 +4563,8 @@ char ClassStr[80]; ...@@ -4539,11 +4563,8 @@ char ClassStr[80];
int SkDrvEnterDiagMode( int SkDrvEnterDiagMode(
SK_AC *pAc) /* pointer to adapter context */ SK_AC *pAc) /* pointer to adapter context */
{ {
SK_AC *pAC = NULL; DEV_NET *pNet = netdev_priv(pAc->dev[0]);
DEV_NET *pNet = NULL; SK_AC *pAC = pNet->pAC;
pNet = (DEV_NET *) pAc->dev[0]->priv;
pAC = pNet->pAC;
SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct),
sizeof(SK_PNMI_STRUCT_DATA)); sizeof(SK_PNMI_STRUCT_DATA));
...@@ -4558,8 +4579,8 @@ SK_AC *pAc) /* pointer to adapter context */ ...@@ -4558,8 +4579,8 @@ SK_AC *pAc) /* pointer to adapter context */
} else { } else {
pAC->WasIfUp[0] = SK_FALSE; pAC->WasIfUp[0] = SK_FALSE;
} }
if (pNet != (DEV_NET *) pAc->dev[1]->priv) { if (pNet != netdev_priv(pAC->dev[1])) {
pNet = (DEV_NET *) pAc->dev[1]->priv; pNet = netdev_priv(pAC->dev[1]);
if (pNet->Up) { if (pNet->Up) {
pAC->WasIfUp[1] = SK_TRUE; pAC->WasIfUp[1] = SK_TRUE;
pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
...@@ -4681,20 +4702,11 @@ int devNbr) /* what device is to be handled */ ...@@ -4681,20 +4702,11 @@ int devNbr) /* what device is to be handled */
dev = pAC->dev[devNbr]; dev = pAC->dev[devNbr];
/* /* On Linux 2.6 the network driver does NOT mess with reference
** Function SkGeClose() uses MOD_DEC_USE_COUNT (2.2/2.4) ** counts. The driver MUST be able to be unloaded at any time
** or module_put() (2.6) to decrease the number of users for ** due to the possibility of hotplug.
** 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.
*/ */
if (!try_module_get(THIS_MODULE)) {
return (-1);
}
if (SkGeClose(dev) != 0) { if (SkGeClose(dev) != 0) {
module_put(THIS_MODULE);
return (-1); return (-1);
} }
return (0); return (0);
...@@ -4723,17 +4735,6 @@ int devNbr) /* what device is to be handled */ ...@@ -4723,17 +4735,6 @@ int devNbr) /* what device is to be handled */
if (SkGeOpen(dev) != 0) { if (SkGeOpen(dev) != 0) {
return (-1); 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);
} }
/* /*
...@@ -4904,9 +4905,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, ...@@ -4904,9 +4905,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
SK_AC *pAC; SK_AC *pAC;
DEV_NET *pNet = NULL; DEV_NET *pNet = NULL;
struct net_device *dev = NULL; struct net_device *dev = NULL;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *pProcFile;
#endif
static int boards_found = 0; static int boards_found = 0;
int error = -ENODEV; int error = -ENODEV;
...@@ -4925,7 +4923,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, ...@@ -4925,7 +4923,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
goto out_disable_device; goto out_disable_device;
} }
pNet = dev->priv; pNet = netdev_priv(dev);
pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
if (!pNet->pAC) { if (!pNet->pAC) {
printk(KERN_ERR "Unable to allocate adapter " printk(KERN_ERR "Unable to allocate adapter "
...@@ -4960,8 +4958,12 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, ...@@ -4960,8 +4958,12 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
dev->set_mac_address = &SkGeSetMacAddr; dev->set_mac_address = &SkGeSetMacAddr;
dev->do_ioctl = &SkGeIoctl; dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu; dev->change_mtu = &SkGeChangeMtu;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = &SkGePollController;
#endif
dev->flags &= ~IFF_RUNNING; dev->flags &= ~IFF_RUNNING;
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
#ifdef SK_ZEROCOPY #ifdef SK_ZEROCOPY
#ifdef USE_SK_TX_CHECKSUM #ifdef USE_SK_TX_CHECKSUM
...@@ -5002,14 +5004,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, ...@@ -5002,14 +5004,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6); memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
#ifdef CONFIG_PROC_FS SkGeProcCreate(dev);
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
pNet->PortNr = 0; pNet->PortNr = 0;
pNet->NetNr = 0; pNet->NetNr = 0;
...@@ -5025,7 +5020,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, ...@@ -5025,7 +5020,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
} }
pAC->dev[1] = dev; pAC->dev[1] = dev;
pNet = dev->priv; pNet = netdev_priv(dev);
pNet->PortNr = 1; pNet->PortNr = 1;
pNet->NetNr = 1; pNet->NetNr = 1;
pNet->pAC = pAC; pNet->pAC = pAC;
...@@ -5041,6 +5036,8 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, ...@@ -5041,6 +5036,8 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
dev->do_ioctl = &SkGeIoctl; dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu; dev->change_mtu = &SkGeChangeMtu;
dev->flags &= ~IFF_RUNNING; dev->flags &= ~IFF_RUNNING;
SET_NETDEV_DEV(dev, &pdev->dev);
SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
#ifdef SK_ZEROCOPY #ifdef SK_ZEROCOPY
#ifdef USE_SK_TX_CHECKSUM #ifdef USE_SK_TX_CHECKSUM
...@@ -5056,16 +5053,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, ...@@ -5056,16 +5053,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
free_netdev(dev); free_netdev(dev);
pAC->dev[1] = pAC->dev[0]; pAC->dev[1] = pAC->dev[0];
} else { } else {
#ifdef CONFIG_PROC_FS SkGeProcCreate(dev);
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
memcpy(&dev->dev_addr, memcpy(&dev->dev_addr,
&pAC->Addr.Net[1].CurrentMacAddress, 6); &pAC->Addr.Net[1].CurrentMacAddress, 6);
...@@ -5101,19 +5089,14 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, ...@@ -5101,19 +5089,14 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
static void __devexit skge_remove_one(struct pci_dev *pdev) static void __devexit skge_remove_one(struct pci_dev *pdev)
{ {
struct net_device *dev = pci_get_drvdata(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; SK_AC *pAC = pNet->pAC;
int have_second_mac = 0; struct net_device *otherdev = pAC->dev[1];
if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2)
have_second_mac = 1;
remove_proc_entry(dev->name, pSkRootDir); SkGeProcRemove(dev);
unregister_netdev(dev); unregister_netdev(dev);
if (have_second_mac) { if (otherdev != dev)
remove_proc_entry(pAC->dev[1]->name, pSkRootDir); SkGeProcRemove(otherdev);
unregister_netdev(pAC->dev[1]);
}
SkGeYellowLED(pAC, pAC->IoBase, 0); SkGeYellowLED(pAC, pAC->IoBase, 0);
...@@ -5146,8 +5129,8 @@ static void __devexit skge_remove_one(struct pci_dev *pdev) ...@@ -5146,8 +5129,8 @@ static void __devexit skge_remove_one(struct pci_dev *pdev)
FreeResources(dev); FreeResources(dev);
free_netdev(dev); free_netdev(dev);
if (have_second_mac) if (otherdev != dev)
free_netdev(pAC->dev[1]); free_netdev(otherdev);
kfree(pAC); kfree(pAC);
} }
...@@ -5180,34 +5163,21 @@ static int __init skge_init(void) ...@@ -5180,34 +5163,21 @@ static int __init skge_init(void)
{ {
int error; int error;
#ifdef CONFIG_PROC_FS pSkRootDir = proc_mkdir(SKRootName, proc_net);
memcpy(&SK_Root_Dir_entry, BOOT_STRING, sizeof(SK_Root_Dir_entry) - 1); if (pSkRootDir)
pSkRootDir->owner = THIS_MODULE;
pSkRootDir = proc_mkdir(SK_Root_Dir_entry, proc_net);
if (!pSkRootDir) { error = pci_register_driver(&skge_driver);
printk(KERN_WARNING "Unable to create /proc/net/%s", if (error)
SK_Root_Dir_entry); proc_net_remove(SKRootName);
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
}
return error; return error;
} }
static void __exit skge_exit(void) static void __exit skge_exit(void)
{ {
pci_unregister_driver(&skge_driver); pci_unregister_driver(&skge_driver);
#ifdef CONFIG_PROC_FS proc_net_remove(SKRootName);
remove_proc_entry(pSkRootDir->name, proc_net);
#endif
} }
module_init(skge_init); module_init(skge_init);
......
...@@ -31,13 +31,9 @@ ...@@ -31,13 +31,9 @@
#include "h/skdrv2nd.h" #include "h/skdrv2nd.h"
#include "h/skversion.h" #include "h/skversion.h"
extern struct SK_NET_DEVICE *SkGeRootDev;
static int sk_proc_print(void *writePtr, char *format, ...);
static void sk_gen_browse(void *buffer);
int len;
static int sk_seq_show(struct seq_file *seq, void *v); static int sk_seq_show(struct seq_file *seq, void *v);
static int sk_proc_open(struct inode *inode, struct file *file); static int sk_proc_open(struct inode *inode, struct file *file);
struct file_operations sk_proc_fops = { struct file_operations sk_proc_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = sk_proc_open, .open = sk_proc_open,
...@@ -45,315 +41,206 @@ struct file_operations sk_proc_fops = { ...@@ -45,315 +41,206 @@ struct file_operations sk_proc_fops = {
.llseek = seq_lseek, .llseek = seq_lseek,
.release = single_release, .release = single_release,
}; };
struct net_device *currDev = NULL;
/***************************************************************************** /*****************************************************************************
* *
* sk_gen_browse -generic print "summaries" entry * sk_seq_show - show proc information of a particular adapter
* *
* Description: * Description:
* This function fills the proc entry with statistic data about * This function fills the proc entry with statistic data about
* the ethernet device. * the ethernet device. It invokes the generic sk_gen_browse() to
* print out all items one per one.
* *
* Returns: - * Returns: 0
* *
*/ */
static void sk_gen_browse(void *buffer) static int sk_seq_show(struct seq_file *seq, void *v)
{ {
struct SK_NET_DEVICE *SkgeProcDev = SkGeRootDev; struct net_device *dev = seq->private;
struct SK_NET_DEVICE *next; DEV_NET *pNet = netdev_priv(dev);
SK_PNMI_STRUCT_DATA *pPnmiStruct; SK_AC *pAC = pNet->pAC;
SK_PNMI_STAT *pPnmiStat; SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
unsigned long Flags; unsigned long Flags;
unsigned int Size; unsigned int Size;
DEV_NET *pNet;
SK_AC *pAC;
char sens_msg[50]; char sens_msg[50];
int MaxSecurityCount = 0;
int t; int t;
int i; int i;
while (SkgeProcDev) { /* NetIndex in GetStruct is now required, zero is only dummy */
MaxSecurityCount++; for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
if (MaxSecurityCount > 100) { if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
printk("Max limit for sk_proc_read security counter!\n"); t--;
return;
}
pNet = (DEV_NET*) SkgeProcDev->priv;
pAC = pNet->pAC;
next = pAC->Next;
pPnmiStruct = &pAC->PnmiStruct;
/* NetIndex in GetStruct is now required, zero is only dummy */
for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
t--;
spin_lock_irqsave(&pAC->SlowPathLock, Flags); spin_lock_irqsave(&pAC->SlowPathLock, Flags);
Size = SK_PNMI_STRUCT_SIZE; Size = SK_PNMI_STRUCT_SIZE;
#ifdef SK_DIAG_SUPPORT #ifdef SK_DIAG_SUPPORT
if (pAC->BoardLevel == SK_INIT_DATA) { if (pAC->BoardLevel == SK_INIT_DATA) {
SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA)); SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
if (pAC->DiagModeActive == DIAG_NOTACTIVE) { if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
pAC->Pnmi.DiagAttached = SK_DIAG_IDLE; pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
}
} else {
SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
} }
} else {
SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
}
#else #else
SkPnmiGetStruct(pAC, pAC->IoBase, SkPnmiGetStruct(pAC, pAC->IoBase,
pPnmiStruct, &Size, t-1); pPnmiStruct, &Size, t-1);
#endif #endif
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
if (strcmp(pAC->dev[t-1]->name, currDev->name) == 0) { if (pAC->dev[t-1] == dev) {
pPnmiStat = &pPnmiStruct->Stat[0]; SK_PNMI_STAT *pPnmiStat = &pPnmiStruct->Stat[0];
len = sk_proc_print(buffer,
"\nDetailed statistic for device %s\n", seq_printf(seq, "\nDetailed statistic for device %s\n",
pAC->dev[t-1]->name); pAC->dev[t-1]->name);
len += sk_proc_print(buffer, seq_printf(seq, "=======================================\n");
"=======================================\n");
/* Board statistics */ /* Board statistics */
len += sk_proc_print(buffer, seq_printf(seq, "\nBoard statistics\n\n");
"\nBoard statistics\n\n"); seq_printf(seq, "Active Port %c\n",
len += sk_proc_print(buffer, 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
"Active Port %c\n", Net[t-1].PrefPort]->PortNumber);
'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. seq_printf(seq, "Preferred Port %c\n",
Net[t-1].PrefPort]->PortNumber); 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
len += sk_proc_print(buffer, Net[t-1].PrefPort]->PortNumber);
"Preferred Port %c\n",
'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
Net[t-1].PrefPort]->PortNumber);
len += sk_proc_print(buffer, seq_printf(seq, "Bus speed (MHz) %d\n",
"Bus speed (MHz) %d\n", pPnmiStruct->BusSpeed);
pPnmiStruct->BusSpeed);
len += sk_proc_print(buffer, seq_printf(seq, "Bus width (Bit) %d\n",
"Bus width (Bit) %d\n", pPnmiStruct->BusWidth);
pPnmiStruct->BusWidth); seq_printf(seq, "Driver version %s\n",
len += sk_proc_print(buffer, VER_STRING);
"Driver version %s\n", seq_printf(seq, "Hardware revision v%d.%d\n",
VER_STRING); (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
len += sk_proc_print(buffer, pAC->GIni.GIPciHwRev & 0x0F);
"Hardware revision v%d.%d\n",
(pAC->GIni.GIPciHwRev >> 4) & 0x0F,
pAC->GIni.GIPciHwRev & 0x0F);
/* Print sensor informations */ /* Print sensor informations */
for (i=0; i < pAC->I2c.MaxSens; i ++) { for (i=0; i < pAC->I2c.MaxSens; i ++) {
/* Check type */ /* Check type */
switch (pAC->I2c.SenTable[i].SenType) { switch (pAC->I2c.SenTable[i].SenType) {
case 1: case 1:
strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
strcat(sens_msg, " (C)"); strcat(sens_msg, " (C)");
len += sk_proc_print(buffer, seq_printf(seq, "%-25s %d.%02d\n",
"%-25s %d.%02d\n", sens_msg,
sens_msg, pAC->I2c.SenTable[i].SenValue / 10,
pAC->I2c.SenTable[i].SenValue / 10, pAC->I2c.SenTable[i].SenValue % 10);
pAC->I2c.SenTable[i].SenValue % 10);
strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
strcat(sens_msg, " (F)"); strcat(sens_msg, " (F)");
len += sk_proc_print(buffer, seq_printf(seq, "%-25s %d.%02d\n",
"%-25s %d.%02d\n", sens_msg,
sens_msg, ((((pAC->I2c.SenTable[i].SenValue)
((((pAC->I2c.SenTable[i].SenValue) *10)*9)/5 + 3200)/100,
*10)*9)/5 + 3200)/100, ((((pAC->I2c.SenTable[i].SenValue)
((((pAC->I2c.SenTable[i].SenValue) *10)*9)/5 + 3200) % 10);
*10)*9)/5 + 3200) % 10); break;
break; case 2:
case 2: strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcat(sens_msg, " (V)");
strcat(sens_msg, " (V)"); seq_printf(seq, "%-25s %d.%03d\n",
len += sk_proc_print(buffer, sens_msg,
"%-25s %d.%03d\n", pAC->I2c.SenTable[i].SenValue / 1000,
sens_msg, pAC->I2c.SenTable[i].SenValue % 1000);
pAC->I2c.SenTable[i].SenValue / 1000, break;
pAC->I2c.SenTable[i].SenValue % 1000); case 3:
break; strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
case 3: strcat(sens_msg, " (rpm)");
strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); seq_printf(seq, "%-25s %d\n",
strcat(sens_msg, " (rpm)"); sens_msg,
len += sk_proc_print(buffer, pAC->I2c.SenTable[i].SenValue);
"%-25s %d\n", break;
sens_msg, default:
pAC->I2c.SenTable[i].SenValue); break;
break;
default:
break;
}
} }
}
/*Receive statistics */ /*Receive statistics */
len += sk_proc_print(buffer, seq_printf(seq, "\nReceive statistics\n\n");
"\nReceive statistics\n\n");
len += sk_proc_print(buffer, seq_printf(seq, "Received bytes %Lu\n",
"Received bytes %Lu\n", (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
(unsigned long long) pPnmiStat->StatRxOctetsOkCts); seq_printf(seq, "Received packets %Lu\n",
len += sk_proc_print(buffer, (unsigned long long) pPnmiStat->StatRxOkCts);
"Received packets %Lu\n",
(unsigned long long) pPnmiStat->StatRxOkCts);
#if 0 #if 0
if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC &&
pAC->HWRevision < 12) { pAC->HWRevision < 12) {
pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
pPnmiStat->StatRxShortsCts; pPnmiStat->StatRxShortsCts;
pPnmiStat->StatRxShortsCts = 0; pPnmiStat->StatRxShortsCts = 0;
} }
#endif #endif
if (pNet->Mtu > 1500) if (dev->mtu > 1500)
pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
pPnmiStat->StatRxTooLongCts; pPnmiStat->StatRxTooLongCts;
len += sk_proc_print(buffer, seq_printf(seq, "Receive errors %Lu\n",
"Receive errors %Lu\n", (unsigned long long) pPnmiStruct->InErrorsCts);
(unsigned long long) pPnmiStruct->InErrorsCts); seq_printf(seq, "Receive dropped %Lu\n",
len += sk_proc_print(buffer, (unsigned long long) pPnmiStruct->RxNoBufCts);
"Receive dropped %Lu\n", seq_printf(seq, "Received multicast %Lu\n",
(unsigned long long) pPnmiStruct->RxNoBufCts); (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
len += sk_proc_print(buffer, seq_printf(seq, "Receive error types\n");
"Received multicast %Lu\n", seq_printf(seq, " length %Lu\n",
(unsigned long long) pPnmiStat->StatRxMulticastOkCts); (unsigned long long) pPnmiStat->StatRxRuntCts);
len += sk_proc_print(buffer, seq_printf(seq, " buffer overflow %Lu\n",
"Receive error types\n"); (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
len += sk_proc_print(buffer, seq_printf(seq, " bad crc %Lu\n",
" length %Lu\n", (unsigned long long) pPnmiStat->StatRxFcsCts);
(unsigned long long) pPnmiStat->StatRxRuntCts); seq_printf(seq, " framing %Lu\n",
len += sk_proc_print(buffer, (unsigned long long) pPnmiStat->StatRxFramingCts);
" buffer overflow %Lu\n", seq_printf(seq, " missed frames %Lu\n",
(unsigned long long) pPnmiStat->StatRxFifoOverflowCts); (unsigned long long) pPnmiStat->StatRxMissedCts);
len += sk_proc_print(buffer,
" bad crc %Lu\n",
(unsigned long long) pPnmiStat->StatRxFcsCts);
len += sk_proc_print(buffer,
" framing %Lu\n",
(unsigned long long) pPnmiStat->StatRxFramingCts);
len += sk_proc_print(buffer,
" missed frames %Lu\n",
(unsigned long long) pPnmiStat->StatRxMissedCts);
if (pNet->Mtu > 1500) if (dev->mtu > 1500)
pPnmiStat->StatRxTooLongCts = 0; pPnmiStat->StatRxTooLongCts = 0;
len += sk_proc_print(buffer, seq_printf(seq, " too long %Lu\n",
" too long %Lu\n", (unsigned long long) pPnmiStat->StatRxTooLongCts);
(unsigned long long) pPnmiStat->StatRxTooLongCts); seq_printf(seq, " carrier extension %Lu\n",
len += sk_proc_print(buffer, (unsigned long long) pPnmiStat->StatRxCextCts);
" carrier extension %Lu\n", seq_printf(seq, " too short %Lu\n",
(unsigned long long) pPnmiStat->StatRxCextCts); (unsigned long long) pPnmiStat->StatRxShortsCts);
len += sk_proc_print(buffer, seq_printf(seq, " symbol %Lu\n",
" too short %Lu\n", (unsigned long long) pPnmiStat->StatRxSymbolCts);
(unsigned long long) pPnmiStat->StatRxShortsCts); seq_printf(seq, " LLC MAC size %Lu\n",
len += sk_proc_print(buffer, (unsigned long long) pPnmiStat->StatRxIRLengthCts);
" symbol %Lu\n", seq_printf(seq, " carrier event %Lu\n",
(unsigned long long) pPnmiStat->StatRxSymbolCts); (unsigned long long) pPnmiStat->StatRxCarrierCts);
len += sk_proc_print(buffer, seq_printf(seq, " jabber %Lu\n",
" LLC MAC size %Lu\n", (unsigned long long) pPnmiStat->StatRxJabberCts);
(unsigned long long) pPnmiStat->StatRxIRLengthCts);
len += sk_proc_print(buffer,
" carrier event %Lu\n",
(unsigned long long) pPnmiStat->StatRxCarrierCts);
len += sk_proc_print(buffer,
" jabber %Lu\n",
(unsigned long long) pPnmiStat->StatRxJabberCts);
/*Transmit statistics */ /*Transmit statistics */
len += sk_proc_print(buffer, seq_printf(seq, "\nTransmit statistics\n\n");
"\nTransmit statistics\n\n");
len += sk_proc_print(buffer, seq_printf(seq, "Transmited bytes %Lu\n",
"Transmited bytes %Lu\n", (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
(unsigned long long) pPnmiStat->StatTxOctetsOkCts); seq_printf(seq, "Transmited packets %Lu\n",
len += sk_proc_print(buffer, (unsigned long long) pPnmiStat->StatTxOkCts);
"Transmited packets %Lu\n", seq_printf(seq, "Transmit errors %Lu\n",
(unsigned long long) pPnmiStat->StatTxOkCts); (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
len += sk_proc_print(buffer, seq_printf(seq, "Transmit dropped %Lu\n",
"Transmit errors %Lu\n", (unsigned long long) pPnmiStruct->TxNoBufCts);
(unsigned long long) pPnmiStat->StatTxSingleCollisionCts); seq_printf(seq, "Transmit collisions %Lu\n",
len += sk_proc_print(buffer, (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
"Transmit dropped %Lu\n", seq_printf(seq, "Transmit error types\n");
(unsigned long long) pPnmiStruct->TxNoBufCts); seq_printf(seq, " excessive collision %ld\n",
len += sk_proc_print(buffer, pAC->stats.tx_aborted_errors);
"Transmit collisions %Lu\n", seq_printf(seq, " carrier %Lu\n",
(unsigned long long) pPnmiStat->StatTxSingleCollisionCts); (unsigned long long) pPnmiStat->StatTxCarrierCts);
len += sk_proc_print(buffer, seq_printf(seq, " fifo underrun %Lu\n",
"Transmit error types\n"); (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
len += sk_proc_print(buffer, seq_printf(seq, " heartbeat %Lu\n",
" excessive collision %ld\n", (unsigned long long) pPnmiStat->StatTxCarrierCts);
pAC->stats.tx_aborted_errors); seq_printf(seq, " window %ld\n",
len += sk_proc_print(buffer, pAC->stats.tx_window_errors);
" carrier %Lu\n",
(unsigned long long) pPnmiStat->StatTxCarrierCts);
len += sk_proc_print(buffer,
" fifo underrun %Lu\n",
(unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
len += sk_proc_print(buffer,
" heartbeat %Lu\n",
(unsigned long long) pPnmiStat->StatTxCarrierCts);
len += sk_proc_print(buffer,
" window %ld\n",
pAC->stats.tx_window_errors);
} /* if (strcmp(pACname, currDeviceName) == 0) */
} }
SkgeProcDev = next;
} }
} return 0;
/*****************************************************************************
*
* sk_proc_print -generic line print
*
* Description:
* This function fills the proc entry with statistic data about
* the ethernet device.
*
* Returns: number of bytes written
*
*/
static int sk_proc_print(void *writePtr, char *format, ...)
{
#define MAX_LEN_SINGLE_LINE 256
char str[MAX_LEN_SINGLE_LINE];
va_list a_start;
int lenght = 0;
struct seq_file *seq = (struct seq_file *) writePtr;
SK_MEMSET(str, 0, MAX_LEN_SINGLE_LINE);
va_start(a_start, format);
vsprintf(str, format, a_start);
va_end(a_start);
lenght = strlen(str);
seq_printf(seq, str);
return lenght;
}
/*****************************************************************************
*
* sk_seq_show - show proc information of a particular adapter
*
* Description:
* This function fills the proc entry with statistic data about
* the ethernet device. It invokes the generic sk_gen_browse() to
* print out all items one per one.
*
* Returns: number of bytes written
*
*/
static int sk_seq_show(struct seq_file *seq, void *v)
{
void *castedBuffer = (void *) seq;
currDev = seq->private;
sk_gen_browse(castedBuffer);
return 0;
} }
/***************************************************************************** /*****************************************************************************
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment