diff options
Diffstat (limited to 'net/ieee802154/6lowpan.c')
-rw-r--r-- | net/ieee802154/6lowpan.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 4b5701c8bf97..32eb4179e8fa 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
@@ -1059,6 +1059,24 @@ static void lowpan_dev_free(struct net_device *dev) | |||
1059 | free_netdev(dev); | 1059 | free_netdev(dev); |
1060 | } | 1060 | } |
1061 | 1061 | ||
1062 | static struct wpan_phy *lowpan_get_phy(const struct net_device *dev) | ||
1063 | { | ||
1064 | struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; | ||
1065 | return ieee802154_mlme_ops(real_dev)->get_phy(real_dev); | ||
1066 | } | ||
1067 | |||
1068 | static u16 lowpan_get_pan_id(const struct net_device *dev) | ||
1069 | { | ||
1070 | struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; | ||
1071 | return ieee802154_mlme_ops(real_dev)->get_pan_id(real_dev); | ||
1072 | } | ||
1073 | |||
1074 | static u16 lowpan_get_short_addr(const struct net_device *dev) | ||
1075 | { | ||
1076 | struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; | ||
1077 | return ieee802154_mlme_ops(real_dev)->get_short_addr(real_dev); | ||
1078 | } | ||
1079 | |||
1062 | static struct header_ops lowpan_header_ops = { | 1080 | static struct header_ops lowpan_header_ops = { |
1063 | .create = lowpan_header_create, | 1081 | .create = lowpan_header_create, |
1064 | }; | 1082 | }; |
@@ -1068,6 +1086,12 @@ static const struct net_device_ops lowpan_netdev_ops = { | |||
1068 | .ndo_set_mac_address = eth_mac_addr, | 1086 | .ndo_set_mac_address = eth_mac_addr, |
1069 | }; | 1087 | }; |
1070 | 1088 | ||
1089 | static struct ieee802154_mlme_ops lowpan_mlme = { | ||
1090 | .get_pan_id = lowpan_get_pan_id, | ||
1091 | .get_phy = lowpan_get_phy, | ||
1092 | .get_short_addr = lowpan_get_short_addr, | ||
1093 | }; | ||
1094 | |||
1071 | static void lowpan_setup(struct net_device *dev) | 1095 | static void lowpan_setup(struct net_device *dev) |
1072 | { | 1096 | { |
1073 | pr_debug("(%s)\n", __func__); | 1097 | pr_debug("(%s)\n", __func__); |
@@ -1085,6 +1109,7 @@ static void lowpan_setup(struct net_device *dev) | |||
1085 | 1109 | ||
1086 | dev->netdev_ops = &lowpan_netdev_ops; | 1110 | dev->netdev_ops = &lowpan_netdev_ops; |
1087 | dev->header_ops = &lowpan_header_ops; | 1111 | dev->header_ops = &lowpan_header_ops; |
1112 | dev->ml_priv = &lowpan_mlme; | ||
1088 | dev->destructor = lowpan_dev_free; | 1113 | dev->destructor = lowpan_dev_free; |
1089 | } | 1114 | } |
1090 | 1115 | ||
@@ -1158,6 +1183,8 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, | |||
1158 | list_add_tail(&entry->list, &lowpan_devices); | 1183 | list_add_tail(&entry->list, &lowpan_devices); |
1159 | mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); | 1184 | mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); |
1160 | 1185 | ||
1186 | spin_lock_init(&flist_lock); | ||
1187 | |||
1161 | register_netdevice(dev); | 1188 | register_netdevice(dev); |
1162 | 1189 | ||
1163 | return 0; | 1190 | return 0; |
@@ -1167,11 +1194,20 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head) | |||
1167 | { | 1194 | { |
1168 | struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev); | 1195 | struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev); |
1169 | struct net_device *real_dev = lowpan_dev->real_dev; | 1196 | struct net_device *real_dev = lowpan_dev->real_dev; |
1170 | struct lowpan_dev_record *entry; | 1197 | struct lowpan_dev_record *entry, *tmp; |
1171 | struct lowpan_dev_record *tmp; | 1198 | struct lowpan_fragment *frame, *tframe; |
1172 | 1199 | ||
1173 | ASSERT_RTNL(); | 1200 | ASSERT_RTNL(); |
1174 | 1201 | ||
1202 | spin_lock(&flist_lock); | ||
1203 | list_for_each_entry_safe(frame, tframe, &lowpan_fragments, list) { | ||
1204 | del_timer(&frame->timer); | ||
1205 | list_del(&frame->list); | ||
1206 | dev_kfree_skb(frame->skb); | ||
1207 | kfree(frame); | ||
1208 | } | ||
1209 | spin_unlock(&flist_lock); | ||
1210 | |||
1175 | mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); | 1211 | mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); |
1176 | list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { | 1212 | list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { |
1177 | if (entry->ldev == dev) { | 1213 | if (entry->ldev == dev) { |