diff options
author | David S. Miller <davem@davemloft.net> | 2009-08-23 22:19:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-08-23 22:19:30 -0400 |
commit | 940917226260d6e029f55742a34a7d7810983c75 (patch) | |
tree | 871af506fa09aa2717c6c27307838f43993dabaf /drivers | |
parent | 9818f660f433b58e770cfeb2ee9566f7b42ca0ae (diff) | |
parent | 929122cdd5d4c344e59f9b55f870a8fcf7aa0d27 (diff) |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ieee802154/fakehard.c | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c index 262536fae905..c1c9697f9fde 100644 --- a/drivers/ieee802154/fakehard.c +++ b/drivers/ieee802154/fakehard.c | |||
@@ -30,6 +30,12 @@ | |||
30 | #include <net/ieee802154_netdev.h> | 30 | #include <net/ieee802154_netdev.h> |
31 | #include <net/ieee802154.h> | 31 | #include <net/ieee802154.h> |
32 | #include <net/nl802154.h> | 32 | #include <net/nl802154.h> |
33 | #include <net/wpan-phy.h> | ||
34 | |||
35 | struct wpan_phy *net_to_phy(struct net_device *dev) | ||
36 | { | ||
37 | return container_of(dev->dev.parent, struct wpan_phy, dev); | ||
38 | } | ||
33 | 39 | ||
34 | /** | 40 | /** |
35 | * fake_get_pan_id - Retrieve the PAN ID of the device. | 41 | * fake_get_pan_id - Retrieve the PAN ID of the device. |
@@ -113,8 +119,15 @@ static u8 fake_get_bsn(struct net_device *dev) | |||
113 | * 802.15.4-2006 document. | 119 | * 802.15.4-2006 document. |
114 | */ | 120 | */ |
115 | static int fake_assoc_req(struct net_device *dev, | 121 | static int fake_assoc_req(struct net_device *dev, |
116 | struct ieee802154_addr *addr, u8 channel, u8 cap) | 122 | struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap) |
117 | { | 123 | { |
124 | struct wpan_phy *phy = net_to_phy(dev); | ||
125 | |||
126 | mutex_lock(&phy->pib_lock); | ||
127 | phy->current_channel = channel; | ||
128 | phy->current_page = page; | ||
129 | mutex_unlock(&phy->pib_lock); | ||
130 | |||
118 | /* We simply emulate it here */ | 131 | /* We simply emulate it here */ |
119 | return ieee802154_nl_assoc_confirm(dev, fake_get_short_addr(dev), | 132 | return ieee802154_nl_assoc_confirm(dev, fake_get_short_addr(dev), |
120 | IEEE802154_SUCCESS); | 133 | IEEE802154_SUCCESS); |
@@ -179,10 +192,17 @@ static int fake_disassoc_req(struct net_device *dev, | |||
179 | * document, with 7.3.8 describing coordinator realignment. | 192 | * document, with 7.3.8 describing coordinator realignment. |
180 | */ | 193 | */ |
181 | static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, | 194 | static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, |
182 | u8 channel, | 195 | u8 channel, u8 page, |
183 | u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, | 196 | u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, |
184 | u8 coord_realign) | 197 | u8 coord_realign) |
185 | { | 198 | { |
199 | struct wpan_phy *phy = net_to_phy(dev); | ||
200 | |||
201 | mutex_lock(&phy->pib_lock); | ||
202 | phy->current_channel = channel; | ||
203 | phy->current_page = page; | ||
204 | mutex_unlock(&phy->pib_lock); | ||
205 | |||
186 | /* We don't emulate beacons here at all, so START should fail */ | 206 | /* We don't emulate beacons here at all, so START should fail */ |
187 | ieee802154_nl_start_confirm(dev, IEEE802154_INVALID_PARAMETER); | 207 | ieee802154_nl_start_confirm(dev, IEEE802154_INVALID_PARAMETER); |
188 | return 0; | 208 | return 0; |
@@ -204,11 +224,11 @@ static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, | |||
204 | * Note: This is in section 7.5.2.1 of the IEEE 802.15.4-2006 document. | 224 | * Note: This is in section 7.5.2.1 of the IEEE 802.15.4-2006 document. |
205 | */ | 225 | */ |
206 | static int fake_scan_req(struct net_device *dev, u8 type, u32 channels, | 226 | static int fake_scan_req(struct net_device *dev, u8 type, u32 channels, |
207 | u8 duration) | 227 | u8 page, u8 duration) |
208 | { | 228 | { |
209 | u8 edl[27] = {}; | 229 | u8 edl[27] = {}; |
210 | return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type, | 230 | return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type, |
211 | channels, | 231 | channels, page, |
212 | type == IEEE802154_MAC_SCAN_ED ? edl : NULL); | 232 | type == IEEE802154_MAC_SCAN_ED ? edl : NULL); |
213 | } | 233 | } |
214 | 234 | ||
@@ -290,6 +310,14 @@ static const struct net_device_ops fake_ops = { | |||
290 | .ndo_set_mac_address = ieee802154_fake_mac_addr, | 310 | .ndo_set_mac_address = ieee802154_fake_mac_addr, |
291 | }; | 311 | }; |
292 | 312 | ||
313 | static void ieee802154_fake_destruct(struct net_device *dev) | ||
314 | { | ||
315 | struct wpan_phy *phy = net_to_phy(dev); | ||
316 | |||
317 | wpan_phy_unregister(phy); | ||
318 | free_netdev(dev); | ||
319 | wpan_phy_free(phy); | ||
320 | } | ||
293 | 321 | ||
294 | static void ieee802154_fake_setup(struct net_device *dev) | 322 | static void ieee802154_fake_setup(struct net_device *dev) |
295 | { | 323 | { |
@@ -302,22 +330,34 @@ static void ieee802154_fake_setup(struct net_device *dev) | |||
302 | dev->type = ARPHRD_IEEE802154; | 330 | dev->type = ARPHRD_IEEE802154; |
303 | dev->flags = IFF_NOARP | IFF_BROADCAST; | 331 | dev->flags = IFF_NOARP | IFF_BROADCAST; |
304 | dev->watchdog_timeo = 0; | 332 | dev->watchdog_timeo = 0; |
333 | dev->destructor = ieee802154_fake_destruct; | ||
305 | } | 334 | } |
306 | 335 | ||
307 | 336 | ||
308 | static int __devinit ieee802154fake_probe(struct platform_device *pdev) | 337 | static int __devinit ieee802154fake_probe(struct platform_device *pdev) |
309 | { | 338 | { |
310 | struct net_device *dev = | 339 | struct net_device *dev; |
311 | alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup); | 340 | struct wpan_phy *phy = wpan_phy_alloc(0); |
312 | int err; | 341 | int err; |
313 | 342 | ||
314 | if (!dev) | 343 | if (!phy) |
344 | return -ENOMEM; | ||
345 | |||
346 | dev = alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup); | ||
347 | if (!dev) { | ||
348 | wpan_phy_free(phy); | ||
315 | return -ENOMEM; | 349 | return -ENOMEM; |
350 | } | ||
351 | |||
352 | phy->dev.platform_data = dev; | ||
316 | 353 | ||
317 | memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef", | 354 | memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef", |
318 | dev->addr_len); | 355 | dev->addr_len); |
319 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | 356 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); |
320 | 357 | ||
358 | phy->channels_supported = (1 << 27) - 1; | ||
359 | phy->transmit_power = 0xbf; | ||
360 | |||
321 | dev->netdev_ops = &fake_ops; | 361 | dev->netdev_ops = &fake_ops; |
322 | dev->ml_priv = &fake_mlme; | 362 | dev->ml_priv = &fake_mlme; |
323 | 363 | ||
@@ -331,15 +371,18 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev) | |||
331 | goto out; | 371 | goto out; |
332 | } | 372 | } |
333 | 373 | ||
334 | SET_NETDEV_DEV(dev, &pdev->dev); | 374 | SET_NETDEV_DEV(dev, &phy->dev); |
335 | 375 | ||
336 | platform_set_drvdata(pdev, dev); | 376 | platform_set_drvdata(pdev, dev); |
337 | 377 | ||
378 | err = wpan_phy_register(&pdev->dev, phy); | ||
379 | if (err) | ||
380 | goto out; | ||
381 | |||
338 | err = register_netdev(dev); | 382 | err = register_netdev(dev); |
339 | if (err < 0) | 383 | if (err < 0) |
340 | goto out; | 384 | goto out; |
341 | 385 | ||
342 | |||
343 | dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n"); | 386 | dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n"); |
344 | return 0; | 387 | return 0; |
345 | 388 | ||
@@ -352,7 +395,6 @@ static int __devexit ieee802154fake_remove(struct platform_device *pdev) | |||
352 | { | 395 | { |
353 | struct net_device *dev = platform_get_drvdata(pdev); | 396 | struct net_device *dev = platform_get_drvdata(pdev); |
354 | unregister_netdev(dev); | 397 | unregister_netdev(dev); |
355 | free_netdev(dev); | ||
356 | return 0; | 398 | return 0; |
357 | } | 399 | } |
358 | 400 | ||