LCOV - code coverage report
Current view: top level - src - device_flx.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 326 0.0 %
Date: 2025-09-09 12:09:29 Functions: 0 47 0.0 %

          Line data    Source code
       1             : #include <cstdint>
       2             : 
       3             : #include "device.hpp"
       4             : 
       5             : #include "flxcard/FlxException.h"
       6             : #include "DFDebug/DFDebug.h"
       7             : 
       8             : #include "felix/felix_fid.h"
       9             : #include "regmap/regmap.h"
      10             : #include "block.hpp"
      11             : #include "log.hpp"
      12             : 
      13             : 
      14           0 : FlxDevice::FlxDevice(Config& cfg, unsigned dev_no)
      15           0 :     : Device(dev_no, cfg.resource.vid, cfg.resource.did, cfg.get_device_cid(dev_no))
      16           0 : { }
      17             : 
      18             : 
      19           0 : FlxDevice::FlxDevice(unsigned dev_no)
      20           0 :     : Device(dev_no, 1, 0, dev_no)
      21           0 : { }
      22             : 
      23             : 
      24           0 : int FlxDevice::open_device(u_int lock_mask)
      25             : {
      26           0 :     u_int current_lock{0};
      27           0 :     LOG_DBG("Initializing device %u asking for lock 0x%x", m_device_number, lock_mask);
      28           0 :     try {
      29           0 :         current_lock = m_dev.get_lock_mask(m_device_number);
      30           0 :         LOG_DBG("Device %d had locks 0x%x", m_device_number, current_lock);
      31             :     }
      32           0 :     catch(FlxException &ex) {
      33           0 :         LOG_ERR("Cannot get lock mask for device %u", m_device_number);
      34           0 :         LOG_ERR("%s", ex.errorString(ex.getErrorId()).c_str());
      35           0 :         return ex.getErrorId();
      36           0 :     }
      37             : 
      38           0 :     try {
      39           0 :         m_dev.card_open(m_device_number, lock_mask);
      40             :     }
      41           0 :     catch(FlxException &ex) {
      42           0 :         LOG_ERR("Could not open device %u", m_device_number);
      43           0 :         LOG_ERR("%s", ex.errorString(ex.getErrorId()).c_str());
      44           0 :         return ex.getErrorId();
      45           0 :     }
      46             : 
      47             :     // Clear various latched signals
      48           0 :     if (current_lock == 0) {
      49           0 :         m_dev.m_bar2->TTC_BUSY_CLEAR = 1;
      50           0 :         uint64_t c;
      51           0 :         c = m_dev.m_bar2->XOFF_FM_HIGH_THRESH.CROSS_LATCHED;
      52           0 :         m_dev.m_bar2->XOFF_FM_HIGH_THRESH.CROSS_LATCHED = c;
      53           0 :         c = m_dev.m_bar2->DMA_BUSY_STATUS.ENABLE;
      54           0 :         m_dev.m_bar2->DMA_BUSY_STATUS.ENABLE = c;
      55           0 :         c = m_dev.m_bar2->FM_BUSY_CHANNEL_STATUS.BUSY;
      56           0 :         m_dev.m_bar2->FM_BUSY_CHANNEL_STATUS.BUSY = c;
      57           0 :         c = m_dev.m_bar2->BUSY_MAIN_OUTPUT_FIFO_STATUS.HIGH_THRESH_CROSSED_LATCHED;
      58           0 :         m_dev.m_bar2->BUSY_MAIN_OUTPUT_FIFO_STATUS.HIGH_THRESH_CROSSED_LATCHED = c;
      59             :     }
      60             : 
      61           0 :     m_firmware_type = m_dev.firmware_type();
      62           0 :     return 0;
      63             : }
      64             : 
      65             : 
      66           0 : void FlxDevice::close_device()
      67             : {
      68             :     //stop all DMAs ?
      69             :     //flxcard->dma_stop(dmaid);
      70           0 :     LOG_DBG("Closing device %d", m_device_number);
      71           0 :     m_dev.card_close();
      72           0 : }
      73             : 
      74             : 
      75           0 : bool FlxDevice::is_primary()
      76             : {
      77           0 :     return not static_cast<bool>(m_dev.m_bar2->PCIE_ENDPOINT);
      78             : }
      79             : 
      80             : 
      81           0 : unsigned int FlxDevice::get_card_endpoints()
      82             : {
      83           0 :     return m_dev.m_bar2->NUMBER_OF_PCIE_ENDPOINTS;
      84             : }
      85             : 
      86             : 
      87           0 : unsigned int FlxDevice::get_card_model()
      88             : {
      89           0 :     return m_dev.m_bar2->CARD_TYPE;
      90             : }
      91             : 
      92             : 
      93           0 : u_int FlxDevice::get_regmap_version()
      94             : {
      95           0 :     return m_dev.m_bar2->REG_MAP_VERSION;
      96             : }
      97             : 
      98             : 
      99           0 : u_int FlxDevice::get_number_of_channels()
     100             : {
     101           0 :     return m_dev.m_bar2->NUM_OF_CHANNELS;
     102             : }
     103             : 
     104             : 
     105           0 : bool FlxDevice::get_wide_mode()
     106             : {
     107           0 :     return (m_dev.m_bar2->WIDE_MODE == 1 ? true : false);
     108             : }
     109             : 
     110             : 
     111           0 : u_int FlxDevice::get_block_size()
     112             : {
     113           0 :     return m_dev.m_bar2->BLOCKSIZE;
     114             : }
     115             : 
     116             : 
     117           0 : u_int FlxDevice::get_trailer_size()
     118             : {
     119           0 :     u_int tsize = m_dev.m_bar2->CHUNK_TRAILER_32B == 1 ? 4 : 2;
     120           0 :     if( tsize != sizeof(subchunk_trailer_t) ){
     121           0 :         throw std::runtime_error("SW/FW trailer size mismatch");
     122             :     }
     123           0 :     return tsize;
     124             : }
     125             : 
     126             : 
     127           0 : flx_fromhost_format FlxDevice::get_fromhost_data_format()
     128             : {
     129             : #if REGMAP_VERSION < 0x0500
     130             :     m_fromHostDataFormat = static_cast<flx_fromhost_format>(FROMHOST_FORMAT_REGMAP4);
     131             : #else
     132           0 :     m_fromHostDataFormat = static_cast<flx_fromhost_format>(m_dev.m_bar2->FROMHOST_DATA_FORMAT);
     133             : #endif
     134           0 :     return m_fromHostDataFormat;
     135             : }
     136             : 
     137             : 
     138           0 : flx_tohost_format FlxDevice::get_tohost_data_format()
     139             : {
     140             : #if REGMAP_VERSION < 0x0500
     141             :     return TOHOST_SUBCHUNK_TRAILER;
     142             : #else
     143           0 :     return static_cast<flx_tohost_format>(m_dev.m_bar2->TOHOST_DATA_FORMAT);
     144             : #endif
     145             : }
     146             : 
     147             : 
     148           0 : int FlxDevice::get_fromhost_dmaid()
     149             : {
     150           0 :     if (m_dev.m_bar2 == nullptr) {
     151           0 :         LOG_ERR("m_dev.m_bar2 is null");
     152           0 :         return -1;
     153             :     }
     154             : 
     155           0 :     int dmaid = m_dev.m_bar2->GENERIC_CONSTANTS.DESCRIPTORS - 1;
     156           0 :     if (dmaid < 0) {
     157           0 :         LOG_ERR("Invalid ToFLx DMA ID %d", dmaid);
     158             :     } else {
     159             :         LOG_TRACE("ToFlx dmaid %d", dmaid);
     160             :     }
     161             :     return dmaid;
     162             : }
     163             : 
     164             : 
     165           0 : int FlxDevice::get_trickle_dmaid()
     166             : {
     167             : #if REGMAP_VERSION >= 0x0500
     168           0 :     int dmaid = m_dev.m_bar2->GENERIC_CONSTANTS.TRICKLE_DESCRIPTOR_INDEX;
     169             :     //int trickle_offset = m_dev.m_bar2->GENERIC_CONSTANTS.TRICKLE_DESCRIPTOR_INDEX;
     170             :     //dmaid = dmaid + trickle_offset;
     171             : 
     172           0 :     if (dmaid < 0) {
     173             :         LOG_ERR("Invalid ToFLx DMA ID %d", dmaid);
     174             :     }
     175           0 :     LOG_TRACE("Trickle dmaid %d", dmaid);
     176           0 :     return dmaid;
     177             : #endif
     178             : 
     179             :     return -1;
     180             : }
     181             : 
     182             : 
     183           0 : int FlxDevice::dma_max_tlp_bytes()
     184             : {
     185           0 :     return m_dev.dma_max_tlp_bytes();
     186             : }
     187             : 
     188             : 
     189           0 : void FlxDevice::set_register(const char *key, uint64_t value)
     190             : {
     191           0 :     try {    
     192           0 :         m_dev.cfg_set_option(key, value);
     193             :     }
     194           0 :     catch(FlxException &ex) {
     195           0 :         LOG_INFO("Register %s not available with current firmware version.", key);
     196           0 :     }
     197           0 : }
     198             : 
     199             : 
     200           0 : uint64_t FlxDevice::get_register(const char *key)
     201             : {
     202           0 :     try {
     203           0 :         return m_dev.cfg_get_option(key);
     204             :     }
     205           0 :     catch(FlxException &ex) {
     206           0 :         LOG_INFO("Register %s not available with current firmware version.", key);
     207           0 :         return 0;
     208           0 :     }
     209             : }
     210             : 
     211             : 
     212           0 : bool FlxDevice::check_register(const char *key)
     213             : {
     214           0 :   try {
     215           0 :         m_dev.cfg_get_option(key);
     216             :         return true;
     217             :     }
     218           0 :     catch(FlxException &ex) {
     219           0 :         LOG_INFO("Register %s not available with current firmware version.", key);
     220           0 :         return false;
     221           0 :     }
     222             : }
     223             : 
     224             : 
     225           0 : void FlxDevice::cancel_irq(int i)
     226             : {
     227           0 :     try{
     228           0 :         m_dev.irq_cancel(i);
     229             :     }
     230           0 :     catch(FlxException &ex) {
     231           0 :         LOG_ERR("%s", ex.errorString(ex.getErrorId()).c_str());
     232           0 :     }
     233           0 : }
     234             : 
     235             : 
     236           0 : void FlxDevice::irq_wait(int i)
     237             : {
     238           0 :     m_dev.irq_wait(i);
     239           0 : }
     240             : 
     241             : 
     242           0 : void FlxDevice::irq_enable(int i)
     243             : {
     244           0 :     try{
     245           0 :         m_dev.irq_enable(i);
     246             :     }
     247           0 :     catch(FlxException &ex) {
     248           0 :         LOG_ERR("%s", ex.errorString(ex.getErrorId()).c_str());
     249           0 :     }
     250           0 : }
     251             : 
     252             : 
     253           0 : void FlxDevice::irq_disable(int i)
     254             : {
     255           0 :     try{
     256           0 :         m_dev.irq_disable(i);
     257             :     }
     258           0 :     catch(FlxException &ex) {
     259           0 :         LOG_ERR("%s", ex.errorString(ex.getErrorId()).c_str());
     260           0 :     }
     261           0 : }
     262             : 
     263             : 
     264             : #if REGMAP_VERSION < 0x0500
     265             : encoding_t FlxDevice::elink_get_encoding(u_int channel, u_int egroup, u_int epath, bool is_to_flx)
     266             : {
     267             :     if (!is_to_flx && (m_firmware_type == FIRMW_FULL || m_firmware_type == FIRMW_MROD)) {
     268             :         return ENC_8b10b;
     269             :     }
     270             :     else {
     271             :         int enc = 0;
     272             :         if (is_to_flx) {
     273             :             uint64_t modebits = m_dev.m_bar2->CR_GBT_CTRL[channel].EGROUP_FROMHOST[egroup].FROMHOST.PATH_ENCODING;
     274             :             uint64_t mask = 0xF << 4*epath; // 4 bits per E-path
     275             :             enc = ((modebits & mask) >> 4*epath);
     276             :         }
     277             :         else {
     278             :             uint64_t modebits = m_dev.m_bar2->CR_GBT_CTRL[channel].EGROUP_TOHOST[egroup].TOHOST.PATH_ENCODING;
     279             :             uint64_t mask = 0x3 << 2*epath; // 2 bits per E-path
     280             :             enc = ((modebits & mask) >> 2*epath);
     281             :         }
     282             :         if(enc < 0 || enc > 100){
     283             :             LOG_ERR("Invalid encoding type %d \
     284             :                     for elink channel %u group %u, epath %u using DIRECT",
     285             :                     enc, channel, egroup, epath);
     286             :             return ENC_DIRECT;
     287             :         }
     288             :         else {
     289             :             return static_cast<encoding_t>(enc);
     290             :         }
     291             :     }
     292             : }
     293             : #else
     294           0 : encoding_t FlxDevice::elink_get_encoding(u_int channel, u_int egroup, u_int epath, bool is_to_flx)
     295             : {
     296           0 :     if (!is_to_flx && (m_firmware_type == FIRMW_FULL)) {
     297             :         return ENC_8b10b;
     298             :     }
     299           0 :     else if (!is_to_flx && (m_firmware_type == FIRMW_INTERLAKEN)){
     300             :         return ENC_INTERLAKEN;
     301             :     }
     302             :     else {
     303           0 :         int enc = 0;
     304           0 :         if (is_to_flx) {
     305           0 :             uint64_t modebits = m_dev.m_bar2->ENCODING_EGROUP_CTRL_GEN[channel].ENCODING_EGROUP[egroup].ENCODING_EGROUP_CTRL.PATH_ENCODING;
     306           0 :             uint64_t mask = 0xF << 4*epath; // 4 bits per E-path
     307           0 :             enc = ((modebits & mask) >> 4*epath);
     308             :         }
     309             :         else {
     310           0 :             uint64_t modebits = m_dev.m_bar2->DECODING_EGROUP_CTRL_GEN[channel].DECODING_EGROUP[egroup].EGROUP.PATH_ENCODING;
     311           0 :             uint64_t mask = 0xF << 4*epath; // 4 bits per E-path
     312           0 :             enc = ((modebits & mask) >> 4*epath);
     313             :         }
     314           0 :         if(enc < 0 || enc > 100){
     315           0 :             LOG_ERR("Invalid encoding type %d \
     316             :                     for elink channel %u group %u, epath %u using DIRECT",
     317             :                     enc, channel, egroup, epath);
     318           0 :             return ENC_DIRECT;
     319             :         }
     320             :         else {
     321           0 :             return static_cast<encoding_t>(enc);
     322             :         }
     323             :     }
     324             : }
     325             : #endif
     326             : 
     327             : 
     328           0 : bool FlxDevice::elink_is_in_dma(local_elink_t elinknr, int dmaid)
     329             : {
     330             : #if REGMAP_VERSION < 0x0500
     331             :     return true;
     332             : #else
     333           0 :     bool is_elink_in_dma = false;
     334           0 :     if (dmaid == m_dev.m_bar2->GENERIC_CONSTANTS.FROMHOST_DESCRIPTOR_INDEX){
     335             :         is_elink_in_dma = true;
     336             :     } else {
     337           0 :         m_dev.m_bar2->CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID = elinknr;
     338           0 :         unsigned int elink_dmaid = m_dev.m_bar2->CRTOHOST_DMA_DESCRIPTOR_2.DESCR_READ & 0xF;
     339           0 :         unsigned int max_id = m_dev.m_bar2->GENERIC_CONSTANTS.DESCRIPTORS - 1;
     340           0 :         if (elink_dmaid > max_id){
     341           0 :             LOG_ERR("Invalid DMA ID %u for E-link %u (DMA ID [0, %u]). Discarded elink.", elink_dmaid, elinknr, max_id);
     342           0 :         } else if (elink_dmaid == static_cast<unsigned int>(dmaid)){
     343           0 :             is_elink_in_dma = true;
     344             :         }
     345             :     }
     346           0 :     return is_elink_in_dma;
     347             : #endif
     348             : }
     349             : 
     350             : 
     351             : #if REGMAP_VERSION < 0x0500
     352             : bool FlxDevice::elink_is_enabled(u_int channel, u_int egroup, u_int epath, bool is_to_flx)
     353             : {
     354             :     if (m_firmware_type == FIRMW_FULL) {
     355             :         return !is_to_flx && ((m_dev.m_bar2->CR_FM_PATH_ENA >> channel) & 1);
     356             :     }
     357             :     // MROD
     358             :     else if (m_firmware_type == FIRMW_MROD) {
     359             :         u_long eproc_ena = m_dev.m_bar2->MROD_EP0_CSMENABLE;
     360             :         return !is_to_flx && ((eproc_ena >> channel) & 1);
     361             :     }
     362             :     // GBT Mode
     363             :     else {
     364             :         u_long eproc_ena = is_to_flx ?
     365             :         m_dev.m_bar2->CR_GBT_CTRL[channel].EGROUP_FROMHOST[egroup].FROMHOST.EPROC_ENA :
     366             :         m_dev.m_bar2->CR_GBT_CTRL[channel].EGROUP_TOHOST[egroup].TOHOST.EPROC_ENA;
     367             :         // Central Router documentation p. 13
     368             :         switch (epath) {
     369             :             case 0: return ((eproc_ena >> 3) & 1) || ((eproc_ena >> 7) & 1);
     370             :             case 1: return ((eproc_ena >> 1) & 1) || ((eproc_ena >> 8) & 1);
     371             :             case 2: return ((eproc_ena >> 4) & 1) || ((eproc_ena >> 9) & 1);
     372             :             case 3: return ((eproc_ena >> 0) & 1) || ((eproc_ena >> 10) & 1);
     373             :             case 4: return ((eproc_ena >> 5) & 1) || ((eproc_ena >> 11) & 1);
     374             :             case 5: return ((eproc_ena >> 2) & 1) || ((eproc_ena >> 12) & 1);
     375             :             case 6: return ((eproc_ena >> 6) & 1) || ((eproc_ena >> 13) & 1);
     376             :             case 7: return ((eproc_ena >> 14) & 1);
     377             :             default: return false;
     378             :         }
     379             :     }
     380             :     return false;
     381             : }
     382             : #else
     383           0 : bool FlxDevice::elink_is_enabled(u_int channel, u_int egroup, u_int epath, bool is_to_flx)
     384             : {
     385           0 :     uint32_t enables_phase2;
     386           0 :     if( is_to_flx ) {
     387           0 :         enables_phase2 = (uint32_t) m_dev.m_bar2->ENCODING_EGROUP_CTRL_GEN[channel].ENCODING_EGROUP[egroup].ENCODING_EGROUP_CTRL.EPATH_ENA;
     388             :     } else {
     389           0 :         enables_phase2 = (uint32_t) m_dev.m_bar2->DECODING_EGROUP_CTRL_GEN[channel].DECODING_EGROUP[egroup].EGROUP.EPATH_ENA;
     390             :     }
     391           0 :     return (enables_phase2 >> epath) & 0x01;
     392             : 
     393             : }
     394             : #endif
     395             : 
     396           0 : uint64_t FlxDevice::get_broadcast_enable_gen(u_int channel) {
     397             : #if REGMAP_VERSION >= 0x0500
     398           0 :   return m_dev.m_bar2->BROADCAST_ENABLE_GEN[channel].BROADCAST_ENABLE;
     399             : #else
     400             :   return 0;
     401             : #endif
     402             : }
     403             : 
     404             : 
     405           0 : local_elink_t FlxDevice::get_ec_elink(bool is_to_flx, u_int channel)
     406             : {
     407           0 :     std::pair<int,int> ec_indices = m_dev.ec_elink_indices();
     408           0 :     if( is_to_flx ) {
     409           0 :         return ((channel<<6) + ec_indices.second);
     410             :     } else {
     411           0 :         return ((channel<<6) + ec_indices.first);
     412             :     }
     413             : }
     414             : 
     415             : 
     416           0 : local_elink_t FlxDevice::get_ic_elink(bool is_to_flx, u_int channel)
     417             : {
     418           0 :     std::pair<int,int> ic_indices = m_dev.ic_elink_indices();
     419           0 :     if( is_to_flx ) {
     420           0 :         return ((channel<<6) + ic_indices.second);
     421             :     } else {
     422           0 :         return ((channel<<6) + ic_indices.first);
     423             :     }
     424             : }
     425             : 
     426             : 
     427           0 : local_elink_t FlxDevice::get_aux_elink(bool is_to_flx, u_int channel)
     428             : {
     429           0 :     local_elink_t ic_elink = get_ic_elink(is_to_flx, channel);
     430             : #if REGMAP_VERSION < 0x0500
     431             :     return (ic_elink - 1);
     432             : #else
     433           0 :     return (ic_elink + 1); // Not (yet) defined
     434             : #endif
     435             : }
     436             : 
     437             : 
     438           0 : bool FlxDevice::elink_is_ec_enabled(bool is_to_flx, u_int channel)
     439             : {
     440             : #if REGMAP_VERSION < 0x0500
     441             :     if( is_to_flx ) {
     442             :         return(m_dev.m_bar2->MINI_EGROUP_CTRL[channel].EC_FROMHOST.ENABLE);
     443             :     } else {
     444             :         return(m_dev.m_bar2->MINI_EGROUP_CTRL[channel].EC_TOHOST.ENABLE);
     445             :     }
     446             : #else
     447           0 :     if( is_to_flx ) {
     448           0 :         return(m_dev.m_bar2->MINI_EGROUP_FROMHOST_GEN[channel].MINI_EGROUP_FROMHOST.EC_ENABLE);
     449             :     } else {
     450           0 :         return(m_dev.m_bar2->MINI_EGROUP_TOHOST_GEN[channel].MINI_EGROUP_TOHOST.EC_ENABLE);
     451             :     }
     452             : #endif
     453             : }
     454             : 
     455             : 
     456           0 : bool FlxDevice::elink_is_ic_enabled(bool is_to_flx, u_int channel)
     457             : {
     458             : #if REGMAP_VERSION < 0x0500
     459             :     if( is_to_flx ) {
     460             :         return(m_dev.m_bar2->MINI_EGROUP_CTRL[channel].EC_FROMHOST.IC_ENABLE);
     461             :     } else {
     462             :         return(m_dev.m_bar2->MINI_EGROUP_CTRL[channel].EC_TOHOST.IC_ENABLE);
     463             :     }
     464             : #else
     465           0 :     if( is_to_flx ) {
     466           0 :         return(m_dev.m_bar2->MINI_EGROUP_FROMHOST_GEN[channel].MINI_EGROUP_FROMHOST.IC_ENABLE);
     467             :     } else {
     468           0 :         return(m_dev.m_bar2->MINI_EGROUP_TOHOST_GEN[channel].MINI_EGROUP_TOHOST.IC_ENABLE);
     469             :     }
     470             : #endif
     471             : }
     472             : 
     473             : 
     474           0 : bool FlxDevice::elink_is_aux_enabled(bool is_to_flx, u_int channel)
     475             : {
     476             : #if REGMAP_VERSION < 0x0500
     477             :     if( is_to_flx ) {
     478             :         return(m_dev.m_bar2->MINI_EGROUP_CTRL[channel].EC_FROMHOST.SCA_AUX_ENABLE);
     479             :     } else {
     480             :         return(m_dev.m_bar2->MINI_EGROUP_CTRL[channel].EC_TOHOST.SCA_AUX_ENABLE);
     481             :     }
     482             : #else
     483           0 :     if( is_to_flx ) {
     484           0 :         return(m_dev.m_bar2->MINI_EGROUP_FROMHOST_GEN[channel].MINI_EGROUP_FROMHOST.AUX_ENABLE);
     485             :     } else {
     486           0 :         return(m_dev.m_bar2->MINI_EGROUP_TOHOST_GEN[channel].MINI_EGROUP_TOHOST.AUX_ENABLE);
     487             :     }
     488             : #endif
     489             : }
     490             : 
     491             : 
     492           0 : bool FlxDevice::elink_has_stream_id(u_int channel, u_int egroup, u_int epath)
     493             : {
     494           0 :     if(channel > get_number_of_channels()){
     495           0 :         LOG_ERR("Checking stream status on invalid channel %u", channel);
     496           0 :         return false;
     497             :     }
     498           0 :     u_long enable = 0;
     499             : #if REGMAP_VERSION < 0x0500
     500             :     switch (egroup)
     501             :     {
     502             :     case 0:
     503             :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].TOHOST.EGROUP0;
     504             :         break;
     505             :     case 1:
     506             :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].TOHOST.EGROUP1;
     507             :         break;
     508             :     case 2:
     509             :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].TOHOST.EGROUP2;
     510             :         break;
     511             :     case 3:
     512             :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].TOHOST.EGROUP3;
     513             :         break;
     514             :     case 4:
     515             :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].TOHOST.EGROUP4;
     516             :         break;
     517             :     case 5:
     518             :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].TOHOST.EGROUP5;
     519             :         break;
     520             :     case 6:
     521             :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].TOHOST.EGROUP6;
     522             :         break;
     523             :     default:
     524             :         LOG_ERR("Checking stream status on invalid egroup %u.", egroup);
     525             :         break;
     526             :     }
     527             : #else
     528           0 :     switch (egroup)
     529             :     {
     530           0 :     case 0:
     531           0 :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].HAS_STREAM_ID.EGROUP0;
     532           0 :         break;
     533           0 :     case 1:
     534           0 :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].HAS_STREAM_ID.EGROUP1;
     535           0 :         break;
     536           0 :     case 2:
     537           0 :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].HAS_STREAM_ID.EGROUP2;
     538           0 :         break;
     539           0 :     case 3:
     540           0 :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].HAS_STREAM_ID.EGROUP3;
     541           0 :         break;
     542           0 :     case 4:
     543           0 :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].HAS_STREAM_ID.EGROUP4;
     544           0 :         break;
     545           0 :     case 5:
     546           0 :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].HAS_STREAM_ID.EGROUP5;
     547           0 :         break;
     548           0 :     case 6:
     549           0 :         enable = m_dev.m_bar2->PATH_HAS_STREAM_ID[channel].HAS_STREAM_ID.EGROUP6;
     550           0 :         break;
     551           0 :     default:
     552           0 :         LOG_ERR("Checking stream status on invalid egroup %u.", egroup);
     553           0 :         break;
     554             :     }
     555             : #endif
     556           0 :     return static_cast<bool>( (enable >> epath) & 1);
     557             : }
     558             : 
     559             : 
     560           0 : std::vector<Elink> FlxDevice::read_enabled_elinks(int dmaid)
     561             : {
     562           0 :     std::vector<Elink> enabled_elinks;
     563             : 
     564             :     // If Trickle mode is active, only the Trickle E-link is enabled and returned
     565           0 :     bool is_trickle = (dmaid == get_trickle_dmaid()) ? true : false;
     566           0 :     if (is_trickle){
     567           0 :         local_elink_t lid = 0xffff;
     568           0 :         uint64_t fid = get_fid_from_ids(m_did, m_cid, lid, 0, m_vid, true, true);
     569           0 :         enabled_elinks.emplace_back(Elink{fid, lid, 0, elink_type_t::DAQ, encoding_t::ENC_8b10b});
     570           0 :         return enabled_elinks;
     571             :     }
     572             : 
     573           0 :     bool is_to_flx = (dmaid == get_fromhost_dmaid()) ? true : false;
     574           0 :     bool fullmode              = is_full_mode();
     575           0 :     u_int no_of_channels       = get_number_of_channels();
     576           0 :     u_int egroups_per_chan     = get_egroups_per_channel(is_to_flx);
     577           0 :     u_int epaths_per_egroup    = get_epaths_per_egroup(is_to_flx);
     578             : 
     579             :   // TTCtoHost e-link = #Nchannels group #7 path #3 (RM4) or 0x600 (RM5)
     580             : #if REGMAP_VERSION < 0x0500
     581             :     if( !is_to_flx && m_dev.m_bar2->CR_TTC_TOHOST.ENABLE) {
     582             : #else
     583           0 :     if( !is_to_flx && m_dev.m_bar2->TTC_TOHOST_ENABLE && elink_is_in_dma(0x600, dmaid)) {
     584             : #endif
     585           0 :         local_elink_t lid = TTC2HOST_LINK(no_of_channels);
     586           0 :         uint64_t fid = get_fid_from_ids(m_did, m_cid, lid, 0, m_vid, false, true);
     587           0 :         bool streams = 0;
     588           0 :         enabled_elinks.emplace_back(Elink{fid, lid, streams, elink_type_t::TTC, encoding_t::ENC_TTC});
     589           0 :         LOG_TRACE("E-Link %d:\t0x%02X\t0x%016lx\t(TTC2H)", enabled_elinks.size(), lid, fid);
     590             :     }
     591             : 
     592             :     // IC, EC, AUX
     593           0 :     if( !fullmode ) {
     594           0 :         for( unsigned channel = 0; channel < no_of_channels; ++channel ) {
     595             : 
     596           0 :             local_elink_t ec_elink = get_ec_elink(is_to_flx, channel);
     597           0 :             bool ec_enabled = elink_is_ec_enabled(is_to_flx, channel) && elink_is_in_dma(ec_elink, dmaid);
     598             : 
     599           0 :             local_elink_t ic_elink = get_ic_elink(is_to_flx, channel);
     600           0 :             bool ic_enabled = elink_is_ic_enabled(is_to_flx, channel) && elink_is_in_dma(ic_elink, dmaid);
     601             : 
     602           0 :             local_elink_t aux_elink = get_aux_elink(is_to_flx, channel);
     603           0 :             bool aux_enabled = elink_is_aux_enabled(is_to_flx, channel) && elink_is_in_dma(aux_elink, dmaid);
     604           0 :             if( ec_enabled ){
     605           0 :                 uint64_t fid = get_fid_from_ids(m_did, m_cid, ec_elink, 0, m_vid, is_to_flx, false);
     606           0 :                 enabled_elinks.emplace_back(Elink{fid, ec_elink, false, elink_type_t::DCS, encoding_t::ENC_HDLC});
     607           0 :                 LOG_TRACE("E-Link %d:\t0x%02X\t0x%016lx\t(EC channel %d)", enabled_elinks.size(), ec_elink, fid, channel);
     608             :             }
     609           0 :             if( ic_enabled ){
     610           0 :                 uint64_t fid = get_fid_from_ids(m_did, m_cid, ic_elink, 0, m_vid, is_to_flx, false);
     611           0 :                 enabled_elinks.emplace_back(Elink{fid, ic_elink, false, elink_type_t::IC, encoding_t::ENC_HDLC});
     612           0 :                 LOG_TRACE("E-Link %d:\t0x%02X\t0x%016lx\t(IC channel %d)", enabled_elinks.size(), ic_elink, fid, channel);
     613             :             }
     614           0 :             if( m_firmware_type == FIRMW_LTDB && aux_enabled ) {
     615           0 :                 uint64_t fid = get_fid_from_ids(m_did, m_cid, aux_elink, 0, m_vid, is_to_flx, false);
     616           0 :                 enabled_elinks.emplace_back(Elink{fid, aux_elink, false, elink_type_t::DCS, encoding_t::ENC_HDLC});
     617           0 :                 LOG_TRACE("E-Link %d:\t0x%02X\t0x%016lx\t(AUX channel %d)", enabled_elinks.size(), aux_elink, fid, channel);
     618             :             }
     619             :         }
     620             :     }
     621             : 
     622           0 :     for( unsigned channel = 0; channel < no_of_channels; ++channel ) {
     623           0 :         for( unsigned egroup = 0; egroup < egroups_per_chan; ++egroup ) {
     624           0 :             for( unsigned epath = 0; epath < epaths_per_egroup; ++epath ) {
     625             : 
     626           0 :                 local_elink_t elinknr = get_elink(channel, egroup, epath);
     627           0 :                 bool enabled = elink_is_enabled(channel, egroup, epath, is_to_flx);
     628           0 :                 bool in_enabled_dma = is_to_flx ? 1 : elink_is_in_dma(elinknr, dmaid);
     629             : 
     630           0 :                 if( enabled && in_enabled_dma ) {
     631           0 :                     bool streams = !is_to_flx && elink_has_stream_id(channel, egroup, epath);
     632           0 :                     encoding_t enc = elink_get_encoding(channel, egroup, epath, is_to_flx);
     633           0 :                     elink_type_t type = elink_type_t::NONE_ELINK_TYPE;
     634           0 :                     if (enc == ENC_HDLC){
     635             :                         type = elink_type_t::DCS;
     636             :                     } else {
     637           0 :                         type = elink_type_t::DAQ;
     638             :                     }
     639             : 
     640           0 :                     uint64_t fid = get_fid_from_ids(m_did, m_cid, elinknr, 0, m_vid, is_to_flx, false);
     641           0 :                     enabled_elinks.emplace_back(Elink{fid, elinknr, streams, type, enc});
     642             :                     LOG_TRACE("E-Link %d:\t0x%02X\t0x%016lx\t(channel %d egroup %d epath %d) type %s, streams %c",
     643             :                         enabled_elinks.size(), elinknr, fid, channel, egroup, epath, 
     644             :                         Device::get_elink_type_str(type).c_str(),
     645           0 :                         streams ? 'Y' : 'N');                   
     646             :                 } //if enabled
     647             :             } //epath
     648             :         } //egroup
     649             :     } //channel
     650             : 
     651             : #if REGMAP_VERSION >= 0x0500
     652             :     // Add Broadcast Elinks
     653           0 :     if (is_to_flx) {
     654             :         // Calculate Broadcast Elinks
     655           0 :         uint64_t broadcast_elinks[MAX_BROADCAST_ELINKS] = {0};
     656           0 :         unsigned no_of_broadcast_elinks = get_broadcast_elinks(broadcast_elinks, no_of_channels);
     657           0 :         LOG_INFO("Adding %d broadcast elinks", no_of_broadcast_elinks);
     658           0 :         for( unsigned i=0; i < no_of_broadcast_elinks; ++i ) {
     659           0 :             bool streams = 0;
     660             :             //broadcast elinks use the same encoding as 
     661             :             //elinks they broadcast into
     662           0 :             encoding_t enc = ENC_DIRECT;
     663           0 :             elink_type_t type = elink_type_t::DAQ;
     664           0 :             local_elink_t elinknr = static_cast<local_elink_t>(broadcast_elinks[i]);
     665           0 :             uint64_t fid = get_fid(0, elinknr, streams, m_vid, is_to_flx, 0);
     666           0 :             enabled_elinks.emplace_back(Elink{fid, elinknr, streams, type, enc});
     667           0 :             LOG_INFO("Broadcast for %8s \t%4d using \tE-Link %d:\t0x%02X\t0x%016lx\t(channel %d egroup %d epath %d)",
     668             :                 Device::broadcast_type_str(elinknr).c_str(), Device::broadcast_for(elinknr), enabled_elinks.size(), elinknr, fid,
     669             :                 Device::get_channel(elinknr), Device::get_egroup(elinknr), Device::get_epath(elinknr));
     670             :         }
     671             :     }
     672             : #endif
     673             :     return enabled_elinks;
     674           0 : }
     675             : 
     676           0 : bool FlxDevice::dma_enabled(int dmaid)
     677             : {
     678           0 :     return m_dev.dma_enabled(dmaid);
     679             : }
     680             : 
     681           0 : void FlxDevice::dma_to_host(DmaBuffer* buf, int dmaid)
     682             : {
     683           0 :     m_dev.dma_stop(dmaid);
     684           0 :     m_dev.dma_to_host(dmaid, buf->paddr, buf->size, FLX_DMA_WRAPAROUND);
     685           0 :     buf->pend = buf->paddr + buf->size;
     686           0 :     buf->pc_ptr = m_dev.dma_get_ptr(dmaid);
     687           0 : }
     688             : 
     689             : 
     690           0 : void FlxDevice::dma_from_host(DmaBuffer* buf, int dmaid)
     691             : {
     692           0 :     m_dev.dma_from_host(dmaid, buf->paddr, buf->size, FLX_DMA_WRAPAROUND);
     693           0 :     buf->pend = buf->paddr + buf->size;
     694           0 :     buf->pc_ptr = m_dev.dma_get_ptr(dmaid);
     695           0 : }
     696             : 
     697             : 
     698           0 : void FlxDevice::dma_from_host_trickle(DmaBuffer* buf, int dmaid, size_t config_size)
     699             : {   
     700           0 :     if(config_size > buf->size){
     701           0 :         LOG_ERR("Trickle config size %lu larger than buffer size %lu", config_size, buf->size);
     702           0 :         return;
     703             :     }
     704             :     // DMA buffer size must be a multiple of 32 bytes
     705           0 :     if(config_size % 32){
     706           0 :         config_size += 32 - (config_size % 32);
     707             :     }
     708             :     // The firmware will read the buffer up until the config_size
     709           0 :     m_dev.dma_from_host(dmaid, buf->paddr, config_size, FLX_DMA_WRAPAROUND);
     710             : }
     711             : 
     712             : 
     713           0 : void FlxDevice::dma_set_oneshot(DmaBuffer* buf, int dmaid, size_t config_size){
     714             :     // DMA buffer size must be a multiple of 32 bytes
     715           0 :     if(config_size % 32){
     716           0 :         config_size += 32 - (config_size % 32);
     717             :     }
     718             :     // The firmware will read the buffer up until the config_size
     719           0 :     m_dev.dma_from_host(dmaid, buf->paddr, config_size, 0 /*FLX_DMA_ONESHOT*/);
     720           0 : }
     721             : 
     722           0 : uint64_t FlxDevice::dma_get_fw_ptr(int dmaid)
     723             : {
     724           0 :     return m_dev.dma_get_fw_ptr(dmaid);
     725             : }
     726             : 
     727             : 
     728           0 : uint64_t FlxDevice::dma_get_sw_ptr(int dmaid)
     729             : {
     730           0 :     return m_dev.dma_get_ptr(dmaid);
     731             : }
     732             : 
     733             : 
     734           0 : void FlxDevice::dma_set_sw_ptr(int dmaid, uint64_t p_phys)
     735             : {
     736           0 :     return m_dev.dma_set_ptr(dmaid, p_phys);
     737             : }
     738             : 
     739             : 
     740           0 : bool FlxDevice::dma_cmp_even_bits(int dmaid)
     741             : {
     742           0 :     return m_dev.dma_cmp_even_bits(dmaid);
     743             : }
     744             : 
     745             : 
     746           0 : void FlxDevice::dma_stop(unsigned int dmaid)
     747             : {
     748           0 :     m_dev.dma_stop(dmaid);
     749           0 : }
     750             : 
     751           0 : monitoring_data_t FlxDevice::hw_get_monitoring_data(unsigned int mon_mask)
     752             : {
     753           0 :     monitoring_data_t data;
     754             :     //memset(&data, 0, sizeof(data));
     755           0 :     try {
     756           0 :         data = m_dev.get_monitoring_data(mon_mask);
     757           0 :     } catch(const FlxException & e) {
     758           0 :         LOG_WARN(e.what());
     759           0 :     }
     760           0 :     return data;
     761           0 : }

Generated by: LCOV version 1.0