diff options
Diffstat (limited to 'net/caif/chnl_net.c')
-rw-r--r-- | net/caif/chnl_net.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index 6008d6dc18a0..649ebacaf6bc 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/caif/if_caif.h> | 20 | #include <linux/caif/if_caif.h> |
21 | #include <net/rtnetlink.h> | 21 | #include <net/rtnetlink.h> |
22 | #include <net/caif/caif_layer.h> | 22 | #include <net/caif/caif_layer.h> |
23 | #include <net/caif/cfcnfg.h> | ||
24 | #include <net/caif/cfpkt.h> | 23 | #include <net/caif/cfpkt.h> |
25 | #include <net/caif/caif_dev.h> | 24 | #include <net/caif/caif_dev.h> |
26 | 25 | ||
@@ -84,10 +83,11 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt) | |||
84 | if (!priv) | 83 | if (!priv) |
85 | return -EINVAL; | 84 | return -EINVAL; |
86 | 85 | ||
86 | skb = (struct sk_buff *) cfpkt_tonative(pkt); | ||
87 | |||
87 | /* Get length of CAIF packet. */ | 88 | /* Get length of CAIF packet. */ |
88 | pktlen = cfpkt_getlen(pkt); | 89 | pktlen = skb->len; |
89 | 90 | ||
90 | skb = (struct sk_buff *) cfpkt_tonative(pkt); | ||
91 | /* Pass some minimum information and | 91 | /* Pass some minimum information and |
92 | * send the packet to the net stack. | 92 | * send the packet to the net stack. |
93 | */ | 93 | */ |
@@ -153,6 +153,18 @@ static void close_work(struct work_struct *work) | |||
153 | } | 153 | } |
154 | static DECLARE_WORK(close_worker, close_work); | 154 | static DECLARE_WORK(close_worker, close_work); |
155 | 155 | ||
156 | static void chnl_hold(struct cflayer *lyr) | ||
157 | { | ||
158 | struct chnl_net *priv = container_of(lyr, struct chnl_net, chnl); | ||
159 | dev_hold(priv->netdev); | ||
160 | } | ||
161 | |||
162 | static void chnl_put(struct cflayer *lyr) | ||
163 | { | ||
164 | struct chnl_net *priv = container_of(lyr, struct chnl_net, chnl); | ||
165 | dev_put(priv->netdev); | ||
166 | } | ||
167 | |||
156 | static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow, | 168 | static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow, |
157 | int phyid) | 169 | int phyid) |
158 | { | 170 | { |
@@ -190,6 +202,7 @@ static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow, | |||
190 | netif_wake_queue(priv->netdev); | 202 | netif_wake_queue(priv->netdev); |
191 | break; | 203 | break; |
192 | case CAIF_CTRLCMD_INIT_RSP: | 204 | case CAIF_CTRLCMD_INIT_RSP: |
205 | caif_client_register_refcnt(&priv->chnl, chnl_hold, chnl_put); | ||
193 | priv->state = CAIF_CONNECTED; | 206 | priv->state = CAIF_CONNECTED; |
194 | priv->flowenabled = true; | 207 | priv->flowenabled = true; |
195 | netif_wake_queue(priv->netdev); | 208 | netif_wake_queue(priv->netdev); |
@@ -257,8 +270,9 @@ static int chnl_net_open(struct net_device *dev) | |||
257 | 270 | ||
258 | if (priv->state != CAIF_CONNECTING) { | 271 | if (priv->state != CAIF_CONNECTING) { |
259 | priv->state = CAIF_CONNECTING; | 272 | priv->state = CAIF_CONNECTING; |
260 | result = caif_connect_client(&priv->conn_req, &priv->chnl, | 273 | result = caif_connect_client(dev_net(dev), &priv->conn_req, |
261 | &llifindex, &headroom, &tailroom); | 274 | &priv->chnl, &llifindex, |
275 | &headroom, &tailroom); | ||
262 | if (result != 0) { | 276 | if (result != 0) { |
263 | pr_debug("err: " | 277 | pr_debug("err: " |
264 | "Unable to register and open device," | 278 | "Unable to register and open device," |
@@ -314,7 +328,7 @@ static int chnl_net_open(struct net_device *dev) | |||
314 | 328 | ||
315 | if (result == 0) { | 329 | if (result == 0) { |
316 | pr_debug("connect timeout\n"); | 330 | pr_debug("connect timeout\n"); |
317 | caif_disconnect_client(&priv->chnl); | 331 | caif_disconnect_client(dev_net(dev), &priv->chnl); |
318 | priv->state = CAIF_DISCONNECTED; | 332 | priv->state = CAIF_DISCONNECTED; |
319 | pr_debug("state disconnected\n"); | 333 | pr_debug("state disconnected\n"); |
320 | result = -ETIMEDOUT; | 334 | result = -ETIMEDOUT; |
@@ -330,7 +344,7 @@ static int chnl_net_open(struct net_device *dev) | |||
330 | return 0; | 344 | return 0; |
331 | 345 | ||
332 | error: | 346 | error: |
333 | caif_disconnect_client(&priv->chnl); | 347 | caif_disconnect_client(dev_net(dev), &priv->chnl); |
334 | priv->state = CAIF_DISCONNECTED; | 348 | priv->state = CAIF_DISCONNECTED; |
335 | pr_debug("state disconnected\n"); | 349 | pr_debug("state disconnected\n"); |
336 | return result; | 350 | return result; |
@@ -344,7 +358,7 @@ static int chnl_net_stop(struct net_device *dev) | |||
344 | ASSERT_RTNL(); | 358 | ASSERT_RTNL(); |
345 | priv = netdev_priv(dev); | 359 | priv = netdev_priv(dev); |
346 | priv->state = CAIF_DISCONNECTED; | 360 | priv->state = CAIF_DISCONNECTED; |
347 | caif_disconnect_client(&priv->chnl); | 361 | caif_disconnect_client(dev_net(dev), &priv->chnl); |
348 | return 0; | 362 | return 0; |
349 | } | 363 | } |
350 | 364 | ||
@@ -373,11 +387,18 @@ static const struct net_device_ops netdev_ops = { | |||
373 | .ndo_start_xmit = chnl_net_start_xmit, | 387 | .ndo_start_xmit = chnl_net_start_xmit, |
374 | }; | 388 | }; |
375 | 389 | ||
390 | static void chnl_net_destructor(struct net_device *dev) | ||
391 | { | ||
392 | struct chnl_net *priv = netdev_priv(dev); | ||
393 | caif_free_client(&priv->chnl); | ||
394 | free_netdev(dev); | ||
395 | } | ||
396 | |||
376 | static void ipcaif_net_setup(struct net_device *dev) | 397 | static void ipcaif_net_setup(struct net_device *dev) |
377 | { | 398 | { |
378 | struct chnl_net *priv; | 399 | struct chnl_net *priv; |
379 | dev->netdev_ops = &netdev_ops; | 400 | dev->netdev_ops = &netdev_ops; |
380 | dev->destructor = free_netdev; | 401 | dev->destructor = chnl_net_destructor; |
381 | dev->flags |= IFF_NOARP; | 402 | dev->flags |= IFF_NOARP; |
382 | dev->flags |= IFF_POINTOPOINT; | 403 | dev->flags |= IFF_POINTOPOINT; |
383 | dev->mtu = GPRS_PDP_MTU; | 404 | dev->mtu = GPRS_PDP_MTU; |
@@ -391,7 +412,7 @@ static void ipcaif_net_setup(struct net_device *dev) | |||
391 | priv->conn_req.link_selector = CAIF_LINK_HIGH_BANDW; | 412 | priv->conn_req.link_selector = CAIF_LINK_HIGH_BANDW; |
392 | priv->conn_req.priority = CAIF_PRIO_LOW; | 413 | priv->conn_req.priority = CAIF_PRIO_LOW; |
393 | /* Insert illegal value */ | 414 | /* Insert illegal value */ |
394 | priv->conn_req.sockaddr.u.dgm.connection_id = -1; | 415 | priv->conn_req.sockaddr.u.dgm.connection_id = 0; |
395 | priv->flowenabled = false; | 416 | priv->flowenabled = false; |
396 | 417 | ||
397 | init_waitqueue_head(&priv->netmgmt_wq); | 418 | init_waitqueue_head(&priv->netmgmt_wq); |
@@ -453,6 +474,10 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev, | |||
453 | pr_warn("device rtml registration failed\n"); | 474 | pr_warn("device rtml registration failed\n"); |
454 | else | 475 | else |
455 | list_add(&caifdev->list_field, &chnl_net_list); | 476 | list_add(&caifdev->list_field, &chnl_net_list); |
477 | |||
478 | /* Take ifindex as connection-id if null */ | ||
479 | if (caifdev->conn_req.sockaddr.u.dgm.connection_id == 0) | ||
480 | caifdev->conn_req.sockaddr.u.dgm.connection_id = dev->ifindex; | ||
456 | return ret; | 481 | return ret; |
457 | } | 482 | } |
458 | 483 | ||