1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) ST-Ericsson AB 2010 |
4 | * Author: Sjur Brendeland |
5 | */ |
6 | |
7 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ |
8 | |
9 | #include <linux/kernel.h> |
10 | #include <linux/types.h> |
11 | #include <linux/slab.h> |
12 | #include <linux/errno.h> |
13 | #include <net/caif/caif_layer.h> |
14 | #include <net/caif/cfsrvl.h> |
15 | #include <net/caif/cfpkt.h> |
16 | |
17 | #define container_obj(layr) ((struct cfsrvl *) layr) |
18 | |
19 | static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt); |
20 | static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt); |
21 | |
22 | struct cflayer *cfvidl_create(u8 channel_id, struct dev_info *dev_info) |
23 | { |
24 | struct cfsrvl *vid = kzalloc(size: sizeof(struct cfsrvl), GFP_ATOMIC); |
25 | if (!vid) |
26 | return NULL; |
27 | caif_assert(offsetof(struct cfsrvl, layer) == 0); |
28 | |
29 | cfsrvl_init(service: vid, channel_id, dev_info, supports_flowctrl: false); |
30 | vid->layer.receive = cfvidl_receive; |
31 | vid->layer.transmit = cfvidl_transmit; |
32 | snprintf(buf: vid->layer.name, CAIF_LAYER_NAME_SZ, fmt: "vid1" ); |
33 | return &vid->layer; |
34 | } |
35 | |
36 | static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt) |
37 | { |
38 | u32 ; |
39 | if (cfpkt_extr_head(pkt, data: &videoheader, len: 4) < 0) { |
40 | pr_err("Packet is erroneous!\n" ); |
41 | cfpkt_destroy(pkt); |
42 | return -EPROTO; |
43 | } |
44 | return layr->up->receive(layr->up, pkt); |
45 | } |
46 | |
47 | static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt) |
48 | { |
49 | struct cfsrvl *service = container_obj(layr); |
50 | struct caif_payload_info *info; |
51 | u32 = 0; |
52 | int ret; |
53 | |
54 | if (!cfsrvl_ready(service, err: &ret)) { |
55 | cfpkt_destroy(pkt); |
56 | return ret; |
57 | } |
58 | |
59 | cfpkt_add_head(pkt, data: &videoheader, len: 4); |
60 | /* Add info for MUX-layer to route the packet out */ |
61 | info = cfpkt_info(pkt); |
62 | info->channel_id = service->layer.id; |
63 | info->dev_info = &service->dev_info; |
64 | return layr->dn->transmit(layr->dn, pkt); |
65 | } |
66 | |