Skip to content

Commit

Permalink
Merge pull request #377 from christopher-s-hall/open-avb-next
Browse files Browse the repository at this point in the history
Fix broken windows code
  • Loading branch information
andrew-elder committed Apr 22, 2016
2 parents 20731bd + e8e8214 commit 1d8f5cc
Show file tree
Hide file tree
Showing 9 changed files with 212 additions and 68 deletions.
6 changes: 3 additions & 3 deletions daemons/gptp/common/avbts_message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,8 @@ class PathTraceTLV {
IdentityList::iterator iter;
*((uint16_t *)byte_str) = tlvType; // tlvType already in network byte order
byte_str += sizeof(tlvType);
*((uint16_t *)byte_str) =
PLAT_htons(identityList.size()*PTP_CLOCK_IDENTITY_LENGTH);
*((uint16_t *)byte_str) = PLAT_htons
((uint16_t)identityList.size()*PTP_CLOCK_IDENTITY_LENGTH);
byte_str += sizeof(uint16_t);
for
(iter = identityList.begin();
Expand Down Expand Up @@ -414,7 +414,7 @@ class PathTraceTLV {
* @return Total length
*/
int length() {
return 2*sizeof(uint16_t) + PTP_CLOCK_IDENTITY_LENGTH*identityList.size();
return (int)(2*sizeof(uint16_t) + PTP_CLOCK_IDENTITY_LENGTH*identityList.size());
}
};

Expand Down
4 changes: 2 additions & 2 deletions daemons/gptp/common/gptp_cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ int GptpIniParser::iniCallBack(void *user, const char *section, const char *name
{
errno = 0;
char *pEnd;
unsigned char p1 = strtoul(value, &pEnd, 10);
unsigned char p1 = (unsigned char) strtoul(value, &pEnd, 10);
if( *pEnd == '\0' && errno == 0) {
valOK = true;
parser->_config.priority1 = p1;
Expand Down Expand Up @@ -140,7 +140,7 @@ int GptpIniParser::iniCallBack(void *user, const char *section, const char *name
{
errno = 0;
char *pEnd;
uint16_t lostpdelayth = strtoul(value, &pEnd, 10);
uint16_t lostpdelayth = (uint16_t) strtoul(value, &pEnd, 10);
if( *pEnd == '\0' && errno == 0 ) {
valOK = true;
parser->_config.lostPdelayRespThresh = lostpdelayth;
Expand Down
18 changes: 17 additions & 1 deletion daemons/gptp/common/ieee1588.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,23 @@ class HWTimestamper {
return 0;
}

/**
/**
* @brief Sets the the PHY delay for TX and RX
* @param [input] struct phy_delay pointer
* @return 0
**/

int set_phy_delay(struct phy_delay *set_delay)
{
delay.mb_tx_phy_delay = set_delay->mb_tx_phy_delay;
delay.mb_rx_phy_delay = set_delay->mb_rx_phy_delay;
delay.gb_tx_phy_delay = set_delay->gb_tx_phy_delay;
delay.gb_rx_phy_delay = set_delay->gb_rx_phy_delay;

return 0;
}

/**
* Default constructor. Sets version to zero.
*/
HWTimestamper() { version = 0; }
Expand Down
7 changes: 4 additions & 3 deletions daemons/gptp/common/ieee1588port.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ IEEE1588Port::IEEE1588Port
void IEEE1588Port::timestamper_init(void)
{
if( _hw_timestamper != NULL ) {
_hw_timestamper->init_phy_delay(this->link_delay);
if( !_hw_timestamper->HWTimestamper_init( net_label, net_iface )) {
XPTPD_ERROR
( "Failed to initialize hardware timestamper, "
Expand All @@ -159,7 +160,6 @@ void IEEE1588Port::timestamper_init(void)
return;
}
}
_hw_timestamper->init_phy_delay(this->link_delay);
}

bool IEEE1588Port::init_port(int delay[4])
Expand Down Expand Up @@ -327,8 +327,9 @@ bool IEEE1588Port::restoreSerializedState( void *buf, off_t *count ) {
void *IEEE1588Port::openPort(IEEE1588Port *port)
{
port_ready_condition->signal();
struct phy_delay get_delay;
port->_hw_timestamper->get_phy_delay(&get_delay);
struct phy_delay get_delay = { 0, 0, 0, 0 };
if(port->_hw_timestamper)
port->_hw_timestamper->get_phy_delay(&get_delay);

while (1) {
PTPMessageCommon *msg;
Expand Down
2 changes: 1 addition & 1 deletion daemons/gptp/common/ptp_message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,7 @@ void PTPMessagePathDelayResp::processMessage(IEEE1588Port * port)
XPTPD_ERROR("Remote misbehaving. Stopping PDelay Requests for 5 minutes.");
port->stopPDelay();
port->getClock()->addEventTimerLocked
(port, PDELAY_RESP_PEER_MISBEHAVING_TIMEOUT_EXPIRES, 300 * 1000000000.0);
(port, PDELAY_RESP_PEER_MISBEHAVING_TIMEOUT_EXPIRES, (int64_t)(300 * 1000000000.0));
}
}
else {
Expand Down
13 changes: 1 addition & 12 deletions daemons/gptp/windows/daemon_cl/daemon_cl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ POSSIBILITY OF SUCH DAMAGE.

#define MACSTR_LENGTH 17

#define PHY_DELAY_GB_TX_I20 184 //1G delay in nanoseconds
#define PHY_DELAY_GB_RX_I20 382 //1G delay in nanoseconds
#define PHY_DELAY_MB_TX_I20 1044 //100M delay in nanoseconds
#define PHY_DELAY_MB_RX_I20 2133 //100M delay in nanoseconds

static bool exit_flag;

void print_usage( char *arg0 ) {
Expand Down Expand Up @@ -87,8 +82,8 @@ int _tmain(int argc, _TCHAR* argv[])
int32_t offset = 0;
bool syntonize = false;
uint8_t priority1 = 248;
int phy_delays[4] = { 0 };
int i;
int phy_delays[4] = { -1, -1, -1, -1 };

// Register default network interface
WindowsPCAPNetworkInterfaceFactory *default_factory = new WindowsPCAPNetworkInterfaceFactory();
Expand Down Expand Up @@ -139,12 +134,6 @@ int _tmain(int argc, _TCHAR* argv[])
parseMacAddr( argv[i], local_addr_ostr );
LinkLayerAddress local_addr(local_addr_ostr);

// Initialize default PHY delays
phy_delays[0] = PHY_DELAY_GB_TX_I20;
phy_delays[1] = PHY_DELAY_GB_RX_I20;
phy_delays[2] = PHY_DELAY_MB_TX_I20;
phy_delays[3] = PHY_DELAY_MB_RX_I20;

// Create HWTimestamper object
HWTimestamper *timestamper = new WindowsTimestamper();
// Create Clock object
Expand Down
89 changes: 72 additions & 17 deletions daemons/gptp/windows/daemon_cl/tsc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@

#include <intrin.h>
#include <stdint.h>

#define BASE_FREQUENCY 100000000 /*!< Base frequency in HZ */
#include <VersionHelpers.h>

/**
* @brief Gets the processor timestamp
Expand All @@ -50,30 +49,86 @@ inline unsigned __int64 PLAT_rdtsc()
return __rdtsc();
}

#define CLOCK_INFO_CPUID_LEAF (0x15)
#define SYSTEM_CLOCK_24MHZ (24000000)
#define MAX_MODEL_LIST_LEN (2)

typedef struct
{
short model_list[MAX_MODEL_LIST_LEN+1]; // Terminate model list with -1
uint32_t clock_rate; // clock_rate of 0 is invalid
}
ModelNumberSystemClockRateMapping;

static ModelNumberSystemClockRateMapping ModelNumberSystemClockRateMap[] =
{
{{ 0x5E, 0x4E, -1 }, SYSTEM_CLOCK_24MHZ },
{{ -1 }, 0 },
};

/**
* @brief Gets the system clock frequency using CPU model number
* @param model_query model number to look up
* @return System frequency, or 0 on error
*/
inline uint32_t FindFrequencyByModel(uint8_t model_query) {
ModelNumberSystemClockRateMapping *map = ModelNumberSystemClockRateMap;
uint32_t ret = 0;

while (map->clock_rate != 0)
{
short *model = map->model_list;

while (*model != -1)
{
if (*model == model_query) {
ret = map->clock_rate;
break;
}
++model;
}
++map;
}

return ret;
}


/**
* @brief Gets the TSC frequnecy
* @param millis time in miliseconds
* @return TSC frequency
* @return TSC frequency, or 0 on error
*/
inline uint64_t getTSCFrequency( unsigned millis ) {
UINT16 multiplierx2;
uint64_t frequency = 0;
DWORD mhz;
DWORD mhz_sz = sizeof(mhz);
int max_cpuid_level;
int tmp[4];

if( RegGetValue( HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "~MHz", RRF_RT_REG_DWORD, NULL, &mhz, &mhz_sz ) != ERROR_SUCCESS ) {
goto done;
// Find the max cpuid level, and if possible find clock info
__cpuid(tmp, 0);
max_cpuid_level = tmp[0];
if (max_cpuid_level >= CLOCK_INFO_CPUID_LEAF)
__cpuid(tmp, CLOCK_INFO_CPUID_LEAF);

// For pre-Win10 on 6th Generation or greater Intel CPUs the raw hardware
// clock will be returned, *else* use QPC for everything else
//
// EAX (tmp[0]) must be >= 1, See Intel SDM 17.15.4 "Invariant Time-keeping"
if (!IsWindows10OrGreater() && max_cpuid_level >= CLOCK_INFO_CPUID_LEAF &&
tmp[0] >= 1) {
SYSTEM_INFO info;

GetSystemInfo(&info);

// Look at processor model (upper byte of revision) number to determine clock rate
return FindFrequencyByModel(info.wProcessorRevision >> 8);
}
fprintf( stderr, "mhz: %u\n", mhz );
multiplierx2 = (UINT16)((2*mhz*1000000ULL)/BASE_FREQUENCY);
if( multiplierx2 % 2 == 1 ) ++multiplierx2;
fprintf( stderr, "Multiplier: %hhu\n", multiplierx2/2 );

frequency = (((uint64_t)multiplierx2)*BASE_FREQUENCY)/2;
fprintf( stderr, "Frequency: %llu\n", frequency );
LARGE_INTEGER freq;

if (QueryPerformanceFrequency(&freq))
return freq.QuadPart;

done:
return frequency;
return 0;
}

#endif/*TSC_HPP*/
59 changes: 54 additions & 5 deletions daemons/gptp/windows/daemon_cl/windows_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ bool WindowsTimestamper::HWTimestamper_init( InterfaceLabel *iface_label, OSNetw
PIP_ADAPTER_INFO pAdapterInfo;
IP_ADAPTER_INFO AdapterInfo[32]; // Allocate information for up to 32 NICs
DWORD dwBufLen = sizeof(AdapterInfo); // Save memory size of buffer
struct phy_delay delay_val;

DWORD dwStatus = GetAdaptersInfo( AdapterInfo, &dwBufLen );
if( dwStatus != ERROR_SUCCESS ) return false;
Expand All @@ -87,12 +88,60 @@ bool WindowsTimestamper::HWTimestamper_init( InterfaceLabel *iface_label, OSNetw

if( pAdapterInfo == NULL ) return false;

if( strstr( pAdapterInfo->Description, NANOSECOND_CLOCK_PART_DESCRIPTION ) != NULL ) {
netclock_hz.QuadPart = NETCLOCK_HZ_NANO;
} else {
netclock_hz.QuadPart = NETCLOCK_HZ_OTHER;
get_phy_delay(&delay_val);

DeviceClockRateMapping *rate_map = DeviceClockRateMap;
while (rate_map->device_desc != NULL)
{
if (strstr(pAdapterInfo->Description, rate_map->device_desc) != NULL)
break;
++rate_map;
}
if (rate_map->device_desc != NULL) {
netclock_hz.QuadPart = rate_map->clock_rate;
}
else {
XPTPD_ERROR("Unable to determine clock rate for interface %s", pAdapterInfo->Description);
return false;
}

DevicePhyDelayMapping *phy_map = DevicePhyDelayMap;
while (phy_map->device_desc != NULL)
{
if (strstr(pAdapterInfo->Description, phy_map->device_desc) != NULL)
break;
++phy_map;
}
if (phy_map->device_desc != NULL) {
if(delay_val.gb_rx_phy_delay == -1)
delay_val.gb_rx_phy_delay = phy_map->delay.gb_rx_phy_delay;
if (delay_val.gb_tx_phy_delay == -1)
delay_val.gb_tx_phy_delay = phy_map->delay.gb_tx_phy_delay;
if (delay_val.mb_rx_phy_delay == -1)
delay_val.mb_rx_phy_delay = phy_map->delay.mb_rx_phy_delay;
if (delay_val.mb_tx_phy_delay == -1)
delay_val.mb_tx_phy_delay = phy_map->delay.mb_tx_phy_delay;
set_phy_delay(&delay_val);
}

if (delay_val.gb_rx_phy_delay == -1) {
XPTPD_ERROR("Warning: Gbit receive PHY delay is unknown using 0");
delay_val.gb_rx_phy_delay = 0;
}
fprintf( stderr, "Adapter UID: %s\n", pAdapterInfo->AdapterName );
if (delay_val.gb_tx_phy_delay == -1) {
XPTPD_ERROR("Warning: Gbit transmit PHY delay is unknown using 0");
delay_val.gb_tx_phy_delay = 0;
}
if (delay_val.mb_rx_phy_delay == -1) {
XPTPD_ERROR("Warning: Mbit receive PHY delay is unknown using 0");
delay_val.mb_rx_phy_delay = 0;
}
if (delay_val.mb_tx_phy_delay == -1) {
XPTPD_ERROR("Warning: Mbit transmit PHY delay is unknown using 0");
delay_val.gb_tx_phy_delay = 0;
}

XPTPD_INFO( "Adapter UID: %s\n", pAdapterInfo->AdapterName );
PLAT_strncpy( network_card_id, NETWORK_CARD_ID_PREFIX, 63 );
PLAT_strncpy( network_card_id+strlen(network_card_id), pAdapterInfo->AdapterName, 63-strlen(network_card_id) );

Expand Down
Loading

0 comments on commit 1d8f5cc

Please sign in to comment.