diff options
| author | Sjur Braendeland <sjur.brandeland@stericsson.com> | 2010-06-17 02:55:40 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-06-20 22:46:06 -0400 |
| commit | 2aa40aef9debc77d55cc87a50d335b6fe97fbeb0 (patch) | |
| tree | 0dccf47cf6cb861c7efa72601fab9511760c7e74 /net/caif | |
| parent | a7da1f55a826c621251874e7684c234972fc3216 (diff) | |
caif: Use link layer MTU instead of fixed MTU
Previously CAIF supported maximum transfer size of ~4050.
The transfer size is now calculated dynamically based on the
link layers mtu size.
Signed-off-by: Sjur Braendeland@stericsson.com
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/caif')
| -rw-r--r-- | net/caif/caif_dev.c | 12 | ||||
| -rw-r--r-- | net/caif/caif_socket.c | 54 | ||||
| -rw-r--r-- | net/caif/cfcnfg.c | 44 | ||||
| -rw-r--r-- | net/caif/cfctrl.c | 6 | ||||
| -rw-r--r-- | net/caif/cfdgml.c | 5 | ||||
| -rw-r--r-- | net/caif/cfpkt_skbuff.c | 4 | ||||
| -rw-r--r-- | net/caif/cfserl.c | 7 | ||||
| -rw-r--r-- | net/caif/cfsrvl.c | 1 | ||||
| -rw-r--r-- | net/caif/cfutill.c | 6 | ||||
| -rw-r--r-- | net/caif/cfveil.c | 5 | ||||
| -rw-r--r-- | net/caif/chnl_net.c | 67 |
11 files changed, 155 insertions, 56 deletions
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index e2b86f1f5a47..0b586e9d1378 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c | |||
| @@ -255,7 +255,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, | |||
| 255 | pref = CFPHYPREF_HIGH_BW; | 255 | pref = CFPHYPREF_HIGH_BW; |
| 256 | break; | 256 | break; |
| 257 | } | 257 | } |
| 258 | 258 | dev_hold(dev); | |
| 259 | cfcnfg_add_phy_layer(get_caif_conf(), | 259 | cfcnfg_add_phy_layer(get_caif_conf(), |
| 260 | phy_type, | 260 | phy_type, |
| 261 | dev, | 261 | dev, |
| @@ -285,6 +285,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, | |||
| 285 | caifd->layer.up->ctrlcmd(caifd->layer.up, | 285 | caifd->layer.up->ctrlcmd(caifd->layer.up, |
| 286 | _CAIF_CTRLCMD_PHYIF_DOWN_IND, | 286 | _CAIF_CTRLCMD_PHYIF_DOWN_IND, |
| 287 | caifd->layer.id); | 287 | caifd->layer.id); |
| 288 | might_sleep(); | ||
| 288 | res = wait_event_interruptible_timeout(caifd->event, | 289 | res = wait_event_interruptible_timeout(caifd->event, |
| 289 | atomic_read(&caifd->in_use) == 0, | 290 | atomic_read(&caifd->in_use) == 0, |
| 290 | TIMEOUT); | 291 | TIMEOUT); |
| @@ -300,6 +301,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, | |||
| 300 | "Unregistering an active CAIF device: %s\n", | 301 | "Unregistering an active CAIF device: %s\n", |
| 301 | __func__, dev->name); | 302 | __func__, dev->name); |
| 302 | cfcnfg_del_phy_layer(get_caif_conf(), &caifd->layer); | 303 | cfcnfg_del_phy_layer(get_caif_conf(), &caifd->layer); |
| 304 | dev_put(dev); | ||
| 303 | atomic_set(&caifd->state, what); | 305 | atomic_set(&caifd->state, what); |
| 304 | break; | 306 | break; |
| 305 | 307 | ||
| @@ -326,7 +328,8 @@ struct cfcnfg *get_caif_conf(void) | |||
| 326 | EXPORT_SYMBOL(get_caif_conf); | 328 | EXPORT_SYMBOL(get_caif_conf); |
| 327 | 329 | ||
| 328 | int caif_connect_client(struct caif_connect_request *conn_req, | 330 | int caif_connect_client(struct caif_connect_request *conn_req, |
| 329 | struct cflayer *client_layer) | 331 | struct cflayer *client_layer, int *ifindex, |
| 332 | int *headroom, int *tailroom) | ||
| 330 | { | 333 | { |
| 331 | struct cfctrl_link_param param; | 334 | struct cfctrl_link_param param; |
| 332 | int ret; | 335 | int ret; |
| @@ -334,8 +337,9 @@ int caif_connect_client(struct caif_connect_request *conn_req, | |||
| 334 | if (ret) | 337 | if (ret) |
| 335 | return ret; | 338 | return ret; |
| 336 | /* Hook up the adaptation layer. */ | 339 | /* Hook up the adaptation layer. */ |
| 337 | return cfcnfg_add_adaptation_layer(get_caif_conf(), | 340 | return cfcnfg_add_adaptation_layer(get_caif_conf(), ¶m, |
| 338 | ¶m, client_layer); | 341 | client_layer, ifindex, |
| 342 | headroom, tailroom); | ||
| 339 | } | 343 | } |
| 340 | EXPORT_SYMBOL(caif_connect_client); | 344 | EXPORT_SYMBOL(caif_connect_client); |
| 341 | 345 | ||
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 848ae755cdd6..8ce904786116 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
| @@ -28,8 +28,8 @@ | |||
| 28 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
| 29 | MODULE_ALIAS_NETPROTO(AF_CAIF); | 29 | MODULE_ALIAS_NETPROTO(AF_CAIF); |
| 30 | 30 | ||
| 31 | #define CAIF_DEF_SNDBUF (CAIF_MAX_PAYLOAD_SIZE*10) | 31 | #define CAIF_DEF_SNDBUF (4096*10) |
| 32 | #define CAIF_DEF_RCVBUF (CAIF_MAX_PAYLOAD_SIZE*100) | 32 | #define CAIF_DEF_RCVBUF (4096*100) |
| 33 | 33 | ||
| 34 | /* | 34 | /* |
| 35 | * CAIF state is re-using the TCP socket states. | 35 | * CAIF state is re-using the TCP socket states. |
| @@ -76,6 +76,7 @@ struct caifsock { | |||
| 76 | struct caif_connect_request conn_req; | 76 | struct caif_connect_request conn_req; |
| 77 | struct mutex readlock; | 77 | struct mutex readlock; |
| 78 | struct dentry *debugfs_socket_dir; | 78 | struct dentry *debugfs_socket_dir; |
| 79 | int headroom, tailroom, maxframe; | ||
| 79 | }; | 80 | }; |
| 80 | 81 | ||
| 81 | static int rx_flow_is_on(struct caifsock *cf_sk) | 82 | static int rx_flow_is_on(struct caifsock *cf_sk) |
| @@ -594,23 +595,32 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 594 | goto err; | 595 | goto err; |
| 595 | noblock = msg->msg_flags & MSG_DONTWAIT; | 596 | noblock = msg->msg_flags & MSG_DONTWAIT; |
| 596 | 597 | ||
| 597 | buffer_size = len + CAIF_NEEDED_HEADROOM + CAIF_NEEDED_TAILROOM; | ||
| 598 | |||
| 599 | timeo = sock_sndtimeo(sk, noblock); | 598 | timeo = sock_sndtimeo(sk, noblock); |
| 600 | timeo = caif_wait_for_flow_on(container_of(sk, struct caifsock, sk), | 599 | timeo = caif_wait_for_flow_on(container_of(sk, struct caifsock, sk), |
| 601 | 1, timeo, &ret); | 600 | 1, timeo, &ret); |
| 602 | 601 | ||
| 602 | if (ret) | ||
| 603 | goto err; | ||
| 603 | ret = -EPIPE; | 604 | ret = -EPIPE; |
| 604 | if (cf_sk->sk.sk_state != CAIF_CONNECTED || | 605 | if (cf_sk->sk.sk_state != CAIF_CONNECTED || |
| 605 | sock_flag(sk, SOCK_DEAD) || | 606 | sock_flag(sk, SOCK_DEAD) || |
| 606 | (sk->sk_shutdown & RCV_SHUTDOWN)) | 607 | (sk->sk_shutdown & RCV_SHUTDOWN)) |
| 607 | goto err; | 608 | goto err; |
| 608 | 609 | ||
| 610 | /* Error if trying to write more than maximum frame size. */ | ||
| 611 | ret = -EMSGSIZE; | ||
| 612 | if (len > cf_sk->maxframe && cf_sk->sk.sk_protocol != CAIFPROTO_RFM) | ||
| 613 | goto err; | ||
| 614 | |||
| 615 | buffer_size = len + cf_sk->headroom + cf_sk->tailroom; | ||
| 616 | |||
| 609 | ret = -ENOMEM; | 617 | ret = -ENOMEM; |
| 610 | skb = sock_alloc_send_skb(sk, buffer_size, noblock, &ret); | 618 | skb = sock_alloc_send_skb(sk, buffer_size, noblock, &ret); |
| 611 | if (!skb) | 619 | |
| 620 | if (!skb || skb_tailroom(skb) < buffer_size) | ||
| 612 | goto err; | 621 | goto err; |
| 613 | skb_reserve(skb, CAIF_NEEDED_HEADROOM); | 622 | |
| 623 | skb_reserve(skb, cf_sk->headroom); | ||
| 614 | 624 | ||
| 615 | ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 625 | ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); |
| 616 | 626 | ||
| @@ -641,7 +651,6 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 641 | long timeo; | 651 | long timeo; |
| 642 | 652 | ||
| 643 | err = -EOPNOTSUPP; | 653 | err = -EOPNOTSUPP; |
| 644 | |||
| 645 | if (unlikely(msg->msg_flags&MSG_OOB)) | 654 | if (unlikely(msg->msg_flags&MSG_OOB)) |
| 646 | goto out_err; | 655 | goto out_err; |
| 647 | 656 | ||
| @@ -658,8 +667,8 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 658 | 667 | ||
| 659 | size = len-sent; | 668 | size = len-sent; |
| 660 | 669 | ||
| 661 | if (size > CAIF_MAX_PAYLOAD_SIZE) | 670 | if (size > cf_sk->maxframe) |
| 662 | size = CAIF_MAX_PAYLOAD_SIZE; | 671 | size = cf_sk->maxframe; |
| 663 | 672 | ||
| 664 | /* If size is more than half of sndbuf, chop up message */ | 673 | /* If size is more than half of sndbuf, chop up message */ |
| 665 | if (size > ((sk->sk_sndbuf >> 1) - 64)) | 674 | if (size > ((sk->sk_sndbuf >> 1) - 64)) |
| @@ -669,14 +678,14 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 669 | size = SKB_MAX_ALLOC; | 678 | size = SKB_MAX_ALLOC; |
| 670 | 679 | ||
| 671 | skb = sock_alloc_send_skb(sk, | 680 | skb = sock_alloc_send_skb(sk, |
| 672 | size + CAIF_NEEDED_HEADROOM | 681 | size + cf_sk->headroom + |
| 673 | + CAIF_NEEDED_TAILROOM, | 682 | cf_sk->tailroom, |
| 674 | msg->msg_flags&MSG_DONTWAIT, | 683 | msg->msg_flags&MSG_DONTWAIT, |
| 675 | &err); | 684 | &err); |
| 676 | if (skb == NULL) | 685 | if (skb == NULL) |
| 677 | goto out_err; | 686 | goto out_err; |
| 678 | 687 | ||
| 679 | skb_reserve(skb, CAIF_NEEDED_HEADROOM); | 688 | skb_reserve(skb, cf_sk->headroom); |
| 680 | /* | 689 | /* |
| 681 | * If you pass two values to the sock_alloc_send_skb | 690 | * If you pass two values to the sock_alloc_send_skb |
| 682 | * it tries to grab the large buffer with GFP_NOFS | 691 | * it tries to grab the large buffer with GFP_NOFS |
| @@ -817,17 +826,15 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 817 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | 826 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); |
| 818 | long timeo; | 827 | long timeo; |
| 819 | int err; | 828 | int err; |
| 829 | int ifindex, headroom, tailroom; | ||
| 830 | struct net_device *dev; | ||
| 831 | |||
| 820 | lock_sock(sk); | 832 | lock_sock(sk); |
| 821 | 833 | ||
| 822 | err = -EAFNOSUPPORT; | 834 | err = -EAFNOSUPPORT; |
| 823 | if (uaddr->sa_family != AF_CAIF) | 835 | if (uaddr->sa_family != AF_CAIF) |
| 824 | goto out; | 836 | goto out; |
| 825 | 837 | ||
| 826 | err = -ESOCKTNOSUPPORT; | ||
| 827 | if (unlikely(!(sk->sk_type == SOCK_STREAM && | ||
| 828 | cf_sk->sk.sk_protocol == CAIFPROTO_AT) && | ||
| 829 | sk->sk_type != SOCK_SEQPACKET)) | ||
| 830 | goto out; | ||
| 831 | switch (sock->state) { | 838 | switch (sock->state) { |
| 832 | case SS_UNCONNECTED: | 839 | case SS_UNCONNECTED: |
| 833 | /* Normal case, a fresh connect */ | 840 | /* Normal case, a fresh connect */ |
| @@ -883,12 +890,23 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 883 | dbfs_atomic_inc(&cnt.num_connect_req); | 890 | dbfs_atomic_inc(&cnt.num_connect_req); |
| 884 | cf_sk->layer.receive = caif_sktrecv_cb; | 891 | cf_sk->layer.receive = caif_sktrecv_cb; |
| 885 | err = caif_connect_client(&cf_sk->conn_req, | 892 | err = caif_connect_client(&cf_sk->conn_req, |
| 886 | &cf_sk->layer); | 893 | &cf_sk->layer, &ifindex, &headroom, &tailroom); |
| 887 | if (err < 0) { | 894 | if (err < 0) { |
| 888 | cf_sk->sk.sk_socket->state = SS_UNCONNECTED; | 895 | cf_sk->sk.sk_socket->state = SS_UNCONNECTED; |
| 889 | cf_sk->sk.sk_state = CAIF_DISCONNECTED; | 896 | cf_sk->sk.sk_state = CAIF_DISCONNECTED; |
| 890 | goto out; | 897 | goto out; |
| 891 | } | 898 | } |
| 899 | dev = dev_get_by_index(sock_net(sk), ifindex); | ||
| 900 | cf_sk->headroom = LL_RESERVED_SPACE_EXTRA(dev, headroom); | ||
| 901 | cf_sk->tailroom = tailroom; | ||
| 902 | cf_sk->maxframe = dev->mtu - (headroom + tailroom); | ||
| 903 | dev_put(dev); | ||
| 904 | if (cf_sk->maxframe < 1) { | ||
| 905 | pr_warning("CAIF: %s(): CAIF Interface MTU too small (%d)\n", | ||
| 906 | __func__, dev->mtu); | ||
| 907 | err = -ENODEV; | ||
| 908 | goto out; | ||
| 909 | } | ||
| 892 | 910 | ||
| 893 | err = -EINPROGRESS; | 911 | err = -EINPROGRESS; |
| 894 | wait_connect: | 912 | wait_connect: |
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index cff2dcb9efe4..1c29189b344d 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
| 7 | #include <linux/stddef.h> | 7 | #include <linux/stddef.h> |
| 8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
| 9 | #include <linux/netdevice.h> | ||
| 9 | #include <net/caif/caif_layer.h> | 10 | #include <net/caif/caif_layer.h> |
| 10 | #include <net/caif/cfpkt.h> | 11 | #include <net/caif/cfpkt.h> |
| 11 | #include <net/caif/cfcnfg.h> | 12 | #include <net/caif/cfcnfg.h> |
| @@ -42,6 +43,15 @@ struct cfcnfg_phyinfo { | |||
| 42 | 43 | ||
| 43 | /* Information about the physical device */ | 44 | /* Information about the physical device */ |
| 44 | struct dev_info dev_info; | 45 | struct dev_info dev_info; |
| 46 | |||
| 47 | /* Interface index */ | ||
| 48 | int ifindex; | ||
| 49 | |||
| 50 | /* Use Start of frame extension */ | ||
| 51 | bool use_stx; | ||
| 52 | |||
| 53 | /* Use Start of frame checksum */ | ||
| 54 | bool use_fcs; | ||
| 45 | }; | 55 | }; |
| 46 | 56 | ||
| 47 | struct cfcnfg { | 57 | struct cfcnfg { |
| @@ -249,9 +259,20 @@ static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id) | |||
| 249 | { | 259 | { |
| 250 | } | 260 | } |
| 251 | 261 | ||
| 262 | int protohead[CFCTRL_SRV_MASK] = { | ||
| 263 | [CFCTRL_SRV_VEI] = 4, | ||
| 264 | [CFCTRL_SRV_DATAGRAM] = 7, | ||
| 265 | [CFCTRL_SRV_UTIL] = 4, | ||
| 266 | [CFCTRL_SRV_RFM] = 3, | ||
| 267 | [CFCTRL_SRV_DBG] = 3, | ||
| 268 | }; | ||
| 269 | |||
| 252 | int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, | 270 | int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, |
| 253 | struct cfctrl_link_param *param, | 271 | struct cfctrl_link_param *param, |
| 254 | struct cflayer *adap_layer) | 272 | struct cflayer *adap_layer, |
| 273 | int *ifindex, | ||
| 274 | int *proto_head, | ||
| 275 | int *proto_tail) | ||
| 255 | { | 276 | { |
| 256 | struct cflayer *frml; | 277 | struct cflayer *frml; |
| 257 | if (adap_layer == NULL) { | 278 | if (adap_layer == NULL) { |
| @@ -277,6 +298,14 @@ int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, | |||
| 277 | param->phyid); | 298 | param->phyid); |
| 278 | caif_assert(cnfg->phy_layers[param->phyid].phy_layer->id == | 299 | caif_assert(cnfg->phy_layers[param->phyid].phy_layer->id == |
| 279 | param->phyid); | 300 | param->phyid); |
| 301 | |||
| 302 | *ifindex = cnfg->phy_layers[param->phyid].ifindex; | ||
| 303 | *proto_head = | ||
| 304 | protohead[param->linktype]+ | ||
| 305 | (cnfg->phy_layers[param->phyid].use_stx ? 1 : 0); | ||
| 306 | |||
| 307 | *proto_tail = 2; | ||
| 308 | |||
| 280 | /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ | 309 | /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ |
| 281 | cfctrl_enum_req(cnfg->ctrl, param->phyid); | 310 | cfctrl_enum_req(cnfg->ctrl, param->phyid); |
| 282 | return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); | 311 | return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); |
| @@ -298,6 +327,8 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, | |||
| 298 | struct cfcnfg *cnfg = container_obj(layer); | 327 | struct cfcnfg *cnfg = container_obj(layer); |
| 299 | struct cflayer *servicel = NULL; | 328 | struct cflayer *servicel = NULL; |
| 300 | struct cfcnfg_phyinfo *phyinfo; | 329 | struct cfcnfg_phyinfo *phyinfo; |
| 330 | struct net_device *netdev; | ||
| 331 | |||
| 301 | if (adapt_layer == NULL) { | 332 | if (adapt_layer == NULL) { |
| 302 | pr_debug("CAIF: %s(): link setup response " | 333 | pr_debug("CAIF: %s(): link setup response " |
| 303 | "but no client exist, send linkdown back\n", | 334 | "but no client exist, send linkdown back\n", |
| @@ -329,8 +360,9 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, | |||
| 329 | servicel = cfdgml_create(channel_id, &phyinfo->dev_info); | 360 | servicel = cfdgml_create(channel_id, &phyinfo->dev_info); |
| 330 | break; | 361 | break; |
| 331 | case CFCTRL_SRV_RFM: | 362 | case CFCTRL_SRV_RFM: |
| 363 | netdev = phyinfo->dev_info.dev; | ||
| 332 | servicel = cfrfml_create(channel_id, &phyinfo->dev_info, | 364 | servicel = cfrfml_create(channel_id, &phyinfo->dev_info, |
| 333 | RFM_FRAGMENT_SIZE); | 365 | netdev->mtu); |
| 334 | break; | 366 | break; |
| 335 | case CFCTRL_SRV_UTIL: | 367 | case CFCTRL_SRV_UTIL: |
| 336 | servicel = cfutill_create(channel_id, &phyinfo->dev_info); | 368 | servicel = cfutill_create(channel_id, &phyinfo->dev_info); |
| @@ -361,8 +393,8 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, | |||
| 361 | 393 | ||
| 362 | void | 394 | void |
| 363 | cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, | 395 | cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, |
| 364 | void *dev, struct cflayer *phy_layer, u16 *phyid, | 396 | struct net_device *dev, struct cflayer *phy_layer, |
| 365 | enum cfcnfg_phy_preference pref, | 397 | u16 *phyid, enum cfcnfg_phy_preference pref, |
| 366 | bool fcs, bool stx) | 398 | bool fcs, bool stx) |
| 367 | { | 399 | { |
| 368 | struct cflayer *frml; | 400 | struct cflayer *frml; |
| @@ -416,6 +448,10 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, | |||
| 416 | cnfg->phy_layers[*phyid].dev_info.dev = dev; | 448 | cnfg->phy_layers[*phyid].dev_info.dev = dev; |
| 417 | cnfg->phy_layers[*phyid].phy_layer = phy_layer; | 449 | cnfg->phy_layers[*phyid].phy_layer = phy_layer; |
| 418 | cnfg->phy_layers[*phyid].phy_ref_count = 0; | 450 | cnfg->phy_layers[*phyid].phy_ref_count = 0; |
| 451 | cnfg->phy_layers[*phyid].ifindex = dev->ifindex; | ||
| 452 | cnfg->phy_layers[*phyid].use_stx = stx; | ||
| 453 | cnfg->phy_layers[*phyid].use_fcs = fcs; | ||
| 454 | |||
| 419 | phy_layer->type = phy_type; | 455 | phy_layer->type = phy_type; |
| 420 | frml = cffrml_create(*phyid, fcs); | 456 | frml = cffrml_create(*phyid, fcs); |
| 421 | if (!frml) { | 457 | if (!frml) { |
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 107c4b2a311e..563145fdc4c3 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | #ifdef CAIF_NO_LOOP | 19 | #ifdef CAIF_NO_LOOP |
| 20 | static int handle_loop(struct cfctrl *ctrl, | 20 | static int handle_loop(struct cfctrl *ctrl, |
| 21 | int cmd, struct cfpkt *pkt){ | 21 | int cmd, struct cfpkt *pkt){ |
| 22 | return CAIF_FAILURE; | 22 | return -1; |
| 23 | } | 23 | } |
| 24 | #else | 24 | #else |
| 25 | static int handle_loop(struct cfctrl *ctrl, | 25 | static int handle_loop(struct cfctrl *ctrl, |
| @@ -395,7 +395,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | |||
| 395 | cmd = cmdrsp & CFCTRL_CMD_MASK; | 395 | cmd = cmdrsp & CFCTRL_CMD_MASK; |
| 396 | if (cmd != CFCTRL_CMD_LINK_ERR | 396 | if (cmd != CFCTRL_CMD_LINK_ERR |
| 397 | && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)) { | 397 | && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)) { |
| 398 | if (handle_loop(cfctrl, cmd, pkt) == CAIF_FAILURE) | 398 | if (handle_loop(cfctrl, cmd, pkt) != 0) |
| 399 | cmdrsp |= CFCTRL_ERR_BIT; | 399 | cmdrsp |= CFCTRL_ERR_BIT; |
| 400 | } | 400 | } |
| 401 | 401 | ||
| @@ -647,6 +647,6 @@ found: | |||
| 647 | default: | 647 | default: |
| 648 | break; | 648 | break; |
| 649 | } | 649 | } |
| 650 | return CAIF_SUCCESS; | 650 | return 0; |
| 651 | } | 651 | } |
| 652 | #endif | 652 | #endif |
diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c index 32d9f0dc8463..ed9d53aff280 100644 --- a/net/caif/cfdgml.c +++ b/net/caif/cfdgml.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #define DGM_FLOW_OFF 0x81 | 17 | #define DGM_FLOW_OFF 0x81 |
| 18 | #define DGM_FLOW_ON 0x80 | 18 | #define DGM_FLOW_ON 0x80 |
| 19 | #define DGM_CTRL_PKT_SIZE 1 | 19 | #define DGM_CTRL_PKT_SIZE 1 |
| 20 | #define DGM_MTU 1500 | ||
| 20 | 21 | ||
| 21 | static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt); | 22 | static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt); |
| 22 | static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt); | 23 | static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt); |
| @@ -89,6 +90,10 @@ static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt) | |||
| 89 | if (!cfsrvl_ready(service, &ret)) | 90 | if (!cfsrvl_ready(service, &ret)) |
| 90 | return ret; | 91 | return ret; |
| 91 | 92 | ||
| 93 | /* STE Modem cannot handle more than 1500 bytes datagrams */ | ||
| 94 | if (cfpkt_getlen(pkt) > DGM_MTU) | ||
| 95 | return -EMSGSIZE; | ||
| 96 | |||
| 92 | cfpkt_add_head(pkt, &zero, 4); | 97 | cfpkt_add_head(pkt, &zero, 4); |
| 93 | 98 | ||
| 94 | /* Add info for MUX-layer to route the packet out. */ | 99 | /* Add info for MUX-layer to route the packet out. */ |
diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c index 318b0f4b416e..01f238ff2346 100644 --- a/net/caif/cfpkt_skbuff.c +++ b/net/caif/cfpkt_skbuff.c | |||
| @@ -9,8 +9,8 @@ | |||
| 9 | #include <linux/hardirq.h> | 9 | #include <linux/hardirq.h> |
| 10 | #include <net/caif/cfpkt.h> | 10 | #include <net/caif/cfpkt.h> |
| 11 | 11 | ||
| 12 | #define PKT_PREFIX CAIF_NEEDED_HEADROOM | 12 | #define PKT_PREFIX 16 |
| 13 | #define PKT_POSTFIX CAIF_NEEDED_TAILROOM | 13 | #define PKT_POSTFIX 2 |
| 14 | #define PKT_LEN_WHEN_EXTENDING 128 | 14 | #define PKT_LEN_WHEN_EXTENDING 128 |
| 15 | #define PKT_ERROR(pkt, errmsg) do { \ | 15 | #define PKT_ERROR(pkt, errmsg) do { \ |
| 16 | cfpkt_priv(pkt)->erronous = true; \ | 16 | cfpkt_priv(pkt)->erronous = true; \ |
diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c index 965c5baace40..a11fbd68a13d 100644 --- a/net/caif/cfserl.c +++ b/net/caif/cfserl.c | |||
| @@ -14,7 +14,8 @@ | |||
| 14 | #define container_obj(layr) ((struct cfserl *) layr) | 14 | #define container_obj(layr) ((struct cfserl *) layr) |
| 15 | 15 | ||
| 16 | #define CFSERL_STX 0x02 | 16 | #define CFSERL_STX 0x02 |
| 17 | #define CAIF_MINIUM_PACKET_SIZE 4 | 17 | #define SERIAL_MINIUM_PACKET_SIZE 4 |
| 18 | #define SERIAL_MAX_FRAMESIZE 4096 | ||
| 18 | struct cfserl { | 19 | struct cfserl { |
| 19 | struct cflayer layer; | 20 | struct cflayer layer; |
| 20 | struct cfpkt *incomplete_frm; | 21 | struct cfpkt *incomplete_frm; |
| @@ -119,8 +120,8 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt) | |||
| 119 | /* | 120 | /* |
| 120 | * Frame error handling | 121 | * Frame error handling |
| 121 | */ | 122 | */ |
| 122 | if (expectlen < CAIF_MINIUM_PACKET_SIZE | 123 | if (expectlen < SERIAL_MINIUM_PACKET_SIZE |
| 123 | || expectlen > CAIF_MAX_FRAMESIZE) { | 124 | || expectlen > SERIAL_MAX_FRAMESIZE) { |
| 124 | if (!layr->usestx) { | 125 | if (!layr->usestx) { |
| 125 | if (pkt != NULL) | 126 | if (pkt != NULL) |
| 126 | cfpkt_destroy(pkt); | 127 | cfpkt_destroy(pkt); |
diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c index 4c9f147c38af..f40939a91211 100644 --- a/net/caif/cfsrvl.c +++ b/net/caif/cfsrvl.c | |||
| @@ -162,7 +162,6 @@ void cfservl_destroy(struct cflayer *layer) | |||
| 162 | void cfsrvl_release(struct kref *kref) | 162 | void cfsrvl_release(struct kref *kref) |
| 163 | { | 163 | { |
| 164 | struct cfsrvl *service = container_of(kref, struct cfsrvl, ref); | 164 | struct cfsrvl *service = container_of(kref, struct cfsrvl, ref); |
| 165 | pr_info("CAIF: %s(): enter\n", __func__); | ||
| 166 | kfree(service); | 165 | kfree(service); |
| 167 | } | 166 | } |
| 168 | 167 | ||
diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c index ce525cac9064..02795aff57a4 100644 --- a/net/caif/cfutill.c +++ b/net/caif/cfutill.c | |||
| @@ -90,12 +90,6 @@ static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt) | |||
| 90 | if (!cfsrvl_ready(service, &ret)) | 90 | if (!cfsrvl_ready(service, &ret)) |
| 91 | return ret; | 91 | return ret; |
| 92 | 92 | ||
| 93 | if (cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { | ||
| 94 | pr_err("CAIF: %s(): packet too large size=%d\n", | ||
| 95 | __func__, cfpkt_getlen(pkt)); | ||
| 96 | return -EOVERFLOW; | ||
| 97 | } | ||
| 98 | |||
| 99 | cfpkt_add_head(pkt, &zero, 1); | 93 | cfpkt_add_head(pkt, &zero, 1); |
| 100 | /* Add info for MUX-layer to route the packet out. */ | 94 | /* Add info for MUX-layer to route the packet out. */ |
| 101 | info = cfpkt_info(pkt); | 95 | info = cfpkt_info(pkt); |
diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c index 637cb0eee13c..77cc09faac9a 100644 --- a/net/caif/cfveil.c +++ b/net/caif/cfveil.c | |||
| @@ -84,11 +84,6 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt) | |||
| 84 | return ret; | 84 | return ret; |
| 85 | caif_assert(layr->dn != NULL); | 85 | caif_assert(layr->dn != NULL); |
| 86 | caif_assert(layr->dn->transmit != NULL); | 86 | caif_assert(layr->dn->transmit != NULL); |
| 87 | if (cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { | ||
| 88 | pr_warning("CAIF: %s(): Packet too large - size=%d\n", | ||
| 89 | __func__, cfpkt_getlen(pkt)); | ||
| 90 | return -EOVERFLOW; | ||
| 91 | } | ||
| 92 | 87 | ||
| 93 | if (cfpkt_add_head(pkt, &tmp, 1) < 0) { | 88 | if (cfpkt_add_head(pkt, &tmp, 1) < 0) { |
| 94 | pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); | 89 | pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); |
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index 610966abe2dc..4293e190ec53 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include <net/caif/caif_dev.h> | 23 | #include <net/caif/caif_dev.h> |
| 24 | 24 | ||
| 25 | /* GPRS PDP connection has MTU to 1500 */ | 25 | /* GPRS PDP connection has MTU to 1500 */ |
| 26 | #define SIZE_MTU 1500 | 26 | #define GPRS_PDP_MTU 1500 |
| 27 | /* 5 sec. connect timeout */ | 27 | /* 5 sec. connect timeout */ |
| 28 | #define CONNECT_TIMEOUT (5 * HZ) | 28 | #define CONNECT_TIMEOUT (5 * HZ) |
| 29 | #define CAIF_NET_DEFAULT_QUEUE_LEN 500 | 29 | #define CAIF_NET_DEFAULT_QUEUE_LEN 500 |
| @@ -232,6 +232,8 @@ static int chnl_net_open(struct net_device *dev) | |||
| 232 | { | 232 | { |
| 233 | struct chnl_net *priv = NULL; | 233 | struct chnl_net *priv = NULL; |
| 234 | int result = -1; | 234 | int result = -1; |
| 235 | int llifindex, headroom, tailroom, mtu; | ||
| 236 | struct net_device *lldev; | ||
| 235 | ASSERT_RTNL(); | 237 | ASSERT_RTNL(); |
| 236 | priv = netdev_priv(dev); | 238 | priv = netdev_priv(dev); |
| 237 | if (!priv) { | 239 | if (!priv) { |
| @@ -241,41 +243,88 @@ static int chnl_net_open(struct net_device *dev) | |||
| 241 | 243 | ||
| 242 | if (priv->state != CAIF_CONNECTING) { | 244 | if (priv->state != CAIF_CONNECTING) { |
| 243 | priv->state = CAIF_CONNECTING; | 245 | priv->state = CAIF_CONNECTING; |
| 244 | result = caif_connect_client(&priv->conn_req, &priv->chnl); | 246 | result = caif_connect_client(&priv->conn_req, &priv->chnl, |
| 247 | &llifindex, &headroom, &tailroom); | ||
| 245 | if (result != 0) { | 248 | if (result != 0) { |
| 246 | priv->state = CAIF_DISCONNECTED; | ||
| 247 | pr_debug("CAIF: %s(): err: " | 249 | pr_debug("CAIF: %s(): err: " |
| 248 | "Unable to register and open device," | 250 | "Unable to register and open device," |
| 249 | " Err:%d\n", | 251 | " Err:%d\n", |
| 250 | __func__, | 252 | __func__, |
| 251 | result); | 253 | result); |
| 252 | return result; | 254 | goto error; |
| 255 | } | ||
| 256 | |||
| 257 | lldev = dev_get_by_index(dev_net(dev), llifindex); | ||
| 258 | |||
| 259 | if (lldev == NULL) { | ||
| 260 | pr_debug("CAIF: %s(): no interface?\n", __func__); | ||
| 261 | result = -ENODEV; | ||
| 262 | goto error; | ||
| 263 | } | ||
| 264 | |||
| 265 | dev->needed_tailroom = tailroom + lldev->needed_tailroom; | ||
| 266 | dev->hard_header_len = headroom + lldev->hard_header_len + | ||
| 267 | lldev->needed_tailroom; | ||
| 268 | |||
| 269 | /* | ||
| 270 | * MTU, head-room etc is not know before we have a | ||
| 271 | * CAIF link layer device available. MTU calculation may | ||
| 272 | * override initial RTNL configuration. | ||
| 273 | * MTU is minimum of current mtu, link layer mtu pluss | ||
| 274 | * CAIF head and tail, and PDP GPRS contexts max MTU. | ||
| 275 | */ | ||
| 276 | mtu = min_t(int, dev->mtu, lldev->mtu - (headroom + tailroom)); | ||
| 277 | mtu = min_t(int, GPRS_PDP_MTU, mtu); | ||
| 278 | dev_set_mtu(dev, mtu); | ||
| 279 | dev_put(lldev); | ||
| 280 | |||
| 281 | if (mtu < 100) { | ||
| 282 | pr_warning("CAIF: %s(): " | ||
| 283 | "CAIF Interface MTU too small (%d)\n", | ||
| 284 | __func__, mtu); | ||
| 285 | result = -ENODEV; | ||
| 286 | goto error; | ||
| 253 | } | 287 | } |
| 254 | } | 288 | } |
| 255 | 289 | ||
| 290 | rtnl_unlock(); /* Release RTNL lock during connect wait */ | ||
| 291 | |||
| 256 | result = wait_event_interruptible_timeout(priv->netmgmt_wq, | 292 | result = wait_event_interruptible_timeout(priv->netmgmt_wq, |
| 257 | priv->state != CAIF_CONNECTING, | 293 | priv->state != CAIF_CONNECTING, |
| 258 | CONNECT_TIMEOUT); | 294 | CONNECT_TIMEOUT); |
| 259 | 295 | ||
| 296 | rtnl_lock(); | ||
| 297 | |||
| 260 | if (result == -ERESTARTSYS) { | 298 | if (result == -ERESTARTSYS) { |
| 261 | pr_debug("CAIF: %s(): wait_event_interruptible" | 299 | pr_debug("CAIF: %s(): wait_event_interruptible" |
| 262 | " woken by a signal\n", __func__); | 300 | " woken by a signal\n", __func__); |
| 263 | return -ERESTARTSYS; | 301 | result = -ERESTARTSYS; |
| 302 | goto error; | ||
| 264 | } | 303 | } |
| 304 | |||
| 265 | if (result == 0) { | 305 | if (result == 0) { |
| 266 | pr_debug("CAIF: %s(): connect timeout\n", __func__); | 306 | pr_debug("CAIF: %s(): connect timeout\n", __func__); |
| 267 | caif_disconnect_client(&priv->chnl); | 307 | caif_disconnect_client(&priv->chnl); |
| 268 | priv->state = CAIF_DISCONNECTED; | 308 | priv->state = CAIF_DISCONNECTED; |
| 269 | pr_debug("CAIF: %s(): state disconnected\n", __func__); | 309 | pr_debug("CAIF: %s(): state disconnected\n", __func__); |
| 270 | return -ETIMEDOUT; | 310 | result = -ETIMEDOUT; |
| 311 | goto error; | ||
| 271 | } | 312 | } |
| 272 | 313 | ||
| 273 | if (priv->state != CAIF_CONNECTED) { | 314 | if (priv->state != CAIF_CONNECTED) { |
| 274 | pr_debug("CAIF: %s(): connect failed\n", __func__); | 315 | pr_debug("CAIF: %s(): connect failed\n", __func__); |
| 275 | return -ECONNREFUSED; | 316 | result = -ECONNREFUSED; |
| 317 | goto error; | ||
| 276 | } | 318 | } |
| 277 | pr_debug("CAIF: %s(): CAIF Netdevice connected\n", __func__); | 319 | pr_debug("CAIF: %s(): CAIF Netdevice connected\n", __func__); |
| 278 | return 0; | 320 | return 0; |
| 321 | |||
| 322 | error: | ||
| 323 | caif_disconnect_client(&priv->chnl); | ||
| 324 | priv->state = CAIF_DISCONNECTED; | ||
| 325 | pr_debug("CAIF: %s(): state disconnected\n", __func__); | ||
| 326 | return result; | ||
| 327 | |||
| 279 | } | 328 | } |
| 280 | 329 | ||
| 281 | static int chnl_net_stop(struct net_device *dev) | 330 | static int chnl_net_stop(struct net_device *dev) |
| @@ -321,9 +370,7 @@ static void ipcaif_net_setup(struct net_device *dev) | |||
| 321 | dev->destructor = free_netdev; | 370 | dev->destructor = free_netdev; |
| 322 | dev->flags |= IFF_NOARP; | 371 | dev->flags |= IFF_NOARP; |
| 323 | dev->flags |= IFF_POINTOPOINT; | 372 | dev->flags |= IFF_POINTOPOINT; |
| 324 | dev->needed_headroom = CAIF_NEEDED_HEADROOM; | 373 | dev->mtu = GPRS_PDP_MTU; |
| 325 | dev->needed_tailroom = CAIF_NEEDED_TAILROOM; | ||
| 326 | dev->mtu = SIZE_MTU; | ||
| 327 | dev->tx_queue_len = CAIF_NET_DEFAULT_QUEUE_LEN; | 374 | dev->tx_queue_len = CAIF_NET_DEFAULT_QUEUE_LEN; |
| 328 | 375 | ||
| 329 | priv = netdev_priv(dev); | 376 | priv = netdev_priv(dev); |
