aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/caif/caif_dev.h29
-rw-r--r--net/caif/caif_socket.c19
-rw-r--r--net/caif/chnl_net.c28
3 files changed, 72 insertions, 4 deletions
diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h
index 7e3f7a6d2ba3..6638435525fc 100644
--- a/include/net/caif/caif_dev.h
+++ b/include/net/caif/caif_dev.h
@@ -74,6 +74,23 @@ int caif_connect_client(struct caif_connect_request *conn_req,
74int caif_disconnect_client(struct cflayer *client_layer); 74int caif_disconnect_client(struct cflayer *client_layer);
75 75
76/** 76/**
77 * caif_client_register_refcnt - register ref-count functions provided by client.
78 *
79 * @adapt_layer: Client layer using CAIF Stack.
80 * @hold: Function provided by client layer increasing ref-count
81 * @put: Function provided by client layer decreasing ref-count
82 *
83 * Client of the CAIF Stack must register functions for reference counting.
84 * These functions are called by the CAIF Stack for every upstream packet,
85 * and must therefore be implemented efficiently.
86 *
87 * Client should call caif_free_client when reference count degrease to zero.
88 */
89
90void caif_client_register_refcnt(struct cflayer *adapt_layer,
91 void (*hold)(struct cflayer *lyr),
92 void (*put)(struct cflayer *lyr));
93/**
77 * caif_connect_req_to_link_param - Translate configuration parameters 94 * caif_connect_req_to_link_param - Translate configuration parameters
78 * from socket format to internal format. 95 * from socket format to internal format.
79 * @cnfg: Pointer to configuration handler 96 * @cnfg: Pointer to configuration handler
@@ -83,8 +100,20 @@ int caif_disconnect_client(struct cflayer *client_layer);
83 * setting up channels. 100 * setting up channels.
84 * 101 *
85 */ 102 */
103
86int caif_connect_req_to_link_param(struct cfcnfg *cnfg, 104int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
87 struct caif_connect_request *con_req, 105 struct caif_connect_request *con_req,
88 struct cfctrl_link_param *setup_param); 106 struct cfctrl_link_param *setup_param);
89 107
108/**
109 * caif_free_client - Free memory used to manage the client in the CAIF Stack.
110 *
111 * @client_layer: Client layer to be removed.
112 *
113 * This function must be called from client layer in order to free memory.
114 * Caller must guarantee that no packets are in flight upstream when calling
115 * this function.
116 */
117void caif_free_client(struct cflayer *adap_layer);
118
90#endif /* CAIF_DEV_H_ */ 119#endif /* CAIF_DEV_H_ */
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 20212424e2e8..01f612df7df1 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -209,6 +209,18 @@ static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt)
209 return 0; 209 return 0;
210} 210}
211 211
212static void cfsk_hold(struct cflayer *layr)
213{
214 struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
215 sock_hold(&cf_sk->sk);
216}
217
218static void cfsk_put(struct cflayer *layr)
219{
220 struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
221 sock_put(&cf_sk->sk);
222}
223
212/* Packet Control Callback function called from CAIF */ 224/* Packet Control Callback function called from CAIF */
213static void caif_ctrl_cb(struct cflayer *layr, 225static void caif_ctrl_cb(struct cflayer *layr,
214 enum caif_ctrlcmd flow, 226 enum caif_ctrlcmd flow,
@@ -232,6 +244,8 @@ static void caif_ctrl_cb(struct cflayer *layr,
232 244
233 case CAIF_CTRLCMD_INIT_RSP: 245 case CAIF_CTRLCMD_INIT_RSP:
234 /* We're now connected */ 246 /* We're now connected */
247 caif_client_register_refcnt(&cf_sk->layer,
248 cfsk_hold, cfsk_put);
235 dbfs_atomic_inc(&cnt.num_connect_resp); 249 dbfs_atomic_inc(&cnt.num_connect_resp);
236 cf_sk->sk.sk_state = CAIF_CONNECTED; 250 cf_sk->sk.sk_state = CAIF_CONNECTED;
237 set_tx_flow_on(cf_sk); 251 set_tx_flow_on(cf_sk);
@@ -242,7 +256,6 @@ static void caif_ctrl_cb(struct cflayer *layr,
242 /* We're now disconnected */ 256 /* We're now disconnected */
243 cf_sk->sk.sk_state = CAIF_DISCONNECTED; 257 cf_sk->sk.sk_state = CAIF_DISCONNECTED;
244 cf_sk->sk.sk_state_change(&cf_sk->sk); 258 cf_sk->sk.sk_state_change(&cf_sk->sk);
245 cfcnfg_release_adap_layer(&cf_sk->layer);
246 break; 259 break;
247 260
248 case CAIF_CTRLCMD_INIT_FAIL_RSP: 261 case CAIF_CTRLCMD_INIT_FAIL_RSP:
@@ -837,8 +850,10 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
837 850
838 dbfs_atomic_inc(&cnt.num_connect_req); 851 dbfs_atomic_inc(&cnt.num_connect_req);
839 cf_sk->layer.receive = caif_sktrecv_cb; 852 cf_sk->layer.receive = caif_sktrecv_cb;
853
840 err = caif_connect_client(&cf_sk->conn_req, 854 err = caif_connect_client(&cf_sk->conn_req,
841 &cf_sk->layer, &ifindex, &headroom, &tailroom); 855 &cf_sk->layer, &ifindex, &headroom, &tailroom);
856
842 if (err < 0) { 857 if (err < 0) {
843 cf_sk->sk.sk_socket->state = SS_UNCONNECTED; 858 cf_sk->sk.sk_socket->state = SS_UNCONNECTED;
844 cf_sk->sk.sk_state = CAIF_DISCONNECTED; 859 cf_sk->sk.sk_state = CAIF_DISCONNECTED;
@@ -940,7 +955,6 @@ static int caif_release(struct socket *sock)
940 wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP); 955 wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP);
941 956
942 sock_orphan(sk); 957 sock_orphan(sk);
943 cf_sk->layer.dn = NULL;
944 sk_stream_kill_queues(&cf_sk->sk); 958 sk_stream_kill_queues(&cf_sk->sk);
945 release_sock(sk); 959 release_sock(sk);
946 sock_put(sk); 960 sock_put(sk);
@@ -1036,6 +1050,7 @@ static void caif_sock_destructor(struct sock *sk)
1036 } 1050 }
1037 sk_stream_kill_queues(&cf_sk->sk); 1051 sk_stream_kill_queues(&cf_sk->sk);
1038 dbfs_atomic_dec(&cnt.caif_nr_socks); 1052 dbfs_atomic_dec(&cnt.caif_nr_socks);
1053 caif_free_client(&cf_sk->layer);
1039} 1054}
1040 1055
1041static int caif_create(struct net *net, struct socket *sock, int protocol, 1056static int caif_create(struct net *net, struct socket *sock, int protocol,
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
index 6008d6dc18a0..9ef8f1660ee1 100644
--- a/net/caif/chnl_net.c
+++ b/net/caif/chnl_net.c
@@ -153,6 +153,18 @@ static void close_work(struct work_struct *work)
153} 153}
154static DECLARE_WORK(close_worker, close_work); 154static DECLARE_WORK(close_worker, close_work);
155 155
156static 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
162static 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
156static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow, 168static 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);
@@ -373,11 +386,18 @@ static const struct net_device_ops netdev_ops = {
373 .ndo_start_xmit = chnl_net_start_xmit, 386 .ndo_start_xmit = chnl_net_start_xmit,
374}; 387};
375 388
389static void chnl_net_destructor(struct net_device *dev)
390{
391 struct chnl_net *priv = netdev_priv(dev);
392 caif_free_client(&priv->chnl);
393 free_netdev(dev);
394}
395
376static void ipcaif_net_setup(struct net_device *dev) 396static void ipcaif_net_setup(struct net_device *dev)
377{ 397{
378 struct chnl_net *priv; 398 struct chnl_net *priv;
379 dev->netdev_ops = &netdev_ops; 399 dev->netdev_ops = &netdev_ops;
380 dev->destructor = free_netdev; 400 dev->destructor = chnl_net_destructor;
381 dev->flags |= IFF_NOARP; 401 dev->flags |= IFF_NOARP;
382 dev->flags |= IFF_POINTOPOINT; 402 dev->flags |= IFF_POINTOPOINT;
383 dev->mtu = GPRS_PDP_MTU; 403 dev->mtu = GPRS_PDP_MTU;
@@ -391,7 +411,7 @@ static void ipcaif_net_setup(struct net_device *dev)
391 priv->conn_req.link_selector = CAIF_LINK_HIGH_BANDW; 411 priv->conn_req.link_selector = CAIF_LINK_HIGH_BANDW;
392 priv->conn_req.priority = CAIF_PRIO_LOW; 412 priv->conn_req.priority = CAIF_PRIO_LOW;
393 /* Insert illegal value */ 413 /* Insert illegal value */
394 priv->conn_req.sockaddr.u.dgm.connection_id = -1; 414 priv->conn_req.sockaddr.u.dgm.connection_id = 0;
395 priv->flowenabled = false; 415 priv->flowenabled = false;
396 416
397 init_waitqueue_head(&priv->netmgmt_wq); 417 init_waitqueue_head(&priv->netmgmt_wq);
@@ -453,6 +473,10 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev,
453 pr_warn("device rtml registration failed\n"); 473 pr_warn("device rtml registration failed\n");
454 else 474 else
455 list_add(&caifdev->list_field, &chnl_net_list); 475 list_add(&caifdev->list_field, &chnl_net_list);
476
477 /* Take ifindex as connection-id if null */
478 if (caifdev->conn_req.sockaddr.u.dgm.connection_id == 0)
479 caifdev->conn_req.sockaddr.u.dgm.connection_id = dev->ifindex;
456 return ret; 480 return ret;
457} 481}
458 482