Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
4e700bcd
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
4e700bcd
编写于
3月 30, 2011
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
上级
6aba74f2
a84b50ce
变更
25
隐藏空白更改
内联
并排
Showing
25 changed file
with
531 addition
and
216 deletion
+531
-216
drivers/atm/solos-pci.c
drivers/atm/solos-pci.c
+11
-28
drivers/connector/cn_queue.c
drivers/connector/cn_queue.c
+17
-41
drivers/connector/connector.c
drivers/connector/connector.c
+12
-35
drivers/net/atlx/atl2.c
drivers/net/atlx/atl2.c
+14
-8
drivers/net/irda/via-ircc.c
drivers/net/irda/via-ircc.c
+21
-73
drivers/net/phy/phy_device.c
drivers/net/phy/phy_device.c
+6
-2
drivers/net/usb/Kconfig
drivers/net/usb/Kconfig
+15
-0
drivers/net/usb/Makefile
drivers/net/usb/Makefile
+1
-0
drivers/net/usb/cdc_ether.c
drivers/net/usb/cdc_ether.c
+15
-6
drivers/net/usb/lg-vl600.c
drivers/net/usb/lg-vl600.c
+346
-0
drivers/net/usb/usbnet.c
drivers/net/usb/usbnet.c
+7
-3
include/linux/atmdev.h
include/linux/atmdev.h
+1
-0
include/linux/connector.h
include/linux/connector.h
+3
-13
include/linux/skbuff.h
include/linux/skbuff.h
+1
-1
include/linux/usb/usbnet.h
include/linux/usb/usbnet.h
+3
-0
include/net/if_inet6.h
include/net/if_inet6.h
+16
-0
include/net/ip.h
include/net/ip.h
+8
-0
net/atm/common.c
net/atm/common.c
+1
-0
net/bridge/br_multicast.c
net/bridge/br_multicast.c
+1
-1
net/bridge/br_stp_if.c
net/bridge/br_stp_if.c
+1
-1
net/core/dev.c
net/core/dev.c
+22
-2
net/ipv4/arp.c
net/ipv4/arp.c
+3
-0
net/ipv4/fib_frontend.c
net/ipv4/fib_frontend.c
+2
-0
net/ipv6/ndisc.c
net/ipv6/ndisc.c
+2
-0
net/sctp/protocol.c
net/sctp/protocol.c
+2
-2
未找到文件。
drivers/atm/solos-pci.c
浏览文件 @
4e700bcd
...
...
@@ -165,7 +165,6 @@ static uint32_t fpga_tx(struct solos_card *);
static
irqreturn_t
solos_irq
(
int
irq
,
void
*
dev_id
);
static
struct
atm_vcc
*
find_vcc
(
struct
atm_dev
*
dev
,
short
vpi
,
int
vci
);
static
int
list_vccs
(
int
vci
);
static
void
release_vccs
(
struct
atm_dev
*
dev
);
static
int
atm_init
(
struct
solos_card
*
,
struct
device
*
);
static
void
atm_remove
(
struct
solos_card
*
);
static
int
send_command
(
struct
solos_card
*
card
,
int
dev
,
const
char
*
buf
,
size_t
size
);
...
...
@@ -384,7 +383,6 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb
/* Anything but 'Showtime' is down */
if
(
strcmp
(
state_str
,
"Showtime"
))
{
atm_dev_signal_change
(
card
->
atmdev
[
port
],
ATM_PHY_SIG_LOST
);
release_vccs
(
card
->
atmdev
[
port
]);
dev_info
(
&
card
->
dev
->
dev
,
"Port %d: %s
\n
"
,
port
,
state_str
);
return
0
;
}
...
...
@@ -697,7 +695,7 @@ void solos_bh(unsigned long card_arg)
size
);
}
if
(
atmdebug
)
{
dev_info
(
&
card
->
dev
->
dev
,
"Received:
device
%d
\n
"
,
port
);
dev_info
(
&
card
->
dev
->
dev
,
"Received:
port
%d
\n
"
,
port
);
dev_info
(
&
card
->
dev
->
dev
,
"size: %d VPI: %d VCI: %d
\n
"
,
size
,
le16_to_cpu
(
header
->
vpi
),
le16_to_cpu
(
header
->
vci
));
...
...
@@ -710,8 +708,8 @@ void solos_bh(unsigned long card_arg)
le16_to_cpu
(
header
->
vci
));
if
(
!
vcc
)
{
if
(
net_ratelimit
())
dev_warn
(
&
card
->
dev
->
dev
,
"Received packet for unknown V
CI.VP
I %d.%d on port %d
\n
"
,
le16_to_cpu
(
header
->
v
ci
),
le16_to_cpu
(
header
->
vp
i
),
dev_warn
(
&
card
->
dev
->
dev
,
"Received packet for unknown V
PI.VC
I %d.%d on port %d
\n
"
,
le16_to_cpu
(
header
->
v
pi
),
le16_to_cpu
(
header
->
vc
i
),
port
);
continue
;
}
...
...
@@ -830,28 +828,6 @@ static int list_vccs(int vci)
return
num_found
;
}
static
void
release_vccs
(
struct
atm_dev
*
dev
)
{
int
i
;
write_lock_irq
(
&
vcc_sklist_lock
);
for
(
i
=
0
;
i
<
VCC_HTABLE_SIZE
;
i
++
)
{
struct
hlist_head
*
head
=
&
vcc_hash
[
i
];
struct
hlist_node
*
node
,
*
tmp
;
struct
sock
*
s
;
struct
atm_vcc
*
vcc
;
sk_for_each_safe
(
s
,
node
,
tmp
,
head
)
{
vcc
=
atm_sk
(
s
);
if
(
vcc
->
dev
==
dev
)
{
vcc_release_async
(
vcc
,
-
EPIPE
);
sk_del_node_init
(
s
);
}
}
}
write_unlock_irq
(
&
vcc_sklist_lock
);
}
static
int
popen
(
struct
atm_vcc
*
vcc
)
{
...
...
@@ -1018,8 +994,15 @@ static uint32_t fpga_tx(struct solos_card *card)
/* Clean up and free oldskb now it's gone */
if
(
atmdebug
)
{
struct
pkt_hdr
*
header
=
(
void
*
)
oldskb
->
data
;
int
size
=
le16_to_cpu
(
header
->
size
);
skb_pull
(
oldskb
,
sizeof
(
*
header
));
dev_info
(
&
card
->
dev
->
dev
,
"Transmitted: port %d
\n
"
,
port
);
dev_info
(
&
card
->
dev
->
dev
,
"size: %d VPI: %d VCI: %d
\n
"
,
size
,
le16_to_cpu
(
header
->
vpi
),
le16_to_cpu
(
header
->
vci
));
print_buffer
(
oldskb
);
}
...
...
@@ -1262,7 +1245,7 @@ static int atm_init(struct solos_card *card, struct device *parent)
card
->
atmdev
[
i
]
->
ci_range
.
vci_bits
=
16
;
card
->
atmdev
[
i
]
->
dev_data
=
card
;
card
->
atmdev
[
i
]
->
phy_data
=
(
void
*
)(
unsigned
long
)
i
;
atm_dev_signal_change
(
card
->
atmdev
[
i
],
ATM_PHY_SIG_
UNKNOWN
);
atm_dev_signal_change
(
card
->
atmdev
[
i
],
ATM_PHY_SIG_
FOUND
);
skb
=
alloc_skb
(
sizeof
(
*
header
),
GFP_ATOMIC
);
if
(
!
skb
)
{
...
...
drivers/connector/cn_queue.c
浏览文件 @
4e700bcd
...
...
@@ -31,24 +31,9 @@
#include <linux/connector.h>
#include <linux/delay.h>
void
cn_queue_wrapper
(
struct
work_struct
*
work
)
{
struct
cn_callback_entry
*
cbq
=
container_of
(
work
,
struct
cn_callback_entry
,
work
);
struct
cn_callback_data
*
d
=
&
cbq
->
data
;
struct
cn_msg
*
msg
=
NLMSG_DATA
(
nlmsg_hdr
(
d
->
skb
));
struct
netlink_skb_parms
*
nsp
=
&
NETLINK_CB
(
d
->
skb
);
d
->
callback
(
msg
,
nsp
);
kfree_skb
(
d
->
skb
);
d
->
skb
=
NULL
;
kfree
(
d
->
free
);
}
static
struct
cn_callback_entry
*
cn_queue_alloc_callback_entry
(
const
char
*
name
,
struct
cb_id
*
id
,
cn_queue_alloc_callback_entry
(
struct
cn_queue_dev
*
dev
,
const
char
*
name
,
struct
cb_id
*
id
,
void
(
*
callback
)(
struct
cn_msg
*
,
struct
netlink_skb_parms
*
))
{
struct
cn_callback_entry
*
cbq
;
...
...
@@ -59,17 +44,23 @@ cn_queue_alloc_callback_entry(const char *name, struct cb_id *id,
return
NULL
;
}
atomic_set
(
&
cbq
->
refcnt
,
1
);
atomic_inc
(
&
dev
->
refcnt
);
cbq
->
pdev
=
dev
;
snprintf
(
cbq
->
id
.
name
,
sizeof
(
cbq
->
id
.
name
),
"%s"
,
name
);
memcpy
(
&
cbq
->
id
.
id
,
id
,
sizeof
(
struct
cb_id
));
cbq
->
data
.
callback
=
callback
;
INIT_WORK
(
&
cbq
->
work
,
&
cn_queue_wrapper
);
cbq
->
callback
=
callback
;
return
cbq
;
}
static
void
cn_queue_fre
e_callback
(
struct
cn_callback_entry
*
cbq
)
void
cn_queue_releas
e_callback
(
struct
cn_callback_entry
*
cbq
)
{
flush_workqueue
(
cbq
->
pdev
->
cn_queue
);
if
(
!
atomic_dec_and_test
(
&
cbq
->
refcnt
))
return
;
atomic_dec
(
&
cbq
->
pdev
->
refcnt
);
kfree
(
cbq
);
}
...
...
@@ -85,13 +76,10 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
struct
cn_callback_entry
*
cbq
,
*
__cbq
;
int
found
=
0
;
cbq
=
cn_queue_alloc_callback_entry
(
name
,
id
,
callback
);
cbq
=
cn_queue_alloc_callback_entry
(
dev
,
name
,
id
,
callback
);
if
(
!
cbq
)
return
-
ENOMEM
;
atomic_inc
(
&
dev
->
refcnt
);
cbq
->
pdev
=
dev
;
spin_lock_bh
(
&
dev
->
queue_lock
);
list_for_each_entry
(
__cbq
,
&
dev
->
queue_list
,
callback_entry
)
{
if
(
cn_cb_equal
(
&
__cbq
->
id
.
id
,
id
))
{
...
...
@@ -104,8 +92,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
spin_unlock_bh
(
&
dev
->
queue_lock
);
if
(
found
)
{
cn_queue_free_callback
(
cbq
);
atomic_dec
(
&
dev
->
refcnt
);
cn_queue_release_callback
(
cbq
);
return
-
EINVAL
;
}
...
...
@@ -130,10 +117,8 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id)
}
spin_unlock_bh
(
&
dev
->
queue_lock
);
if
(
found
)
{
cn_queue_free_callback
(
cbq
);
atomic_dec
(
&
dev
->
refcnt
);
}
if
(
found
)
cn_queue_release_callback
(
cbq
);
}
struct
cn_queue_dev
*
cn_queue_alloc_dev
(
const
char
*
name
,
struct
sock
*
nls
)
...
...
@@ -151,12 +136,6 @@ struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls)
dev
->
nls
=
nls
;
dev
->
cn_queue
=
alloc_ordered_workqueue
(
dev
->
name
,
0
);
if
(
!
dev
->
cn_queue
)
{
kfree
(
dev
);
return
NULL
;
}
return
dev
;
}
...
...
@@ -164,9 +143,6 @@ void cn_queue_free_dev(struct cn_queue_dev *dev)
{
struct
cn_callback_entry
*
cbq
,
*
n
;
flush_workqueue
(
dev
->
cn_queue
);
destroy_workqueue
(
dev
->
cn_queue
);
spin_lock_bh
(
&
dev
->
queue_lock
);
list_for_each_entry_safe
(
cbq
,
n
,
&
dev
->
queue_list
,
callback_entry
)
list_del
(
&
cbq
->
callback_entry
);
...
...
drivers/connector/connector.c
浏览文件 @
4e700bcd
...
...
@@ -122,51 +122,28 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
*/
static
int
cn_call_callback
(
struct
sk_buff
*
skb
)
{
struct
cn_callback_entry
*
__cbq
,
*
__new_cbq
;
struct
cn_callback_entry
*
i
,
*
cbq
=
NULL
;
struct
cn_dev
*
dev
=
&
cdev
;
struct
cn_msg
*
msg
=
NLMSG_DATA
(
nlmsg_hdr
(
skb
));
struct
netlink_skb_parms
*
nsp
=
&
NETLINK_CB
(
skb
);
int
err
=
-
ENODEV
;
spin_lock_bh
(
&
dev
->
cbdev
->
queue_lock
);
list_for_each_entry
(
__cbq
,
&
dev
->
cbdev
->
queue_list
,
callback_entry
)
{
if
(
cn_cb_equal
(
&
__cbq
->
id
.
id
,
&
msg
->
id
))
{
if
(
likely
(
!
work_pending
(
&
__cbq
->
work
)
&&
__cbq
->
data
.
skb
==
NULL
))
{
__cbq
->
data
.
skb
=
skb
;
if
(
queue_work
(
dev
->
cbdev
->
cn_queue
,
&
__cbq
->
work
))
err
=
0
;
else
err
=
-
EINVAL
;
}
else
{
struct
cn_callback_data
*
d
;
err
=
-
ENOMEM
;
__new_cbq
=
kzalloc
(
sizeof
(
struct
cn_callback_entry
),
GFP_ATOMIC
);
if
(
__new_cbq
)
{
d
=
&
__new_cbq
->
data
;
d
->
skb
=
skb
;
d
->
callback
=
__cbq
->
data
.
callback
;
d
->
free
=
__new_cbq
;
INIT_WORK
(
&
__new_cbq
->
work
,
&
cn_queue_wrapper
);
if
(
queue_work
(
dev
->
cbdev
->
cn_queue
,
&
__new_cbq
->
work
))
err
=
0
;
else
{
kfree
(
__new_cbq
);
err
=
-
EINVAL
;
}
}
}
list_for_each_entry
(
i
,
&
dev
->
cbdev
->
queue_list
,
callback_entry
)
{
if
(
cn_cb_equal
(
&
i
->
id
.
id
,
&
msg
->
id
))
{
atomic_inc
(
&
i
->
refcnt
);
cbq
=
i
;
break
;
}
}
spin_unlock_bh
(
&
dev
->
cbdev
->
queue_lock
);
if
(
cbq
!=
NULL
)
{
cbq
->
callback
(
msg
,
nsp
);
kfree_skb
(
skb
);
cn_queue_release_callback
(
cbq
);
}
return
err
;
}
...
...
drivers/net/atlx/atl2.c
浏览文件 @
4e700bcd
...
...
@@ -1996,13 +1996,15 @@ static int atl2_set_eeprom(struct net_device *netdev,
if
(
!
eeprom_buff
)
return
-
ENOMEM
;
ptr
=
(
u32
*
)
eeprom_buff
;
ptr
=
eeprom_buff
;
if
(
eeprom
->
offset
&
3
)
{
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
if
(
!
atl2_read_eeprom
(
hw
,
first_dword
*
4
,
&
(
eeprom_buff
[
0
])))
return
-
EIO
;
if
(
!
atl2_read_eeprom
(
hw
,
first_dword
*
4
,
&
(
eeprom_buff
[
0
])))
{
ret_val
=
-
EIO
;
goto
out
;
}
ptr
++
;
}
if
(((
eeprom
->
offset
+
eeprom
->
len
)
&
3
))
{
...
...
@@ -2011,18 +2013,22 @@ static int atl2_set_eeprom(struct net_device *netdev,
* only the first byte of the word is being modified
*/
if
(
!
atl2_read_eeprom
(
hw
,
last_dword
*
4
,
&
(
eeprom_buff
[
last_dword
-
first_dword
])))
return
-
EIO
;
&
(
eeprom_buff
[
last_dword
-
first_dword
])))
{
ret_val
=
-
EIO
;
goto
out
;
}
}
/* Device's eeprom is always little-endian, word addressable */
memcpy
(
ptr
,
bytes
,
eeprom
->
len
);
for
(
i
=
0
;
i
<
last_dword
-
first_dword
+
1
;
i
++
)
{
if
(
!
atl2_write_eeprom
(
hw
,
((
first_dword
+
i
)
*
4
),
eeprom_buff
[
i
]))
return
-
EIO
;
if
(
!
atl2_write_eeprom
(
hw
,
((
first_dword
+
i
)
*
4
),
eeprom_buff
[
i
]))
{
ret_val
=
-
EIO
;
goto
out
;
}
}
out:
kfree
(
eeprom_buff
);
return
ret_val
;
}
...
...
drivers/net/irda/via-ircc.c
浏览文件 @
4e700bcd
...
...
@@ -75,15 +75,9 @@ static int dongle_id = 0; /* default: probe */
/* We can't guess the type of connected dongle, user *must* supply it. */
module_param
(
dongle_id
,
int
,
0
);
/* FIXME : we should not need this, because instances should be automatically
* managed by the PCI layer. Especially that we seem to only be using the
* first entry. Jean II */
/* Max 4 instances for now */
static
struct
via_ircc_cb
*
dev_self
[]
=
{
NULL
,
NULL
,
NULL
,
NULL
};
/* Some prototypes */
static
int
via_ircc_open
(
int
i
,
chipio_t
*
info
,
unsigned
int
id
);
static
int
via_ircc_close
(
struct
via_ircc_cb
*
self
);
static
int
via_ircc_open
(
struct
pci_dev
*
pdev
,
chipio_t
*
info
,
unsigned
int
id
);
static
int
via_ircc_dma_receive
(
struct
via_ircc_cb
*
self
);
static
int
via_ircc_dma_receive_complete
(
struct
via_ircc_cb
*
self
,
int
iobase
);
...
...
@@ -215,7 +209,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi
pci_write_config_byte
(
pcidev
,
0x42
,(
bTmp
|
0xf0
));
pci_write_config_byte
(
pcidev
,
0x5a
,
0xc0
);
WriteLPCReg
(
0x28
,
0x70
);
if
(
via_ircc_open
(
0
,
&
info
,
0x3076
)
==
0
)
if
(
via_ircc_open
(
pcidev
,
&
info
,
0x3076
)
==
0
)
rc
=
0
;
}
else
rc
=
-
ENODEV
;
//IR not turn on
...
...
@@ -254,7 +248,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi
info
.
irq
=
FirIRQ
;
info
.
dma
=
FirDRQ1
;
info
.
dma2
=
FirDRQ0
;
if
(
via_ircc_open
(
0
,
&
info
,
0x3096
)
==
0
)
if
(
via_ircc_open
(
pcidev
,
&
info
,
0x3096
)
==
0
)
rc
=
0
;
}
else
rc
=
-
ENODEV
;
//IR not turn on !!!!!
...
...
@@ -264,48 +258,10 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi
return
rc
;
}
/*
* Function via_ircc_clean ()
*
* Close all configured chips
*
*/
static
void
via_ircc_clean
(
void
)
{
int
i
;
IRDA_DEBUG
(
3
,
"%s()
\n
"
,
__func__
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
dev_self
);
i
++
)
{
if
(
dev_self
[
i
])
via_ircc_close
(
dev_self
[
i
]);
}
}
static
void
__devexit
via_remove_one
(
struct
pci_dev
*
pdev
)
{
IRDA_DEBUG
(
3
,
"%s()
\n
"
,
__func__
);
/* FIXME : This is ugly. We should use pci_get_drvdata(pdev);
* to get our driver instance and call directly via_ircc_close().
* See vlsi_ir for details...
* Jean II */
via_ircc_clean
();
/* FIXME : This should be in via_ircc_close(), because here we may
* theoritically disable still configured devices :-( - Jean II */
pci_disable_device
(
pdev
);
}
static
void
__exit
via_ircc_cleanup
(
void
)
{
IRDA_DEBUG
(
3
,
"%s()
\n
"
,
__func__
);
/* FIXME : This should be redundant, as pci_unregister_driver()
* should call via_remove_one() on each device.
* Jean II */
via_ircc_clean
();
/* Cleanup all instances of the driver */
pci_unregister_driver
(
&
via_driver
);
}
...
...
@@ -324,12 +280,13 @@ static const struct net_device_ops via_ircc_fir_ops = {
};
/*
* Function via_ircc_open
(
iobase, irq)
* Function via_ircc_open
(pdev,
iobase, irq)
*
* Open driver instance
*
*/
static
__devinit
int
via_ircc_open
(
int
i
,
chipio_t
*
info
,
unsigned
int
id
)
static
__devinit
int
via_ircc_open
(
struct
pci_dev
*
pdev
,
chipio_t
*
info
,
unsigned
int
id
)
{
struct
net_device
*
dev
;
struct
via_ircc_cb
*
self
;
...
...
@@ -337,9 +294,6 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
IRDA_DEBUG
(
3
,
"%s()
\n
"
,
__func__
);
if
(
i
>=
ARRAY_SIZE
(
dev_self
))
return
-
ENOMEM
;
/* Allocate new instance of the driver */
dev
=
alloc_irdadev
(
sizeof
(
struct
via_ircc_cb
));
if
(
dev
==
NULL
)
...
...
@@ -349,13 +303,8 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
self
->
netdev
=
dev
;
spin_lock_init
(
&
self
->
lock
);
/* FIXME : We should store our driver instance in the PCI layer,
* using pci_set_drvdata(), not in this array.
* See vlsi_ir for details... - Jean II */
/* FIXME : 'i' is always 0 (see via_init_one()) :-( - Jean II */
/* Need to store self somewhere */
dev_self
[
i
]
=
self
;
self
->
index
=
i
;
pci_set_drvdata
(
pdev
,
self
);
/* Initialize Resource */
self
->
io
.
cfg_base
=
info
->
cfg_base
;
self
->
io
.
fir_base
=
info
->
fir_base
;
...
...
@@ -414,7 +363,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
/* Allocate memory if needed */
self
->
rx_buff
.
head
=
dma_alloc_coherent
(
NULL
,
self
->
rx_buff
.
truesize
,
dma_alloc_coherent
(
&
pdev
->
dev
,
self
->
rx_buff
.
truesize
,
&
self
->
rx_buff_dma
,
GFP_KERNEL
);
if
(
self
->
rx_buff
.
head
==
NULL
)
{
err
=
-
ENOMEM
;
...
...
@@ -423,7 +372,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
memset
(
self
->
rx_buff
.
head
,
0
,
self
->
rx_buff
.
truesize
);
self
->
tx_buff
.
head
=
dma_alloc_coherent
(
NULL
,
self
->
tx_buff
.
truesize
,
dma_alloc_coherent
(
&
pdev
->
dev
,
self
->
tx_buff
.
truesize
,
&
self
->
tx_buff_dma
,
GFP_KERNEL
);
if
(
self
->
tx_buff
.
head
==
NULL
)
{
err
=
-
ENOMEM
;
...
...
@@ -455,33 +404,32 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
via_hw_init
(
self
);
return
0
;
err_out4:
dma_free_coherent
(
NULL
,
self
->
tx_buff
.
truesize
,
dma_free_coherent
(
&
pdev
->
dev
,
self
->
tx_buff
.
truesize
,
self
->
tx_buff
.
head
,
self
->
tx_buff_dma
);
err_out3:
dma_free_coherent
(
NULL
,
self
->
rx_buff
.
truesize
,
dma_free_coherent
(
&
pdev
->
dev
,
self
->
rx_buff
.
truesize
,
self
->
rx_buff
.
head
,
self
->
rx_buff_dma
);
err_out2:
release_region
(
self
->
io
.
fir_base
,
self
->
io
.
fir_ext
);
err_out1:
pci_set_drvdata
(
pdev
,
NULL
);
free_netdev
(
dev
);
dev_self
[
i
]
=
NULL
;
return
err
;
}
/*
* Function via_
ircc_close (self
)
* Function via_
remove_one(pdev
)
*
* Close driver instance
*
*/
static
int
via_ircc_close
(
struct
via_ircc_cb
*
self
)
static
void
__devexit
via_remove_one
(
struct
pci_dev
*
pdev
)
{
struct
via_ircc_cb
*
self
=
pci_get_drvdata
(
pdev
);
int
iobase
;
IRDA_DEBUG
(
3
,
"%s()
\n
"
,
__func__
);
IRDA_ASSERT
(
self
!=
NULL
,
return
-
1
;);
iobase
=
self
->
io
.
fir_base
;
ResetChip
(
iobase
,
5
);
//hardware reset.
...
...
@@ -493,16 +441,16 @@ static int via_ircc_close(struct via_ircc_cb *self)
__func__
,
self
->
io
.
fir_base
);
release_region
(
self
->
io
.
fir_base
,
self
->
io
.
fir_ext
);
if
(
self
->
tx_buff
.
head
)
dma_free_coherent
(
NULL
,
self
->
tx_buff
.
truesize
,
dma_free_coherent
(
&
pdev
->
dev
,
self
->
tx_buff
.
truesize
,
self
->
tx_buff
.
head
,
self
->
tx_buff_dma
);
if
(
self
->
rx_buff
.
head
)
dma_free_coherent
(
NULL
,
self
->
rx_buff
.
truesize
,
dma_free_coherent
(
&
pdev
->
dev
,
self
->
rx_buff
.
truesize
,
self
->
rx_buff
.
head
,
self
->
rx_buff_dma
);
dev_self
[
self
->
index
]
=
NULL
;
pci_set_drvdata
(
pdev
,
NULL
)
;
free_netdev
(
self
->
netdev
);
return
0
;
pci_disable_device
(
pdev
)
;
}
/*
...
...
drivers/net/phy/phy_device.c
浏览文件 @
4e700bcd
...
...
@@ -442,11 +442,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
u32
flags
,
phy_interface_t
interface
)
{
struct
device
*
d
=
&
phydev
->
dev
;
int
err
;
/* Assume that if there is no driver, that it doesn't
* exist, and we should use the genphy driver. */
if
(
NULL
==
d
->
driver
)
{
int
err
;
d
->
driver
=
&
genphy_driver
.
driver
;
err
=
d
->
driver
->
probe
(
d
);
...
...
@@ -474,7 +474,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
/* Do initial configuration here, now that
* we have certain key parameters
* (dev_flags and interface) */
return
phy_init_hw
(
phydev
);
err
=
phy_init_hw
(
phydev
);
if
(
err
)
phy_detach
(
phydev
);
return
err
;
}
/**
...
...
drivers/net/usb/Kconfig
浏览文件 @
4e700bcd
...
...
@@ -433,4 +433,19 @@ config USB_SIERRA_NET
To compile this driver as a module, choose M here: the
module will be called sierra_net.
config USB_VL600
tristate "LG VL600 modem dongle"
depends on USB_NET_CDCETHER
select USB_ACM
help
Select this if you want to use an LG Electronics 4G/LTE usb modem
called VL600. This driver only handles the ethernet
interface exposed by the modem firmware. To establish a connection
you will first need a userspace program that sends the right
command to the modem through its CDC ACM port, and most
likely also a DHCP client. See this thread about using the
4G modem from Verizon:
http://ubuntuforums.org/showpost.php?p=10589647&postcount=17
endmenu
drivers/net/usb/Makefile
浏览文件 @
4e700bcd
...
...
@@ -27,4 +27,5 @@ obj-$(CONFIG_USB_IPHETH) += ipheth.o
obj-$(CONFIG_USB_SIERRA_NET)
+=
sierra_net.o
obj-$(CONFIG_USB_NET_CX82310_ETH)
+=
cx82310_eth.o
obj-$(CONFIG_USB_NET_CDC_NCM)
+=
cdc_ncm.o
obj-$(CONFIG_USB_VL600)
+=
lg-vl600.o
drivers/net/usb/cdc_ether.c
浏览文件 @
4e700bcd
...
...
@@ -378,7 +378,7 @@ static void dumpspeed(struct usbnet *dev, __le32 *speeds)
__le32_to_cpu
(
speeds
[
1
])
/
1000
);
}
static
void
cdc_status
(
struct
usbnet
*
dev
,
struct
urb
*
urb
)
void
usbnet_
cdc_status
(
struct
usbnet
*
dev
,
struct
urb
*
urb
)
{
struct
usb_cdc_notification
*
event
;
...
...
@@ -418,8 +418,9 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
break
;
}
}
EXPORT_SYMBOL_GPL
(
usbnet_cdc_status
);
static
int
cdc_bind
(
struct
usbnet
*
dev
,
struct
usb_interface
*
intf
)
int
usbnet_
cdc_bind
(
struct
usbnet
*
dev
,
struct
usb_interface
*
intf
)
{
int
status
;
struct
cdc_state
*
info
=
(
void
*
)
&
dev
->
data
;
...
...
@@ -441,6 +442,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
*/
return
0
;
}
EXPORT_SYMBOL_GPL
(
usbnet_cdc_bind
);
static
int
cdc_manage_power
(
struct
usbnet
*
dev
,
int
on
)
{
...
...
@@ -452,18 +454,18 @@ static const struct driver_info cdc_info = {
.
description
=
"CDC Ethernet Device"
,
.
flags
=
FLAG_ETHER
,
// .check_connect = cdc_check_connect,
.
bind
=
cdc_bind
,
.
bind
=
usbnet_
cdc_bind
,
.
unbind
=
usbnet_cdc_unbind
,
.
status
=
cdc_status
,
.
status
=
usbnet_
cdc_status
,
.
manage_power
=
cdc_manage_power
,
};
static
const
struct
driver_info
mbm_info
=
{
.
description
=
"Mobile Broadband Network Device"
,
.
flags
=
FLAG_WWAN
,
.
bind
=
cdc_bind
,
.
bind
=
usbnet_
cdc_bind
,
.
unbind
=
usbnet_cdc_unbind
,
.
status
=
cdc_status
,
.
status
=
usbnet_
cdc_status
,
.
manage_power
=
cdc_manage_power
,
};
...
...
@@ -560,6 +562,13 @@ static const struct usb_device_id products [] = {
.
driver_info
=
0
,
},
/* LG Electronics VL600 wants additional headers on every frame */
{
USB_DEVICE_AND_INTERFACE_INFO
(
0x1004
,
0x61aa
,
USB_CLASS_COMM
,
USB_CDC_SUBCLASS_ETHERNET
,
USB_CDC_PROTO_NONE
),
.
driver_info
=
0
,
},
/*
* WHITELIST!!!
*
...
...
drivers/net/usb/lg-vl600.c
0 → 100644
浏览文件 @
4e700bcd
/*
* Ethernet interface part of the LG VL600 LTE modem (4G dongle)
*
* Copyright (C) 2011 Intel Corporation
* Author: Andrzej Zaborowski <balrogg@gmail.com>
*
* This program is free software; you can redistribute 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/usb/cdc.h>
#include <linux/usb/usbnet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/inetdevice.h>
/*
* The device has a CDC ACM port for modem control (it claims to be
* CDC ACM anyway) and a CDC Ethernet port for actual network data.
* It will however ignore data on both ports that is not encapsulated
* in a specific way, any data returned is also encapsulated the same
* way. The headers don't seem to follow any popular standard.
*
* This driver adds and strips these headers from the ethernet frames
* sent/received from the CDC Ethernet port. The proprietary header
* replaces the standard ethernet header in a packet so only actual
* ethernet frames are allowed. The headers allow some form of
* multiplexing by using non standard values of the .h_proto field.
* Windows/Mac drivers do send a couple of such frames to the device
* during initialisation, with protocol set to 0x0906 or 0x0b06 and (what
* seems to be) a flag in the .dummy_flags. This doesn't seem necessary
* for modem operation but can possibly be used for GPS or other funcitons.
*/
struct
vl600_frame_hdr
{
__le32
len
;
__le32
serial
;
__le32
pkt_cnt
;
__le32
dummy_flags
;
__le32
dummy
;
__le32
magic
;
}
__attribute__
((
packed
));
struct
vl600_pkt_hdr
{
__le32
dummy
[
2
];
__le32
len
;
__be16
h_proto
;
}
__attribute__
((
packed
));
struct
vl600_state
{
struct
sk_buff
*
current_rx_buf
;
};
static
int
vl600_bind
(
struct
usbnet
*
dev
,
struct
usb_interface
*
intf
)
{
int
ret
;
struct
vl600_state
*
s
=
kzalloc
(
sizeof
(
struct
vl600_state
),
GFP_KERNEL
);
if
(
!
s
)
return
-
ENOMEM
;
ret
=
usbnet_cdc_bind
(
dev
,
intf
);
if
(
ret
)
{
kfree
(
s
);
return
ret
;
}
dev
->
driver_priv
=
s
;
/* ARP packets don't go through, but they're also of no use. The
* subnet has only two hosts anyway: us and the gateway / DHCP
* server (probably simulated by modem firmware or network operator)
* whose address changes everytime we connect to the intarwebz and
* who doesn't bother answering ARP requests either. So hardware
* addresses have no meaning, the destination and the source of every
* packet depend only on whether it is on the IN or OUT endpoint. */
dev
->
net
->
flags
|=
IFF_NOARP
;
return
ret
;
}
static
void
vl600_unbind
(
struct
usbnet
*
dev
,
struct
usb_interface
*
intf
)
{
struct
vl600_state
*
s
=
dev
->
driver_priv
;
if
(
s
->
current_rx_buf
)
dev_kfree_skb
(
s
->
current_rx_buf
);
kfree
(
s
);
return
usbnet_cdc_unbind
(
dev
,
intf
);
}
static
int
vl600_rx_fixup
(
struct
usbnet
*
dev
,
struct
sk_buff
*
skb
)
{
struct
vl600_frame_hdr
*
frame
;
struct
vl600_pkt_hdr
*
packet
;
struct
ethhdr
*
ethhdr
;
int
packet_len
,
count
;
struct
sk_buff
*
buf
=
skb
;
struct
sk_buff
*
clone
;
struct
vl600_state
*
s
=
dev
->
driver_priv
;
/* Frame lengths are generally 4B multiplies but every couple of
* hours there's an odd number of bytes sized yet correct frame,
* so don't require this. */
/* Allow a packet (or multiple packets batched together) to be
* split across many frames. We don't allow a new batch to
* begin in the same frame another one is ending however, and no
* leading or trailing pad bytes. */
if
(
s
->
current_rx_buf
)
{
frame
=
(
struct
vl600_frame_hdr
*
)
s
->
current_rx_buf
->
data
;
if
(
skb
->
len
+
s
->
current_rx_buf
->
len
>
le32_to_cpup
(
&
frame
->
len
))
{
netif_err
(
dev
,
ifup
,
dev
->
net
,
"Fragment too long
\n
"
);
dev
->
net
->
stats
.
rx_length_errors
++
;
goto
error
;
}
buf
=
s
->
current_rx_buf
;
memcpy
(
skb_put
(
buf
,
skb
->
len
),
skb
->
data
,
skb
->
len
);
}
else
if
(
skb
->
len
<
4
)
{
netif_err
(
dev
,
ifup
,
dev
->
net
,
"Frame too short
\n
"
);
dev
->
net
->
stats
.
rx_length_errors
++
;
goto
error
;
}
frame
=
(
struct
vl600_frame_hdr
*
)
buf
->
data
;
/* NOTE: Should check that frame->magic == 0x53544448?
* Otherwise if we receive garbage at the beginning of the frame
* we may end up allocating a huge buffer and saving all the
* future incoming data into it. */
if
(
buf
->
len
<
sizeof
(
*
frame
)
||
buf
->
len
!=
le32_to_cpup
(
&
frame
->
len
))
{
/* Save this fragment for later assembly */
if
(
s
->
current_rx_buf
)
return
0
;
s
->
current_rx_buf
=
skb_copy_expand
(
skb
,
0
,
le32_to_cpup
(
&
frame
->
len
),
GFP_ATOMIC
);
if
(
!
s
->
current_rx_buf
)
{
netif_err
(
dev
,
ifup
,
dev
->
net
,
"Reserving %i bytes "
"for packet assembly failed.
\n
"
,
le32_to_cpup
(
&
frame
->
len
));
dev
->
net
->
stats
.
rx_errors
++
;
}
return
0
;
}
count
=
le32_to_cpup
(
&
frame
->
pkt_cnt
);
skb_pull
(
buf
,
sizeof
(
*
frame
));
while
(
count
--
)
{
if
(
buf
->
len
<
sizeof
(
*
packet
))
{
netif_err
(
dev
,
ifup
,
dev
->
net
,
"Packet too short
\n
"
);
goto
error
;
}
packet
=
(
struct
vl600_pkt_hdr
*
)
buf
->
data
;
packet_len
=
sizeof
(
*
packet
)
+
le32_to_cpup
(
&
packet
->
len
);
if
(
packet_len
>
buf
->
len
)
{
netif_err
(
dev
,
ifup
,
dev
->
net
,
"Bad packet length stored in header
\n
"
);
goto
error
;
}
/* Packet header is same size as the ethernet header
* (sizeof(*packet) == sizeof(*ethhdr)), additionally
* the h_proto field is in the same place so we just leave it
* alone and fill in the remaining fields.
*/
ethhdr
=
(
struct
ethhdr
*
)
skb
->
data
;
if
(
be16_to_cpup
(
&
ethhdr
->
h_proto
)
==
ETH_P_ARP
&&
buf
->
len
>
0x26
)
{
/* Copy the addresses from packet contents */
memcpy
(
ethhdr
->
h_source
,
&
buf
->
data
[
sizeof
(
*
ethhdr
)
+
0x8
],
ETH_ALEN
);
memcpy
(
ethhdr
->
h_dest
,
&
buf
->
data
[
sizeof
(
*
ethhdr
)
+
0x12
],
ETH_ALEN
);
}
else
{
memset
(
ethhdr
->
h_source
,
0
,
ETH_ALEN
);
memcpy
(
ethhdr
->
h_dest
,
dev
->
net
->
dev_addr
,
ETH_ALEN
);
}
if
(
count
)
{
/* Not the last packet in this batch */
clone
=
skb_clone
(
buf
,
GFP_ATOMIC
);
if
(
!
clone
)
goto
error
;
skb_trim
(
clone
,
packet_len
);
usbnet_skb_return
(
dev
,
clone
);
skb_pull
(
buf
,
(
packet_len
+
3
)
&
~
3
);
}
else
{
skb_trim
(
buf
,
packet_len
);
if
(
s
->
current_rx_buf
)
{
usbnet_skb_return
(
dev
,
buf
);
s
->
current_rx_buf
=
NULL
;
return
0
;
}
return
1
;
}
}
error:
if
(
s
->
current_rx_buf
)
{
dev_kfree_skb_any
(
s
->
current_rx_buf
);
s
->
current_rx_buf
=
NULL
;
}
dev
->
net
->
stats
.
rx_errors
++
;
return
0
;
}
static
struct
sk_buff
*
vl600_tx_fixup
(
struct
usbnet
*
dev
,
struct
sk_buff
*
skb
,
gfp_t
flags
)
{
struct
sk_buff
*
ret
;
struct
vl600_frame_hdr
*
frame
;
struct
vl600_pkt_hdr
*
packet
;
static
uint32_t
serial
=
1
;
int
orig_len
=
skb
->
len
-
sizeof
(
struct
ethhdr
);
int
full_len
=
(
skb
->
len
+
sizeof
(
struct
vl600_frame_hdr
)
+
3
)
&
~
3
;
frame
=
(
struct
vl600_frame_hdr
*
)
skb
->
data
;
if
(
skb
->
len
>
sizeof
(
*
frame
)
&&
skb
->
len
==
le32_to_cpup
(
&
frame
->
len
))
return
skb
;
/* Already encapsulated? */
if
(
skb
->
len
<
sizeof
(
struct
ethhdr
))
/* Drop, device can only deal with ethernet packets */
return
NULL
;
if
(
!
skb_cloned
(
skb
))
{
int
headroom
=
skb_headroom
(
skb
);
int
tailroom
=
skb_tailroom
(
skb
);
if
(
tailroom
>=
full_len
-
skb
->
len
-
sizeof
(
*
frame
)
&&
headroom
>=
sizeof
(
*
frame
))
/* There's enough head and tail room */
goto
encapsulate
;
if
(
headroom
+
tailroom
+
skb
->
len
>=
full_len
)
{
/* There's enough total room, just readjust */
skb
->
data
=
memmove
(
skb
->
head
+
sizeof
(
*
frame
),
skb
->
data
,
skb
->
len
);
skb_set_tail_pointer
(
skb
,
skb
->
len
);
goto
encapsulate
;
}
}
/* Alloc a new skb with the required size */
ret
=
skb_copy_expand
(
skb
,
sizeof
(
struct
vl600_frame_hdr
),
full_len
-
skb
->
len
-
sizeof
(
struct
vl600_frame_hdr
),
flags
);
dev_kfree_skb_any
(
skb
);
if
(
!
ret
)
return
ret
;
skb
=
ret
;
encapsulate:
/* Packet header is same size as ethernet packet header
* (sizeof(*packet) == sizeof(struct ethhdr)), additionally the
* h_proto field is in the same place so we just leave it alone and
* overwrite the remaining fields.
*/
packet
=
(
struct
vl600_pkt_hdr
*
)
skb
->
data
;
memset
(
&
packet
->
dummy
,
0
,
sizeof
(
packet
->
dummy
));
packet
->
len
=
cpu_to_le32
(
orig_len
);
frame
=
(
struct
vl600_frame_hdr
*
)
skb_push
(
skb
,
sizeof
(
*
frame
));
memset
(
frame
,
0
,
sizeof
(
*
frame
));
frame
->
len
=
cpu_to_le32
(
full_len
);
frame
->
serial
=
cpu_to_le32
(
serial
++
);
frame
->
pkt_cnt
=
cpu_to_le32
(
1
);
if
(
skb
->
len
<
full_len
)
/* Pad */
skb_put
(
skb
,
full_len
-
skb
->
len
);
return
skb
;
}
static
const
struct
driver_info
vl600_info
=
{
.
description
=
"LG VL600 modem"
,
.
flags
=
FLAG_ETHER
|
FLAG_RX_ASSEMBLE
,
.
bind
=
vl600_bind
,
.
unbind
=
vl600_unbind
,
.
status
=
usbnet_cdc_status
,
.
rx_fixup
=
vl600_rx_fixup
,
.
tx_fixup
=
vl600_tx_fixup
,
};
static
const
struct
usb_device_id
products
[]
=
{
{
USB_DEVICE_AND_INTERFACE_INFO
(
0x1004
,
0x61aa
,
USB_CLASS_COMM
,
USB_CDC_SUBCLASS_ETHERNET
,
USB_CDC_PROTO_NONE
),
.
driver_info
=
(
unsigned
long
)
&
vl600_info
,
},
{},
/* End */
};
MODULE_DEVICE_TABLE
(
usb
,
products
);
static
struct
usb_driver
lg_vl600_driver
=
{
.
name
=
"lg-vl600"
,
.
id_table
=
products
,
.
probe
=
usbnet_probe
,
.
disconnect
=
usbnet_disconnect
,
.
suspend
=
usbnet_suspend
,
.
resume
=
usbnet_resume
,
};
static
int
__init
vl600_init
(
void
)
{
return
usb_register
(
&
lg_vl600_driver
);
}
module_init
(
vl600_init
);
static
void
__exit
vl600_exit
(
void
)
{
usb_deregister
(
&
lg_vl600_driver
);
}
module_exit
(
vl600_exit
);
MODULE_AUTHOR
(
"Anrzej Zaborowski"
);
MODULE_DESCRIPTION
(
"LG-VL600 modem's ethernet link"
);
MODULE_LICENSE
(
"GPL"
);
drivers/net/usb/usbnet.c
浏览文件 @
4e700bcd
...
...
@@ -387,8 +387,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
static
inline
void
rx_process
(
struct
usbnet
*
dev
,
struct
sk_buff
*
skb
)
{
if
(
dev
->
driver_info
->
rx_fixup
&&
!
dev
->
driver_info
->
rx_fixup
(
dev
,
skb
))
goto
error
;
!
dev
->
driver_info
->
rx_fixup
(
dev
,
skb
))
{
/* With RX_ASSEMBLE, rx_fixup() must update counters */
if
(
!
(
dev
->
driver_info
->
flags
&
FLAG_RX_ASSEMBLE
))
dev
->
net
->
stats
.
rx_errors
++
;
goto
done
;
}
// else network stack removes extra byte if we forced a short packet
if
(
skb
->
len
)
{
...
...
@@ -401,8 +405,8 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
}
netif_dbg
(
dev
,
rx_err
,
dev
->
net
,
"drop
\n
"
);
error:
dev
->
net
->
stats
.
rx_errors
++
;
done:
skb_queue_tail
(
&
dev
->
done
,
skb
);
}
...
...
include/linux/atmdev.h
浏览文件 @
4e700bcd
...
...
@@ -443,6 +443,7 @@ void atm_dev_signal_change(struct atm_dev *dev, char signal);
void
vcc_insert_socket
(
struct
sock
*
sk
);
void
atm_dev_release_vccs
(
struct
atm_dev
*
dev
);
/*
* This is approximately the algorithm used by alloc_skb.
...
...
include/linux/connector.h
浏览文件 @
4e700bcd
...
...
@@ -88,8 +88,6 @@ struct cn_queue_dev {
atomic_t
refcnt
;
unsigned
char
name
[
CN_CBQ_NAMELEN
];
struct
workqueue_struct
*
cn_queue
;
struct
list_head
queue_list
;
spinlock_t
queue_lock
;
...
...
@@ -101,20 +99,13 @@ struct cn_callback_id {
struct
cb_id
id
;
};
struct
cn_callback_data
{
struct
sk_buff
*
skb
;
void
(
*
callback
)
(
struct
cn_msg
*
,
struct
netlink_skb_parms
*
);
void
*
free
;
};
struct
cn_callback_entry
{
struct
list_head
callback_entry
;
struct
work_struct
work
;
atomic_t
refcnt
;
struct
cn_queue_dev
*
pdev
;
struct
cn_callback_id
id
;
struct
cn_callback_data
data
;
void
(
*
callback
)
(
struct
cn_msg
*
,
struct
netlink_skb_parms
*
)
;
u32
seq
,
group
;
};
...
...
@@ -138,13 +129,12 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
struct
cb_id
*
id
,
void
(
*
callback
)(
struct
cn_msg
*
,
struct
netlink_skb_parms
*
));
void
cn_queue_del_callback
(
struct
cn_queue_dev
*
dev
,
struct
cb_id
*
id
);
void
cn_queue_release_callback
(
struct
cn_callback_entry
*
);
struct
cn_queue_dev
*
cn_queue_alloc_dev
(
const
char
*
name
,
struct
sock
*
);
void
cn_queue_free_dev
(
struct
cn_queue_dev
*
dev
);
int
cn_cb_equal
(
struct
cb_id
*
,
struct
cb_id
*
);
void
cn_queue_wrapper
(
struct
work_struct
*
work
);
#endif
/* __KERNEL__ */
#endif
/* __CONNECTOR_H */
include/linux/skbuff.h
浏览文件 @
4e700bcd
...
...
@@ -126,7 +126,7 @@ struct sk_buff;
* GRO uses frags we allocate at least 16 regardless of page size.
*/
#if (65536/PAGE_SIZE + 2) < 16
#define MAX_SKB_FRAGS 16
#define MAX_SKB_FRAGS 16
UL
#else
#define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2)
#endif
...
...
include/linux/usb/usbnet.h
浏览文件 @
4e700bcd
...
...
@@ -102,6 +102,7 @@ struct driver_info {
* Affects statistic (counters) and short packet handling.
*/
#define FLAG_MULTI_PACKET 0x1000
#define FLAG_RX_ASSEMBLE 0x2000
/* rx packets may span >1 frames */
/* init device ... can sleep, or cause probe() failure */
int
(
*
bind
)(
struct
usbnet
*
,
struct
usb_interface
*
);
...
...
@@ -172,7 +173,9 @@ struct cdc_state {
};
extern
int
usbnet_generic_cdc_bind
(
struct
usbnet
*
,
struct
usb_interface
*
);
extern
int
usbnet_cdc_bind
(
struct
usbnet
*
,
struct
usb_interface
*
);
extern
void
usbnet_cdc_unbind
(
struct
usbnet
*
,
struct
usb_interface
*
);
extern
void
usbnet_cdc_status
(
struct
usbnet
*
,
struct
urb
*
);
/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
...
...
include/net/if_inet6.h
浏览文件 @
4e700bcd
...
...
@@ -286,5 +286,21 @@ static inline void ipv6_ib_mc_map(const struct in6_addr *addr,
buf
[
9
]
=
broadcast
[
9
];
memcpy
(
buf
+
10
,
addr
->
s6_addr
+
6
,
10
);
}
static
inline
int
ipv6_ipgre_mc_map
(
const
struct
in6_addr
*
addr
,
const
unsigned
char
*
broadcast
,
char
*
buf
)
{
if
((
broadcast
[
0
]
|
broadcast
[
1
]
|
broadcast
[
2
]
|
broadcast
[
3
])
!=
0
)
{
memcpy
(
buf
,
broadcast
,
4
);
}
else
{
/* v4mapped? */
if
((
addr
->
s6_addr32
[
0
]
|
addr
->
s6_addr32
[
1
]
|
(
addr
->
s6_addr32
[
2
]
^
htonl
(
0x0000ffff
)))
!=
0
)
return
-
EINVAL
;
memcpy
(
buf
,
&
addr
->
s6_addr32
[
3
],
4
);
}
return
0
;
}
#endif
#endif
include/net/ip.h
浏览文件 @
4e700bcd
...
...
@@ -339,6 +339,14 @@ static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, ch
buf
[
16
]
=
addr
&
0x0f
;
}
static
inline
void
ip_ipgre_mc_map
(
__be32
naddr
,
const
unsigned
char
*
broadcast
,
char
*
buf
)
{
if
((
broadcast
[
0
]
|
broadcast
[
1
]
|
broadcast
[
2
]
|
broadcast
[
3
])
!=
0
)
memcpy
(
buf
,
broadcast
,
4
);
else
memcpy
(
buf
,
&
naddr
,
sizeof
(
naddr
));
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#include <linux/ipv6.h>
#endif
...
...
net/atm/common.c
浏览文件 @
4e700bcd
...
...
@@ -252,6 +252,7 @@ void atm_dev_release_vccs(struct atm_dev *dev)
}
write_unlock_irq
(
&
vcc_sklist_lock
);
}
EXPORT_SYMBOL
(
atm_dev_release_vccs
);
static
int
adjust_tp
(
struct
atm_trafprm
*
tp
,
unsigned
char
aal
)
{
...
...
net/bridge/br_multicast.c
浏览文件 @
4e700bcd
...
...
@@ -1475,7 +1475,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
ip6h
->
payload_len
==
0
)
return
0
;
len
=
ntohs
(
ip6h
->
payload_len
);
len
=
ntohs
(
ip6h
->
payload_len
)
+
sizeof
(
*
ip6h
)
;
if
(
skb
->
len
<
len
)
return
-
EINVAL
;
...
...
net/bridge/br_stp_if.c
浏览文件 @
4e700bcd
...
...
@@ -213,7 +213,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br)
/* user has chosen a value so keep it */
if
(
br
->
flags
&
BR_SET_MAC_ADDR
)
return
;
return
false
;
list_for_each_entry
(
p
,
&
br
->
port_list
,
list
)
{
if
(
addr
==
br_mac_zero
||
...
...
net/core/dev.c
浏览文件 @
4e700bcd
...
...
@@ -1454,6 +1454,27 @@ static inline void net_timestamp_check(struct sk_buff *skb)
__net_timestamp
(
skb
);
}
static
inline
bool
is_skb_forwardable
(
struct
net_device
*
dev
,
struct
sk_buff
*
skb
)
{
unsigned
int
len
;
if
(
!
(
dev
->
flags
&
IFF_UP
))
return
false
;
len
=
dev
->
mtu
+
dev
->
hard_header_len
+
VLAN_HLEN
;
if
(
skb
->
len
<=
len
)
return
true
;
/* if TSO is enabled, we don't care about the length as the packet
* could be forwarded without being segmented before
*/
if
(
skb_is_gso
(
skb
))
return
true
;
return
false
;
}
/**
* dev_forward_skb - loopback an skb to another netif
*
...
...
@@ -1477,8 +1498,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
skb_orphan
(
skb
);
nf_reset
(
skb
);
if
(
unlikely
(
!
(
dev
->
flags
&
IFF_UP
)
||
(
skb
->
len
>
(
dev
->
mtu
+
dev
->
hard_header_len
+
VLAN_HLEN
))))
{
if
(
unlikely
(
!
is_skb_forwardable
(
dev
,
skb
)))
{
atomic_long_inc
(
&
dev
->
rx_dropped
);
kfree_skb
(
skb
);
return
NET_RX_DROP
;
...
...
net/ipv4/arp.c
浏览文件 @
4e700bcd
...
...
@@ -215,6 +215,9 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir)
case
ARPHRD_INFINIBAND
:
ip_ib_mc_map
(
addr
,
dev
->
broadcast
,
haddr
);
return
0
;
case
ARPHRD_IPGRE
:
ip_ipgre_mc_map
(
addr
,
dev
->
broadcast
,
haddr
);
return
0
;
default:
if
(
dir
)
{
memcpy
(
haddr
,
dev
->
broadcast
,
dev
->
addr_len
);
...
...
net/ipv4/fib_frontend.c
浏览文件 @
4e700bcd
...
...
@@ -1068,6 +1068,7 @@ static void ip_fib_net_exit(struct net *net)
fib4_rules_exit
(
net
);
#endif
rtnl_lock
();
for
(
i
=
0
;
i
<
FIB_TABLE_HASHSZ
;
i
++
)
{
struct
fib_table
*
tb
;
struct
hlist_head
*
head
;
...
...
@@ -1080,6 +1081,7 @@ static void ip_fib_net_exit(struct net *net)
fib_free_table
(
tb
);
}
}
rtnl_unlock
();
kfree
(
net
->
ipv4
.
fib_table_hash
);
}
...
...
net/ipv6/ndisc.c
浏览文件 @
4e700bcd
...
...
@@ -341,6 +341,8 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d
case
ARPHRD_INFINIBAND
:
ipv6_ib_mc_map
(
addr
,
dev
->
broadcast
,
buf
);
return
0
;
case
ARPHRD_IPGRE
:
return
ipv6_ipgre_mc_map
(
addr
,
dev
->
broadcast
,
buf
);
default:
if
(
dir
)
{
memcpy
(
buf
,
dev
->
broadcast
,
dev
->
addr_len
);
...
...
net/sctp/protocol.c
浏览文件 @
4e700bcd
...
...
@@ -1205,7 +1205,7 @@ SCTP_STATIC __init int sctp_init(void)
if
((
sctp_assoc_hashsize
>
(
64
*
1024
))
&&
order
>
0
)
continue
;
sctp_assoc_hashtable
=
(
struct
sctp_hashbucket
*
)
__get_free_pages
(
GFP_ATOMIC
,
order
);
__get_free_pages
(
GFP_ATOMIC
|
__GFP_NOWARN
,
order
);
}
while
(
!
sctp_assoc_hashtable
&&
--
order
>
0
);
if
(
!
sctp_assoc_hashtable
)
{
pr_err
(
"Failed association hash alloc
\n
"
);
...
...
@@ -1238,7 +1238,7 @@ SCTP_STATIC __init int sctp_init(void)
if
((
sctp_port_hashsize
>
(
64
*
1024
))
&&
order
>
0
)
continue
;
sctp_port_hashtable
=
(
struct
sctp_bind_hashbucket
*
)
__get_free_pages
(
GFP_ATOMIC
,
order
);
__get_free_pages
(
GFP_ATOMIC
|
__GFP_NOWARN
,
order
);
}
while
(
!
sctp_port_hashtable
&&
--
order
>
0
);
if
(
!
sctp_port_hashtable
)
{
pr_err
(
"Failed bind hash alloc
\n
"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录