aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee802154/6lowpan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee802154/6lowpan.c')
-rw-r--r--net/ieee802154/6lowpan.c40
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
1062static 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
1068static 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
1074static 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
1062static struct header_ops lowpan_header_ops = { 1080static 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
1089static 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
1071static void lowpan_setup(struct net_device *dev) 1095static 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) {