Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] dib8000: improve block statistics

PER/UCB statistics are collected once on each 1 second.
However, it doesn't provide the total number of packets
needed to calculate PER.

Yet, as we know the bit rate, it is possible to estimate
such number. So, do it.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Acked-by: Patrick Boettcher <pboettcher@kernellabs.com>

+75 -34
+75 -34
drivers/media/dvb-frontends/dib8000.c
··· 121 121 122 122 /* for DVBv5 stats */ 123 123 s64 init_ucb; 124 - unsigned long jiffies_stats; 125 - unsigned long jiffies_stats_layer[3]; 124 + unsigned long per_jiffies_stats; 125 + unsigned long ber_jiffies_stats; 126 + unsigned long ber_jiffies_stats_layer[3]; 126 127 127 128 #ifdef DIB8000_AGC_FREEZE 128 129 u16 agc1_max; ··· 1007 1006 c->strength.len = 1; 1008 1007 c->cnr.len = 1; 1009 1008 c->block_error.len = 1; 1009 + c->block_count.len = 1; 1010 1010 c->post_bit_error.len = 1; 1011 1011 c->post_bit_count.len = 1; 1012 1012 ··· 1016 1014 1017 1015 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 1018 1016 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 1017 + c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 1019 1018 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 1020 1019 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 1021 1020 1022 1021 dib8000_read_unc_blocks(fe, &ucb); 1023 1022 1024 1023 state->init_ucb = -ucb; 1025 - state->jiffies_stats = 0; 1026 - memset(&state->jiffies_stats_layer, 0, 1027 - sizeof(state->jiffies_stats_layer)); 1024 + state->ber_jiffies_stats = 0; 1025 + state->per_jiffies_stats = 0; 1026 + memset(&state->ber_jiffies_stats_layer, 0, 1027 + sizeof(state->ber_jiffies_stats_layer)); 1028 1028 } 1029 1029 1030 1030 static int dib8000_reset(struct dvb_frontend *fe) ··· 4063 4059 struct dib8000_state *state = fe->demodulator_priv; 4064 4060 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache; 4065 4061 int i; 4066 - u32 time_us, snr, val; 4062 + int show_per_stats = 0; 4063 + u32 time_us = 0, snr, val; 4064 + u64 blocks; 4067 4065 s32 db; 4068 4066 u16 strength; 4069 4067 ··· 4080 4074 /* UCB/BER/CNR measures require lock */ 4081 4075 if (!(stat & FE_HAS_LOCK)) { 4082 4076 c->cnr.len = 1; 4077 + c->block_count.len = 1; 4083 4078 c->block_error.len = 1; 4084 4079 c->post_bit_error.len = 1; 4085 4080 c->post_bit_count.len = 1; ··· 4088 4081 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 4089 4082 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 4090 4083 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 4084 + c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 4091 4085 return 0; 4092 4086 } 4093 4087 4094 4088 /* Check if time for stats was elapsed */ 4095 - if (time_after(jiffies, state->jiffies_stats)) { 4096 - time_us = dib8000_get_time_us(fe, -1); 4097 - state->jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000); 4098 - 4099 - dprintk("Next all layers stats available in %u us.\n", time_us); 4089 + if (time_after(jiffies, state->per_jiffies_stats)) { 4090 + state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000); 4100 4091 4101 4092 /* Get SNR */ 4102 4093 snr = dib8000_get_snr(fe); ··· 4113 4108 c->cnr.stat[0].svalue = snr; 4114 4109 c->cnr.stat[0].scale = FE_SCALE_DECIBEL; 4115 4110 4116 - /* Get UCB and post-BER measures */ 4111 + /* Get UCB measures */ 4112 + dib8000_read_unc_blocks(fe, &val); 4113 + if (val < state->init_ucb) 4114 + state->init_ucb += 0x100000000L; 4115 + 4116 + c->block_error.stat[0].scale = FE_SCALE_COUNTER; 4117 + c->block_error.stat[0].uvalue = val + state->init_ucb; 4118 + 4119 + /* Estimate the number of packets based on bitrate */ 4120 + if (!time_us) 4121 + time_us = dib8000_get_time_us(fe, -1); 4122 + 4123 + if (time_us) { 4124 + blocks = 1250000UL * 1000000UL; 4125 + do_div(blocks, time_us * 8 * 204); 4126 + c->block_count.stat[0].scale = FE_SCALE_COUNTER; 4127 + c->block_count.stat[0].uvalue += blocks; 4128 + } 4129 + 4130 + show_per_stats = 1; 4131 + } 4132 + 4133 + /* Get post-BER measures */ 4134 + if (time_after(jiffies, state->ber_jiffies_stats)) { 4135 + time_us = dib8000_get_time_us(fe, -1); 4136 + state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000); 4137 + 4138 + dprintk("Next all layers stats available in %u us.", time_us); 4117 4139 4118 4140 dib8000_read_ber(fe, &val); 4119 4141 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; ··· 4148 4116 4149 4117 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 4150 4118 c->post_bit_count.stat[0].uvalue += 100000000; 4151 - 4152 - dib8000_read_unc_blocks(fe, &val); 4153 - if (val < state->init_ucb) 4154 - state->init_ucb += 1L << 32; 4155 - 4156 - c->block_error.stat[0].scale = FE_SCALE_COUNTER; 4157 - c->block_error.stat[0].uvalue = val + state->init_ucb; 4158 4119 } 4159 4120 4160 4121 if (state->revision < 0x8002) ··· 4158 4133 c->post_bit_count.len = 4; 4159 4134 4160 4135 for (i = 0; i < 3; i++) { 4161 - if (!time_after(jiffies, state->jiffies_stats_layer[i])) 4136 + unsigned nsegs = c->layer[i].segment_count; 4137 + 4138 + if (nsegs == 0 || nsegs > 13) 4162 4139 continue; 4163 - time_us = dib8000_get_time_us(fe, i); 4164 - if (!time_us) 4165 - continue; 4166 4140 4167 - state->jiffies_stats_layer[i] = jiffies + msecs_to_jiffies((time_us + 500) / 1000); 4168 - dprintk("Next layer %c stats will be available in %u us\n", 4169 - 'A' + i, time_us); 4141 + time_us = 0; 4170 4142 4171 - val = dib8000_read_word(state, per_layer_regs[i].ber); 4172 - c->post_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER; 4173 - c->post_bit_error.stat[1 + i].uvalue += val; 4143 + if (time_after(jiffies, state->ber_jiffies_stats_layer[i])) { 4144 + time_us = dib8000_get_time_us(fe, i); 4174 4145 4175 - c->post_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER; 4176 - c->post_bit_count.stat[1 + i].uvalue += 100000000; 4146 + state->ber_jiffies_stats_layer[i] = jiffies + msecs_to_jiffies((time_us + 500) / 1000); 4147 + dprintk("Next layer %c stats will be available in %u us\n", 4148 + 'A' + i, time_us); 4177 4149 4178 - val = dib8000_read_word(state, per_layer_regs[i].per); 4150 + val = dib8000_read_word(state, per_layer_regs[i].ber); 4151 + c->post_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER; 4152 + c->post_bit_error.stat[1 + i].uvalue += val; 4179 4153 4180 - c->block_error.stat[1 + i].scale = FE_SCALE_COUNTER; 4181 - c->block_error.stat[1 + i].uvalue += val; 4154 + c->post_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER; 4155 + c->post_bit_count.stat[1 + i].uvalue += 100000000; 4156 + } 4157 + 4158 + if (show_per_stats) { 4159 + val = dib8000_read_word(state, per_layer_regs[i].per); 4160 + 4161 + c->block_error.stat[1 + i].scale = FE_SCALE_COUNTER; 4162 + c->block_error.stat[1 + i].uvalue += val; 4163 + 4164 + if (!time_us) 4165 + time_us = dib8000_get_time_us(fe, i); 4166 + if (time_us) { 4167 + blocks = 1250000UL * 1000000UL; 4168 + do_div(blocks, time_us * 8 * 204); 4169 + c->block_count.stat[0].scale = FE_SCALE_COUNTER; 4170 + c->block_count.stat[0].uvalue += blocks; 4171 + } 4172 + } 4182 4173 } 4183 4174 return 0; 4184 4175 }