in source/code/scxsystemlib/networkinterface/networkinterface.cpp [1486:1771]
void NetworkInterfaceInfo::Get_NDD_STAT(SCXHandle<NetworkInterfaceDependencies> deps)
{
SCX_LOGTRACE(m_log, L"NetworkInterfaceInfo::Get_NDD_STAT entry");
/* This function provides the support for those drivers which report
* speed related stats as part of configuration parameters.
* (defined in header files: /usr/include/sys/cdli_*.h)
*
* The list of supported drivers is as follows:
* kent_config for the PCI Ethernet Device Driver (22100020)
* phxent for the 10/100 Mbps Ethernet PCI Adapter Device Driver (23100020)
* scent for the 10/100 Mbps Ethernet PCI Adapter II Device Driver (1410ff01)
* gxent for the Gigabit Ethernet-SX PCI Adapter Device Driver (14100401)
* goent for Gigabit Ethernet-SX PCI-X Adapter Device Driver (14106802),
* 10/100/1000 Base-T Ethernet PCI-X Adapter Device Driver (14106902),
* 2-Port Gigabit Ethernet-SX PCI-X Adapter Device Driver (14108802),
* 2-Port 10/100/1000 Base-TX PCI-X Adapter Device Driver (14108902),
* 4-Port 10/100/1000 Base-TX PCI-X Adapter Device Driver (14101103),
* 4-Port 10/100/1000 Base-TX PCI-Exp Adapter Dev Driver(14106803),
* 2-Port Gigabit Ethernet-SX PCI-Express Adapter Device Driver
* (14103f03),
* 2-Port 10/100/1000 Base-TX PCI-Express Adapter Device Driver
* (14104003).
*
* ment Gigabit Ethernet-SX PCI-X Adapter Device Driver (14106703).
*
* hea for Host Ethernet Adapter Device Driver.
*********************END OF SUPPORTED DRIVERS ************************************/
/* This function doesn't provide the support for the following drivers
* due to the overlap of their device_type values with some of the
* above list drivers:
*
* bent for the Gigabit Ethernet-SX Adapter Device Driver (e414a816).
* (reason: ENT_BT_PCI, ENT_UTP_PCI, ENT_BT_PCI_OTHER,and ENT_UTP_PCI_OTHER
* have the same value as ENT_CENT_PCI_TX,ENT_UTP_PCI,
* ENT_GX_PCI_OTHER, ENT_UTP_PCI_OTHER(defined for gxent) respectively
*
* ment for Gigabit Ethernet-SX Adapter Device Driver (14101403)
* (reason: ENT_MT_SX_PCI has the same value as ENT_GX_PCI defined for gxent)
*
* kngent for the 10 Gigabit Ethernet-SR PCI-X 2.0 DDR Adapter Device
* Driver (1410eb02) and the 10 Gigabit Ethernet-LR PCI_X 2.0 DDR
* Adapter Device Driver (1410ec02).
* (reason: ENT_KNGENT_LR_PCIX and ENT_KNGENT_SR_PCIX have the same value as
* ENT_CENT_PCI_TX and ENT_EPENT_PCI_TX respectively (defined for
* goent driver))
*/
union ARG
{
kent_all_stats_t kent;
phxent_all_stats_t phxent;
scent_all_stats_t scent;
gxent_all_stats_t gxent;
goent_all_stats_t goent;
ment_all_stats_t ment;
hea_all_stats_t hea;
lncent_all_stats_t lncent;
shient_all_stats_t shient;
} arg; // Used for ioctl argument.
// First, we need to connect to the adapter in question.
struct sockaddr_ndd_8022 sa;
int s;
SCX_LOGTRACE(m_log, L"NetworkInterfaceInfo::Get_NDD_STAT Connecting to socket");
s = socket(AF_NDD, SOCK_DGRAM, 0);
if (s < 0)
{
std::wstringstream errMsg;
errMsg.str(L"");
errMsg << L"socket(AF_NDD,SOCK_DGRAM,0) failed. errno: " << errno << L"- interface: " << m_name;
SCXCoreLib::SCXLogSeverity severity(suppressor.GetSeverity(SCXCoreLib::StrFrom(errMsg.str())));
SCX_LOG(m_log, severity, errMsg.str());
return;
}
// Close the resource through a helper class, should an exception happens.
SCX_LOGTRACE(m_log, L"NetworkInterfaceInfo::Get_NDD_STAT Setting up AutoClose");
AutoClose _fd(m_log, s);
sa.sndd_8022_family = AF_NDD;
sa.sndd_8022_len = sizeof(struct sockaddr_ndd_8022);
sa.sndd_8022_filtertype = NS_TAP;
sa.sndd_8022_filterlen = sizeof(ns_8022_t);
strcpy((char *)sa.sndd_8022_nddname, SCXCoreLib::StrToUTF8(m_name).c_str());
SCX_LOGTRACE(m_log, wstring(L"NetworkInterfaceInfo::Get_NDD_STAT Binding to socket") + m_name);
if (deps->bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_ndd_8022)) < 0)
{
// This is to log file name and line number along with the rest of error message.
SCXCoreLib::SCXErrnoException e(L"bind() failed. errno: ", errno, SCXSRCLOCATION);
SCX_LOGERROR(m_log, e.What());
return;
}
int on = 1;
SCX_LOGTRACE(m_log, L"NetworkInterfaceInfo::Get_NDD_STAT Setting option SO_REUSEADDR");
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
{
SCXCoreLib::SCXErrnoException e(L"setsockopt() failed. errno: ", errno, SCXSRCLOCATION);
SCX_LOGERROR(m_log, e.What());
return;
}
// Populate the ioctl argument accordingly.
// The ioctl argument for the stat related commands must be struct nddctl.
SCX_LOGTRACE(m_log, L"NetworkInterfaceInfo::Get_NDD_STAT Populating ioctl");
nddctl ioctl_arg;
ioctl_arg.nddctl_buflen = sizeof(ARG);
ioctl_arg.nddctl_buf = (caddr_t)&arg;
// Issue the ioctl command to get the device extended stats.
// (http://pic.dhe.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.kernelext%2Fdoc%2Fkernextc%2Fndd_get_all_stats_devctrlop.htm)
SCX_LOGTRACE(m_log, L"NetworkInterfaceInfo::Get_NDD_STAT Issuing ioctl");
if (deps->ioctl(s,NDD_GET_ALL_STATS,&ioctl_arg) < 0)
{
SCXCoreLib::SCXErrnoException e(L"ioctl(s,NDD_GET_ALL_STATS,&arg) failed. errno: ", errno, SCXSRCLOCATION);
SCX_LOGERROR(m_log, e.What());
return;
}
m_autoSense = false;
m_speed = 0;
m_maxSpeed = 0;
unsigned int device_type = arg.kent.ent_gen_stats.device_type;
scxulong auto_speed = 0; // meida_speed, speed_negotiated, or link_negotiated.
SCX_LOGTRACE(m_log, L"NetworkInterfaceInfo::Get_NDD_STAT At device switch");
// Find out which driver we are dealing with.
// If supported then retrieve the intended info.
// (http://pic.dhe.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.kernelext%2Fdoc%2Fkernextc%2Fconfig.htm)
switch (device_type)
{
// kent
case ENT_3COM:
case ENT_IENT:
case ENT_IEN_ISA:
case ENT_LCE:
case ENT_KEN_PCI:
case ENT_LSA:
case ENT_IEN_PCMCIA:
// PCI Ethernet Adapter Device Driver (22100020) only supports the
// following additional configuration parameters
// (speed is not one of them!):
// Full Duplex, Hardware Transmit Queue, Hardware Receive Queue.
m_maxSpeed = SPEED_100; // This is a 10/100Mbps Eth PCI adapter.
break;
// phxent
case ENT_PHX_PCI:
case ENT_CLVR_PCI:
case ENT_PHX_INT_PCI:
case ENT_CLVR_INT_PCI:
m_maxSpeed = SPEED_100; // This is a 10/100Mbps Eth PCI adapter.
set_speed(arg.phxent.phxent_stats.speed_selected, arg.phxent.phxent_stats.media_speed);
break;
// scent
case ENT_SCENT_PCI:
m_maxSpeed = SPEED_100; // This is a 10/100Mbps Eth PCI adapter.
set_speed(arg.scent.scent_stats.speed_selected, arg.scent.scent_stats.speed_negotiated);
break;
// gxent
case ENT_GX_PCI:
case ENT_UTP_PCI:
case ENT_GX_PCI_OTHER:
case ENT_UTP_PCI_OTHER:
m_maxSpeed = SPEED_1000; // This is a Gigabit Ethernet PCI adapter.
auto_speed = arg.gxent.gxent_stats.link_negotiated;
if (auto_speed & NDD_GXENT_LNK_10MB)
{
auto_speed = MEDIA_10_FULL;
}
else if (auto_speed & NDD_GXENT_LNK_100MB)
{
auto_speed = MEDIA_100_FULL;
}
else if (auto_speed & NDD_GXENT_LNK_1000MB)
{
auto_speed = MEDIA_1000_FULL;
}
set_speed(arg.gxent.gxent_stats.speed_selected, auto_speed);
break;
// goent
case ENT_GOENT_PCI_TX:
case ENT_GOENT_PCI_SX:
case ENT_DENT_PCI_TX:
case ENT_DENT_PCI_SX:
case ENT_CENT_PCI_TX:
case ENT_EPENT_PCI_TX:
case ENT_EPENT_PCI_SX:
case ENT_CLENT_PCI_TX:
m_maxSpeed = SPEED_1000; // This is a Gigabit Ethernet PCI adapter.
set_speed(arg.goent.goent_stats.speed_selected, arg.goent.goent_stats.speed_negotiated);
break;
// ment
case ENT_SM_SX_PCI:
m_maxSpeed = SPEED_1000; // This is a Gigabit Ethernet-SX Adapter.
auto_speed = arg.ment.ment_stats.link_negotiated;
if (auto_speed & NDD_MENT_LNK_10MB)
{
auto_speed = MEDIA_10_FULL;
}
else if (arg.ment.ment_stats.link_negotiated & NDD_MENT_LNK_100MB)
{
auto_speed = MEDIA_100_FULL;
}
else if (arg.ment.ment_stats.link_negotiated & NDD_MENT_LNK_1000MB)
{
auto_speed = MEDIA_1000_FULL;
}
set_speed(arg.ment.ment_stats.speed_selected, auto_speed);
break;
// lncent
case ENT_LNC_TYPE:
case ENT_LNC_VF:
//Support for Lancer drivers
m_maxSpeed = SPEED_10000; // This is 10 Gigabit Ethernet PCI adapter.
break;
default:
// Is it a Host Ethernet Adapter?
// The reason I am using the sizeof() to indentify
// the HEA device type, is that there is no device type for it.
// The ndd_2_flags in ndd_t structure represents the HEA device
// type. I couldn't find a way to query the ndd_t structure.
// (I tried the NDD_GET_NDD command defined in ndd.h but
// it didn't work!
if (ioctl_arg.nddctl_buflen = sizeof(hea_all_stats_t))
{
switch(arg.hea.hea_stats.speed_selected)
{
case HEA_MEDIA_10_HALF:
case HEA_MEDIA_10_FULL:
m_speed = m_maxSpeed = SPEED_10;
break;
case HEA_MEDIA_100_HALF:
case HEA_MEDIA_100_FULL:
m_speed = m_maxSpeed = SPEED_100;
break;
case HEA_MEDIA_1000_FULL:
m_speed = m_maxSpeed = SPEED_1000;
break;
case HEA_MEDIA_10000_FULL:
m_speed = m_maxSpeed = SPEED_10000;
break;
case HEA_MEDIA_AUTO:
m_autoSense = true;
break;
default:
std::wstringstream errMsg;
errMsg.str(L"");
errMsg << L"Invalid seleced speed: " << arg.hea.hea_stats.speed_selected << L"- interface: " << m_name;
SCXCoreLib::SCXLogSeverity severity(suppressor.GetSeverity(SCXCoreLib::StrFrom(errMsg.str())));
SCX_LOG(m_log, severity, errMsg.str());
break;
}
}
else // Not supported driver.
{
std::wstringstream errMsg;
errMsg.str(L"");
errMsg << L"The driver not supported for the interface: " << m_name << " with device type: " << device_type;
SCXCoreLib::SCXLogSeverity severity(suppressor.GetSeverity(SCXCoreLib::StrFrom(errMsg.str())));
SCX_LOG(m_log, severity, errMsg.str());
}
break;
}
SCX_LOGTRACE(m_log, L"NetworkInterfaceInfo::Get_NDD_STAT After device switch");
m_knownAttributesMask |= eAutoSense;
} // End of Get_NDD_STAT()