summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2015-05-17 15:44:50 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-05-19 05:44:44 -0400
commit2d9fe7ab372a75c0148027bc48a18a64f150a7e7 (patch)
treeb09b869c560efe529243372385fbc4039f040d5e /drivers/net
parent6f4da3f897906d0e1f27e3e44bd445f8e6d7bd85 (diff)
at86rf230: rework tx cca energy detection level
This patch reworks the cca energy detection level handling. This contains a calculation which works on all transceiver types and add support for dump cca energy detection levels. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ieee802154/at86rf230.c79
1 files changed, 59 insertions, 20 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index dff7e47f5afb..833c42640e40 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -50,7 +50,6 @@ struct at86rf2xx_chip_data {
50 int rssi_base_val; 50 int rssi_base_val;
51 51
52 int (*set_channel)(struct at86rf230_local *, u8, u8); 52 int (*set_channel)(struct at86rf230_local *, u8, u8);
53 int (*get_desense_steps)(struct at86rf230_local *, s32);
54 int (*set_txpower)(struct at86rf230_local *, s32); 53 int (*set_txpower)(struct at86rf230_local *, s32);
55}; 54};
56 55
@@ -1080,6 +1079,50 @@ at86rf23x_set_channel(struct at86rf230_local *lp, u8 page, u8 channel)
1080 return at86rf230_write_subreg(lp, SR_CHANNEL, channel); 1079 return at86rf230_write_subreg(lp, SR_CHANNEL, channel);
1081} 1080}
1082 1081
1082#define AT86RF2XX_MAX_ED_LEVELS 0xF
1083static const s32 at86rf23x_ed_levels[AT86RF2XX_MAX_ED_LEVELS + 1] = {
1084 -9100, -8900, -8700, -8500, -8300, -8100, -7900, -7700, -7500, -7300,
1085 -7100, -6900, -6700, -6500, -6300, -6100,
1086};
1087
1088static const s32 at86rf212_ed_levels_100[AT86RF2XX_MAX_ED_LEVELS + 1] = {
1089 -10000, -9800, -9600, -9400, -9200, -9000, -8800, -8600, -8400, -8200,
1090 -8000, -7800, -7600, -7400, -7200,
1091};
1092
1093static const s32 at86rf212_ed_levels_98[AT86RF2XX_MAX_ED_LEVELS + 1] = {
1094 -9800, -9600, -9400, -9200, -9000, -8800, -8600, -8400, -8200, -8000,
1095 -7800, -7600, -7400, -7200, -7000,
1096};
1097
1098static inline int
1099at86rf212_update_cca_ed_level(struct at86rf230_local *lp, int rssi_base_val)
1100{
1101 unsigned int cca_ed_thres;
1102 int rc;
1103
1104 rc = at86rf230_read_subreg(lp, SR_CCA_ED_THRES, &cca_ed_thres);
1105 if (rc < 0)
1106 return rc;
1107
1108 switch (rssi_base_val) {
1109 case -98:
1110 lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_98;
1111 lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_98);
1112 lp->hw->phy->cca_ed_level = at86rf212_ed_levels_98[cca_ed_thres];
1113 break;
1114 case -100:
1115 lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_100;
1116 lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_100);
1117 lp->hw->phy->cca_ed_level = at86rf212_ed_levels_100[cca_ed_thres];
1118 break;
1119 default:
1120 WARN_ON(1);
1121 }
1122
1123 return 0;
1124}
1125
1083static int 1126static int
1084at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel) 1127at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel)
1085{ 1128{
@@ -1102,6 +1145,10 @@ at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel)
1102 if (rc < 0) 1145 if (rc < 0)
1103 return rc; 1146 return rc;
1104 1147
1148 rc = at86rf212_update_cca_ed_level(lp, lp->data->rssi_base_val);
1149 if (rc < 0)
1150 return rc;
1151
1105 /* This sets the symbol_duration according frequency on the 212. 1152 /* This sets the symbol_duration according frequency on the 212.
1106 * TODO move this handling while set channel and page in cfg802154. 1153 * TODO move this handling while set channel and page in cfg802154.
1107 * We can do that, this timings are according 802.15.4 standard. 1154 * We can do that, this timings are according 802.15.4 standard.
@@ -1291,29 +1338,19 @@ at86rf230_set_cca_mode(struct ieee802154_hw *hw,
1291 return at86rf230_write_subreg(lp, SR_CCA_MODE, val); 1338 return at86rf230_write_subreg(lp, SR_CCA_MODE, val);
1292} 1339}
1293 1340
1294static int
1295at86rf212_get_desens_steps(struct at86rf230_local *lp, s32 level)
1296{
1297 return (level - lp->data->rssi_base_val) * 100 / 207;
1298}
1299
1300static int
1301at86rf23x_get_desens_steps(struct at86rf230_local *lp, s32 level)
1302{
1303 return (level - lp->data->rssi_base_val) / 2;
1304}
1305 1341
1306static int 1342static int
1307at86rf230_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm) 1343at86rf230_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
1308{ 1344{
1309 struct at86rf230_local *lp = hw->priv; 1345 struct at86rf230_local *lp = hw->priv;
1310 s32 level = mbm / 100; 1346 u32 i;
1311 1347
1312 if (level < lp->data->rssi_base_val || level > 30) 1348 for (i = 0; i < hw->phy->supported.cca_ed_levels_size; i++) {
1313 return -EINVAL; 1349 if (hw->phy->supported.cca_ed_levels[i] == mbm)
1350 return at86rf230_write_subreg(lp, SR_CCA_ED_THRES, i);
1351 }
1314 1352
1315 return at86rf230_write_subreg(lp, SR_CCA_ED_THRES, 1353 return -EINVAL;
1316 lp->data->get_desense_steps(lp, level));
1317} 1354}
1318 1355
1319static int 1356static int
@@ -1403,7 +1440,6 @@ static struct at86rf2xx_chip_data at86rf233_data = {
1403 .t_p_ack = 545, 1440 .t_p_ack = 545,
1404 .rssi_base_val = -91, 1441 .rssi_base_val = -91,
1405 .set_channel = at86rf23x_set_channel, 1442 .set_channel = at86rf23x_set_channel,
1406 .get_desense_steps = at86rf23x_get_desens_steps,
1407 .set_txpower = at86rf23x_set_txpower, 1443 .set_txpower = at86rf23x_set_txpower,
1408}; 1444};
1409 1445
@@ -1417,7 +1453,6 @@ static struct at86rf2xx_chip_data at86rf231_data = {
1417 .t_p_ack = 545, 1453 .t_p_ack = 545,
1418 .rssi_base_val = -91, 1454 .rssi_base_val = -91,
1419 .set_channel = at86rf23x_set_channel, 1455 .set_channel = at86rf23x_set_channel,
1420 .get_desense_steps = at86rf23x_get_desens_steps,
1421 .set_txpower = at86rf23x_set_txpower, 1456 .set_txpower = at86rf23x_set_txpower,
1422}; 1457};
1423 1458
@@ -1431,7 +1466,6 @@ static struct at86rf2xx_chip_data at86rf212_data = {
1431 .t_p_ack = 545, 1466 .t_p_ack = 545,
1432 .rssi_base_val = -100, 1467 .rssi_base_val = -100,
1433 .set_channel = at86rf212_set_channel, 1468 .set_channel = at86rf212_set_channel,
1434 .get_desense_steps = at86rf212_get_desens_steps,
1435 .set_txpower = at86rf212_set_txpower, 1469 .set_txpower = at86rf212_set_txpower,
1436}; 1470};
1437 1471
@@ -1618,6 +1652,9 @@ at86rf230_detect_device(struct at86rf230_local *lp)
1618 lp->hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) | 1652 lp->hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) |
1619 BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR); 1653 BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR);
1620 1654
1655 lp->hw->phy->supported.cca_ed_levels = at86rf23x_ed_levels;
1656 lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf23x_ed_levels);
1657
1621 lp->hw->phy->cca.mode = NL802154_CCA_ENERGY; 1658 lp->hw->phy->cca.mode = NL802154_CCA_ENERGY;
1622 1659
1623 switch (part) { 1660 switch (part) {
@@ -1645,6 +1682,8 @@ at86rf230_detect_device(struct at86rf230_local *lp)
1645 lp->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH; 1682 lp->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH;
1646 lp->hw->phy->supported.tx_powers = at86rf212_powers; 1683 lp->hw->phy->supported.tx_powers = at86rf212_powers;
1647 lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf212_powers); 1684 lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf212_powers);
1685 lp->hw->phy->supported.cca_ed_levels = at86rf212_ed_levels_100;
1686 lp->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(at86rf212_ed_levels_100);
1648 break; 1687 break;
1649 case 11: 1688 case 11:
1650 chip = "at86rf233"; 1689 chip = "at86rf233";