📄 nsmos.c
字号:
// Stop Netstack from sending more pkts
netif_stop_queue(netdev);
// Reset Receive Engine - To get back pending fragments
spin_lock_irq(&adapter->rxLock);
MplReceiveReset(adapter->mplContext);
spin_unlock_irq(&adapter->rxLock);
// Reset Transmit Engine - To get back pending pkt
spin_lock_irq(&adapter->txLock);
MplTransmitReset(adapter->mplContext);
spin_unlock_irq(&adapter->txLock);
#ifdef LINUX_POWER_DEBUG
MplWolCfg(adapter->mplContext, NS_TRUE, adapter->wolModes);
#endif //NSM_DEBUG
// Put device in LOW_POWER mode - Ask MPL to set PME for us
status = MplPowerSetState(adapter->mplContext,
MPL_POWER_STATE_LOW, NS_TRUE);
}
// Detach our device from active list
netif_device_detach(netdev);
rtnl_unlock();
return 0;
}
NS_SINT
NsmResume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv;
MPL_STATUS status;
NS_SINT ret;
rtnl_lock();
if (netif_device_present(netdev))
{
rtnl_unlock();
return 0x0;
}
if (netif_running(netdev))
{
// Enable PCI device
ret = pci_enable_device(pdev);
// Put device in HIGH_POWER mode
status = MplPowerSetState(adapter->mplContext,
MPL_POWER_STATE_HIGH, NS_TRUE);
// Replenish MPL with Receive Buffers
replenishTask((unsigned long)adapter);
// Enable Interrupts
MplInterruptEnable(adapter->mplContext);
// Configure the Link - Done after Ints are enabled
configLink(adapter);
}
// Attach our device to active list
netif_device_attach(netdev);
rtnl_unlock();
return 0x0;
}
#endif
NS_VOID
NsmRemove(struct pci_dev *pdev)
{
struct net_device *netdev;
NSM_CONTEXT *adapter;
NI(NsmRemove);
netdev = pci_get_drvdata(pdev);
// Adapter not found!
if(netdev == NULL)
{
NSM_DBG(DBG_ERR,("Adapter Not Found! \n"));
NO(NsmRemove);
return;
}
// Get our private device struct
adapter = (NSM_CONTEXT *) netdev->priv;
// Unregister this Net device from the OS
if (adapter->netdevReg == NS_TRUE)
{
unregister_netdev(netdev);
}
// MPL:UnInitialize the adapter
if (adapter->mplContext != NULL)
{
MplUnload(adapter->mplContext);
}
// Free system resources
#ifdef NSM_IO_MAP
if(adapter->regAddr != NULL)
{
adapter->regAddr = NULL;
}
#else
if(adapter->regAddr != NULL)
{
// First unmap the memory
iounmap(adapter->regAddr);
adapter->regAddr = NULL;
}
#endif
// Release the PCI address space
pci_release_regions(pdev);
// Free the Netdev struct and my NSM context struct
kfree(netdev);
// Decrement cards found
NsmAdapterCnt--;
NO(NsmRemove);
return;
}
NS_SINT
NsmOpen(struct net_device *netdev)
{
NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv;
NI(NsmOpen);
// Register Interrupt Service Routine
if (request_irq(netdev->irq, &NsmIsr, SA_SHIRQ, DP_driverName, adapter))
{
NSM_DBG(DBG_ERR,("Failed to Get IRQ \n"));
NO(NsmOpen);
return -EAGAIN;
}
// Initialize SpinLocks
spin_lock_init(&adapter->txLock);
spin_lock_init(&adapter->rxLock);
spin_lock_init(&adapter->linkLock);
// Get Mpl Capabilities
MplGetCaps(adapter->mplContext, &adapter->mplCaps);
// Normal and Monitor mode : Cfg Mac, Link, RxFrags
// Load only mode : Open only
if (adapter->opMode != MPL_MODE_LOAD_ONLY)
{
// Configure the MAC
if (configMac(adapter) == NS_FALSE)
{
NSM_DBG(DBG_ERR,("Config Mac Failed \n"));
free_irq(netdev->irq, adapter);
NO(NsmOpen);
return -EAGAIN;
}
// Initialize link monitor tasklet
tasklet_init(&adapter->linkMonTask, linkTask, (unsigned long) adapter);
//Task Offloads Enables
// Rx Filter (Multicast and Unicast Filtering)
MplTaskFilterCfg(adapter->mplContext, NS_TRUE);
// Allocate and setup MPL_FRAGs to hold Receive Buffers
// These are wrapper structures used to post new buffers to MPL rx
if (setupRxFrags(adapter) == NS_FALSE)
{
NSM_DBG(DBG_ERR,("Frag Setup Failed \n"));
free_irq(netdev->irq, adapter);
NO(NsmOpen);
return -ENOMEM;
}
}
#ifdef NSM_DIAG_MODE
// Initialize Diag Module
if (adapter->opMode != MPL_MODE_NORMAL)
{
if (NsmDiagInitialize(adapter) != NS_STATUS_SUCCESS)
{
NSM_DBG(DBG_ERR,("Diag Setup Failed \n"));
// Free the MPL Pkt Fragments
freeRxFrags(adapter);
free_irq(netdev->irq, adapter);
NO(NsmOpen);
return -ENOMEM;
}
}
#endif //NSM_DIAG_MODE
// Open the adapter for operations
if (adapter->opMode != MPL_MODE_LOAD_ONLY)
{
// Replenish MPL with Receive Buffers
replenishTask((unsigned long)adapter);
// Open the MPL Adapter
MplOpen(adapter->mplContext);
// Configure the Link - Done after Ints are enabled
configLink(adapter);
}
else
{
// Open the MPL Adapter - No other setups required here
// We just assume the link is up - the diag app would need
// to ensure this is the case before doing any tx/rx
MplOpen(adapter->mplContext);
adapter->linkStatus = MPL_LINK_STATUS_UP;
}
// If the Link is not UP, notify Net Stack
if ((adapter->linkStatus != MPL_LINK_STATUS_UP) ||
(adapter->opMode != MPL_MODE_NORMAL))
{
netif_stop_queue(netdev);
}
NO(NsmOpen);
return 0x0;
}
NS_SINT
NsmXmit(struct sk_buff *skb, struct net_device *netdev)
{
NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv;
MPL_PKT mplPkt;
MPL_PKT_FRAG mplFrag;
MPL_STATUS status;
NI(NsmXmit);
// Test if the link is down
if (adapter->linkStatus != MPL_LINK_STATUS_UP)
{
NSM_DBG(DBG_ERR,("Link Down \n"));
netif_stop_queue(netdev);
NO(NsmXmit);
return -EAGAIN;
}
mplPkt.pNextPacket = NULL;
mplPkt.fragCount = 0x01;
// Set priority - FM: Map to higher level protocol?
mplPkt.txOOB.pQueue = 1;
// Prep MPL frag
mplFrag.pNextFrag = NULL;
mplFrag.fragSize = skb->len;
mplFrag.physAddr = pci_map_single(adapter->pdev,
skb->data, skb->len, PCI_DMA_TODEVICE);
mplFrag.pAddr = skb->data;
// Store in the physAddr of the skb in the private field
*(NS_UINT *)skb->cb = mplFrag.physAddr;
// Send Packet
mplPkt.pFragHead = &mplFrag;
mplPkt.packetSize = skb->len;
mplPkt.pNsmPrivate = skb; //Set Skb ptr as NSM private
spin_lock_irq(&adapter->txLock);
status = MplTransmit(adapter->mplContext, 0x01, &mplPkt);
spin_unlock_irq(&adapter->txLock);
// Check status
if (status != NS_STATUS_SUCCESS)
{
if (mplPkt.packetStatus == NS_STATUS_RESOURCES)
{
// Stop the Net Stack
netif_stop_queue(netdev);
return -ENOMEM;
}
else
{
// Drop the pkt - Free the skb
pci_unmap_single(adapter->pdev, mplFrag.physAddr,
skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb(skb);
adapter->netStats.tx_dropped++;
}
}
NO(NsmXmit);
return 0x0;
}
void
NsmSetMulti(struct net_device *netdev)
{
NSM_CONTEXT *adapter = netdev->priv;
NS_UINT filterFlag, i;
struct dev_mc_list *mcAddr;
NI(NsmSetMulti);
if (adapter->opMode != MPL_MODE_NORMAL)
{
return;
}
// Check if we need to go to Promiscuous Mode
if (netdev->flags & IFF_PROMISC)
{
filterFlag = MPL_RECEIVE_FILTER_PROMISCUOUS_MODE;
}
else
{
// We always receive directed unicast and broadcast
filterFlag = MPL_RECEIVE_FILTER_DIRECTED_UNICAST |
MPL_RECEIVE_FILTER_ACCEPTALL_BROADCAST;
if (netdev->flags & IFF_ALLMULTI)
{
// All multicasts
filterFlag |= MPL_RECEIVE_FILTER_ACCEPTALL_MCAST;
}
else
{
// Accept multicasts directed to our interest list
filterFlag |= MPL_RECEIVE_FILTER_DIRECTED_MCAST;
// Add multicast list to the device
if(netdev->mc_count > 0x0)
{
// Clear the current MC list
MplTaskFilterMcastClearList(adapter->mplContext);
// Report the list to MPL
mcAddr = netdev->mc_list;
for (i = 0x0; i < netdev->mc_count; i++)
{
if (mcAddr != NULL)
{
// Add the MC addr
MplTaskFilterMcastAddAddr(adapter->mplContext,
mcAddr->dmi_addr);
// Get the next MC addr
mcAddr = mcAddr->next;
}
}
}
}
}
MplReceiveSetFilter(adapter->mplContext, filterFlag);
NO(NsmSetMulti);
return;
}
struct net_device_stats *
NsmStats(struct net_device *netdev)
{
NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv;
// NI(NsmStats);
//FM: Update Stats from MPL
// NO(NsmStats);
return &adapter->netStats;
}
NS_SINT
NsmSetMac(struct net_device *netdev, void *p)
{
struct sockaddr *mac = p;
NSM_CONTEXT *adapter = netdev->priv;
NI(NsmSetMac);
memcpy(netdev->dev_addr, mac->sa_data, netdev->addr_len);
MplSetMacAddress(adapter->mplContext, netdev->dev_addr);
NO(NsmSetMac);
return 0x0;
}
NS_SINT
NsmIoctl(struct net_device *netdev, struct ifreq *rq, NS_SINT cmd)
{
NS_SINT ret = 0x0;
NSM_CONTEXT *adapter = netdev->priv;
struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
// NI(NsmIoctl);
switch(cmd)
{
#ifdef NSM_DIAG_MODE
// National's Integrity Tool
case NS_APP_IOCTL_CODE:
{
NS_UINT status;
// Handle the ioctl
status = NsmDiagIoctl(adapter,
(NS_VOID *) rq->ifr_data);
if (status != NS_STATUS_SUCCESS)
{
switch (status)
{
case NS_STATUS_NOT_SUPPORTED:
ret = -EOPNOTSUPP;
break;
case NS_STATUS_INVALID_PARM:
ret = -EINVAL;
break;
case NS_STATUS_RESOURCES:
ret = -ENOMEM;
break;
default :
ret = -EFAULT;
}
}
break;
}
#endif //NSM_DIAG_MODE
// Other Linux Community Tools
case SIOCETHTOOL :
ret = -EOPNOTSUPP; //Soon to be supported
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -