📄 nsmdiag.c
字号:
//******************************************************************************
//
// NSMDIAG.C
//
// Copyright (c) 2004 National Semiconductor Corporation.
// All Rights Reserved
//
// NSM Adapter Diagostics Interface API
//
// OpMode Combinations
// ==========================================================
// | || NORMAL | LOAD_ONLY | MONITOR |
// | Op Mode ||(non-Diag) | (Diag Mode) | (Diag Mode) |
// ==========================================================
// | Operation|| O W N E R |
// |----------------------------------------------------------
// | H/w Init || NSM | Diag App | NSM |
// ---------------------------------------------------------
// | Tx/Rx || NSM | Diag App | Diag App |
// ==========================================================
//
// This file contains the API implementations for
// o Adapter Txd and Rxd Setup - Diag Mode
// o Packet Tx
// o Packet Rx
// o Cmd demultiplexer
//
//******************************************************************************
#include <nsmos.h>
#include <nsm.h>
#ifdef NSM_DIAG_MODE
// Local functions
static NS_BOOLEAN setupTxFrags(NSM_CONTEXT *adapter);
static NS_VOID freeTxFrags(NSM_CONTEXT *adapter);
static NS_BOOLEAN pktSetup(NSM_CONTEXT *adapter);
static NS_VOID pktFree(NSM_CONTEXT *adapter);
static NS_UINT
txPkt( NSM_CONTEXT *adapter, NS_APP_XFER_CMD *txCmd, NS_UINT8 *txData);
static NS_BOOLEAN
checkAvailTxFrag( NSM_CONTEXT *adapter, NS_UINT reqFrags);
static NS_UINT pktStatus(
NSM_CONTEXT *adapter, MPL_LIST *pList,
MPL_PKT_FRAG **ppTailFrag, spinlock_t *pLock,
NS_APP_XFER_CMD *pCmd, NS_UINT8 *pData);
static NS_VOID pktValidate(NSM_CONTEXT *adapter, MPL_PKT_FRAG *pHeadFrag);
static NS_VOID flushTx(NSM_CONTEXT *adapter);
static NS_VOID flushRx(NSM_CONTEXT *adapter);
static NS_VOID getDiagStats(NSM_CONTEXT *adapter, NS_APP_STATS_CMD *pCmd);
static NS_UINT xferCfgSet( NSM_CONTEXT *adapter, NS_APP_XFER_CFG_CMD *pCmd);
static NS_UINT xferCfgGet( NSM_CONTEXT *adapter, NS_APP_XFER_CFG_CMD *pCmd);
//*****************************************************************************
// NsmDiagInitialize
// Diag module initialization
//
// Parameters
// adapter
// NSM Context
//
// Return Value
// NS_STATUS_SUCCESS
// The configurations were successfully applied
// NS_STATUS_RESOURCES
// Failed to allocate required resources
//*****************************************************************************
NS_UINT
NsmDiagInitialize(
NSM_CONTEXT *adapter)
{
NI(NsmDiagInitialize);
if (adapter->opMode != MPL_MODE_LOAD_ONLY)
{
// Setup the free MPL frag list (for Tx)
if (setupTxFrags(adapter) != NS_TRUE)
{
NO(NsmDiagInitialize);
return NS_STATUS_RESOURCES;
}
// Setup the Diag packet list (for both Tx and Rx use)
if (pktSetup(adapter) != NS_TRUE)
{
freeTxFrags(adapter);
pktFree(adapter);
NO(NsmDiagInitialize);
return NS_STATUS_RESOURCES;
}
}
else
{
// Only initialize the lists - The population of the list
// happens when the app calls xferCfg
MplListInit(&adapter->diagFreeList, NS_FALSE);
MplListInit(&adapter->diagTxDoneList, NS_FALSE);
MplListInit(&adapter->diagRxDoneList, NS_FALSE);
}
NO(NsmDiagInitialize);
return NS_STATUS_SUCCESS;
}
//*****************************************************************************
// NsmDiagUnInitialize
// Diag module uninitialization
//
// Parameters
// adapter
// NSM Context
//
// Return Value
// None
//*****************************************************************************
NS_VOID
NsmDiagUnInitialize(
NSM_CONTEXT *adapter)
{
NI(NsmDiagUnInitialize);
// Free the Diag Pkt cache
pktFree(adapter);
// Free the MPL_FRAGs cache for Tx
freeTxFrags(adapter);
NO(NsmDiagUnInitialize);
return;
}
//*****************************************************************************
// NsmDiagIoctl
// Diag Cmd Multiplexer
//
// Parameters
// adapter
// NSM Context
// userAddr
// Pointer to user buffer (Would need OS specific tweaking)
//
// Return Value
// NS_STATUS_SUCCESS
// The configurations were successfully applied
// NS_STATUS_INVALID_PARM
// An invalid parameter value was detected
// NS_STATUS_RESOURCES
// Failed to allocate required resources
// NS_STATUS_NOT_SUPPORTED
// Operation not supported
// NS_STATUS_FAILURE
// Operation failed
//*****************************************************************************
NS_UINT
NsmDiagIoctl(
NSM_CONTEXT *adapter,
NS_VOID *useraddr)
{
NS_UINT ret = NS_STATUS_SUCCESS;
NS_APP_REG_CMD regCmd;
NS_APP_INTRO_CMD introCmd;
NS_APP_XFER_CMD xferCmd;
NS_APP_XFER_CFG_CMD cfgCmd;
NS_APP_STATS_CMD statCmd;
NS_APP_CMD baseCmd;
NS_UINT cmd;
NI(NsmDiagIoctl);
// FM: Make all user access funcations as abstracted APIs
if (get_user(cmd, (NS_UINT32 *)useraddr))
{
NO(NsmDiagIoctl);
return NS_STATUS_FAILURE;;
}
// Handle basic Reg read/write kind of requests here
// This is available in all modes
switch (cmd)
{
case NSM_APP_INTRO:
if (copy_from_user(&introCmd, useraddr,
sizeof(introCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
if (introCmd.app == NS_APP_SIGN)
{
introCmd.driver = NS_DRIVER_SIGN;
introCmd.numPorts = 0x01;
introCmd.driverVerMajor = DP_driverVersionMaj;
introCmd.driverVerMinor = DP_driverVersionMin;
}
if (copy_to_user(useraddr, &introCmd,
sizeof(introCmd)))
{
ret = NS_STATUS_FAILURE;
}
}
break;
case NSM_REG_READ:
if (copy_from_user(®Cmd, useraddr,
sizeof(regCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
regCmd.data = MplRegRead(adapter->mplContext,
regCmd.offset);
if (copy_to_user(useraddr, ®Cmd,
sizeof(regCmd)))
{
ret = NS_STATUS_FAILURE;
}
}
break;
case NSM_REG_WRITE:
if (copy_from_user(®Cmd, useraddr,
sizeof(regCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
MplRegWrite(adapter->mplContext, regCmd.offset,
regCmd.data);
}
break;
case NSM_PCI_READ:
if (copy_from_user(®Cmd, useraddr,
sizeof(regCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
pci_read_config_dword(adapter->pdev, regCmd.offset,
(unsigned int *)®Cmd.data);
if (copy_to_user(useraddr, ®Cmd,
sizeof(regCmd)))
{
ret = NS_STATUS_FAILURE;
}
}
break;
case NSM_PCI_WRITE:
if (copy_from_user(®Cmd, useraddr,
sizeof(regCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
pci_write_config_dword(adapter->pdev,
regCmd.offset, regCmd.data);
}
break;
default :
ret = NS_STATUS_NOT_SUPPORTED;
}
// Check if the request is for a Tx/Rx related operation
// Note this is only available when we are in one of the two debug modes
if (adapter->opMode != MPL_MODE_NORMAL && ret == NS_STATUS_NOT_SUPPORTED)
{
ret = NS_STATUS_SUCCESS;
switch (cmd)
{
case NSM_XFER_CFG_SET:
if (copy_from_user(&cfgCmd, useraddr,
sizeof(cfgCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
// Call cfg handler
cfgCmd.status = xferCfgSet(adapter, &cfgCmd);
// Copy results back
if (copy_to_user(useraddr, &cfgCmd,
sizeof(cfgCmd)))
{
ret = NS_STATUS_FAILURE;
}
}
break;
case NSM_XFER_CFG_GET:
if (copy_from_user(&cfgCmd, useraddr,
sizeof(cfgCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
// Call cfg handler
cfgCmd.status = xferCfgGet(adapter, &cfgCmd);
// Copy results back
if (copy_to_user(useraddr, &cfgCmd,
sizeof(cfgCmd)))
{
ret = NS_STATUS_FAILURE;
}
}
break;
case NSM_TRANSMIT:
if (copy_from_user(&xferCmd, useraddr,
sizeof(xferCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
// Call Tx pkt handler
xferCmd.status =
txPkt(adapter, &xferCmd,
(NS_UINT8 *)useraddr + sizeof(xferCmd));
// Copy results back
if (copy_to_user(useraddr, &xferCmd,
sizeof(xferCmd)))
{
ret = NS_STATUS_FAILURE;
}
}
break;
case NSM_TRANSMIT_STATUS:
if (copy_from_user(&xferCmd, useraddr,
sizeof(xferCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
// Call pkt handler
xferCmd.status =
pktStatus(adapter, &adapter->diagTxDoneList,
&adapter->txFragsTail, &adapter->txLock,
&xferCmd,
(NS_UINT8 *)useraddr + sizeof(xferCmd));
// Copy results back
if (copy_to_user(useraddr, &xferCmd,
sizeof(xferCmd)))
{
ret = NS_STATUS_FAILURE;
}
}
break;
case NSM_TRANSMIT_FLUSH:
if (copy_from_user(&baseCmd, useraddr,
sizeof(baseCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
flushTx(adapter);
}
break;
case NSM_RECEIVE:
if (copy_from_user(&xferCmd, useraddr,
sizeof(xferCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
// Call pkt handler
xferCmd.pktHandle = 0x0;
xferCmd.status =
pktStatus(adapter, &adapter->diagRxDoneList,
&adapter->rxFragsTail, &adapter->rxLock,
&xferCmd,
(NS_UINT8 *)useraddr + sizeof(xferCmd));
// Copy results back
if (copy_to_user(useraddr, &xferCmd,
sizeof(xferCmd)))
{
ret = NS_STATUS_FAILURE;
}
}
break;
case NSM_RECEIVE_FLUSH:
if (copy_from_user(&baseCmd, useraddr,
sizeof(baseCmd)))
{
ret = NS_STATUS_FAILURE;
}
else
{
flushRx(adapter);
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -