LCOV - code coverage report
Current view: top level - felix-star/src - elinktable.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 66 74 89.2 %
Date: 2025-06-10 03:23:28 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include <assert.h>
       2             : #include <string.h>
       3             : 
       4             : #include "felix/felix_fid.h"
       5             : #include "log.h"
       6             : #include "elinktable.h"
       7             : #include "flx_api.h"
       8             : #include "app.h"
       9             : 
      10             : #define BLOCK_EGROUP_MASK          0x0038
      11             : #define BLOCK_EGROUP_SHIFT         3
      12             : 
      13          61 : static void init_counters(struct elink_entry* e)
      14             : {
      15          61 :   e->counters.processed_blocks = 0;
      16          61 :   e->counters.processed_chunks = 0;
      17          61 :   e->counters.number_send_retries = 0;
      18          61 :   e->counters.dropped = 0;
      19          61 :   e->counters.l1id_jump = 0;
      20          61 :   e->counters.largest_chunksize = 0;
      21          61 :   e->counters.total_chunksize = 0;
      22          61 :   e->counters.received_chunks = 0;
      23          61 :   e->last_counters.total_chunksize = 0;
      24          61 :   e->last_counters.processed_chunks = 0;
      25          61 :   e->last_counters.received_chunks = 0;
      26          61 :   e->received_chunk_rate = 0.0;
      27             : }
      28             : 
      29             : 
      30          44 : void felix_elinktable_init(struct application* app, struct elinktable* table,
      31             :   struct elink_descr* elinks, size_t num,
      32             :   unsigned buffered_readout, int mode, unsigned block_size, int trailer_size,
      33             :   struct flx* flx, struct config* cfg)
      34             : {
      35             :   #if REGMAP_VERSION < 0x0500
      36          23 :   unsigned no_of_channels = flx_get_number_of_channels(flx) + 1; //because TTC is on #links +1
      37          23 :   unsigned no_of_groups = 8;
      38          23 :   unsigned epaths_per_egroup = 8;
      39          23 :   unsigned max_elinks = (no_of_channels * no_of_groups * epaths_per_egroup);
      40             : #else
      41          21 :   unsigned no_of_channels = 24;
      42          21 :   unsigned no_of_groups = 8;
      43          21 :   unsigned epaths_per_egroup = 8;
      44          21 :   unsigned max_elinks = (no_of_channels * no_of_groups * epaths_per_egroup) + 1; //TTC is 0x600(1536)
      45             : #endif
      46             : 
      47          44 :   table->entries = (struct elink_entry*)calloc(max_elinks, sizeof(struct elink_entry));
      48          44 :   table->num_elinks = num;
      49          44 :   table->elinks = (local_elink_t*)malloc(num * sizeof(local_elink_t));
      50          44 :   table->elink_offset = 0;
      51          44 :   table->max_elinks = max_elinks;
      52             : 
      53             : 
      54         105 :   for(unsigned i = 0; i < num; i++) {
      55          61 :     unsigned elink = elinks[i].elink;
      56             : 
      57          61 :     assert(elink < max_elinks);
      58          61 :     LOG_DBG("Elinktable entry number %u for elink %x", i, elink);
      59          61 :     table->elinks[i] = elink;
      60          61 :     table->entries[elink].is_throttled = 0;
      61          61 :     table->entries[elink].is_virtual = elinks[i].type == TTC ? 1 : 0;
      62          61 :     table->entries[elink].last_xl1id.l1id.xl1id = 0x00ffffff;
      63          61 :     table->entries[elink].decoder.last_seqnr = -1;
      64          61 :     table->entries[elink].has_streams = elinks[i].has_streams;
      65         122 :     table->entries[elink].fid = get_fid(flx->co, elink + table->elink_offset,
      66          61 :         0, flx->vid, 0, table->entries[elink].is_virtual);
      67             : 
      68             :     // E-group based override for NSW TP
      69          61 :     if(flx->mode == FLX_MODE_GBT && cfg->dcs_egroup != -1 ){
      70           0 :       uint32_t egroup = (elink & BLOCK_EGROUP_MASK) >> BLOCK_EGROUP_SHIFT;
      71           0 :       if (cfg->dcs_egroup == egroup){
      72           0 :         elinks[i].type = DCS;
      73           0 :         LOG_INFO("E-Link %d:\t0x%02X\t0x%016lx\t converted to type type %s",
      74             :             i, elink, table->entries[elink].fid, flx_get_type_str(elinks[i].type));
      75             :       }
      76             :     }
      77             : 
      78          61 :     table->entries[elink].type = elinks[i].type;
      79             : 
      80          61 :     int stream_num = elinks[i].has_streams ? 256 : 1;
      81          61 :     table->entries[elink].stream = (struct stream*)calloc(stream_num, sizeof(struct stream));
      82        1142 :     for(unsigned s=0; s<stream_num; s++) {
      83        1081 :       table->entries[elink].stream[s].again = 0;
      84        1081 :       netio_subscription_cache_init(&table->entries[elink].stream[s].subscription_cache);
      85             :     }
      86             : 
      87          61 :     init_counters(&table->entries[elink]);
      88             : 
      89          61 :     if(elinks[i].type == TTC){
      90           4 :       table->entries[elink].pub_socket = &app->ttc2h_socket;
      91           4 :       init_decoder(&table->entries[elink].decoder, elink, &table->entries[elink],
      92             :           1, block_size, trailer_size, cfg);
      93             :     }
      94          57 :     else if(elinks[i].type == DCS || elinks[i].type == IC){
      95           0 :       if (cfg->dcs_buffered){
      96           0 :         table->entries[elink].pub_socket = &app->dcs_socket;
      97             :       } else {
      98           0 :         table->entries[elink].pub_socket = &app->dcs_usocket;
      99             :       }
     100           0 :       init_decoder(&table->entries[elink].decoder, elink, &table->entries[elink],
     101             :           cfg->dcs_buffered, block_size, trailer_size, cfg);
     102             :     }
     103             :     else {
     104          57 :       if (buffered_readout){
     105          33 :         table->entries[elink].pub_socket = &app->gbt_socket;
     106             :       } else {
     107          24 :         table->entries[elink].pub_socket = &app->fm_socket;
     108             :       }
     109          57 :       init_decoder(&table->entries[elink].decoder, elink, &table->entries[elink],
     110             :           buffered_readout, block_size, trailer_size, cfg);
     111             :     }
     112             :   }
     113             : 
     114          44 : }
     115             : 
     116             : 
     117          44 : void felix_elinktable_free(struct elinktable* table)
     118             : {
     119         105 :   for(unsigned i=0; i<table->num_elinks; ++i) {
     120          61 :     unsigned elink = table->elinks[i];
     121          61 :     free(table->entries[elink].stream);
     122          61 :     free_decoder(&table->entries[elink].decoder);
     123             :   }
     124          44 :   free(table->elinks);
     125          44 :   free(table->entries);
     126          44 :   table->elinks = NULL;
     127          44 :   table->num_elinks = 0;
     128          44 : }

Generated by: LCOV version 1.0