diff options
author | Alexander Aring <alex.aring@gmail.com> | 2015-05-17 15:44:50 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-05-19 05:44:44 -0400 |
commit | 2d9fe7ab372a75c0148027bc48a18a64f150a7e7 (patch) | |
tree | b09b869c560efe529243372385fbc4039f040d5e /drivers/net | |
parent | 6f4da3f897906d0e1f27e3e44bd445f8e6d7bd85 (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.c | 79 |
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 | ||
1083 | static 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 | |||
1088 | static 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 | |||
1093 | static 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 | |||
1098 | static inline int | ||
1099 | at86rf212_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 | |||
1083 | static int | 1126 | static int |
1084 | at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel) | 1127 | at86rf212_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 | ||
1294 | static int | ||
1295 | at86rf212_get_desens_steps(struct at86rf230_local *lp, s32 level) | ||
1296 | { | ||
1297 | return (level - lp->data->rssi_base_val) * 100 / 207; | ||
1298 | } | ||
1299 | |||
1300 | static int | ||
1301 | at86rf23x_get_desens_steps(struct at86rf230_local *lp, s32 level) | ||
1302 | { | ||
1303 | return (level - lp->data->rssi_base_val) / 2; | ||
1304 | } | ||
1305 | 1341 | ||
1306 | static int | 1342 | static int |
1307 | at86rf230_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm) | 1343 | at86rf230_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 | ||
1319 | static int | 1356 | static 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"; |