diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-10-26 04:37:08 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-10-26 12:24:04 -0400 |
commit | ed0a5dce0c29f30ee53a87793206156cf38ae70d (patch) | |
tree | bb2f9e7a5c1017679f7918cd665b2c825550f6c7 | |
parent | cdb66beaa0da7d326069b10bef090645d61d813f (diff) |
mac802154: tx: add support for xmit_async callback
This patch renames the existsing xmit callback to xmit_sync and
introduces an asynchronous xmit_async function. If ieee802154_ops
doesn't provide the xmit_async callback, then we have a fallback to
the xmit_sync callback.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Cc: Alan Ott <alan@signal11.us>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r-- | drivers/net/ieee802154/at86rf230.c | 2 | ||||
-rw-r--r-- | drivers/net/ieee802154/cc2520.c | 2 | ||||
-rw-r--r-- | drivers/net/ieee802154/fakelb.c | 2 | ||||
-rw-r--r-- | drivers/net/ieee802154/mrf24j40.c | 2 | ||||
-rw-r--r-- | include/net/mac802154.h | 17 | ||||
-rw-r--r-- | net/mac802154/main.c | 4 | ||||
-rw-r--r-- | net/mac802154/tx.c | 20 |
7 files changed, 35 insertions, 14 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index b0d68d7061c1..06a3e9013d60 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c | |||
@@ -1237,7 +1237,7 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) | |||
1237 | 1237 | ||
1238 | static struct ieee802154_ops at86rf230_ops = { | 1238 | static struct ieee802154_ops at86rf230_ops = { |
1239 | .owner = THIS_MODULE, | 1239 | .owner = THIS_MODULE, |
1240 | .xmit = at86rf230_xmit, | 1240 | .xmit_sync = at86rf230_xmit, |
1241 | .ed = at86rf230_ed, | 1241 | .ed = at86rf230_ed, |
1242 | .set_channel = at86rf230_channel, | 1242 | .set_channel = at86rf230_channel, |
1243 | .start = at86rf230_start, | 1243 | .start = at86rf230_start, |
diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index b827e04d481b..f6f07f4eb0ec 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c | |||
@@ -635,7 +635,7 @@ static struct ieee802154_ops cc2520_ops = { | |||
635 | .owner = THIS_MODULE, | 635 | .owner = THIS_MODULE, |
636 | .start = cc2520_start, | 636 | .start = cc2520_start, |
637 | .stop = cc2520_stop, | 637 | .stop = cc2520_stop, |
638 | .xmit = cc2520_tx, | 638 | .xmit_sync = cc2520_tx, |
639 | .ed = cc2520_ed, | 639 | .ed = cc2520_ed, |
640 | .set_channel = cc2520_set_channel, | 640 | .set_channel = cc2520_set_channel, |
641 | .set_hw_addr_filt = cc2520_filter, | 641 | .set_hw_addr_filt = cc2520_filter, |
diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 51e3c589d2e4..db0703f0fa41 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c | |||
@@ -131,7 +131,7 @@ fakelb_hw_stop(struct ieee802154_hw *hw) { | |||
131 | 131 | ||
132 | static struct ieee802154_ops fakelb_ops = { | 132 | static struct ieee802154_ops fakelb_ops = { |
133 | .owner = THIS_MODULE, | 133 | .owner = THIS_MODULE, |
134 | .xmit = fakelb_hw_xmit, | 134 | .xmit_sync = fakelb_hw_xmit, |
135 | .ed = fakelb_hw_ed, | 135 | .ed = fakelb_hw_ed, |
136 | .set_channel = fakelb_hw_channel, | 136 | .set_channel = fakelb_hw_channel, |
137 | .start = fakelb_hw_start, | 137 | .start = fakelb_hw_start, |
diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 2e267c5c44da..3d775afa217f 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c | |||
@@ -581,7 +581,7 @@ out: | |||
581 | 581 | ||
582 | static struct ieee802154_ops mrf24j40_ops = { | 582 | static struct ieee802154_ops mrf24j40_ops = { |
583 | .owner = THIS_MODULE, | 583 | .owner = THIS_MODULE, |
584 | .xmit = mrf24j40_tx, | 584 | .xmit_sync = mrf24j40_tx, |
585 | .ed = mrf24j40_ed, | 585 | .ed = mrf24j40_ed, |
586 | .start = mrf24j40_start, | 586 | .start = mrf24j40_start, |
587 | .stop = mrf24j40_stop, | 587 | .stop = mrf24j40_stop, |
diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 29af5c346ebf..57b120281afc 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h | |||
@@ -109,7 +109,16 @@ struct ieee802154_hw { | |||
109 | * stop: Handler that 802.15.4 module calls for device cleanup. | 109 | * stop: Handler that 802.15.4 module calls for device cleanup. |
110 | * This function is called after the last interface is removed. | 110 | * This function is called after the last interface is removed. |
111 | * | 111 | * |
112 | * xmit: Handler that 802.15.4 module calls for each transmitted frame. | 112 | * xmit_sync: |
113 | * Handler that 802.15.4 module calls for each transmitted frame. | ||
114 | * skb cntains the buffer starting from the IEEE 802.15.4 header. | ||
115 | * The low-level driver should send the frame based on available | ||
116 | * configuration. This is called by a workqueue and useful for | ||
117 | * synchronous 802.15.4 drivers. | ||
118 | * This function should return zero or negative errno. | ||
119 | * | ||
120 | * xmit_async: | ||
121 | * Handler that 802.15.4 module calls for each transmitted frame. | ||
113 | * skb cntains the buffer starting from the IEEE 802.15.4 header. | 122 | * skb cntains the buffer starting from the IEEE 802.15.4 header. |
114 | * The low-level driver should send the frame based on available | 123 | * The low-level driver should send the frame based on available |
115 | * configuration. | 124 | * configuration. |
@@ -160,8 +169,10 @@ struct ieee802154_ops { | |||
160 | struct module *owner; | 169 | struct module *owner; |
161 | int (*start)(struct ieee802154_hw *hw); | 170 | int (*start)(struct ieee802154_hw *hw); |
162 | void (*stop)(struct ieee802154_hw *hw); | 171 | void (*stop)(struct ieee802154_hw *hw); |
163 | int (*xmit)(struct ieee802154_hw *hw, | 172 | int (*xmit_sync)(struct ieee802154_hw *hw, |
164 | struct sk_buff *skb); | 173 | struct sk_buff *skb); |
174 | int (*xmit_async)(struct ieee802154_hw *hw, | ||
175 | struct sk_buff *skb); | ||
165 | int (*ed)(struct ieee802154_hw *hw, u8 *level); | 176 | int (*ed)(struct ieee802154_hw *hw, u8 *level); |
166 | int (*set_channel)(struct ieee802154_hw *hw, | 177 | int (*set_channel)(struct ieee802154_hw *hw, |
167 | int page, | 178 | int page, |
diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 0e9a6a203f7a..3c0a824d24ac 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c | |||
@@ -229,8 +229,8 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) | |||
229 | struct ieee802154_local *local; | 229 | struct ieee802154_local *local; |
230 | size_t priv_size; | 230 | size_t priv_size; |
231 | 231 | ||
232 | if (!ops || !ops->xmit || !ops->ed || !ops->start || | 232 | if (!ops || !(ops->xmit_async || ops->xmit_sync) || !ops->ed || |
233 | !ops->stop || !ops->set_channel) { | 233 | !ops->start || !ops->stop || !ops->set_channel) { |
234 | pr_err("undefined IEEE802.15.4 device operations\n"); | 234 | pr_err("undefined IEEE802.15.4 device operations\n"); |
235 | return NULL; | 235 | return NULL; |
236 | } | 236 | } |
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 23139cae0764..1a4f6d91ab8c 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c | |||
@@ -50,7 +50,7 @@ static void mac802154_xmit_worker(struct work_struct *work) | |||
50 | struct sk_buff *skb = cb->skb; | 50 | struct sk_buff *skb = cb->skb; |
51 | int res; | 51 | int res; |
52 | 52 | ||
53 | res = local->ops->xmit(&local->hw, skb); | 53 | res = local->ops->xmit_sync(&local->hw, skb); |
54 | if (res) { | 54 | if (res) { |
55 | pr_debug("transmission failed\n"); | 55 | pr_debug("transmission failed\n"); |
56 | /* Restart the netif queue on each sub_if_data object. */ | 56 | /* Restart the netif queue on each sub_if_data object. */ |
@@ -66,6 +66,7 @@ static netdev_tx_t | |||
66 | mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) | 66 | mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) |
67 | { | 67 | { |
68 | struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); | 68 | struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); |
69 | int ret; | ||
69 | 70 | ||
70 | mac802154_monitors_rx(local, skb); | 71 | mac802154_monitors_rx(local, skb); |
71 | 72 | ||
@@ -83,11 +84,20 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) | |||
83 | /* Stop the netif queue on each sub_if_data object. */ | 84 | /* Stop the netif queue on each sub_if_data object. */ |
84 | ieee802154_stop_queue(&local->hw); | 85 | ieee802154_stop_queue(&local->hw); |
85 | 86 | ||
86 | INIT_WORK(&cb->work, mac802154_xmit_worker); | 87 | /* async is priority, otherwise sync is fallback */ |
87 | cb->skb = skb; | 88 | if (local->ops->xmit_async) { |
88 | cb->local = local; | 89 | ret = local->ops->xmit_async(&local->hw, skb); |
90 | if (ret) { | ||
91 | ieee802154_wake_queue(&local->hw); | ||
92 | goto err_tx; | ||
93 | } | ||
94 | } else { | ||
95 | INIT_WORK(&cb->work, mac802154_xmit_worker); | ||
96 | cb->skb = skb; | ||
97 | cb->local = local; | ||
89 | 98 | ||
90 | queue_work(local->workqueue, &cb->work); | 99 | queue_work(local->workqueue, &cb->work); |
100 | } | ||
91 | 101 | ||
92 | return NETDEV_TX_OK; | 102 | return NETDEV_TX_OK; |
93 | 103 | ||