diff options
Diffstat (limited to 'daemons/gptp/windows/daemon_cl/intel_wireless.cpp')
-rw-r--r-- | daemons/gptp/windows/daemon_cl/intel_wireless.cpp | 424 |
1 files changed, 0 insertions, 424 deletions
diff --git a/daemons/gptp/windows/daemon_cl/intel_wireless.cpp b/daemons/gptp/windows/daemon_cl/intel_wireless.cpp deleted file mode 100644 index a6f8f99f..00000000 --- a/daemons/gptp/windows/daemon_cl/intel_wireless.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2015, Intel Corporation -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. Neither the name of the Intel Corporation nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -******************************************************************************/ - -#include <intel_wireless.hpp> -#include <windows_hal.hpp> -#include <work_queue.hpp> -#include <memory> -#include <map> - -#define INTEL_EVENT_OFFSET 0x1141 -#define GP2_ROLLOVER 4294967296ULL - -GetAdapterList_t GetAdapterList; -WifiCmdTimingMeasurementRequest_t WifiCmdTimingMeasurementRequest; -WifiCmdTimingPtmWa_t WifiCmdTimingPtmWa; -RegisterIntelCallback_t RegisterIntelCallback; -DeregisterIntelCallback_t DeregisterIntelCallback; - -struct TimestamperContext -{ - WindowsWorkQueue work_queue; - WindowsWirelessTimestamper *timestamper; - ~TimestamperContext() - { - work_queue.stop(); - } -}; - -typedef std::map< LinkLayerAddress, TimestamperContext > TimestamperContextMap; - -class LockedTimestamperContextMap -{ -public: - LockedTimestamperContextMap() - { - InitializeSRWLock(&lock); - } - TimestamperContextMap map; - SRWLOCK lock; -}; - -LockedTimestamperContextMap timestamperContextMap; -HANDLE IntelTimestamperThread; -bool IntelTimestamperThreadStop = false; - -void IntelWirelessTimestamperEventHandler( INTEL_EVENT iEvent, void *pContext ) -{ - WindowsWirelessTimestamper *timestamper; - IntelWirelessAdapter *adapter; - LockedTimestamperContextMap *timestamperContextMap = - (LockedTimestamperContextMap *)pContext; - WirelessTimestamperCallbackArg *arg = - new WirelessTimestamperCallbackArg(); - int vendor_extension_copy_length; - bool error = false; - bool submit = false; // If true submit the event for later processing - - // We share driver callback with other events, subtract the offset for - // timing measurement related events and check this is time sync event - iEvent.eType = - (WIRELESS_EVENT_TYPE) (iEvent.eType - INTEL_EVENT_OFFSET); - switch( iEvent.eType ) - { - default: - return; - case TIMINGMSMT_CONFIRM_EVENT: - case TIMINGMSMT_EVENT: - case TIMINGMSMT_CORRELATEDTIME_EVENT: - break; - } - - LinkLayerAddress event_source( iEvent.BtMacAddress ); - arg->iEvent_type = (WIRELESS_EVENT_TYPE) iEvent.eType; - AcquireSRWLockShared( ×tamperContextMap->lock ); - if( timestamperContextMap->map.find( event_source ) - != timestamperContextMap->map.cend()) - { - arg->timestamper = - timestamperContextMap->map[event_source].timestamper; - } else - { - goto bail; - } - - timestamper = dynamic_cast <WindowsWirelessTimestamper *> - (arg->timestamper); - if( timestamper == NULL ) - { - GPTP_LOG_ERROR( "Unexpected timestamper type encountered" ); - goto bail; - } - adapter = dynamic_cast <IntelWirelessAdapter *> - (timestamper->getAdapter( )); - if( adapter == NULL ) - { - GPTP_LOG_ERROR( "Unexpected adapter type encountered" ); - goto bail; - } - - // The driver implementation makes no guarantee of the lifetime of the - // iEvent object we make a copy and delete the copy when processing is - // complete - switch( arg->iEvent_type ) - { - case TIMINGMSMT_CONFIRM_EVENT: - arg->event_data.confirm = - *(TIMINGMSMT_CONFIRM_EVENT_DATA *)iEvent.data; - arg->event_data.confirm.T1 = - adapter->calc_rollover( arg->event_data.confirm.T1 ); - arg->event_data.confirm.T4 = - adapter->calc_rollover( arg->event_data.confirm.T4 ); - submit = true; - - break; - - case TIMINGMSMT_EVENT: - arg->event_data.indication.indication = - *(TIMINGMSMT_EVENT_DATA *)iEvent.data; - arg->event_data.indication.indication.T2 = - adapter->calc_rollover - ( arg->event_data.indication.indication.T2/100 ); - arg->event_data.indication.indication.T3 = - adapter->calc_rollover - ( arg->event_data.indication.indication.T3/100 ); - // Calculate copy length, at most followup message - // (See S8021AS indication) - vendor_extension_copy_length = arg->event_data. - indication.indication.WiFiVSpecHdr.Length - 1; - vendor_extension_copy_length -= vendor_extension_copy_length - - sizeof(arg->event_data.indication.followup) > 0 ? - vendor_extension_copy_length - - sizeof(arg->event_data.indication.followup) : 0; - // Copy the rest of the vendor specific field - memcpy( arg->event_data.indication.followup, - ((BYTE *)iEvent.data) + - sizeof( arg->event_data.indication.indication ), - vendor_extension_copy_length ); - submit = true; - break; - case TIMINGMSMT_CORRELATEDTIME_EVENT: - AcquireSRWLockExclusive(&adapter->ct_lock); - if (adapter->ct_miss > 0) - { - --adapter->ct_miss; - } else - { - arg->event_data.ptm_wa = - *(WIRELESS_CORRELATEDTIME *)iEvent.data; - arg->event_data.ptm_wa.LocalClk = - adapter->calc_rollover - (arg->event_data.ptm_wa.LocalClk); - adapter->ct_done = true; - // No need to schedule this, it returns immediately - WirelessTimestamperCallback(arg); - WakeAllConditionVariable(&adapter->ct_cond); - } - ReleaseSRWLockExclusive(&adapter->ct_lock); - - break; - } - - if (submit && - !timestamperContextMap->map[event_source].work_queue.submit - ( WirelessTimestamperCallback, arg )) - GPTP_LOG_ERROR("Failed to submit WiFi event"); -bail: - ReleaseSRWLockShared(×tamperContextMap->lock); -} - -DWORD WINAPI IntelWirelessLoop(LPVOID arg) -{ - // Register for callback - INTEL_CALLBACK tempCallback; - tempCallback.fnIntelCallback = IntelWirelessTimestamperEventHandler; - tempCallback.pContext = arg; - - if (RegisterIntelCallback(&tempCallback) != S_OK) { - GPTP_LOG_ERROR( "Failed to register WiFi callback" ); - return 0; - } - - while (!IntelTimestamperThreadStop) - { - SleepEx(320, true); - } - - DeregisterIntelCallback(tempCallback.fnIntelCallback); - - return 0; -} - -bool IntelWirelessAdapter::initialize(void) -{ - HMODULE MurocApiDLL = LoadLibrary("MurocApi.dll"); - - GetAdapterList = (GetAdapterList_t) - GetProcAddress(MurocApiDLL, "GetAdapterList"); - if( GetAdapterList == NULL ) - return false; - - RegisterIntelCallback = (RegisterIntelCallback_t) - GetProcAddress(MurocApiDLL, "RegisterIntelCallback"); - if( RegisterIntelCallback == NULL ) - return false; - - DeregisterIntelCallback = (DeregisterIntelCallback_t) - GetProcAddress(MurocApiDLL, "DeregisterIntelCallback"); - if( DeregisterIntelCallback == NULL ) - return false; - - WifiCmdTimingPtmWa = (WifiCmdTimingPtmWa_t) - GetProcAddress(MurocApiDLL, "WifiCmdTimingPtmWa"); - if( WifiCmdTimingPtmWa == NULL ) - return false; - - WifiCmdTimingMeasurementRequest = (WifiCmdTimingMeasurementRequest_t) - GetProcAddress(MurocApiDLL, "WifiCmdTimingMeasurementRequest"); - if (WifiCmdTimingMeasurementRequest == NULL) - return false; - - // Initialize crosstimestamp condition - InitializeConditionVariable(&ct_cond); - InitializeSRWLock(&ct_lock); - ct_miss = 0; - - // Spawn thread - IntelTimestamperThread = CreateThread - ( NULL, 0, IntelWirelessLoop, ×tamperContextMap, 0, NULL); - return true; -} - -void IntelWirelessAdapter::shutdown(void) { - // Signal thread exit - IntelTimestamperThreadStop = true; - // Join thread - WaitForSingleObject(IntelTimestamperThread, INFINITE); -} - -bool IntelWirelessAdapter::refreshCrossTimestamp(void) { - INTEL_WIFI_HEADER header; - WIRELESS_CORRELATEDTIME ptm_wa; - DWORD wait_return = TRUE; - DWORD start = 0; - - AcquireSRWLockExclusive(&ct_lock); - ct_done = false; - header.dwSize = sizeof(ptm_wa); - header.dwStructVersion = INTEL_STRUCT_VER_LATEST; - HRESULT hres = WifiCmdTimingPtmWa(hAdapter, &header, &ptm_wa); - if (hres != S_OK) - return false; - - while (!ct_done && wait_return == TRUE) { - DWORD now = GetTickCount(); - start = start == 0 ? now : start; - DWORD wait = now - start < CORRELATEDTIME_TRANSACTION_TIMEOUT ? - CORRELATEDTIME_TRANSACTION_TIMEOUT - - (now - start) : 0; - wait_return = SleepConditionVariableSRW - ( &ct_cond, &ct_lock, wait, 0 ); - } - ct_miss += wait_return != TRUE ? 1 : 0; - ReleaseSRWLockExclusive(&ct_lock); - - return wait_return == TRUE ? true : false; -} - -bool IntelWirelessAdapter::initiateTimingRequest -( TIMINGMSMT_REQUEST *tm_request ) -{ - INTEL_WIFI_HEADER header; - HRESULT err; - - memset(&header, 0, sizeof(header)); - // Proset wants an equivalent, but slightly different struct definition - header.dwSize = sizeof(*tm_request) - sizeof(PTP_SPEC) + 1; - header.dwStructVersion = INTEL_STRUCT_VER_LATEST; - if(( err = WifiCmdTimingMeasurementRequest - (hAdapter, &header, tm_request)) != S_OK ) - return false; - - return true; -} - -// Find Intel adapter given MAC address and return adapter ID -// -// @adapter(out): Adapter identifier used for all driver interaction -// @mac_addr: HW address of the adapter -// @return: *false* if adapter is not found or driver communication failure -// occurs, otherwise *true* -// -bool IntelWirelessAdapter::attachAdapter(uint8_t *mac_addr) -{ - PINTEL_ADAPTER_LIST adapter_list; - int i; - - if (GetAdapterList(&adapter_list) != S_OK) - return false; - - GPTP_LOG_VERBOSE("Driver query returned %d adapters\n", - adapter_list->count); - for (i = 0; i < adapter_list->count; ++i) { - if( memcmp(adapter_list->adapter[i].btMACAddress, - mac_addr, ETHER_ADDR_OCTETS) == 0 ) - break; - } - - if (i == adapter_list->count) - { - GPTP_LOG_ERROR("Driver failed to find the requested adapter"); - return false; - } - hAdapter = adapter_list->adapter[i].hAdapter; - - return true; -} - -// Register timestamper with Intel wireless subsystem. -// -// @timestamper: timestamper object that should receive events -// @source: MAC address of local interface -// @return: *false* if the MAC address has already been registered, *true* if -// -bool IntelWirelessAdapter::registerTimestamper -(WindowsWirelessTimestamper *timestamper) -{ - bool ret = false; - - AcquireSRWLockExclusive(×tamperContextMap.lock); - // Do not "re-add" the same timestamper - if( timestamperContextMap.map.find - ( *timestamper->getPort()->getLocalAddr() ) - == timestamperContextMap.map.cend()) - { - // Initialize per timestamper context and add - timestamperContextMap.map - [*timestamper->getPort()->getLocalAddr()]. - work_queue.init(0); - timestamperContextMap.map - [*timestamper->getPort()->getLocalAddr()]. - timestamper = timestamper; - ret = true; - } - ReleaseSRWLockExclusive(×tamperContextMap.lock); - - return ret; -} - -bool IntelWirelessAdapter::deregisterTimestamper -( WindowsWirelessTimestamper *timestamper ) -{ - bool ret; - - TimestamperContextMap::iterator iter; - AcquireSRWLockExclusive(×tamperContextMap.lock); - // Find timestamper - iter = timestamperContextMap.map.find - ( *timestamper->getPort()->getLocalAddr( )); - if( iter != timestamperContextMap.map.end( )) - { - // Shutdown work queue - iter->second.work_queue.stop(); - // Remove timestamper from list - timestamperContextMap.map.erase(iter); - ret = true; - } - ReleaseSRWLockExclusive(×tamperContextMap.lock); - - return ret; -} - -uint64_t IntelWirelessAdapter::calc_rollover( uint64_t gp2 ) -{ - gp2 = gp2 & 0xFFFFFFFF; - uint64_t l_gp2_ext; - - if (gp2_last == ULLONG_MAX) - { - gp2_last = gp2; - - return gp2; - } - - if (gp2 < GP2_ROLLOVER/4 && gp2_last > (GP2_ROLLOVER*3)/4) - ++gp2_ext; - - l_gp2_ext = gp2_ext; - if( gp2_last < GP2_ROLLOVER / 4 && gp2 >(GP2_ROLLOVER * 3) / 4 ) - --l_gp2_ext; - else - gp2_last = gp2; - - return gp2 + ( l_gp2_ext * GP2_ROLLOVER ); -} |