Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
8f961fae
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 3 年多
通知
13
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
8f961fae
编写于
7月 07, 2012
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-davem' of
git://gitorious.org/linux-can/linux-can-next
上级
95162d65
f057bbb6
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
320 addition
and
23 deletion
+320
-23
Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
+3
-0
drivers/net/can/cc770/cc770.c
drivers/net/can/cc770/cc770.c
+1
-1
drivers/net/can/dev.c
drivers/net/can/dev.c
+1
-1
drivers/net/can/flexcan.c
drivers/net/can/flexcan.c
+55
-16
include/linux/can.h
include/linux/can.h
+3
-0
include/linux/pkt_cls.h
include/linux/pkt_cls.h
+3
-2
net/can/af_can.h
net/can/af_can.h
+3
-0
net/can/proc.c
net/can/proc.c
+0
-3
net/sched/Kconfig
net/sched/Kconfig
+10
-0
net/sched/Makefile
net/sched/Makefile
+1
-0
net/sched/em_canid.c
net/sched/em_canid.c
+240
-0
未找到文件。
Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
浏览文件 @
8f961fae
...
...
@@ -11,6 +11,9 @@ Required properties:
- reg : Offset and length of the register set for this device
- interrupts : Interrupt tuple for this device
Optional properties:
- clock-frequency : The oscillator frequency driving the flexcan device
Example:
...
...
drivers/net/can/cc770/cc770.c
浏览文件 @
8f961fae
...
...
@@ -695,7 +695,7 @@ static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
netif_wake_queue
(
dev
);
}
irqreturn_t
cc770_interrupt
(
int
irq
,
void
*
dev_id
)
static
irqreturn_t
cc770_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
dev_id
;
struct
cc770_priv
*
priv
=
netdev_priv
(
dev
);
...
...
drivers/net/can/dev.c
浏览文件 @
8f961fae
...
...
@@ -401,7 +401,7 @@ EXPORT_SYMBOL_GPL(can_free_echo_skb);
/*
* CAN device restart for bus-off recovery
*/
void
can_restart
(
unsigned
long
data
)
static
void
can_restart
(
unsigned
long
data
)
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
data
;
struct
can_priv
*
priv
=
netdev_priv
(
dev
);
...
...
drivers/net/can/flexcan.c
浏览文件 @
8f961fae
...
...
@@ -34,6 +34,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
...
...
@@ -165,10 +166,21 @@ struct flexcan_regs {
u32
imask1
;
/* 0x28 */
u32
iflag2
;
/* 0x2c */
u32
iflag1
;
/* 0x30 */
u32
_reserved2
[
19
];
u32
crl2
;
/* 0x34 */
u32
esr2
;
/* 0x38 */
u32
imeur
;
/* 0x3c */
u32
lrfr
;
/* 0x40 */
u32
crcr
;
/* 0x44 */
u32
rxfgmask
;
/* 0x48 */
u32
rxfir
;
/* 0x4c */
u32
_reserved3
[
12
];
struct
flexcan_mb
cantxfg
[
64
];
};
struct
flexcan_devtype_data
{
u32
hw_ver
;
/* hardware controller version */
};
struct
flexcan_priv
{
struct
can_priv
can
;
struct
net_device
*
dev
;
...
...
@@ -180,6 +192,15 @@ struct flexcan_priv {
struct
clk
*
clk
;
struct
flexcan_platform_data
*
pdata
;
struct
flexcan_devtype_data
*
devtype_data
;
};
static
struct
flexcan_devtype_data
fsl_p1010_devtype_data
=
{
.
hw_ver
=
3
,
};
static
struct
flexcan_devtype_data
fsl_imx6q_devtype_data
=
{
.
hw_ver
=
10
,
};
static
struct
can_bittiming_const
flexcan_bittiming_const
=
{
...
...
@@ -750,6 +771,9 @@ static int flexcan_chip_start(struct net_device *dev)
flexcan_write
(
0x0
,
&
regs
->
rx14mask
);
flexcan_write
(
0x0
,
&
regs
->
rx15mask
);
if
(
priv
->
devtype_data
->
hw_ver
>=
10
)
flexcan_write
(
0x0
,
&
regs
->
rxfgmask
);
flexcan_transceiver_switch
(
priv
,
1
);
/* synchronize with the can bus */
...
...
@@ -922,8 +946,21 @@ static void __devexit unregister_flexcandev(struct net_device *dev)
unregister_candev
(
dev
);
}
static
const
struct
of_device_id
flexcan_of_match
[]
=
{
{
.
compatible
=
"fsl,p1010-flexcan"
,
.
data
=
&
fsl_p1010_devtype_data
,
},
{
.
compatible
=
"fsl,imx6q-flexcan"
,
.
data
=
&
fsl_imx6q_devtype_data
,
},
{
/* sentinel */
},
};
static
const
struct
platform_device_id
flexcan_id_table
[]
=
{
{
.
name
=
"flexcan"
,
.
driver_data
=
(
kernel_ulong_t
)
&
fsl_p1010_devtype_data
,
},
{
/* sentinel */
},
};
static
int
__devinit
flexcan_probe
(
struct
platform_device
*
pdev
)
{
const
struct
of_device_id
*
of_id
;
struct
flexcan_devtype_data
*
devtype_data
;
struct
net_device
*
dev
;
struct
flexcan_priv
*
priv
;
struct
resource
*
mem
;
...
...
@@ -938,14 +975,9 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
if
(
IS_ERR
(
pinctrl
))
return
PTR_ERR
(
pinctrl
);
if
(
pdev
->
dev
.
of_node
)
{
const
__be32
*
clock_freq_p
;
clock_freq_p
=
of_get_property
(
pdev
->
dev
.
of_node
,
"clock-frequency"
,
NULL
);
if
(
clock_freq_p
)
clock_freq
=
be32_to_cpup
(
clock_freq_p
);
}
if
(
pdev
->
dev
.
of_node
)
of_property_read_u32
(
pdev
->
dev
.
of_node
,
"clock-frequency"
,
&
clock_freq
);
if
(
!
clock_freq
)
{
clk
=
clk_get
(
&
pdev
->
dev
,
NULL
);
...
...
@@ -982,6 +1014,17 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
goto
failed_alloc
;
}
of_id
=
of_match_device
(
flexcan_of_match
,
&
pdev
->
dev
);
if
(
of_id
)
{
devtype_data
=
of_id
->
data
;
}
else
if
(
pdev
->
id_entry
->
driver_data
)
{
devtype_data
=
(
struct
flexcan_devtype_data
*
)
pdev
->
id_entry
->
driver_data
;
}
else
{
err
=
-
ENODEV
;
goto
failed_devtype
;
}
dev
->
netdev_ops
=
&
flexcan_netdev_ops
;
dev
->
irq
=
irq
;
dev
->
flags
|=
IFF_ECHO
;
...
...
@@ -998,6 +1041,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
priv
->
dev
=
dev
;
priv
->
clk
=
clk
;
priv
->
pdata
=
pdev
->
dev
.
platform_data
;
priv
->
devtype_data
=
devtype_data
;
netif_napi_add
(
dev
,
&
priv
->
napi
,
flexcan_poll
,
FLEXCAN_NAPI_WEIGHT
);
...
...
@@ -1016,6 +1060,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
return
0
;
failed_register:
failed_devtype:
free_candev
(
dev
);
failed_alloc:
iounmap
(
base
);
...
...
@@ -1049,13 +1094,6 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
return
0
;
}
static
struct
of_device_id
flexcan_of_match
[]
=
{
{
.
compatible
=
"fsl,p1010-flexcan"
,
},
{},
};
#ifdef CONFIG_PM
static
int
flexcan_suspend
(
struct
platform_device
*
pdev
,
pm_message_t
state
)
{
...
...
@@ -1102,6 +1140,7 @@ static struct platform_driver flexcan_driver = {
.
remove
=
__devexit_p
(
flexcan_remove
),
.
suspend
=
flexcan_suspend
,
.
resume
=
flexcan_resume
,
.
id_table
=
flexcan_id_table
,
};
module_platform_driver
(
flexcan_driver
);
...
...
include/linux/can.h
浏览文件 @
8f961fae
...
...
@@ -38,6 +38,9 @@
*/
typedef
__u32
canid_t
;
#define CAN_SFF_ID_BITS 11
#define CAN_EFF_ID_BITS 29
/*
* Controller Area Network Error Message Frame Mask structure
*
...
...
include/linux/pkt_cls.h
浏览文件 @
8f961fae
...
...
@@ -451,8 +451,9 @@ enum {
#define TCF_EM_U32 3
#define TCF_EM_META 4
#define TCF_EM_TEXT 5
#define TCF_EM_VLAN 6
#define TCF_EM_MAX 6
#define TCF_EM_VLAN 6
#define TCF_EM_CANID 7
#define TCF_EM_MAX 7
enum
{
TCF_EM_PROG_TC
...
...
net/can/af_can.h
浏览文件 @
8f961fae
...
...
@@ -104,6 +104,9 @@ struct s_pstats {
unsigned
long
rcv_entries_max
;
};
/* receive filters subscribed for 'all' CAN devices */
extern
struct
dev_rcv_lists
can_rx_alldev_list
;
/* function prototypes for the CAN networklayer procfs (proc.c) */
extern
void
can_init_proc
(
void
);
extern
void
can_remove_proc
(
void
);
...
...
net/can/proc.c
浏览文件 @
8f961fae
...
...
@@ -83,9 +83,6 @@ static const char rx_list_name[][8] = {
[
RX_EFF
]
=
"rx_eff"
,
};
/* receive filters subscribed for 'all' CAN devices */
extern
struct
dev_rcv_lists
can_rx_alldev_list
;
/*
* af_can statistics stuff
*/
...
...
net/sched/Kconfig
浏览文件 @
8f961fae
...
...
@@ -507,6 +507,16 @@ config NET_EMATCH_TEXT
To compile this code as a module, choose M here: the
module will be called em_text.
config NET_EMATCH_CANID
tristate "CAN Identifier"
depends on NET_EMATCH && CAN
---help---
Say Y here if you want to be able to classify CAN frames based
on CAN Identifier.
To compile this code as a module, choose M here: the
module will be called em_canid.
config NET_CLS_ACT
bool "Actions"
---help---
...
...
net/sched/Makefile
浏览文件 @
8f961fae
...
...
@@ -55,3 +55,4 @@ obj-$(CONFIG_NET_EMATCH_NBYTE) += em_nbyte.o
obj-$(CONFIG_NET_EMATCH_U32)
+=
em_u32.o
obj-$(CONFIG_NET_EMATCH_META)
+=
em_meta.o
obj-$(CONFIG_NET_EMATCH_TEXT)
+=
em_text.o
obj-$(CONFIG_NET_EMATCH_CANID)
+=
em_canid.o
net/sched/em_canid.c
0 → 100644
浏览文件 @
8f961fae
/*
* em_canid.c Ematch rule to match CAN frames according to their CAN IDs
*
* This program is free software; you can distribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Idea: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
* Copyright: (c) 2011 Czech Technical University in Prague
* (c) 2011 Volkswagen Group Research
* Authors: Michal Sojka <sojkam1@fel.cvut.cz>
* Pavel Pisa <pisa@cmp.felk.cvut.cz>
* Rostislav Lisovy <lisovy@gmail.cz>
* Funded by: Volkswagen Group Research
*/
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <net/pkt_cls.h>
#include <linux/can.h>
#define EM_CAN_RULES_MAX 500
struct
canid_match
{
/* For each SFF CAN ID (11 bit) there is one record in this bitfield */
DECLARE_BITMAP
(
match_sff
,
(
1
<<
CAN_SFF_ID_BITS
));
int
rules_count
;
int
sff_rules_count
;
int
eff_rules_count
;
/*
* Raw rules copied from netlink message; Used for sending
* information to userspace (when 'tc filter show' is invoked)
* AND when matching EFF frames
*/
struct
can_filter
rules_raw
[];
};
/**
* em_canid_get_id() - Extracts Can ID out of the sk_buff structure.
*/
static
canid_t
em_canid_get_id
(
struct
sk_buff
*
skb
)
{
/* CAN ID is stored within the data field */
struct
can_frame
*
cf
=
(
struct
can_frame
*
)
skb
->
data
;
return
cf
->
can_id
;
}
static
void
em_canid_sff_match_add
(
struct
canid_match
*
cm
,
u32
can_id
,
u32
can_mask
)
{
int
i
;
/*
* Limit can_mask and can_id to SFF range to
* protect against write after end of array
*/
can_mask
&=
CAN_SFF_MASK
;
can_id
&=
can_mask
;
/* Single frame */
if
(
can_mask
==
CAN_SFF_MASK
)
{
set_bit
(
can_id
,
cm
->
match_sff
);
return
;
}
/* All frames */
if
(
can_mask
==
0
)
{
bitmap_fill
(
cm
->
match_sff
,
(
1
<<
CAN_SFF_ID_BITS
));
return
;
}
/*
* Individual frame filter.
* Add record (set bit to 1) for each ID that
* conforms particular rule
*/
for
(
i
=
0
;
i
<
(
1
<<
CAN_SFF_ID_BITS
);
i
++
)
{
if
((
i
&
can_mask
)
==
can_id
)
set_bit
(
i
,
cm
->
match_sff
);
}
}
static
inline
struct
canid_match
*
em_canid_priv
(
struct
tcf_ematch
*
m
)
{
return
(
struct
canid_match
*
)
m
->
data
;
}
static
int
em_canid_match
(
struct
sk_buff
*
skb
,
struct
tcf_ematch
*
m
,
struct
tcf_pkt_info
*
info
)
{
struct
canid_match
*
cm
=
em_canid_priv
(
m
);
canid_t
can_id
;
int
match
=
0
;
int
i
;
const
struct
can_filter
*
lp
;
can_id
=
em_canid_get_id
(
skb
);
if
(
can_id
&
CAN_EFF_FLAG
)
{
for
(
i
=
0
,
lp
=
cm
->
rules_raw
;
i
<
cm
->
eff_rules_count
;
i
++
,
lp
++
)
{
if
(
!
(((
lp
->
can_id
^
can_id
)
&
lp
->
can_mask
)))
{
match
=
1
;
break
;
}
}
}
else
{
/* SFF */
can_id
&=
CAN_SFF_MASK
;
match
=
(
test_bit
(
can_id
,
cm
->
match_sff
)
?
1
:
0
);
}
return
match
;
}
static
int
em_canid_change
(
struct
tcf_proto
*
tp
,
void
*
data
,
int
len
,
struct
tcf_ematch
*
m
)
{
struct
can_filter
*
conf
=
data
;
/* Array with rules */
struct
canid_match
*
cm
;
struct
canid_match
*
cm_old
=
(
struct
canid_match
*
)
m
->
data
;
int
i
;
if
(
!
len
)
return
-
EINVAL
;
if
(
len
%
sizeof
(
struct
can_filter
))
return
-
EINVAL
;
if
(
len
>
sizeof
(
struct
can_filter
)
*
EM_CAN_RULES_MAX
)
return
-
EINVAL
;
cm
=
kzalloc
(
sizeof
(
struct
canid_match
)
+
len
,
GFP_KERNEL
);
if
(
!
cm
)
return
-
ENOMEM
;
cm
->
rules_count
=
len
/
sizeof
(
struct
can_filter
);
/*
* We need two for() loops for copying rules into two contiguous
* areas in rules_raw to process all eff rules with a simple loop.
* NB: The configuration interface supports sff and eff rules.
* We do not support filters here that match for the same can_id
* provided in a SFF and EFF frame (e.g. 0x123 / 0x80000123).
* For this (unusual case) two filters have to be specified. The
* SFF/EFF separation is done with the CAN_EFF_FLAG in the can_id.
*/
/* Fill rules_raw with EFF rules first */
for
(
i
=
0
;
i
<
cm
->
rules_count
;
i
++
)
{
if
(
conf
[
i
].
can_id
&
CAN_EFF_FLAG
)
{
memcpy
(
cm
->
rules_raw
+
cm
->
eff_rules_count
,
&
conf
[
i
],
sizeof
(
struct
can_filter
));
cm
->
eff_rules_count
++
;
}
}
/* append SFF frame rules */
for
(
i
=
0
;
i
<
cm
->
rules_count
;
i
++
)
{
if
(
!
(
conf
[
i
].
can_id
&
CAN_EFF_FLAG
))
{
memcpy
(
cm
->
rules_raw
+
cm
->
eff_rules_count
+
cm
->
sff_rules_count
,
&
conf
[
i
],
sizeof
(
struct
can_filter
));
cm
->
sff_rules_count
++
;
em_canid_sff_match_add
(
cm
,
conf
[
i
].
can_id
,
conf
[
i
].
can_mask
);
}
}
m
->
datalen
=
sizeof
(
struct
canid_match
)
+
len
;
m
->
data
=
(
unsigned
long
)
cm
;
if
(
cm_old
!=
NULL
)
{
pr_err
(
"canid: Configuring an existing ematch!
\n
"
);
kfree
(
cm_old
);
}
return
0
;
}
static
void
em_canid_destroy
(
struct
tcf_proto
*
tp
,
struct
tcf_ematch
*
m
)
{
struct
canid_match
*
cm
=
em_canid_priv
(
m
);
kfree
(
cm
);
}
static
int
em_canid_dump
(
struct
sk_buff
*
skb
,
struct
tcf_ematch
*
m
)
{
struct
canid_match
*
cm
=
em_canid_priv
(
m
);
/*
* When configuring this ematch 'rules_count' is set not to exceed
* 'rules_raw' array size
*/
if
(
nla_put_nohdr
(
skb
,
sizeof
(
struct
can_filter
)
*
cm
->
rules_count
,
&
cm
->
rules_raw
)
<
0
)
return
-
EMSGSIZE
;
return
0
;
}
static
struct
tcf_ematch_ops
em_canid_ops
=
{
.
kind
=
TCF_EM_CANID
,
.
change
=
em_canid_change
,
.
match
=
em_canid_match
,
.
destroy
=
em_canid_destroy
,
.
dump
=
em_canid_dump
,
.
owner
=
THIS_MODULE
,
.
link
=
LIST_HEAD_INIT
(
em_canid_ops
.
link
)
};
static
int
__init
init_em_canid
(
void
)
{
return
tcf_em_register
(
&
em_canid_ops
);
}
static
void
__exit
exit_em_canid
(
void
)
{
tcf_em_unregister
(
&
em_canid_ops
);
}
MODULE_LICENSE
(
"GPL"
);
module_init
(
init_em_canid
);
module_exit
(
exit_em_canid
);
MODULE_ALIAS_TCF_EMATCH
(
TCF_EM_CANID
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录