mt76x2_eeprom.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. /*
  2. * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <asm/unaligned.h>
  17. #include "mt76x2.h"
  18. #include "mt76x2_eeprom.h"
  19. #define EE_FIELD(_name, _value) [MT_EE_##_name] = (_value) | 1
  20. static int
  21. mt76x2_eeprom_copy(struct mt76x2_dev *dev, enum mt76x2_eeprom_field field,
  22. void *dest, int len)
  23. {
  24. if (field + len > dev->mt76.eeprom.size)
  25. return -1;
  26. memcpy(dest, dev->mt76.eeprom.data + field, len);
  27. return 0;
  28. }
  29. static int
  30. mt76x2_eeprom_get_macaddr(struct mt76x2_dev *dev)
  31. {
  32. void *src = dev->mt76.eeprom.data + MT_EE_MAC_ADDR;
  33. memcpy(dev->mt76.macaddr, src, ETH_ALEN);
  34. return 0;
  35. }
  36. static void
  37. mt76x2_eeprom_parse_hw_cap(struct mt76x2_dev *dev)
  38. {
  39. u16 val = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_0);
  40. switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, val)) {
  41. case BOARD_TYPE_5GHZ:
  42. dev->mt76.cap.has_5ghz = true;
  43. break;
  44. case BOARD_TYPE_2GHZ:
  45. dev->mt76.cap.has_2ghz = true;
  46. break;
  47. default:
  48. dev->mt76.cap.has_2ghz = true;
  49. dev->mt76.cap.has_5ghz = true;
  50. break;
  51. }
  52. }
  53. static int
  54. mt76x2_efuse_read(struct mt76x2_dev *dev, u16 addr, u8 *data)
  55. {
  56. u32 val;
  57. int i;
  58. val = mt76_rr(dev, MT_EFUSE_CTRL);
  59. val &= ~(MT_EFUSE_CTRL_AIN |
  60. MT_EFUSE_CTRL_MODE);
  61. val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf);
  62. val |= MT_EFUSE_CTRL_KICK;
  63. mt76_wr(dev, MT_EFUSE_CTRL, val);
  64. if (!mt76_poll(dev, MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
  65. return -ETIMEDOUT;
  66. udelay(2);
  67. val = mt76_rr(dev, MT_EFUSE_CTRL);
  68. if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT) {
  69. memset(data, 0xff, 16);
  70. return 0;
  71. }
  72. for (i = 0; i < 4; i++) {
  73. val = mt76_rr(dev, MT_EFUSE_DATA(i));
  74. put_unaligned_le32(val, data + 4 * i);
  75. }
  76. return 0;
  77. }
  78. static int
  79. mt76x2_get_efuse_data(struct mt76x2_dev *dev, void *buf, int len)
  80. {
  81. int ret, i;
  82. for (i = 0; i + 16 <= len; i += 16) {
  83. ret = mt76x2_efuse_read(dev, i, buf + i);
  84. if (ret)
  85. return ret;
  86. }
  87. return 0;
  88. }
  89. static bool
  90. mt76x2_has_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
  91. {
  92. u16 *efuse_w = (u16 *) efuse;
  93. if (efuse_w[MT_EE_NIC_CONF_0] != 0)
  94. return false;
  95. if (efuse_w[MT_EE_XTAL_TRIM_1] == 0xffff)
  96. return false;
  97. if (efuse_w[MT_EE_TX_POWER_DELTA_BW40] != 0)
  98. return false;
  99. if (efuse_w[MT_EE_TX_POWER_0_START_2G] == 0xffff)
  100. return false;
  101. if (efuse_w[MT_EE_TX_POWER_0_GRP3_TX_POWER_DELTA] != 0)
  102. return false;
  103. if (efuse_w[MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE] == 0xffff)
  104. return false;
  105. return true;
  106. }
  107. static void
  108. mt76x2_apply_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
  109. {
  110. #define GROUP_5G(_id) \
  111. MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id), \
  112. MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1, \
  113. MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id), \
  114. MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1
  115. static const u8 cal_free_bytes[] = {
  116. MT_EE_XTAL_TRIM_1,
  117. MT_EE_TX_POWER_EXT_PA_5G + 1,
  118. MT_EE_TX_POWER_0_START_2G,
  119. MT_EE_TX_POWER_0_START_2G + 1,
  120. MT_EE_TX_POWER_1_START_2G,
  121. MT_EE_TX_POWER_1_START_2G + 1,
  122. GROUP_5G(0),
  123. GROUP_5G(1),
  124. GROUP_5G(2),
  125. GROUP_5G(3),
  126. GROUP_5G(4),
  127. GROUP_5G(5),
  128. MT_EE_RF_2G_TSSI_OFF_TXPOWER,
  129. MT_EE_RF_2G_RX_HIGH_GAIN + 1,
  130. MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN,
  131. MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN + 1,
  132. MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN,
  133. MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN + 1,
  134. MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN,
  135. MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN + 1,
  136. };
  137. u8 *eeprom = dev->mt76.eeprom.data;
  138. u8 prev_grp0[4] = {
  139. eeprom[MT_EE_TX_POWER_0_START_5G],
  140. eeprom[MT_EE_TX_POWER_0_START_5G + 1],
  141. eeprom[MT_EE_TX_POWER_1_START_5G],
  142. eeprom[MT_EE_TX_POWER_1_START_5G + 1]
  143. };
  144. u16 val;
  145. int i;
  146. if (!mt76x2_has_cal_free_data(dev, efuse))
  147. return;
  148. for (i = 0; i < ARRAY_SIZE(cal_free_bytes); i++) {
  149. int offset = cal_free_bytes[i];
  150. eeprom[offset] = efuse[offset];
  151. }
  152. if (!(efuse[MT_EE_TX_POWER_0_START_5G] |
  153. efuse[MT_EE_TX_POWER_0_START_5G + 1]))
  154. memcpy(eeprom + MT_EE_TX_POWER_0_START_5G, prev_grp0, 2);
  155. if (!(efuse[MT_EE_TX_POWER_1_START_5G] |
  156. efuse[MT_EE_TX_POWER_1_START_5G + 1]))
  157. memcpy(eeprom + MT_EE_TX_POWER_1_START_5G, prev_grp0 + 2, 2);
  158. val = get_unaligned_le16(efuse + MT_EE_BT_RCAL_RESULT);
  159. if (val != 0xffff)
  160. eeprom[MT_EE_BT_RCAL_RESULT] = val & 0xff;
  161. val = get_unaligned_le16(efuse + MT_EE_BT_VCDL_CALIBRATION);
  162. if (val != 0xffff)
  163. eeprom[MT_EE_BT_VCDL_CALIBRATION + 1] = val >> 8;
  164. val = get_unaligned_le16(efuse + MT_EE_BT_PMUCFG);
  165. if (val != 0xffff)
  166. eeprom[MT_EE_BT_PMUCFG] = val & 0xff;
  167. }
  168. static int mt76x2_check_eeprom(struct mt76x2_dev *dev)
  169. {
  170. u16 val = get_unaligned_le16(dev->mt76.eeprom.data);
  171. if (!val)
  172. val = get_unaligned_le16(dev->mt76.eeprom.data + MT_EE_PCI_ID);
  173. switch (val) {
  174. case 0x7662:
  175. case 0x7612:
  176. return 0;
  177. default:
  178. dev_err(dev->mt76.dev, "EEPROM data check failed: %04x\n", val);
  179. return -EINVAL;
  180. }
  181. }
  182. static int
  183. mt76x2_eeprom_load(struct mt76x2_dev *dev)
  184. {
  185. void *efuse;
  186. bool found;
  187. int ret;
  188. ret = mt76_eeprom_init(&dev->mt76, MT7662_EEPROM_SIZE);
  189. if (ret < 0)
  190. return ret;
  191. found = ret;
  192. if (found)
  193. found = !mt76x2_check_eeprom(dev);
  194. dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, MT7662_EEPROM_SIZE,
  195. GFP_KERNEL);
  196. dev->mt76.otp.size = MT7662_EEPROM_SIZE;
  197. if (!dev->mt76.otp.data)
  198. return -ENOMEM;
  199. efuse = dev->mt76.otp.data;
  200. if (mt76x2_get_efuse_data(dev, efuse, MT7662_EEPROM_SIZE))
  201. goto out;
  202. if (found) {
  203. mt76x2_apply_cal_free_data(dev, efuse);
  204. } else {
  205. /* FIXME: check if efuse data is complete */
  206. found = true;
  207. memcpy(dev->mt76.eeprom.data, efuse, MT7662_EEPROM_SIZE);
  208. }
  209. out:
  210. if (!found)
  211. return -ENOENT;
  212. return 0;
  213. }
  214. static inline int
  215. mt76x2_sign_extend(u32 val, unsigned int size)
  216. {
  217. bool sign = val & BIT(size - 1);
  218. val &= BIT(size - 1) - 1;
  219. return sign ? val : -val;
  220. }
  221. static inline int
  222. mt76x2_sign_extend_optional(u32 val, unsigned int size)
  223. {
  224. bool enable = val & BIT(size);
  225. return enable ? mt76x2_sign_extend(val, size) : 0;
  226. }
  227. static bool
  228. field_valid(u8 val)
  229. {
  230. return val != 0 && val != 0xff;
  231. }
  232. static void
  233. mt76x2_set_rx_gain_group(struct mt76x2_dev *dev, u8 val)
  234. {
  235. s8 *dest = dev->cal.rx.high_gain;
  236. if (!field_valid(val)) {
  237. dest[0] = 0;
  238. dest[1] = 0;
  239. return;
  240. }
  241. dest[0] = mt76x2_sign_extend(val, 4);
  242. dest[1] = mt76x2_sign_extend(val >> 4, 4);
  243. }
  244. static void
  245. mt76x2_set_rssi_offset(struct mt76x2_dev *dev, int chain, u8 val)
  246. {
  247. s8 *dest = dev->cal.rx.rssi_offset;
  248. if (!field_valid(val)) {
  249. dest[chain] = 0;
  250. return;
  251. }
  252. dest[chain] = mt76x2_sign_extend_optional(val, 7);
  253. }
  254. static enum mt76x2_cal_channel_group
  255. mt76x2_get_cal_channel_group(int channel)
  256. {
  257. if (channel >= 184 && channel <= 196)
  258. return MT_CH_5G_JAPAN;
  259. if (channel <= 48)
  260. return MT_CH_5G_UNII_1;
  261. if (channel <= 64)
  262. return MT_CH_5G_UNII_2;
  263. if (channel <= 114)
  264. return MT_CH_5G_UNII_2E_1;
  265. if (channel <= 144)
  266. return MT_CH_5G_UNII_2E_2;
  267. return MT_CH_5G_UNII_3;
  268. }
  269. static u8
  270. mt76x2_get_5g_rx_gain(struct mt76x2_dev *dev, u8 channel)
  271. {
  272. enum mt76x2_cal_channel_group group;
  273. group = mt76x2_get_cal_channel_group(channel);
  274. switch (group) {
  275. case MT_CH_5G_JAPAN:
  276. return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN);
  277. case MT_CH_5G_UNII_1:
  278. return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN) >> 8;
  279. case MT_CH_5G_UNII_2:
  280. return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN);
  281. case MT_CH_5G_UNII_2E_1:
  282. return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN) >> 8;
  283. case MT_CH_5G_UNII_2E_2:
  284. return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN);
  285. default:
  286. return mt76x2_eeprom_get(dev, MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN) >> 8;
  287. }
  288. }
  289. void mt76x2_read_rx_gain(struct mt76x2_dev *dev)
  290. {
  291. struct ieee80211_channel *chan = dev->mt76.chandef.chan;
  292. int channel = chan->hw_value;
  293. s8 lna_5g[3], lna_2g;
  294. u8 lna;
  295. u16 val;
  296. if (chan->band == NL80211_BAND_2GHZ)
  297. val = mt76x2_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN) >> 8;
  298. else
  299. val = mt76x2_get_5g_rx_gain(dev, channel);
  300. mt76x2_set_rx_gain_group(dev, val);
  301. if (chan->band == NL80211_BAND_2GHZ) {
  302. val = mt76x2_eeprom_get(dev, MT_EE_RSSI_OFFSET_2G_0);
  303. mt76x2_set_rssi_offset(dev, 0, val);
  304. mt76x2_set_rssi_offset(dev, 1, val >> 8);
  305. } else {
  306. val = mt76x2_eeprom_get(dev, MT_EE_RSSI_OFFSET_5G_0);
  307. mt76x2_set_rssi_offset(dev, 0, val);
  308. mt76x2_set_rssi_offset(dev, 1, val >> 8);
  309. }
  310. val = mt76x2_eeprom_get(dev, MT_EE_LNA_GAIN);
  311. lna_2g = val & 0xff;
  312. lna_5g[0] = val >> 8;
  313. val = mt76x2_eeprom_get(dev, MT_EE_RSSI_OFFSET_2G_1);
  314. lna_5g[1] = val >> 8;
  315. val = mt76x2_eeprom_get(dev, MT_EE_RSSI_OFFSET_5G_1);
  316. lna_5g[2] = val >> 8;
  317. if (!field_valid(lna_5g[1]))
  318. lna_5g[1] = lna_5g[0];
  319. if (!field_valid(lna_5g[2]))
  320. lna_5g[2] = lna_5g[0];
  321. dev->cal.rx.mcu_gain = (lna_2g & 0xff);
  322. dev->cal.rx.mcu_gain |= (lna_5g[0] & 0xff) << 8;
  323. dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16;
  324. dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24;
  325. val = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1);
  326. if (val & MT_EE_NIC_CONF_1_LNA_EXT_2G)
  327. lna_2g = 0;
  328. if (val & MT_EE_NIC_CONF_1_LNA_EXT_5G)
  329. memset(lna_5g, 0, sizeof(lna_5g));
  330. if (chan->band == NL80211_BAND_2GHZ)
  331. lna = lna_2g;
  332. else if (channel <= 64)
  333. lna = lna_5g[0];
  334. else if (channel <= 128)
  335. lna = lna_5g[1];
  336. else
  337. lna = lna_5g[2];
  338. if (lna == 0xff)
  339. lna = 0;
  340. dev->cal.rx.lna_gain = mt76x2_sign_extend(lna, 8);
  341. }
  342. static s8
  343. mt76x2_rate_power_val(u8 val)
  344. {
  345. if (!field_valid(val))
  346. return 0;
  347. return mt76x2_sign_extend_optional(val, 7);
  348. }
  349. void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t,
  350. struct ieee80211_channel *chan)
  351. {
  352. bool is_5ghz;
  353. u16 val;
  354. is_5ghz = chan->band == NL80211_BAND_5GHZ;
  355. memset(t, 0, sizeof(*t));
  356. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_CCK);
  357. t->cck[0] = t->cck[1] = mt76x2_rate_power_val(val);
  358. t->cck[2] = t->cck[3] = mt76x2_rate_power_val(val >> 8);
  359. if (is_5ghz)
  360. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_OFDM_5G_6M);
  361. else
  362. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_OFDM_2G_6M);
  363. t->ofdm[0] = t->ofdm[1] = mt76x2_rate_power_val(val);
  364. t->ofdm[2] = t->ofdm[3] = mt76x2_rate_power_val(val >> 8);
  365. if (is_5ghz)
  366. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_OFDM_5G_24M);
  367. else
  368. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_OFDM_2G_24M);
  369. t->ofdm[4] = t->ofdm[5] = mt76x2_rate_power_val(val);
  370. t->ofdm[6] = t->ofdm[7] = mt76x2_rate_power_val(val >> 8);
  371. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS0);
  372. t->ht[0] = t->ht[1] = mt76x2_rate_power_val(val);
  373. t->ht[2] = t->ht[3] = mt76x2_rate_power_val(val >> 8);
  374. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS4);
  375. t->ht[4] = t->ht[5] = mt76x2_rate_power_val(val);
  376. t->ht[6] = t->ht[7] = mt76x2_rate_power_val(val >> 8);
  377. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS8);
  378. t->ht[8] = t->ht[9] = mt76x2_rate_power_val(val);
  379. t->ht[10] = t->ht[11] = mt76x2_rate_power_val(val >> 8);
  380. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS12);
  381. t->ht[12] = t->ht[13] = mt76x2_rate_power_val(val);
  382. t->ht[14] = t->ht[15] = mt76x2_rate_power_val(val >> 8);
  383. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS0);
  384. t->vht[0] = t->vht[1] = mt76x2_rate_power_val(val);
  385. t->vht[2] = t->vht[3] = mt76x2_rate_power_val(val >> 8);
  386. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS4);
  387. t->vht[4] = t->vht[5] = mt76x2_rate_power_val(val);
  388. t->vht[6] = t->vht[7] = mt76x2_rate_power_val(val >> 8);
  389. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS8);
  390. if (!is_5ghz)
  391. val >>= 8;
  392. t->vht[8] = t->vht[9] = mt76x2_rate_power_val(val >> 8);
  393. }
  394. int mt76x2_get_max_rate_power(struct mt76_rate_power *r)
  395. {
  396. int i;
  397. s8 ret = 0;
  398. for (i = 0; i < sizeof(r->all); i++)
  399. ret = max(ret, r->all[i]);
  400. return ret;
  401. }
  402. static void
  403. mt76x2_get_power_info_2g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info *t,
  404. struct ieee80211_channel *chan, int chain, int offset)
  405. {
  406. int channel = chan->hw_value;
  407. int delta_idx;
  408. u8 data[6];
  409. u16 val;
  410. if (channel < 6)
  411. delta_idx = 3;
  412. else if (channel < 11)
  413. delta_idx = 4;
  414. else
  415. delta_idx = 5;
  416. mt76x2_eeprom_copy(dev, offset, data, sizeof(data));
  417. t->chain[chain].tssi_slope = data[0];
  418. t->chain[chain].tssi_offset = data[1];
  419. t->chain[chain].target_power = data[2];
  420. t->chain[chain].delta = mt76x2_sign_extend_optional(data[delta_idx], 7);
  421. val = mt76x2_eeprom_get(dev, MT_EE_RF_2G_TSSI_OFF_TXPOWER);
  422. t->target_power = val >> 8;
  423. }
  424. static void
  425. mt76x2_get_power_info_5g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info *t,
  426. struct ieee80211_channel *chan, int chain, int offset)
  427. {
  428. int channel = chan->hw_value;
  429. enum mt76x2_cal_channel_group group;
  430. int delta_idx;
  431. u16 val;
  432. u8 data[5];
  433. group = mt76x2_get_cal_channel_group(channel);
  434. offset += group * MT_TX_POWER_GROUP_SIZE_5G;
  435. if (channel >= 192)
  436. delta_idx = 4;
  437. else if (channel >= 184)
  438. delta_idx = 3;
  439. else if (channel < 44)
  440. delta_idx = 3;
  441. else if (channel < 52)
  442. delta_idx = 4;
  443. else if (channel < 58)
  444. delta_idx = 3;
  445. else if (channel < 98)
  446. delta_idx = 4;
  447. else if (channel < 106)
  448. delta_idx = 3;
  449. else if (channel < 116)
  450. delta_idx = 4;
  451. else if (channel < 130)
  452. delta_idx = 3;
  453. else if (channel < 149)
  454. delta_idx = 4;
  455. else if (channel < 157)
  456. delta_idx = 3;
  457. else
  458. delta_idx = 4;
  459. mt76x2_eeprom_copy(dev, offset, data, sizeof(data));
  460. t->chain[chain].tssi_slope = data[0];
  461. t->chain[chain].tssi_offset = data[1];
  462. t->chain[chain].target_power = data[2];
  463. t->chain[chain].delta = mt76x2_sign_extend_optional(data[delta_idx], 7);
  464. val = mt76x2_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN);
  465. t->target_power = val & 0xff;
  466. }
  467. void mt76x2_get_power_info(struct mt76x2_dev *dev,
  468. struct mt76x2_tx_power_info *t,
  469. struct ieee80211_channel *chan)
  470. {
  471. u16 bw40, bw80;
  472. memset(t, 0, sizeof(*t));
  473. bw40 = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW40);
  474. bw80 = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW80);
  475. if (chan->band == NL80211_BAND_5GHZ) {
  476. bw40 >>= 8;
  477. mt76x2_get_power_info_5g(dev, t, chan, 0,
  478. MT_EE_TX_POWER_0_START_5G);
  479. mt76x2_get_power_info_5g(dev, t, chan, 1,
  480. MT_EE_TX_POWER_1_START_5G);
  481. } else {
  482. mt76x2_get_power_info_2g(dev, t, chan, 0,
  483. MT_EE_TX_POWER_0_START_2G);
  484. mt76x2_get_power_info_2g(dev, t, chan, 1,
  485. MT_EE_TX_POWER_1_START_2G);
  486. }
  487. if (mt76x2_tssi_enabled(dev) || !field_valid(t->target_power))
  488. t->target_power = t->chain[0].target_power;
  489. t->delta_bw40 = mt76x2_rate_power_val(bw40);
  490. t->delta_bw80 = mt76x2_rate_power_val(bw80);
  491. }
  492. int mt76x2_get_temp_comp(struct mt76x2_dev *dev, struct mt76x2_temp_comp *t)
  493. {
  494. enum nl80211_band band = dev->mt76.chandef.chan->band;
  495. u16 val, slope;
  496. u8 bounds;
  497. memset(t, 0, sizeof(*t));
  498. val = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1);
  499. if (!(val & MT_EE_NIC_CONF_1_TEMP_TX_ALC))
  500. return -EINVAL;
  501. if (!mt76x2_ext_pa_enabled(dev, band))
  502. return -EINVAL;
  503. val = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G) >> 8;
  504. if (!(val & BIT(7)))
  505. return -EINVAL;
  506. t->temp_25_ref = val & 0x7f;
  507. if (band == NL80211_BAND_5GHZ) {
  508. slope = mt76x2_eeprom_get(dev, MT_EE_RF_TEMP_COMP_SLOPE_5G);
  509. bounds = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G);
  510. } else {
  511. slope = mt76x2_eeprom_get(dev, MT_EE_RF_TEMP_COMP_SLOPE_2G);
  512. bounds = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW80) >> 8;
  513. }
  514. t->high_slope = slope & 0xff;
  515. t->low_slope = slope >> 8;
  516. t->lower_bound = 0 - (bounds & 0xf);
  517. t->upper_bound = (bounds >> 4) & 0xf;
  518. return 0;
  519. }
  520. bool mt76x2_ext_pa_enabled(struct mt76x2_dev *dev, enum nl80211_band band)
  521. {
  522. u16 conf0 = mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_0);
  523. if (band == NL80211_BAND_5GHZ)
  524. return !(conf0 & MT_EE_NIC_CONF_0_PA_INT_5G);
  525. else
  526. return !(conf0 & MT_EE_NIC_CONF_0_PA_INT_2G);
  527. }
  528. int mt76x2_eeprom_init(struct mt76x2_dev *dev)
  529. {
  530. int ret;
  531. ret = mt76x2_eeprom_load(dev);
  532. if (ret)
  533. return ret;
  534. mt76x2_eeprom_parse_hw_cap(dev);
  535. mt76x2_eeprom_get_macaddr(dev);
  536. mt76_eeprom_override(&dev->mt76);
  537. dev->mt76.macaddr[0] &= ~BIT(1);
  538. return 0;
  539. }