diff options
Diffstat (limited to 'drivers/ieee802154')
-rw-r--r-- | drivers/ieee802154/fakehard.c | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c index 7c544f7c74c4..5f67540e669c 100644 --- a/drivers/ieee802154/fakehard.c +++ b/drivers/ieee802154/fakehard.c | |||
@@ -32,9 +32,29 @@ | |||
32 | #include <net/nl802154.h> | 32 | #include <net/nl802154.h> |
33 | #include <net/wpan-phy.h> | 33 | #include <net/wpan-phy.h> |
34 | 34 | ||
35 | struct wpan_phy *net_to_phy(struct net_device *dev) | 35 | struct fakehard_priv { |
36 | struct wpan_phy *phy; | ||
37 | }; | ||
38 | |||
39 | static struct wpan_phy *fake_to_phy(const struct net_device *dev) | ||
40 | { | ||
41 | struct fakehard_priv *priv = netdev_priv(dev); | ||
42 | return priv->phy; | ||
43 | } | ||
44 | |||
45 | /** | ||
46 | * fake_get_phy - Return a phy corresponding to this device. | ||
47 | * @dev: The network device for which to return the wan-phy object | ||
48 | * | ||
49 | * This function returns a wpan-phy object corresponding to the passed | ||
50 | * network device. Reference counter for wpan-phy object is incremented, | ||
51 | * so when the wpan-phy isn't necessary, you should drop the reference | ||
52 | * via @wpan_phy_put() call. | ||
53 | */ | ||
54 | static struct wpan_phy *fake_get_phy(const struct net_device *dev) | ||
36 | { | 55 | { |
37 | return container_of(dev->dev.parent, struct wpan_phy, dev); | 56 | struct wpan_phy *phy = fake_to_phy(dev); |
57 | return to_phy(get_device(&phy->dev)); | ||
38 | } | 58 | } |
39 | 59 | ||
40 | /** | 60 | /** |
@@ -43,7 +63,7 @@ struct wpan_phy *net_to_phy(struct net_device *dev) | |||
43 | * | 63 | * |
44 | * Return the ID of the PAN from the PIB. | 64 | * Return the ID of the PAN from the PIB. |
45 | */ | 65 | */ |
46 | static u16 fake_get_pan_id(struct net_device *dev) | 66 | static u16 fake_get_pan_id(const struct net_device *dev) |
47 | { | 67 | { |
48 | BUG_ON(dev->type != ARPHRD_IEEE802154); | 68 | BUG_ON(dev->type != ARPHRD_IEEE802154); |
49 | 69 | ||
@@ -58,7 +78,7 @@ static u16 fake_get_pan_id(struct net_device *dev) | |||
58 | * device. If the device has not yet had a short address assigned | 78 | * device. If the device has not yet had a short address assigned |
59 | * then this should return 0xFFFF to indicate a lack of association. | 79 | * then this should return 0xFFFF to indicate a lack of association. |
60 | */ | 80 | */ |
61 | static u16 fake_get_short_addr(struct net_device *dev) | 81 | static u16 fake_get_short_addr(const struct net_device *dev) |
62 | { | 82 | { |
63 | BUG_ON(dev->type != ARPHRD_IEEE802154); | 83 | BUG_ON(dev->type != ARPHRD_IEEE802154); |
64 | 84 | ||
@@ -78,7 +98,7 @@ static u16 fake_get_short_addr(struct net_device *dev) | |||
78 | * Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006 | 98 | * Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006 |
79 | * document. | 99 | * document. |
80 | */ | 100 | */ |
81 | static u8 fake_get_dsn(struct net_device *dev) | 101 | static u8 fake_get_dsn(const struct net_device *dev) |
82 | { | 102 | { |
83 | BUG_ON(dev->type != ARPHRD_IEEE802154); | 103 | BUG_ON(dev->type != ARPHRD_IEEE802154); |
84 | 104 | ||
@@ -98,7 +118,7 @@ static u8 fake_get_dsn(struct net_device *dev) | |||
98 | * Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006 | 118 | * Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006 |
99 | * document. | 119 | * document. |
100 | */ | 120 | */ |
101 | static u8 fake_get_bsn(struct net_device *dev) | 121 | static u8 fake_get_bsn(const struct net_device *dev) |
102 | { | 122 | { |
103 | BUG_ON(dev->type != ARPHRD_IEEE802154); | 123 | BUG_ON(dev->type != ARPHRD_IEEE802154); |
104 | 124 | ||
@@ -121,7 +141,7 @@ static u8 fake_get_bsn(struct net_device *dev) | |||
121 | static int fake_assoc_req(struct net_device *dev, | 141 | static int fake_assoc_req(struct net_device *dev, |
122 | struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap) | 142 | struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap) |
123 | { | 143 | { |
124 | struct wpan_phy *phy = net_to_phy(dev); | 144 | struct wpan_phy *phy = fake_to_phy(dev); |
125 | 145 | ||
126 | mutex_lock(&phy->pib_lock); | 146 | mutex_lock(&phy->pib_lock); |
127 | phy->current_channel = channel; | 147 | phy->current_channel = channel; |
@@ -196,7 +216,7 @@ static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, | |||
196 | u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, | 216 | u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, |
197 | u8 coord_realign) | 217 | u8 coord_realign) |
198 | { | 218 | { |
199 | struct wpan_phy *phy = net_to_phy(dev); | 219 | struct wpan_phy *phy = fake_to_phy(dev); |
200 | 220 | ||
201 | mutex_lock(&phy->pib_lock); | 221 | mutex_lock(&phy->pib_lock); |
202 | phy->current_channel = channel; | 222 | phy->current_channel = channel; |
@@ -239,6 +259,8 @@ static struct ieee802154_mlme_ops fake_mlme = { | |||
239 | .start_req = fake_start_req, | 259 | .start_req = fake_start_req, |
240 | .scan_req = fake_scan_req, | 260 | .scan_req = fake_scan_req, |
241 | 261 | ||
262 | .get_phy = fake_get_phy, | ||
263 | |||
242 | .get_pan_id = fake_get_pan_id, | 264 | .get_pan_id = fake_get_pan_id, |
243 | .get_short_addr = fake_get_short_addr, | 265 | .get_short_addr = fake_get_short_addr, |
244 | .get_dsn = fake_get_dsn, | 266 | .get_dsn = fake_get_dsn, |
@@ -260,6 +282,9 @@ static int ieee802154_fake_close(struct net_device *dev) | |||
260 | static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb, | 282 | static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb, |
261 | struct net_device *dev) | 283 | struct net_device *dev) |
262 | { | 284 | { |
285 | skb->skb_iif = dev->ifindex; | ||
286 | skb->dev = dev; | ||
287 | |||
263 | dev->stats.tx_packets++; | 288 | dev->stats.tx_packets++; |
264 | dev->stats.tx_bytes += skb->len; | 289 | dev->stats.tx_bytes += skb->len; |
265 | 290 | ||
@@ -310,7 +335,7 @@ static const struct net_device_ops fake_ops = { | |||
310 | 335 | ||
311 | static void ieee802154_fake_destruct(struct net_device *dev) | 336 | static void ieee802154_fake_destruct(struct net_device *dev) |
312 | { | 337 | { |
313 | struct wpan_phy *phy = net_to_phy(dev); | 338 | struct wpan_phy *phy = fake_to_phy(dev); |
314 | 339 | ||
315 | wpan_phy_unregister(phy); | 340 | wpan_phy_unregister(phy); |
316 | free_netdev(dev); | 341 | free_netdev(dev); |
@@ -335,13 +360,14 @@ static void ieee802154_fake_setup(struct net_device *dev) | |||
335 | static int __devinit ieee802154fake_probe(struct platform_device *pdev) | 360 | static int __devinit ieee802154fake_probe(struct platform_device *pdev) |
336 | { | 361 | { |
337 | struct net_device *dev; | 362 | struct net_device *dev; |
363 | struct fakehard_priv *priv; | ||
338 | struct wpan_phy *phy = wpan_phy_alloc(0); | 364 | struct wpan_phy *phy = wpan_phy_alloc(0); |
339 | int err; | 365 | int err; |
340 | 366 | ||
341 | if (!phy) | 367 | if (!phy) |
342 | return -ENOMEM; | 368 | return -ENOMEM; |
343 | 369 | ||
344 | dev = alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup); | 370 | dev = alloc_netdev(sizeof(struct fakehard_priv), "hardwpan%d", ieee802154_fake_setup); |
345 | if (!dev) { | 371 | if (!dev) { |
346 | wpan_phy_free(phy); | 372 | wpan_phy_free(phy); |
347 | return -ENOMEM; | 373 | return -ENOMEM; |
@@ -353,12 +379,23 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev) | |||
353 | dev->addr_len); | 379 | dev->addr_len); |
354 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | 380 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); |
355 | 381 | ||
356 | phy->channels_supported = (1 << 27) - 1; | 382 | /* |
383 | * For now we'd like to emulate 2.4 GHz-only device, | ||
384 | * both O-QPSK and CSS | ||
385 | */ | ||
386 | /* 2.4 GHz O-QPSK 802.15.4-2003 */ | ||
387 | phy->channels_supported[0] |= 0x7FFF800; | ||
388 | /* 2.4 GHz CSS 802.15.4a-2007 */ | ||
389 | phy->channels_supported[3] |= 0x3fff; | ||
390 | |||
357 | phy->transmit_power = 0xbf; | 391 | phy->transmit_power = 0xbf; |
358 | 392 | ||
359 | dev->netdev_ops = &fake_ops; | 393 | dev->netdev_ops = &fake_ops; |
360 | dev->ml_priv = &fake_mlme; | 394 | dev->ml_priv = &fake_mlme; |
361 | 395 | ||
396 | priv = netdev_priv(dev); | ||
397 | priv->phy = phy; | ||
398 | |||
362 | /* | 399 | /* |
363 | * If the name is a format string the caller wants us to do a | 400 | * If the name is a format string the caller wants us to do a |
364 | * name allocation. | 401 | * name allocation. |
@@ -369,11 +406,12 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev) | |||
369 | goto out; | 406 | goto out; |
370 | } | 407 | } |
371 | 408 | ||
409 | wpan_phy_set_dev(phy, &pdev->dev); | ||
372 | SET_NETDEV_DEV(dev, &phy->dev); | 410 | SET_NETDEV_DEV(dev, &phy->dev); |
373 | 411 | ||
374 | platform_set_drvdata(pdev, dev); | 412 | platform_set_drvdata(pdev, dev); |
375 | 413 | ||
376 | err = wpan_phy_register(&pdev->dev, phy); | 414 | err = wpan_phy_register(phy); |
377 | if (err) | 415 | if (err) |
378 | goto out; | 416 | goto out; |
379 | 417 | ||