diff options
-rw-r--r-- | drivers/net/ieee802154/at86rf230.c | 26 | ||||
-rw-r--r-- | include/linux/nl802154.h | 1 | ||||
-rw-r--r-- | include/net/mac802154.h | 7 | ||||
-rw-r--r-- | include/net/wpan-phy.h | 2 | ||||
-rw-r--r-- | net/ieee802154/nl-phy.c | 30 | ||||
-rw-r--r-- | net/ieee802154/nl_policy.c | 1 | ||||
-rw-r--r-- | net/mac802154/ieee802154_dev.c | 11 |
7 files changed, 73 insertions, 5 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index c60871aff333..20596be61028 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c | |||
@@ -52,6 +52,8 @@ struct at86rf230_local { | |||
52 | spinlock_t lock; | 52 | spinlock_t lock; |
53 | bool irq_busy; | 53 | bool irq_busy; |
54 | bool is_tx; | 54 | bool is_tx; |
55 | |||
56 | int rssi_base_val; | ||
55 | }; | 57 | }; |
56 | 58 | ||
57 | static inline int is_rf212(struct at86rf230_local *local) | 59 | static inline int is_rf212(struct at86rf230_local *local) |
@@ -580,6 +582,8 @@ at86rf230_stop(struct ieee802154_dev *dev) | |||
580 | static int | 582 | static int |
581 | at86rf230_set_channel(struct at86rf230_local *lp, int page, int channel) | 583 | at86rf230_set_channel(struct at86rf230_local *lp, int page, int channel) |
582 | { | 584 | { |
585 | lp->rssi_base_val = -91; | ||
586 | |||
583 | return at86rf230_write_subreg(lp, SR_CHANNEL, channel); | 587 | return at86rf230_write_subreg(lp, SR_CHANNEL, channel); |
584 | } | 588 | } |
585 | 589 | ||
@@ -595,10 +599,13 @@ at86rf212_set_channel(struct at86rf230_local *lp, int page, int channel) | |||
595 | if (rc < 0) | 599 | if (rc < 0) |
596 | return rc; | 600 | return rc; |
597 | 601 | ||
598 | if (page == 0) | 602 | if (page == 0) { |
599 | rc = at86rf230_write_subreg(lp, SR_BPSK_QPSK, 0); | 603 | rc = at86rf230_write_subreg(lp, SR_BPSK_QPSK, 0); |
600 | else | 604 | lp->rssi_base_val = -100; |
605 | } else { | ||
601 | rc = at86rf230_write_subreg(lp, SR_BPSK_QPSK, 1); | 606 | rc = at86rf230_write_subreg(lp, SR_BPSK_QPSK, 1); |
607 | lp->rssi_base_val = -98; | ||
608 | } | ||
602 | if (rc < 0) | 609 | if (rc < 0) |
603 | return rc; | 610 | return rc; |
604 | 611 | ||
@@ -802,6 +809,20 @@ at86rf212_set_cca_mode(struct ieee802154_dev *dev, u8 mode) | |||
802 | return at86rf230_write_subreg(lp, SR_CCA_MODE, mode); | 809 | return at86rf230_write_subreg(lp, SR_CCA_MODE, mode); |
803 | } | 810 | } |
804 | 811 | ||
812 | static int | ||
813 | at86rf212_set_cca_ed_level(struct ieee802154_dev *dev, s32 level) | ||
814 | { | ||
815 | struct at86rf230_local *lp = dev->priv; | ||
816 | int desens_steps; | ||
817 | |||
818 | if (level < lp->rssi_base_val || level > 30) | ||
819 | return -EINVAL; | ||
820 | |||
821 | desens_steps = (level - lp->rssi_base_val) * 100 / 207; | ||
822 | |||
823 | return at86rf230_write_subreg(lp, SR_CCA_ED_THRES, desens_steps); | ||
824 | } | ||
825 | |||
805 | static struct ieee802154_ops at86rf230_ops = { | 826 | static struct ieee802154_ops at86rf230_ops = { |
806 | .owner = THIS_MODULE, | 827 | .owner = THIS_MODULE, |
807 | .xmit = at86rf230_xmit, | 828 | .xmit = at86rf230_xmit, |
@@ -823,6 +844,7 @@ static struct ieee802154_ops at86rf212_ops = { | |||
823 | .set_txpower = at86rf212_set_txpower, | 844 | .set_txpower = at86rf212_set_txpower, |
824 | .set_lbt = at86rf212_set_lbt, | 845 | .set_lbt = at86rf212_set_lbt, |
825 | .set_cca_mode = at86rf212_set_cca_mode, | 846 | .set_cca_mode = at86rf212_set_cca_mode, |
847 | .set_cca_ed_level = at86rf212_set_cca_ed_level, | ||
826 | }; | 848 | }; |
827 | 849 | ||
828 | static void at86rf230_irqwork(struct work_struct *work) | 850 | static void at86rf230_irqwork(struct work_struct *work) |
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h index 5edefc14bd83..0594a0ae71ba 100644 --- a/include/linux/nl802154.h +++ b/include/linux/nl802154.h | |||
@@ -73,6 +73,7 @@ enum { | |||
73 | IEEE802154_ATTR_TXPOWER, | 73 | IEEE802154_ATTR_TXPOWER, |
74 | IEEE802154_ATTR_LBT_ENABLED, | 74 | IEEE802154_ATTR_LBT_ENABLED, |
75 | IEEE802154_ATTR_CCA_MODE, | 75 | IEEE802154_ATTR_CCA_MODE, |
76 | IEEE802154_ATTR_CCA_ED_LEVEL, | ||
76 | 77 | ||
77 | __IEEE802154_ATTR_MAX, | 78 | __IEEE802154_ATTR_MAX, |
78 | }; | 79 | }; |
diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 1a98e5014e66..15fe6bca80f0 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h | |||
@@ -126,6 +126,11 @@ struct ieee802154_dev { | |||
126 | * set_cca_mode | 126 | * set_cca_mode |
127 | * Sets the CCA mode used by the device. Called with pib_lock held. | 127 | * Sets the CCA mode used by the device. Called with pib_lock held. |
128 | * Returns either zero, or negative errno. | 128 | * Returns either zero, or negative errno. |
129 | * | ||
130 | * set_cca_ed_level | ||
131 | * Sets the CCA energy detection threshold in dBm. Called with pib_lock | ||
132 | * held. | ||
133 | * Returns either zero, or negative errno. | ||
129 | */ | 134 | */ |
130 | struct ieee802154_ops { | 135 | struct ieee802154_ops { |
131 | struct module *owner; | 136 | struct module *owner; |
@@ -145,6 +150,8 @@ struct ieee802154_ops { | |||
145 | int (*set_txpower)(struct ieee802154_dev *dev, int db); | 150 | int (*set_txpower)(struct ieee802154_dev *dev, int db); |
146 | int (*set_lbt)(struct ieee802154_dev *dev, bool on); | 151 | int (*set_lbt)(struct ieee802154_dev *dev, bool on); |
147 | int (*set_cca_mode)(struct ieee802154_dev *dev, u8 mode); | 152 | int (*set_cca_mode)(struct ieee802154_dev *dev, u8 mode); |
153 | int (*set_cca_ed_level)(struct ieee802154_dev *dev, | ||
154 | s32 level); | ||
148 | }; | 155 | }; |
149 | 156 | ||
150 | /* Basic interface to register ieee802154 device */ | 157 | /* Basic interface to register ieee802154 device */ |
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h index 03b59051972d..0b570ad5e5fa 100644 --- a/include/net/wpan-phy.h +++ b/include/net/wpan-phy.h | |||
@@ -48,6 +48,7 @@ struct wpan_phy { | |||
48 | u8 cca_mode; | 48 | u8 cca_mode; |
49 | 49 | ||
50 | bool lbt; | 50 | bool lbt; |
51 | s32 cca_ed_level; | ||
51 | 52 | ||
52 | struct device dev; | 53 | struct device dev; |
53 | int idx; | 54 | int idx; |
@@ -59,6 +60,7 @@ struct wpan_phy { | |||
59 | int (*set_txpower)(struct wpan_phy *phy, int db); | 60 | int (*set_txpower)(struct wpan_phy *phy, int db); |
60 | int (*set_lbt)(struct wpan_phy *phy, bool on); | 61 | int (*set_lbt)(struct wpan_phy *phy, bool on); |
61 | int (*set_cca_mode)(struct wpan_phy *phy, u8 cca_mode); | 62 | int (*set_cca_mode)(struct wpan_phy *phy, u8 cca_mode); |
63 | int (*set_cca_ed_level)(struct wpan_phy *phy, int level); | ||
62 | 64 | ||
63 | char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); | 65 | char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); |
64 | }; | 66 | }; |
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index 36f58d633868..0af0d424dee0 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c | |||
@@ -58,7 +58,8 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid, | |||
58 | nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel) || | 58 | nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel) || |
59 | nla_put_s8(msg, IEEE802154_ATTR_TXPOWER, phy->transmit_power) || | 59 | nla_put_s8(msg, IEEE802154_ATTR_TXPOWER, phy->transmit_power) || |
60 | nla_put_u8(msg, IEEE802154_ATTR_LBT_ENABLED, phy->lbt) || | 60 | nla_put_u8(msg, IEEE802154_ATTR_LBT_ENABLED, phy->lbt) || |
61 | nla_put_u8(msg, IEEE802154_ATTR_CCA_MODE, phy->cca_mode)) | 61 | nla_put_u8(msg, IEEE802154_ATTR_CCA_MODE, phy->cca_mode) || |
62 | nla_put_s32(msg, IEEE802154_ATTR_CCA_ED_LEVEL, phy->cca_ed_level)) | ||
62 | goto nla_put_failure; | 63 | goto nla_put_failure; |
63 | for (i = 0; i < 32; i++) { | 64 | for (i = 0; i < 32; i++) { |
64 | if (phy->channels_supported[i]) | 65 | if (phy->channels_supported[i]) |
@@ -403,6 +404,20 @@ static int phy_set_cca_mode(struct wpan_phy *phy, struct genl_info *info) | |||
403 | return 0; | 404 | return 0; |
404 | } | 405 | } |
405 | 406 | ||
407 | static int phy_set_cca_ed_level(struct wpan_phy *phy, struct genl_info *info) | ||
408 | { | ||
409 | s32 level = nla_get_s32(info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]); | ||
410 | int rc; | ||
411 | |||
412 | rc = phy->set_cca_ed_level(phy, level); | ||
413 | if (rc < 0) | ||
414 | return rc; | ||
415 | |||
416 | phy->cca_ed_level = level; | ||
417 | |||
418 | return 0; | ||
419 | } | ||
420 | |||
406 | int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info) | 421 | int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info) |
407 | { | 422 | { |
408 | struct wpan_phy *phy; | 423 | struct wpan_phy *phy; |
@@ -413,7 +428,8 @@ int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info) | |||
413 | 428 | ||
414 | if (!info->attrs[IEEE802154_ATTR_PHY_NAME] && | 429 | if (!info->attrs[IEEE802154_ATTR_PHY_NAME] && |
415 | !info->attrs[IEEE802154_ATTR_LBT_ENABLED] && | 430 | !info->attrs[IEEE802154_ATTR_LBT_ENABLED] && |
416 | !info->attrs[IEEE802154_ATTR_CCA_MODE]) | 431 | !info->attrs[IEEE802154_ATTR_CCA_MODE] && |
432 | !info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) | ||
417 | return -EINVAL; | 433 | return -EINVAL; |
418 | 434 | ||
419 | name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]); | 435 | name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]); |
@@ -426,7 +442,9 @@ int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info) | |||
426 | 442 | ||
427 | if ((!phy->set_txpower && info->attrs[IEEE802154_ATTR_TXPOWER]) || | 443 | if ((!phy->set_txpower && info->attrs[IEEE802154_ATTR_TXPOWER]) || |
428 | (!phy->set_lbt && info->attrs[IEEE802154_ATTR_LBT_ENABLED]) || | 444 | (!phy->set_lbt && info->attrs[IEEE802154_ATTR_LBT_ENABLED]) || |
429 | (!phy->set_cca_mode && info->attrs[IEEE802154_ATTR_CCA_MODE])) | 445 | (!phy->set_cca_mode && info->attrs[IEEE802154_ATTR_CCA_MODE]) || |
446 | (!phy->set_cca_ed_level && | ||
447 | info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL])) | ||
430 | goto out; | 448 | goto out; |
431 | 449 | ||
432 | mutex_lock(&phy->pib_lock); | 450 | mutex_lock(&phy->pib_lock); |
@@ -449,6 +467,12 @@ int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info) | |||
449 | goto error; | 467 | goto error; |
450 | } | 468 | } |
451 | 469 | ||
470 | if (info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) { | ||
471 | rc = phy_set_cca_ed_level(phy, info); | ||
472 | if (rc < 0) | ||
473 | goto error; | ||
474 | } | ||
475 | |||
452 | mutex_unlock(&phy->pib_lock); | 476 | mutex_unlock(&phy->pib_lock); |
453 | 477 | ||
454 | wpan_phy_put(phy); | 478 | wpan_phy_put(phy); |
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c index d87c2c904110..55b5616295ff 100644 --- a/net/ieee802154/nl_policy.c +++ b/net/ieee802154/nl_policy.c | |||
@@ -56,5 +56,6 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = { | |||
56 | [IEEE802154_ATTR_TXPOWER] = { .type = NLA_S8, }, | 56 | [IEEE802154_ATTR_TXPOWER] = { .type = NLA_S8, }, |
57 | [IEEE802154_ATTR_LBT_ENABLED] = { .type = NLA_U8, }, | 57 | [IEEE802154_ATTR_LBT_ENABLED] = { .type = NLA_U8, }, |
58 | [IEEE802154_ATTR_CCA_MODE] = { .type = NLA_U8, }, | 58 | [IEEE802154_ATTR_CCA_MODE] = { .type = NLA_U8, }, |
59 | [IEEE802154_ATTR_CCA_ED_LEVEL] = { .type = NLA_S32, }, | ||
59 | }; | 60 | }; |
60 | 61 | ||
diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c index 4965e4ce6b5b..4707f36546d3 100644 --- a/net/mac802154/ieee802154_dev.c +++ b/net/mac802154/ieee802154_dev.c | |||
@@ -195,6 +195,16 @@ static int mac802154_set_cca_mode(struct wpan_phy *phy, u8 mode) | |||
195 | return priv->ops->set_cca_mode(&priv->hw, mode); | 195 | return priv->ops->set_cca_mode(&priv->hw, mode); |
196 | } | 196 | } |
197 | 197 | ||
198 | static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level) | ||
199 | { | ||
200 | struct mac802154_priv *priv = wpan_phy_priv(phy); | ||
201 | |||
202 | if (!priv->ops->set_cca_ed_level) | ||
203 | return -ENOTSUPP; | ||
204 | |||
205 | return priv->ops->set_cca_ed_level(&priv->hw, level); | ||
206 | } | ||
207 | |||
198 | struct ieee802154_dev * | 208 | struct ieee802154_dev * |
199 | ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) | 209 | ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) |
200 | { | 210 | { |
@@ -275,6 +285,7 @@ int ieee802154_register_device(struct ieee802154_dev *dev) | |||
275 | priv->phy->set_txpower = mac802154_set_txpower; | 285 | priv->phy->set_txpower = mac802154_set_txpower; |
276 | priv->phy->set_lbt = mac802154_set_lbt; | 286 | priv->phy->set_lbt = mac802154_set_lbt; |
277 | priv->phy->set_cca_mode = mac802154_set_cca_mode; | 287 | priv->phy->set_cca_mode = mac802154_set_cca_mode; |
288 | priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level; | ||
278 | 289 | ||
279 | rc = wpan_phy_register(priv->phy); | 290 | rc = wpan_phy_register(priv->phy); |
280 | if (rc < 0) | 291 | if (rc < 0) |