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 : }