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 368515885368..840821b90bcd 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
@@ -1044,6 +1044,24 @@ static void lowpan_dev_free(struct net_device *dev) | |||
1044 | free_netdev(dev); | 1044 | free_netdev(dev); |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | static struct wpan_phy *lowpan_get_phy(const struct net_device *dev) | ||
1048 | { | ||
1049 | struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; | ||
1050 | return ieee802154_mlme_ops(real_dev)->get_phy(real_dev); | ||
1051 | } | ||
1052 | |||
1053 | static u16 lowpan_get_pan_id(const struct net_device *dev) | ||
1054 | { | ||
1055 | struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; | ||
1056 | return ieee802154_mlme_ops(real_dev)->get_pan_id(real_dev); | ||
1057 | } | ||
1058 | |||
1059 | static u16 lowpan_get_short_addr(const struct net_device *dev) | ||
1060 | { | ||
1061 | struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; | ||
1062 | return ieee802154_mlme_ops(real_dev)->get_short_addr(real_dev); | ||
1063 | } | ||
1064 | |||
1047 | static struct header_ops lowpan_header_ops = { | 1065 | static struct header_ops lowpan_header_ops = { |
1048 | .create = lowpan_header_create, | 1066 | .create = lowpan_header_create, |
1049 | }; | 1067 | }; |
@@ -1053,6 +1071,12 @@ static const struct net_device_ops lowpan_netdev_ops = { | |||
1053 | .ndo_set_mac_address = eth_mac_addr, | 1071 | .ndo_set_mac_address = eth_mac_addr, |
1054 | }; | 1072 | }; |
1055 | 1073 | ||
1074 | static struct ieee802154_mlme_ops lowpan_mlme = { | ||
1075 | .get_pan_id = lowpan_get_pan_id, | ||
1076 | .get_phy = lowpan_get_phy, | ||
1077 | .get_short_addr = lowpan_get_short_addr, | ||
1078 | }; | ||
1079 | |||
1056 | static void lowpan_setup(struct net_device *dev) | 1080 | static void lowpan_setup(struct net_device *dev) |
1057 | { | 1081 | { |
1058 | pr_debug("(%s)\n", __func__); | 1082 | pr_debug("(%s)\n", __func__); |
@@ -1070,6 +1094,7 @@ static void lowpan_setup(struct net_device *dev) | |||
1070 | 1094 | ||
1071 | dev->netdev_ops = &lowpan_netdev_ops; | 1095 | dev->netdev_ops = &lowpan_netdev_ops; |
1072 | dev->header_ops = &lowpan_header_ops; | 1096 | dev->header_ops = &lowpan_header_ops; |
1097 | dev->ml_priv = &lowpan_mlme; | ||
1073 | dev->destructor = lowpan_dev_free; | 1098 | dev->destructor = lowpan_dev_free; |
1074 | } | 1099 | } |
1075 | 1100 | ||
@@ -1143,6 +1168,8 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, | |||
1143 | list_add_tail(&entry->list, &lowpan_devices); | 1168 | list_add_tail(&entry->list, &lowpan_devices); |
1144 | mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); | 1169 | mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); |
1145 | 1170 | ||
1171 | spin_lock_init(&flist_lock); | ||
1172 | |||
1146 | register_netdevice(dev); | 1173 | register_netdevice(dev); |
1147 | 1174 | ||
1148 | return 0; | 1175 | return 0; |
@@ -1152,11 +1179,20 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head) | |||
1152 | { | 1179 | { |
1153 | struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev); | 1180 | struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev); |
1154 | struct net_device *real_dev = lowpan_dev->real_dev; | 1181 | struct net_device *real_dev = lowpan_dev->real_dev; |
1155 | struct lowpan_dev_record *entry; | 1182 | struct lowpan_dev_record *entry, *tmp; |
1156 | struct lowpan_dev_record *tmp; | 1183 | struct lowpan_fragment *frame, *tframe; |
1157 | 1184 | ||
1158 | ASSERT_RTNL(); | 1185 | ASSERT_RTNL(); |
1159 | 1186 | ||
1187 | spin_lock(&flist_lock); | ||
1188 | list_for_each_entry_safe(frame, tframe, &lowpan_fragments, list) { | ||
1189 | del_timer(&frame->timer); | ||
1190 | list_del(&frame->list); | ||
1191 | dev_kfree_skb(frame->skb); | ||
1192 | kfree(frame); | ||
1193 | } | ||
1194 | spin_unlock(&flist_lock); | ||
1195 | |||
1160 | mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); | 1196 | mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); |
1161 | list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { | 1197 | list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { |
1162 | if (entry->ldev == dev) { | 1198 | if (entry->ldev == dev) { |