Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
caif
cfdgml.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) ST-Ericsson AB 2010
3
* Author: Sjur Brendeland/
[email protected]
4
* License terms: GNU General Public License (GPL) version 2
5
*/
6
7
#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
8
9
#include <linux/stddef.h>
10
#include <
linux/spinlock.h
>
11
#include <linux/slab.h>
12
#include <
net/caif/caif_layer.h
>
13
#include <
net/caif/cfsrvl.h
>
14
#include <
net/caif/cfpkt.h
>
15
16
17
#define container_obj(layr) ((struct cfsrvl *) layr)
18
19
#define DGM_CMD_BIT 0x80
20
#define DGM_FLOW_OFF 0x81
21
#define DGM_FLOW_ON 0x80
22
#define DGM_MTU 1500
23
24
static
int
cfdgml_receive(
struct
cflayer
*layr,
struct
cfpkt
*pkt);
25
static
int
cfdgml_transmit(
struct
cflayer
*layr,
struct
cfpkt
*pkt);
26
27
struct
cflayer
*
cfdgml_create
(
u8
channel_id,
struct
dev_info
*
dev_info
)
28
{
29
struct
cfsrvl
*dgm = kzalloc(
sizeof
(
struct
cfsrvl
),
GFP_ATOMIC
);
30
if
(!dgm)
31
return
NULL
;
32
caif_assert
(
offsetof
(
struct
cfsrvl
,
layer
) == 0);
33
cfsrvl_init
(dgm, channel_id, dev_info,
true
);
34
dgm->
layer
.receive = cfdgml_receive;
35
dgm->
layer
.transmit = cfdgml_transmit;
36
snprintf
(dgm->
layer
.name,
CAIF_LAYER_NAME_SZ
- 1,
"dgm%d"
, channel_id);
37
dgm->
layer
.name[
CAIF_LAYER_NAME_SZ
- 1] =
'\0'
;
38
return
&dgm->
layer
;
39
}
40
41
static
int
cfdgml_receive(
struct
cflayer
*layr,
struct
cfpkt
*pkt)
42
{
43
u8
cmd
= -1;
44
u8
dgmhdr[3];
45
int
ret
;
46
caif_assert
(layr->
up
!=
NULL
);
47
caif_assert
(layr->
receive
!=
NULL
);
48
caif_assert
(layr->
ctrlcmd
!=
NULL
);
49
50
if
(
cfpkt_extr_head
(pkt, &cmd, 1) < 0) {
51
pr_err
(
"Packet is erroneous!\n"
);
52
cfpkt_destroy
(pkt);
53
return
-
EPROTO
;
54
}
55
56
if
((cmd &
DGM_CMD_BIT
) == 0) {
57
if
(
cfpkt_extr_head
(pkt, &dgmhdr, 3) < 0) {
58
pr_err
(
"Packet is erroneous!\n"
);
59
cfpkt_destroy
(pkt);
60
return
-
EPROTO
;
61
}
62
ret = layr->
up
->receive(layr->
up
, pkt);
63
return
ret
;
64
}
65
66
switch
(cmd) {
67
case
DGM_FLOW_OFF
:
/* FLOW OFF */
68
layr->
ctrlcmd
(layr,
CAIF_CTRLCMD_FLOW_OFF_IND
, 0);
69
cfpkt_destroy
(pkt);
70
return
0;
71
case
DGM_FLOW_ON
:
/* FLOW ON */
72
layr->
ctrlcmd
(layr,
CAIF_CTRLCMD_FLOW_ON_IND
, 0);
73
cfpkt_destroy
(pkt);
74
return
0;
75
default
:
76
cfpkt_destroy
(pkt);
77
pr_info
(
"Unknown datagram control %d (0x%x)\n"
, cmd, cmd);
78
return
-
EPROTO
;
79
}
80
}
81
82
static
int
cfdgml_transmit(
struct
cflayer
*layr,
struct
cfpkt
*pkt)
83
{
84
u8
packet_type
;
85
u32
zero
= 0;
86
struct
caif_payload_info
*
info
;
87
struct
cfsrvl
*
service
=
container_obj
(layr);
88
int
ret
;
89
90
if
(!
cfsrvl_ready
(service, &ret)) {
91
cfpkt_destroy
(pkt);
92
return
ret
;
93
}
94
95
/* STE Modem cannot handle more than 1500 bytes datagrams */
96
if
(
cfpkt_getlen
(pkt) >
DGM_MTU
) {
97
cfpkt_destroy
(pkt);
98
return
-
EMSGSIZE
;
99
}
100
101
cfpkt_add_head
(pkt, &zero, 3);
102
packet_type = 0x08;
/* B9 set - UNCLASSIFIED */
103
cfpkt_add_head
(pkt, &packet_type, 1);
104
105
/* Add info for MUX-layer to route the packet out. */
106
info =
cfpkt_info
(pkt);
107
info->
channel_id
= service->
layer
.id;
108
/* To optimize alignment, we add up the size of CAIF header
109
* before payload.
110
*/
111
info->
hdr_len
= 4;
112
info->
dev_info
= &service->
dev_info
;
113
return
layr->
dn
->transmit(layr->
dn
, pkt);
114
}
Generated on Thu Jan 10 2013 14:57:17 for Linux Kernel by
1.8.2