Skip to content

Commit dc82a01

Browse files
committed
eep9880: otp: add calibration data decompression
Add support for calibration data extraction from OTP memory as part of generic OTP data parsing procedure. I.e. add handler for calibration data Id. QCA988x calibration data is compressed in the same way as AR93xx calibration data, so reuse AR93xx data decompression routines, that were moved to the common handlers earlier.
1 parent 3053c02 commit dc82a01

File tree

3 files changed

+1785
-1
lines changed

3 files changed

+1785
-1
lines changed

eep_9880.c

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,76 @@
1818
#include "utils.h"
1919
#include "eep_common.h"
2020
#include "eep_9880.h"
21+
#include "eep_9880_templates.h"
2122

2223
static const uint8_t eep_9880_otp_magic[2] = {0xaa, 0x55};
2324

2425
struct eep_9880_priv {
26+
int curr_ref_tpl; /* Current reference EEPROM template */
2527
struct qca9880_eeprom eep;
26-
} __attribute__((aligned(4))); /* Force alignment to make gcc happy */
28+
};
29+
30+
#define QCA9880_TEMPLATE_DESC(__name, __tpl) \
31+
{ qca9880_tpl_ver_ ## __tpl, __name, &qca9880_ ## __tpl }
32+
33+
static const struct eeptemplate eep_9880_templates[] = {
34+
QCA9880_TEMPLATE_DESC("CUS223", cus223),
35+
QCA9880_TEMPLATE_DESC("XB140", xb140),
36+
{ 0, NULL }
37+
};
38+
39+
static const uint8_t *qca9880_template_find_by_id(int id)
40+
{
41+
const struct eeptemplate *tpl;
42+
43+
for (tpl = eep_9880_templates; tpl->name; ++tpl)
44+
if (tpl->id == id)
45+
break;
46+
47+
return tpl->data;
48+
}
49+
50+
static void eep_9880_proc_otp_caldata(struct atheepmgr *aem,
51+
const uint8_t *data, int len)
52+
{
53+
struct eep_9880_priv *emp = aem->eepmap_priv;
54+
struct ar9300_comp_hdr hdr;
55+
uint16_t cksum, _cksum;
56+
57+
ar9300_comp_hdr_unpack(data, &hdr);
58+
if (aem->verbose)
59+
printf("Found block at %x: comp=%d ref=%d length=%d major=%d minor=%d\n",
60+
0, hdr.comp, hdr.ref, hdr.len, hdr.maj, hdr.min);
61+
62+
data += sizeof(AR9300_COMP_HDR_LEN);
63+
len -= AR9300_COMP_HDR_LEN + sizeof(cksum);
64+
if (hdr.len > len) {
65+
if (aem->verbose)
66+
printf("Caldata block length greater then OTP stream length\n");
67+
return;
68+
}
69+
70+
cksum = ar9300_comp_cksum(data, hdr.len);
71+
_cksum = data[hdr.len + 0] | (data[hdr.len + 1] << 8);
72+
if (cksum != _cksum) {
73+
if (aem->verbose)
74+
printf("Bad caldata block checksum (got 0x%04x, expect 0x%04x)\n",
75+
cksum, _cksum);
76+
return;
77+
}
78+
79+
ar9300_compress_decision(aem, 0, &hdr, aem->unpacked_buf, data,
80+
sizeof(emp->eep), &emp->curr_ref_tpl,
81+
qca9880_template_find_by_id);
82+
}
2783

2884
static struct eep_9880_otp_str_desc {
2985
const char *name;
3086
void (*proc)(struct atheepmgr *aem, const uint8_t *data, int len);
3187
} eep_9880_otp_streams[] = {
88+
[QCA9880_OTP_STR_TYPE_CALDATA] = {
89+
"calibration data", eep_9880_proc_otp_caldata
90+
},
3291
};
3392

3493
static bool eep_9880_load_blob(struct atheepmgr *aem)
@@ -54,6 +113,8 @@ static bool eep_9880_load_blob(struct atheepmgr *aem)
54113

55114
static bool eep_9880_load_otp(struct atheepmgr *aem)
56115
{
116+
struct eep_9880_priv *emp = aem->eepmap_priv;
117+
struct qca9880_eeprom *eep;
57118
uint8_t *buf = (uint8_t *)aem->eep_buf; /* Use as an array of bytes */
58119
unsigned int addr, end_mark_seen;
59120
uint8_t strcode;
@@ -80,6 +141,8 @@ static bool eep_9880_load_otp(struct atheepmgr *aem)
80141
goto exit;
81142
}
82143

144+
emp->curr_ref_tpl = -1; /* Reset reference template */
145+
83146
/**
84147
* Now we are ready to parse OTP memory content.
85148
*
@@ -155,7 +218,19 @@ static bool eep_9880_load_otp(struct atheepmgr *aem)
155218
}
156219
}
157220

221+
/**
222+
* OTP does not contain a checksum correction, so update unpacked
223+
* caldata checksum manually.
224+
*/
225+
eep = (void *)aem->unpacked_buf;
226+
eep->baseEepHeader.checksum = 0xffff;
227+
eep->baseEepHeader.checksum =
228+
eep_calc_csum((uint16_t *)aem->unpacked_buf,
229+
sizeof(*eep) / sizeof(uint16_t));
230+
158231
aem->eep_len = QCA9880_OTP_SIZE / sizeof(uint16_t);
232+
aem->unpacked_len = sizeof(struct qca9880_eeprom);
233+
memcpy(&emp->eep, aem->unpacked_buf, sizeof(emp->eep));
159234

160235
exit:
161236
return aem->eep_len != 0;
@@ -487,6 +562,8 @@ const struct eepmap eepmap_9880 = {
487562
.desc = "EEPROM map for earlier .11ac chips (QCA9880/QCA9882/QCA9892/etc.)",
488563
.priv_data_sz = sizeof(struct eep_9880_priv),
489564
.eep_buf_sz = QCA9880_EEPROM_SIZE / sizeof(uint16_t),
565+
.unpacked_buf_sz = sizeof(struct qca9880_eeprom),
566+
.templates = eep_9880_templates,
490567
.load_blob = eep_9880_load_blob,
491568
.load_otp = eep_9880_load_otp,
492569
.check_eeprom = eep_9880_check,

eep_9880.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103

104104
enum qca9880_otp_str_types {
105105
QCA9880_OTP_STR_TYPE_UNKNOWN = 0,
106+
QCA9880_OTP_STR_TYPE_CALDATA = 1,
106107
};
107108

108109
struct qca9880_otp_str {

0 commit comments

Comments
 (0)