V4L/DVB (13846): smsdvb: Properly implement stats for both DVB and ISDB-T
authorMauro Carvalho Chehab <mchehab@redhat.com>
Fri, 25 Dec 2009 14:29:42 +0000 (11:29 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Fri, 26 Feb 2010 18:10:26 +0000 (15:10 -0300)
After taking a look at the driver's history and doing some tests with
DVB and ISDB-T, it was noticed that the stats were incomplete, for
ISDB-T, and weren't working for DVB.

Fixed the code and added a debug code to print the complete stats at
dmesg. This debug is useful to improve the stats of this driver.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/siano/smscoreapi.h
drivers/media/dvb/siano/smsdvb.c

index 7393e2b..8ecadec 100644 (file)
@@ -341,8 +341,8 @@ struct SmsFirmware_ST {
 
 /* Statistics information returned as response for
  * SmsHostApiGetStatistics_Req */
-struct SMSHOSTLIB_STATISTICS_S {
-       u8 Reserved[5];         /* Reserved */
+struct SMSHOSTLIB_STATISTICS_ST {
+       u32 Reserved;           /* Reserved */
 
        /* Common parameters */
        u32 IsRfLocked;         /* 0 - not locked, 1 - locked */
@@ -426,6 +426,79 @@ struct SMSHOSTLIB_STATISTICS_S {
        u32 ReservedFields[10]; /* Reserved */
 };
 
+struct SmsMsgStatisticsInfo_ST {
+       u32 RequestResult;
+
+       struct SMSHOSTLIB_STATISTICS_ST Stat;
+
+       /* Split the calc of the SNR in DAB */
+       u32 Signal; /* dB */
+       u32 Noise; /* dB */
+
+};
+
+struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
+       /* Per-layer information */
+       u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
+                      * 255 means layer does not exist */
+       u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
+                           * 255 means layer does not exist */
+       u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
+       u32 BERErrorCount; /* Post Viterbi Error Bits Count */
+       u32 BERBitCount; /* Post Viterbi Total Bits Count */
+       u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
+       u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
+       u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
+       u32 TotalTSPackets; /* Total number of transport-stream packets */
+       u32 TILdepthI; /* Time interleaver depth I parameter,
+                       * 255 means layer does not exist */
+       u32 NumberOfSegments; /* Number of segments in layer A,
+                              * 255 means layer does not exist */
+       u32 TMCCErrors; /* TMCC errors */
+};
+
+struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
+       u32 StatisticsType; /* Enumerator identifying the type of the
+                               * structure.  Values are the same as
+                               * SMSHOSTLIB_DEVICE_MODES_E
+                               *
+                               * This field MUST always be first in any
+                               * statistics structure */
+
+       u32 FullSize; /* Total size of the structure returned by the modem.
+                      * If the size requested by the host is smaller than
+                      * FullSize, the struct will be truncated */
+
+       /* Common parameters */
+       u32 IsRfLocked; /* 0 - not locked, 1 - locked */
+       u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
+       u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
+
+       /* Reception quality */
+       s32  SNR; /* dB */
+       s32  RSSI; /* dBm */
+       s32  InBandPwr; /* In band power in dBM */
+       s32  CarrierOffset; /* Carrier Offset in Hz */
+
+       /* Transmission parameters */
+       u32 Frequency; /* Frequency in Hz */
+       u32 Bandwidth; /* Bandwidth in MHz */
+       u32 TransmissionMode; /* ISDB-T transmission mode */
+       u32 ModemState; /* 0 - Acquisition, 1 - Locked */
+       u32 GuardInterval; /* Guard Interval, 1 divided by value */
+       u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
+       u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
+       u32 NumOfLayers; /* Number of ISDB-T layers in the network */
+
+       /* Per-layer information */
+       /* Layers A, B and C */
+       struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST   LayerInfo[3];
+       /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
+
+       /* Interface information */
+       u32 SmsToHostTxErrors; /* Total number of transmission errors. */
+};
+
 struct PID_STATISTICS_DATA_S {
        struct PID_BURST_S {
                u32 size;
index 2f675cd..b44ba39 100644 (file)
@@ -116,6 +116,119 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client,
        }
 }
 
+
+static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
+                                  struct SMSHOSTLIB_STATISTICS_ST *p)
+{
+       if (sms_dbg & 2) {
+               printk(KERN_DEBUG "Reserved = %d", p->Reserved);
+               printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
+               printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
+               printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
+               printk(KERN_DEBUG "SNR = %d", p->SNR);
+               printk(KERN_DEBUG "BER = %d", p->BER);
+               printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC);
+               printk(KERN_DEBUG "TS_PER = %d", p->TS_PER);
+               printk(KERN_DEBUG "MFER = %d", p->MFER);
+               printk(KERN_DEBUG "RSSI = %d", p->RSSI);
+               printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
+               printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
+               printk(KERN_DEBUG "Frequency = %d", p->Frequency);
+               printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
+               printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
+               printk(KERN_DEBUG "ModemState = %d", p->ModemState);
+               printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
+               printk(KERN_DEBUG "CodeRate = %d", p->CodeRate);
+               printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate);
+               printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy);
+               printk(KERN_DEBUG "Constellation = %d", p->Constellation);
+               printk(KERN_DEBUG "BurstSize = %d", p->BurstSize);
+               printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration);
+               printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime);
+               printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime);
+               printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows);
+               printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols);
+               printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols);
+               printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets);
+               printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets);
+               printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs);
+               printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs);
+               printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs);
+               printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount);
+               printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount);
+               printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
+               printk(KERN_DEBUG "PreBER = %d", p->PreBER);
+               printk(KERN_DEBUG "CellId = %d", p->CellId);
+               printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP);
+               printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP);
+               printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived);
+               printk(KERN_DEBUG "ReservedFields[10] = %d", p->ReservedFields[10]);
+       }
+
+       pReceptionData->IsDemodLocked = p->IsDemodLocked;
+
+       pReceptionData->SNR = p->SNR;
+       pReceptionData->BER = p->BER;
+       pReceptionData->BERErrorCount = p->BERErrorCount;
+       pReceptionData->InBandPwr = p->InBandPwr;
+       pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
+};
+
+
+static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
+                                   struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
+{
+       int i;
+
+       if (sms_dbg & 2) {
+               printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
+               printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
+               printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
+               printk(KERN_DEBUG "SNR = %d", p->SNR);
+               printk(KERN_DEBUG "RSSI = %d", p->RSSI);
+               printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
+               printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
+               printk(KERN_DEBUG "Frequency = %d", p->Frequency);
+               printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
+               printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
+               printk(KERN_DEBUG "ModemState = %d", p->ModemState);
+               printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
+               printk(KERN_DEBUG "SystemType = %d", p->SystemType);
+               printk(KERN_DEBUG "PartialReception = %d", p->PartialReception);
+               printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers);
+               printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
+
+               for (i = 0; i < 3; i++) {
+                       printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate);
+                       printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation);
+                       printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER);
+                       printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount);
+                       printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount);
+                       printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER);
+                       printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER);
+                       printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets);
+                       printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets);
+                       printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI);
+                       printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments);
+                       printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors);
+               }
+       }
+
+       pReceptionData->IsDemodLocked = p->IsDemodLocked;
+
+       pReceptionData->SNR = p->SNR;
+       pReceptionData->InBandPwr = p->InBandPwr;
+
+       pReceptionData->ErrorTSPackets = 0;
+       pReceptionData->BER = 0;
+       pReceptionData->BERErrorCount = 0;
+       for (i = 0; i < 3; i++) {
+               pReceptionData->BER += p->LayerInfo[i].BER;
+               pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount;
+               pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets;
+       }
+}
+
 static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
 {
        struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
@@ -219,32 +332,33 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
                break;
        }
        case MSG_SMS_GET_STATISTICS_RES: {
-               struct SMSHOSTLIB_STATISTICS_S *p =
-                       (struct SMSHOSTLIB_STATISTICS_S *)(phdr + 1);
+               union {
+                       struct SMSHOSTLIB_STATISTICS_ISDBT_ST  isdbt;
+                       struct SmsMsgStatisticsInfo_ST         dvb;
+               } *p = (void *) (phdr + 1);
                struct RECEPTION_STATISTICS_S *pReceptionData =
                                &client->sms_stat_dvb.ReceptionData;
 
                sms_info("MSG_SMS_GET_STATISTICS_RES");
 
                is_status_update = true;
-               pReceptionData->IsDemodLocked = p->IsDemodLocked;
+
+               switch (smscore_get_device_mode(client->coredev)) {
+               case DEVICE_MODE_ISDBT:
+               case DEVICE_MODE_ISDBT_BDA:
+                       smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt);
+                       break;
+               default:
+                       smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat);
+               }
                if (!pReceptionData->IsDemodLocked) {
                        pReceptionData->SNR = 0;
                        pReceptionData->BER = 0;
                        pReceptionData->BERErrorCount = 0;
                        pReceptionData->InBandPwr = 0;
                        pReceptionData->ErrorTSPackets = 0;
-
-                       complete(&client->tune_done);
-                       break;
                }
 
-               pReceptionData->SNR = p->SNR;
-               pReceptionData->BER = p->BER;
-               pReceptionData->BERErrorCount = p->BERErrorCount;
-               pReceptionData->InBandPwr = p->InBandPwr;
-               pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
-
                complete(&client->tune_done);
                break;
        }