📄 nsmos.c
字号:
//******************************************************************************
//
// NSMOS.C
//
// Copyright (c) 2005 National Semiconductor Corporation.
// All Rights Reserved
//
// NSM Driver for MPL based MacPhyter Devices
//
//******************************************************************************
#include <nsm.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NSC");
MODULE_DESCRIPTION("NSC DP8381X 10/100Mbps MacPhyter Ethernet");
// Max NICs supported by this driver
#define DP_MAX_NIC 8
// Globals
char DP_driverName[] = "DP8381X";
char DP_driverString[]="NSC Macphyter Driver";
char DP_driverVersionMaj = 1; // Major Ver
char DP_driverVersionMin = 6; // Minor Ver
char DP_driverVersion[] = "n.1.6";
char DP_copyright[] = "Copyright (c) 2005-2007 National Semiconductor";
char DP83815_ID[] = "DP83815 (MacPhyter-I)";
char DP83816_ID[] = "DP83816 (MacPhyter-II)";
char DP83818_ID[] = "DP83818 (MacPhyter-III)";
char UNKNOWN_ID[] = "UNKNOWN";
// Module Params
// Initialize all to -1 i.e not configured
#define DP_PARAM_INIT { [0 ... (DP_MAX_NIC - 1)] = -1}
#define DP_PARAM(PARM, DESC) \
static const int __devinitdata PARM[DP_MAX_NIC] = DP_PARAM_INIT; \
MODULE_PARM(PARM, "1-" __MODULE_STRING(DP_MAX_NIC) "i"); \
MODULE_PARM_DESC(PARM, DESC);
// Number of Transmit Descriptors (32bytes each)
// Default : 64
DP_PARAM(TxDCnt, "Number Of Transmit Descriptors");
// Number of Transmit Queues to be enabled
// Default : 1, Max : 4 (only on DP83818)
DP_PARAM(TxQCnt, "Number Of Transmit Queues");
// Number of Receive Descriptors (32bytes each)
// Default : 64
DP_PARAM(RxDCnt, "Number Of Receive Descriptors");
// Number of Receive Queues to be enabled
// Default : 1, Max : 1
DP_PARAM(RxQCnt, "Number Of Receive Queues");
// Desired Link Setup Mode
// 0 : Auto Negotiate (Default)
// 1 : Force Speed and Duplex Mode
DP_PARAM(LinkMode, "Link Setup Mode");
// Desired Link Speed
// Note : If set in AutoNeg mode then this is the Max speed advertized
// 0 : 100Mbps (Default)
// 1 : 10Mbps
DP_PARAM(LinkSpeed, "Link Speed");
// Desired Link Duplex Mode
// Note : If set in AutoNeg mode then this is the mode advertized
// 0 : Full Duplex (Default)
// 1 : Half Duplex
DP_PARAM(LinkDuplex, "Link Duplex Mode");
// Desired Link Pause Mode
// Note : If set in AutoNeg mode then this is the mode advertized
// 0 : Receive Pause Only (Default)
// 1 : Transmit Pause Only
// 2 : Transmit and Receive Pause (Symmetrical)
// 3 : No Pause generation
DP_PARAM(LinkPause, "Link Pause Mode");
// Interrupt Holdoff in usec (Micro)
// Default : 100
// Max : 25500 (i.e. 25.5 msec)
DP_PARAM(IntTimeHold, "Interrupt Holdoff");
// Interrupt Holdoff in Tx pkt count
// Default : 2
// Max : 63
DP_PARAM(IntTxHold, "Interrupt Holdoff in Tx Packets");
// Interrupt Holdoff in Rx pkt count
// Default : 2
// Max : 63
DP_PARAM(IntRxHold, "Interrupt Holdoff in Rx Packets");
// Driver Operation Mode
// 0 : Normal (Default)
// 1 : Monitor (National Semiconductor Internal)
// 2 : Load Only (National Semiconductor Internal)
DP_PARAM(OpMode, "Driver Operational Mode");
// Desired Wol Events (Logical OR)
// 0x01 : MPL_WOL_MAGIC - Enable wake on Magic Pattern.
// 0x04 : MPL_WOL_BROADCAST - Enable wake on any broadcast packet.
// 0x08 : MPL_WOL_MULTICAST - Enable wake on multicast packet.
// 0x10 : MPL_WOL_DIRECTED - Enable wake on directed (unicast) packet to
// the device's address.
// 0x20 : MPL_WOL_LINK - Enable wake on link status change.
// 0x40 : MPL_WOL_ARP - Enable wake on any ARP packet.
DP_PARAM(Wol, "Wake-on-LAN Events");
#ifdef NSM_DIAG_MODE
// Number of pkts possible in the status queue
// Default : 256
DP_PARAM(DiagStsQueue, "Size of the Diag Status Queue");
#endif //NSM_DIAG_MODE
#ifdef NSM_DEBUG
// NSM (OS Specific Module) Debug Zones to be enabled
DP_PARAM(NsmDebugZones, "Debug Zones For NSM Module");
// MPL (Hardware Abstraction Layer) Debug Zones to be enabled
DP_PARAM(MplDebugZones, "Debug Zones For MPL Module");
// Debug Zones for this file
NS_UINT NsmDbgSettings =
DBG_INFO |
DBG_FUNC |
DBG_TMP |
DBG_ERR;
NS_UINT MplPathZones =
DZONE_MPL_INIT_DOWN |
DZONE_MPL_TRANS |
DZONE_MPL_RECV |
DZONE_MPL_INTR |
DZONE_MPL_LINK |
DZONE_MPL_PWR |
DZONE_MPL_DIAG |
DZONE_MPL_MISC;
NS_UINT MplMsgZones =
DZONE_MPL_INIT_DOWN |
DZONE_MPL_TRANS |
DZONE_MPL_RECV |
DZONE_MPL_INTR |
DZONE_MPL_LINK |
DZONE_MPL_PWR |
DZONE_MPL_DIAG |
DZONE_MPL_MISC;
#else
NS_UINT NsmDbgSettings = 0x0;
NS_UINT MplPathZones = 0x0;
NS_UINT MplMsgZones = 0x0;
#endif
// Adapter count
unsigned NsmAdapterCnt = 0x0;
/*********************************************************************
* PCI device list for NSC MacPhyter adapters
* { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
* Class, Class Mask, String Index }
* Last device should be 0
*********************************************************************/
#define PCI_DEVICE_ID_DP8381X 0x0020
static struct pci_device_id DP_pciTable[] = {
{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_DP8381X,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, DP_pciTable);
// PCI driver struct for this driver
static struct pci_driver DP_driver = {
name: DP_driverName,
id_table: DP_pciTable,
probe: NsmProbe,
remove: NsmRemove,
#ifdef CONFIG_PM
suspend: NsmSuspend,
resume: NsmResume
#endif
};
// Locals
static NS_VOID readPciInfo(NSM_CONTEXT *adapter);
static NS_VOID setDataFields(NSM_CONTEXT *adapter);
static NS_VOID readUserOptions(NSM_CONTEXT *adapter);
static NS_BOOLEAN configMac(NSM_CONTEXT *adapter);
static NS_BOOLEAN configLink(NSM_CONTEXT *adapter);
static NS_VOID linkTask(unsigned long data);
static
NS_SINT __init NsmInitModule(void)
{
NI(NsmInitModule);
// Print driver ver
printk(KERN_INFO"%s - version %s\n%s\n", DP_driverString,
DP_driverVersion,
DP_copyright);
/* Register to PCI subsystem */
NO(NsmInitModule);
return pci_module_init(&DP_driver);
}
static
NS_VOID __exit NsmExitModule(void)
{
NI(NsmExitModule);
// UnRegister from PCI subsystem
pci_unregister_driver(&DP_driver);
NO(NsmExitModule);
return;
}
// Module entry/exit points
module_init(NsmInitModule);
module_exit(NsmExitModule);
NS_SINT
NsmProbe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct net_device *netdev = NULL;
NSM_CONTEXT *adapter;
NS_CHAR *nicId = NULL;
NI(NsmProbe);
// Make sure we are not exceeding our max card count
if (NsmAdapterCnt == DP_MAX_NIC)
{
NSM_DBG(DBG_ERR,("Card Found exceeds limit \n"));
NO(NsmProbe);
return -ENODEV;
}
// Enable this PCI device
if(pci_enable_device(pdev) != 0) \
{
NSM_DBG(DBG_ERR,("pci_enable_device failed\n"));
NO(NsmProbe);
return -ENODEV;
}
// Set the device as Master capable
pci_set_master(pdev);
// Check to see if our PCI addressing needs are supported
if(!pci_dma_supported(pdev, NSM_DMA_MASK))
{
NSM_DBG(DBG_ERR,("PCI DMA not supported by the system\n"));
NO(NsmProbe);
return -ENODEV;
}
else
pdev->dma_mask = NSM_DMA_MASK;
// Init the net device, allocate adapter context
netdev = alloc_etherdev(sizeof (NSM_CONTEXT));
if(netdev == NULL)
{
NSM_DBG(DBG_ERR,("Unable to allocate net_device struct\n"));
NO(NsmProbe);
return -ENOMEM;
}
// Init adapter context
adapter = (NSM_CONTEXT *) netdev->priv;
memset(adapter, 0, sizeof(NSM_CONTEXT));
adapter->netdev = netdev;
adapter->pdev = pdev;
adapter->regAddr = NULL;
pci_set_drvdata(pdev, netdev);
// Default MTU
netdev->mtu = ENET_MTU;
if (pci_request_regions(pdev, DP_driverName))
{
NSM_DBG(DBG_ERR,("pci_request_region failed\n"));
NsmRemove(pdev);
NO(NsmProbe);
return -ENOMEM;
}
#ifdef NSM_IO_MAP
// We are operating on the IO space
netdev->base_addr = pci_resource_start(pdev, BAR_0);
adapter->regAddr = (NS_VOID *)netdev->base_addr;
netdev->mem_start = pci_resource_start(pdev, BAR_0);
netdev->mem_end = netdev->mem_start + pci_resource_len(pdev, BAR_0);
#else
// We are operating on the Mem space
// Remap the IO region
adapter->regAddr = ioremap(pci_resource_start(pdev, BAR_1),
pci_resource_len(pdev, BAR_1));
if(adapter->regAddr == NULL)
{
NSM_DBG(DBG_ERR,("ioremap failed\n"));
NsmRemove(pdev);
NO(NsmProbe);
return -ENOMEM;
}
else
{
// Let the Net stack know about the IO region
netdev->base_addr = pci_resource_start(pdev, BAR_1);
netdev->mem_start = pci_resource_start(pdev, BAR_1);
netdev->mem_end = netdev->mem_start + pci_resource_len(pdev, BAR_1);
}
#endif
// Read the Pci info
readPciInfo(adapter);
// Set default values for this adapter struct
setDataFields(adapter);
// Read module params and note in adapter struct
readUserOptions(adapter);
// Enable MPL debug levels
MplDebEnablePathTracing(MplPathZones);
MplDebEnableMsgsAndChecks(MplMsgZones);
// MPL Intializations
adapter->mplContext = NULL;
if (MplInitialize(adapter, adapter->regAddr, adapter->opMode,
&adapter->mplContext)
!= NS_STATUS_SUCCESS)
{
NsmRemove(pdev);
NO(NsmProbe);
printk(KERN_INFO"%s - Failed to Initialize Device! \n",
DP_driverString);
return -ENODEV;
}
// Set the Netdevice entry points for this adapter
netdev->open = &NsmOpen;
netdev->stop = &NsmClose;
netdev->hard_start_xmit = &NsmXmit;
netdev->get_stats = &NsmStats;
netdev->set_multicast_list = &NsmSetMulti;
netdev->set_mac_address = &NsmSetMac;
netdev->do_ioctl = &NsmIoctl;
netdev->change_mtu = &NsmChangeMtu;
// Register this device to Net Stack
SET_MODULE_OWNER(netdev);
#ifdef L26
SET_NETDEV_DEV(netdev, &pdev->dev);
#endif
if (register_netdev(netdev))
{
NsmRemove(pdev);
NO(NsmProbe);
return -ENODEV;
}
else
{
adapter->netdevReg = NS_TRUE;
}
// Hold-off the netdev till we have a link
netif_carrier_off(netdev);
// Note our irq - The line itself requested after we are open
netdev->irq = pdev->irq;
// Set Netdevice features - FM: Checksum?
netdev->features = NETIF_F_SG;
// Note the instance count for this adapter and increment cards found
adapter->cardIndex = ++NsmAdapterCnt;
nicId = UNKNOWN_ID;
if (adapter->opMode != MPL_MODE_LOAD_ONLY)
{
// Get the current mac addr
MplGetMacAddress(adapter->mplContext, NS_FALSE, netdev->dev_addr);
// Display device
adapter->deviceId = MplGetDeviceId(adapter->mplContext);
switch (adapter->deviceId)
{
case MPL_DEVICE_ID_DP83815 : nicId = DP83815_ID;
break;
case MPL_DEVICE_ID_DP83816 : nicId = DP83816_ID;
break;
case MPL_DEVICE_ID_DP83818 : nicId = DP83818_ID;
break;
default : nicId = UNKNOWN_ID;
}
}
adapter->verMajor = DP_driverVersionMaj;
adapter->verMinor = DP_driverVersionMin;
printk("%s: v-%d.%d NSC-%s:%x-%x Mem:0x%p IRQ:%d RegAddr:0x%p Mode:%d \n",
netdev->name,adapter->verMajor, adapter->verMinor,
nicId, adapter->pciSubVendorId,
adapter->pciSubDeviceId, (void *)netdev->mem_start, netdev->irq,
adapter->regAddr, adapter->opMode);
// AOK!
NO(NsmProbe);
return 0;
}
#ifdef CONFIG_PM
NS_SINT
NsmSuspend(struct pci_dev *pdev, NS_UINT state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv;
MPL_STATUS status;
rtnl_lock();
if (netif_running(netdev))
{
// We are currently running so, prep for suspend
// Disable further Interrupts
MplInterruptDisable(adapter->mplContext);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -