Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
e74b3f7d
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看板
提交
e74b3f7d
编写于
12月 25, 2008
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-david' of
git://git.kernel.org/pub/scm/linux/kernel/git/chris/linux-2.6
上级
13e620e0
59f8500e
变更
9
展开全部
隐藏空白更改
内联
并排
Showing
9 changed file
with
1585 addition
and
184 deletion
+1585
-184
MAINTAINERS
MAINTAINERS
+6
-1
arch/arm/mach-ixp4xx/include/mach/qmgr.h
arch/arm/mach-ixp4xx/include/mach/qmgr.h
+33
-2
arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
+33
-11
drivers/net/arm/Kconfig
drivers/net/arm/Kconfig
+1
-1
drivers/net/arm/ixp4xx_eth.c
drivers/net/arm/ixp4xx_eth.c
+173
-164
drivers/net/wan/Kconfig
drivers/net/wan/Kconfig
+7
-0
drivers/net/wan/Makefile
drivers/net/wan/Makefile
+1
-0
drivers/net/wan/hdlc_ppp.c
drivers/net/wan/hdlc_ppp.c
+6
-5
drivers/net/wan/ixp4xx_hss.c
drivers/net/wan/ixp4xx_hss.c
+1325
-0
未找到文件。
MAINTAINERS
浏览文件 @
e74b3f7d
...
...
@@ -1844,7 +1844,7 @@ P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
S: Supported
GENERIC HDLC
DRIVER, N2, C101, PCI200SYN and WANXL
DRIVERS
GENERIC HDLC
(WAN)
DRIVERS
P: Krzysztof Halasa
M: khc@pm.waw.pl
W: http://www.kernel.org/pub/linux/utils/net/hdlc/
...
...
@@ -2243,6 +2243,11 @@ M: dan.j.williams@intel.com
L: linux-kernel@vger.kernel.org
S: Supported
INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
P: Krzysztof Halasa
M: khc@pm.waw.pl
S: Maintained
INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
P: Deepak Saxena
M: dsaxena@plexity.net
...
...
arch/arm/mach-ixp4xx/include/mach/qmgr.h
浏览文件 @
e74b3f7d
...
...
@@ -12,6 +12,8 @@
#include <linux/io.h>
#include <linux/kernel.h>
#define DEBUG_QMGR 0
#define HALF_QUEUES 32
#define QUEUES 64
/* only 32 lower queues currently supported */
#define MAX_QUEUE_LENGTH 4
/* in dwords */
...
...
@@ -61,22 +63,51 @@ void qmgr_enable_irq(unsigned int queue);
void
qmgr_disable_irq
(
unsigned
int
queue
);
/* request_ and release_queue() must be called from non-IRQ context */
#if DEBUG_QMGR
extern
char
qmgr_queue_descs
[
QUEUES
][
32
];
int
qmgr_request_queue
(
unsigned
int
queue
,
unsigned
int
len
/* dwords */
,
unsigned
int
nearly_empty_watermark
,
unsigned
int
nearly_full_watermark
);
unsigned
int
nearly_full_watermark
,
const
char
*
desc_format
,
const
char
*
name
);
#else
int
__qmgr_request_queue
(
unsigned
int
queue
,
unsigned
int
len
/* dwords */
,
unsigned
int
nearly_empty_watermark
,
unsigned
int
nearly_full_watermark
);
#define qmgr_request_queue(queue, len, nearly_empty_watermark, \
nearly_full_watermark, desc_format, name) \
__qmgr_request_queue(queue, len, nearly_empty_watermark, \
nearly_full_watermark)
#endif
void
qmgr_release_queue
(
unsigned
int
queue
);
static
inline
void
qmgr_put_entry
(
unsigned
int
queue
,
u32
val
)
{
extern
struct
qmgr_regs
__iomem
*
qmgr_regs
;
#if DEBUG_QMGR
BUG_ON
(
!
qmgr_queue_descs
[
queue
]);
/* not yet requested */
printk
(
KERN_DEBUG
"Queue %s(%i) put %X
\n
"
,
qmgr_queue_descs
[
queue
],
queue
,
val
);
#endif
__raw_writel
(
val
,
&
qmgr_regs
->
acc
[
queue
][
0
]);
}
static
inline
u32
qmgr_get_entry
(
unsigned
int
queue
)
{
u32
val
;
extern
struct
qmgr_regs
__iomem
*
qmgr_regs
;
return
__raw_readl
(
&
qmgr_regs
->
acc
[
queue
][
0
]);
val
=
__raw_readl
(
&
qmgr_regs
->
acc
[
queue
][
0
]);
#if DEBUG_QMGR
BUG_ON
(
!
qmgr_queue_descs
[
queue
]);
/* not yet requested */
printk
(
KERN_DEBUG
"Queue %s(%i) get %X
\n
"
,
qmgr_queue_descs
[
queue
],
queue
,
val
);
#endif
return
val
;
}
static
inline
int
qmgr_get_stat1
(
unsigned
int
queue
)
...
...
arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
浏览文件 @
e74b3f7d
...
...
@@ -14,8 +14,6 @@
#include <linux/module.h>
#include <mach/qmgr.h>
#define DEBUG 0
struct
qmgr_regs
__iomem
*
qmgr_regs
;
static
struct
resource
*
mem_res
;
static
spinlock_t
qmgr_lock
;
...
...
@@ -23,6 +21,10 @@ static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
static
void
(
*
irq_handlers
[
HALF_QUEUES
])(
void
*
pdev
);
static
void
*
irq_pdevs
[
HALF_QUEUES
];
#if DEBUG_QMGR
char
qmgr_queue_descs
[
QUEUES
][
32
];
#endif
void
qmgr_set_irq
(
unsigned
int
queue
,
int
src
,
void
(
*
handler
)(
void
*
pdev
),
void
*
pdev
)
{
...
...
@@ -70,6 +72,7 @@ void qmgr_disable_irq(unsigned int queue)
spin_lock_irqsave
(
&
qmgr_lock
,
flags
);
__raw_writel
(
__raw_readl
(
&
qmgr_regs
->
irqen
[
0
])
&
~
(
1
<<
queue
),
&
qmgr_regs
->
irqen
[
0
]);
__raw_writel
(
1
<<
queue
,
&
qmgr_regs
->
irqstat
[
0
]);
/* clear */
spin_unlock_irqrestore
(
&
qmgr_lock
,
flags
);
}
...
...
@@ -81,9 +84,16 @@ static inline void shift_mask(u32 *mask)
mask
[
0
]
<<=
1
;
}
#if DEBUG_QMGR
int
qmgr_request_queue
(
unsigned
int
queue
,
unsigned
int
len
/* dwords */
,
unsigned
int
nearly_empty_watermark
,
unsigned
int
nearly_full_watermark
)
unsigned
int
nearly_full_watermark
,
const
char
*
desc_format
,
const
char
*
name
)
#else
int
__qmgr_request_queue
(
unsigned
int
queue
,
unsigned
int
len
/* dwords */
,
unsigned
int
nearly_empty_watermark
,
unsigned
int
nearly_full_watermark
)
#endif
{
u32
cfg
,
addr
=
0
,
mask
[
4
];
/* in 16-dwords */
int
err
;
...
...
@@ -151,12 +161,13 @@ int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
used_sram_bitmap
[
2
]
|=
mask
[
2
];
used_sram_bitmap
[
3
]
|=
mask
[
3
];
__raw_writel
(
cfg
|
(
addr
<<
14
),
&
qmgr_regs
->
sram
[
queue
]);
spin_unlock_irq
(
&
qmgr_lock
);
#if DEBUG
printk
(
KERN_DEBUG
"qmgr: requested queue %
i,
addr = 0x%02X
\n
"
,
queue
,
addr
);
#if DEBUG_QMGR
snprintf
(
qmgr_queue_descs
[
queue
],
sizeof
(
qmgr_queue_descs
[
0
]),
desc_format
,
name
);
printk
(
KERN_DEBUG
"qmgr: requested queue %
s(%i)
addr = 0x%02X
\n
"
,
q
mgr_queue_descs
[
queue
],
q
ueue
,
addr
);
#endif
spin_unlock_irq
(
&
qmgr_lock
);
return
0
;
err:
...
...
@@ -189,6 +200,11 @@ void qmgr_release_queue(unsigned int queue)
while
(
addr
--
)
shift_mask
(
mask
);
#if DEBUG_QMGR
printk
(
KERN_DEBUG
"qmgr: releasing queue %s(%i)
\n
"
,
qmgr_queue_descs
[
queue
],
queue
);
qmgr_queue_descs
[
queue
][
0
]
=
'\x0'
;
#endif
__raw_writel
(
0
,
&
qmgr_regs
->
sram
[
queue
]);
used_sram_bitmap
[
0
]
&=
~
mask
[
0
];
...
...
@@ -199,9 +215,10 @@ void qmgr_release_queue(unsigned int queue)
spin_unlock_irq
(
&
qmgr_lock
);
module_put
(
THIS_MODULE
);
#if DEBUG
printk
(
KERN_DEBUG
"qmgr: released queue %i
\n
"
,
queue
);
#endif
while
((
addr
=
qmgr_get_entry
(
queue
)))
printk
(
KERN_ERR
"qmgr: released queue %i not empty: 0x%08X
\n
"
,
queue
,
addr
);
}
static
int
qmgr_init
(
void
)
...
...
@@ -272,5 +289,10 @@ EXPORT_SYMBOL(qmgr_regs);
EXPORT_SYMBOL
(
qmgr_set_irq
);
EXPORT_SYMBOL
(
qmgr_enable_irq
);
EXPORT_SYMBOL
(
qmgr_disable_irq
);
#if DEBUG_QMGR
EXPORT_SYMBOL
(
qmgr_queue_descs
);
EXPORT_SYMBOL
(
qmgr_request_queue
);
#else
EXPORT_SYMBOL
(
__qmgr_request_queue
);
#endif
EXPORT_SYMBOL
(
qmgr_release_queue
);
drivers/net/arm/Kconfig
浏览文件 @
e74b3f7d
...
...
@@ -59,7 +59,7 @@ config EP93XX_ETH
config IXP4XX_ETH
tristate "Intel IXP4xx Ethernet support"
depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
select
MII
select
PHYLIB
help
Say Y here if you want to use built-in Ethernet ports
on IXP4xx processor.
drivers/net/arm/ixp4xx_eth.c
浏览文件 @
e74b3f7d
...
...
@@ -30,12 +30,11 @@
#include <linux/etherdevice.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/
mii
.h>
#include <linux/
phy
.h>
#include <linux/platform_device.h>
#include <mach/npe.h>
#include <mach/qmgr.h>
#define DEBUG_QUEUES 0
#define DEBUG_DESC 0
#define DEBUG_RX 0
#define DEBUG_TX 0
...
...
@@ -59,7 +58,6 @@
#define NAPI_WEIGHT 16
#define MDIO_INTERVAL (3 * HZ)
#define MAX_MDIO_RETRIES 100
/* microseconds, typically 30 cycles */
#define MAX_MII_RESET_RETRIES 100
/* mdio_read() cycles, typically 4 */
#define MAX_CLOSE_WAIT 1000
/* microseconds, typically 2-3 cycles */
#define NPE_ID(port_id) ((port_id) >> 4)
...
...
@@ -164,15 +162,14 @@ struct port {
struct
npe
*
npe
;
struct
net_device
*
netdev
;
struct
napi_struct
napi
;
struct
net_device_stats
stat
;
struct
mii_if_info
mii
;
struct
delayed_work
mdio_thread
;
struct
phy_device
*
phydev
;
struct
eth_plat_info
*
plat
;
buffer_t
*
rx_buff_tab
[
RX_DESCS
],
*
tx_buff_tab
[
TX_DESCS
];
struct
desc
*
desc_tab
;
/* coherent */
u32
desc_tab_phys
;
int
id
;
/* logical port ID */
u16
mii_bmcr
;
int
speed
,
duplex
;
u8
firmware
[
4
];
};
/* NPE message structure */
...
...
@@ -243,19 +240,20 @@ static inline void memcpy_swab32(u32 *dest, u32 *src, int cnt)
static
spinlock_t
mdio_lock
;
static
struct
eth_regs
__iomem
*
mdio_regs
;
/* mdio command and status only */
struct
mii_bus
*
mdio_bus
;
static
int
ports_open
;
static
struct
port
*
npe_port_tab
[
MAX_NPES
];
static
struct
dma_pool
*
dma_pool
;
static
u16
mdio_cmd
(
struct
net_device
*
dev
,
int
phy_id
,
int
location
,
int
write
,
u16
cmd
)
static
int
ixp4xx_mdio_cmd
(
struct
mii_bus
*
bus
,
int
phy_id
,
int
location
,
int
write
,
u16
cmd
)
{
int
cycles
=
0
;
if
(
__raw_readl
(
&
mdio_regs
->
mdio_command
[
3
])
&
0x80
)
{
printk
(
KERN_ERR
"%s: MII not ready to transmit
\n
"
,
dev
->
name
);
return
0
;
printk
(
KERN_ERR
"%s: MII not ready to transmit
\n
"
,
bus
->
name
);
return
-
1
;
}
if
(
write
)
{
...
...
@@ -274,107 +272,119 @@ static u16 mdio_cmd(struct net_device *dev, int phy_id, int location,
}
if
(
cycles
==
MAX_MDIO_RETRIES
)
{
printk
(
KERN_ERR
"%s: MII write failed
\n
"
,
dev
->
name
);
return
0
;
printk
(
KERN_ERR
"%s #%i: MII write failed
\n
"
,
bus
->
name
,
phy_id
);
return
-
1
;
}
#if DEBUG_MDIO
printk
(
KERN_DEBUG
"%s
: mdio_cmd() took %i cycles
\n
"
,
dev
->
name
,
cycles
);
printk
(
KERN_DEBUG
"%s
#%i: mdio_%s() took %i cycles
\n
"
,
bus
->
name
,
phy_id
,
write
?
"write"
:
"read"
,
cycles
);
#endif
if
(
write
)
return
0
;
if
(
__raw_readl
(
&
mdio_regs
->
mdio_status
[
3
])
&
0x80
)
{
printk
(
KERN_ERR
"%s: MII read failed
\n
"
,
dev
->
name
);
return
0
;
#if DEBUG_MDIO
printk
(
KERN_DEBUG
"%s #%i: MII read failed
\n
"
,
bus
->
name
,
phy_id
);
#endif
return
0xFFFF
;
/* don't return error */
}
return
(
__raw_readl
(
&
mdio_regs
->
mdio_status
[
0
])
&
0xFF
)
|
(
__raw_readl
(
&
mdio_regs
->
mdio_status
[
1
]
)
<<
8
);
(
(
__raw_readl
(
&
mdio_regs
->
mdio_status
[
1
])
&
0xFF
)
<<
8
);
}
static
int
mdio_read
(
struct
net_device
*
dev
,
int
phy_id
,
int
location
)
static
int
ixp4xx_mdio_read
(
struct
mii_bus
*
bus
,
int
phy_id
,
int
location
)
{
unsigned
long
flags
;
u16
val
;
int
ret
;
spin_lock_irqsave
(
&
mdio_lock
,
flags
);
val
=
mdio_cmd
(
dev
,
phy_id
,
location
,
0
,
0
);
ret
=
ixp4xx_mdio_cmd
(
bus
,
phy_id
,
location
,
0
,
0
);
spin_unlock_irqrestore
(
&
mdio_lock
,
flags
);
return
val
;
#if DEBUG_MDIO
printk
(
KERN_DEBUG
"%s #%i: MII read [%i] -> 0x%X
\n
"
,
bus
->
name
,
phy_id
,
location
,
ret
);
#endif
return
ret
;
}
static
void
mdio_write
(
struct
net_device
*
dev
,
int
phy_id
,
int
location
,
int
val
)
static
int
ixp4xx_mdio_write
(
struct
mii_bus
*
bus
,
int
phy_id
,
int
location
,
u16
val
)
{
unsigned
long
flags
;
int
ret
;
spin_lock_irqsave
(
&
mdio_lock
,
flags
);
mdio_cmd
(
dev
,
phy_id
,
location
,
1
,
val
);
ret
=
ixp4xx_mdio_cmd
(
bus
,
phy_id
,
location
,
1
,
val
);
spin_unlock_irqrestore
(
&
mdio_lock
,
flags
);
#if DEBUG_MDIO
printk
(
KERN_DEBUG
"%s #%i: MII read [%i] <- 0x%X, err = %i
\n
"
,
bus
->
name
,
phy_id
,
location
,
val
,
ret
);
#endif
return
ret
;
}
static
void
phy_reset
(
struct
net_device
*
dev
,
int
phy_
id
)
static
int
ixp4xx_mdio_register
(
vo
id
)
{
struct
port
*
port
=
netdev_priv
(
dev
);
int
cycles
=
0
;
int
err
;
mdio_write
(
dev
,
phy_id
,
MII_BMCR
,
port
->
mii_bmcr
|
BMCR_RESET
);
if
(
!
(
mdio_bus
=
mdiobus_alloc
()))
return
-
ENOMEM
;
while
(
cycles
<
MAX_MII_RESET_RETRIES
)
{
if
(
!
(
mdio_read
(
dev
,
phy_id
,
MII_BMCR
)
&
BMCR_RESET
))
{
#if DEBUG_MDIO
printk
(
KERN_DEBUG
"%s: phy_reset() took %i cycles
\n
"
,
dev
->
name
,
cycles
);
#endif
return
;
}
udelay
(
1
);
cycles
++
;
}
/* All MII PHY accesses use NPE-B Ethernet registers */
spin_lock_init
(
&
mdio_lock
);
mdio_regs
=
(
struct
eth_regs
__iomem
*
)
IXP4XX_EthB_BASE_VIRT
;
__raw_writel
(
DEFAULT_CORE_CNTRL
,
&
mdio_regs
->
core_control
);
mdio_bus
->
name
=
"IXP4xx MII Bus"
;
mdio_bus
->
read
=
&
ixp4xx_mdio_read
;
mdio_bus
->
write
=
&
ixp4xx_mdio_write
;
strcpy
(
mdio_bus
->
id
,
"0"
);
printk
(
KERN_ERR
"%s: MII reset failed
\n
"
,
dev
->
name
);
if
((
err
=
mdiobus_register
(
mdio_bus
)))
mdiobus_free
(
mdio_bus
);
return
err
;
}
static
void
eth_set_duplex
(
struct
port
*
port
)
static
void
ixp4xx_mdio_remove
(
void
)
{
if
(
port
->
mii
.
full_duplex
)
__raw_writel
(
DEFAULT_TX_CNTRL0
&
~
TX_CNTRL0_HALFDUPLEX
,
&
port
->
regs
->
tx_control
[
0
]);
else
__raw_writel
(
DEFAULT_TX_CNTRL0
|
TX_CNTRL0_HALFDUPLEX
,
&
port
->
regs
->
tx_control
[
0
]);
mdiobus_unregister
(
mdio_bus
);
mdiobus_free
(
mdio_bus
);
}
static
void
phy_check_media
(
struct
port
*
port
,
int
init
)
static
void
ixp4xx_adjust_link
(
struct
net_device
*
dev
)
{
if
(
mii_check_media
(
&
port
->
mii
,
1
,
init
))
eth_set_duplex
(
port
);
if
(
port
->
mii
.
force_media
)
{
/* mii_check_media() doesn't work */
struct
net_device
*
dev
=
port
->
netdev
;
int
cur_link
=
mii_link_ok
(
&
port
->
mii
);
int
prev_link
=
netif_carrier_ok
(
dev
);
if
(
!
prev_link
&&
cur_link
)
{
printk
(
KERN_INFO
"%s: link up
\n
"
,
dev
->
name
);
netif_carrier_on
(
dev
);
}
else
if
(
prev_link
&&
!
cur_link
)
{
struct
port
*
port
=
netdev_priv
(
dev
);
struct
phy_device
*
phydev
=
port
->
phydev
;
if
(
!
phydev
->
link
)
{
if
(
port
->
speed
)
{
port
->
speed
=
0
;
printk
(
KERN_INFO
"%s: link down
\n
"
,
dev
->
name
);
netif_carrier_off
(
dev
);
}
return
;
}
}
if
(
port
->
speed
==
phydev
->
speed
&&
port
->
duplex
==
phydev
->
duplex
)
return
;
static
void
mdio_thread
(
struct
work_struct
*
work
)
{
struct
port
*
port
=
container_of
(
work
,
struct
port
,
mdio_thread
.
work
);
port
->
speed
=
phydev
->
speed
;
port
->
duplex
=
phydev
->
duplex
;
if
(
port
->
duplex
)
__raw_writel
(
DEFAULT_TX_CNTRL0
&
~
TX_CNTRL0_HALFDUPLEX
,
&
port
->
regs
->
tx_control
[
0
]);
else
__raw_writel
(
DEFAULT_TX_CNTRL0
|
TX_CNTRL0_HALFDUPLEX
,
&
port
->
regs
->
tx_control
[
0
]);
p
hy_check_media
(
port
,
0
);
schedule_delayed_work
(
&
port
->
mdio_thread
,
MDIO_INTERVAL
);
p
rintk
(
KERN_INFO
"%s: link up, speed %u Mb/s, %s duplex
\n
"
,
dev
->
name
,
port
->
speed
,
port
->
duplex
?
"full"
:
"half"
);
}
...
...
@@ -412,47 +422,13 @@ static inline void debug_desc(u32 phys, struct desc *desc)
#endif
}
static
inline
void
debug_queue
(
unsigned
int
queue
,
int
is_get
,
u32
phys
)
{
#if DEBUG_QUEUES
static
struct
{
int
queue
;
char
*
name
;
}
names
[]
=
{
{
TX_QUEUE
(
0x10
),
"TX#0 "
},
{
TX_QUEUE
(
0x20
),
"TX#1 "
},
{
TX_QUEUE
(
0x00
),
"TX#2 "
},
{
RXFREE_QUEUE
(
0x10
),
"RX-free#0 "
},
{
RXFREE_QUEUE
(
0x20
),
"RX-free#1 "
},
{
RXFREE_QUEUE
(
0x00
),
"RX-free#2 "
},
{
TXDONE_QUEUE
,
"TX-done "
},
};
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
names
);
i
++
)
if
(
names
[
i
].
queue
==
queue
)
break
;
printk
(
KERN_DEBUG
"Queue %i %s%s %X
\n
"
,
queue
,
i
<
ARRAY_SIZE
(
names
)
?
names
[
i
].
name
:
""
,
is_get
?
"->"
:
"<-"
,
phys
);
#endif
}
static
inline
u32
queue_get_entry
(
unsigned
int
queue
)
{
u32
phys
=
qmgr_get_entry
(
queue
);
debug_queue
(
queue
,
1
,
phys
);
return
phys
;
}
static
inline
int
queue_get_desc
(
unsigned
int
queue
,
struct
port
*
port
,
int
is_tx
)
{
u32
phys
,
tab_phys
,
n_desc
;
struct
desc
*
tab
;
if
(
!
(
phys
=
q
ueue
_get_entry
(
queue
)))
if
(
!
(
phys
=
q
mgr
_get_entry
(
queue
)))
return
-
1
;
phys
&=
~
0x1F
;
/* mask out non-address bits */
...
...
@@ -468,7 +444,6 @@ static inline int queue_get_desc(unsigned int queue, struct port *port,
static
inline
void
queue_put_desc
(
unsigned
int
queue
,
u32
phys
,
struct
desc
*
desc
)
{
debug_queue
(
queue
,
0
,
phys
);
debug_desc
(
phys
,
desc
);
BUG_ON
(
phys
&
0x1F
);
qmgr_put_entry
(
queue
,
phys
);
...
...
@@ -562,7 +537,7 @@ static int eth_poll(struct napi_struct *napi, int budget)
#endif
if
(
!
skb
)
{
port
->
stat
.
rx_dropped
++
;
dev
->
stats
.
rx_dropped
++
;
/* put the desc back on RX-ready queue */
desc
->
buf_len
=
MAX_MRU
;
desc
->
pkt_len
=
0
;
...
...
@@ -588,8 +563,8 @@ static int eth_poll(struct napi_struct *napi, int budget)
debug_pkt
(
dev
,
"eth_poll"
,
skb
->
data
,
skb
->
len
);
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
port
->
stat
.
rx_packets
++
;
port
->
stat
.
rx_bytes
+=
skb
->
len
;
dev
->
stats
.
rx_packets
++
;
dev
->
stats
.
rx_bytes
+=
skb
->
len
;
netif_receive_skb
(
skb
);
/* put the new buffer on RX-free queue */
...
...
@@ -617,7 +592,7 @@ static void eth_txdone_irq(void *unused)
#if DEBUG_TX
printk
(
KERN_DEBUG
DRV_NAME
": eth_txdone_irq
\n
"
);
#endif
while
((
phys
=
q
ueue
_get_entry
(
TXDONE_QUEUE
))
!=
0
)
{
while
((
phys
=
q
mgr
_get_entry
(
TXDONE_QUEUE
))
!=
0
)
{
u32
npe_id
,
n_desc
;
struct
port
*
port
;
struct
desc
*
desc
;
...
...
@@ -634,8 +609,8 @@ static void eth_txdone_irq(void *unused)
debug_desc
(
phys
,
desc
);
if
(
port
->
tx_buff_tab
[
n_desc
])
{
/* not the draining packet */
port
->
stat
.
tx_packets
++
;
port
->
stat
.
tx_bytes
+=
desc
->
pkt_len
;
port
->
netdev
->
stats
.
tx_packets
++
;
port
->
netdev
->
stats
.
tx_bytes
+=
desc
->
pkt_len
;
dma_unmap_tx
(
port
,
desc
);
#if DEBUG_TX
...
...
@@ -673,7 +648,7 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
if
(
unlikely
(
skb
->
len
>
MAX_MRU
))
{
dev_kfree_skb
(
skb
);
port
->
stat
.
tx_errors
++
;
dev
->
stats
.
tx_errors
++
;
return
NETDEV_TX_OK
;
}
...
...
@@ -689,7 +664,7 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
bytes
=
ALIGN
(
offset
+
len
,
4
);
if
(
!
(
mem
=
kmalloc
(
bytes
,
GFP_ATOMIC
)))
{
dev_kfree_skb
(
skb
);
port
->
stat
.
tx_dropped
++
;
dev
->
stats
.
tx_dropped
++
;
return
NETDEV_TX_OK
;
}
memcpy_swab32
(
mem
,
(
u32
*
)((
int
)
skb
->
data
&
~
3
),
bytes
/
4
);
...
...
@@ -703,7 +678,7 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
#else
kfree
(
mem
);
#endif
port
->
stat
.
tx_dropped
++
;
dev
->
stats
.
tx_dropped
++
;
return
NETDEV_TX_OK
;
}
...
...
@@ -746,12 +721,6 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
}
static
struct
net_device_stats
*
eth_stats
(
struct
net_device
*
dev
)
{
struct
port
*
port
=
netdev_priv
(
dev
);
return
&
port
->
stat
;
}
static
void
eth_set_mcast_list
(
struct
net_device
*
dev
)
{
struct
port
*
port
=
netdev_priv
(
dev
);
...
...
@@ -785,41 +754,80 @@ static void eth_set_mcast_list(struct net_device *dev)
static
int
eth_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
req
,
int
cmd
)
{
struct
port
*
port
=
netdev_priv
(
dev
);
unsigned
int
duplex_chg
;
int
err
;
if
(
!
netif_running
(
dev
))
return
-
EINVAL
;
err
=
generic_mii_ioctl
(
&
port
->
mii
,
if_mii
(
req
),
cmd
,
&
duplex_chg
);
if
(
duplex_chg
)
eth_set_duplex
(
port
);
return
err
;
return
phy_mii_ioctl
(
port
->
phydev
,
if_mii
(
req
),
cmd
);
}
/* ethtool support */
static
void
ixp4xx_get_drvinfo
(
struct
net_device
*
dev
,
struct
ethtool_drvinfo
*
info
)
{
struct
port
*
port
=
netdev_priv
(
dev
);
strcpy
(
info
->
driver
,
DRV_NAME
);
snprintf
(
info
->
fw_version
,
sizeof
(
info
->
fw_version
),
"%u:%u:%u:%u"
,
port
->
firmware
[
0
],
port
->
firmware
[
1
],
port
->
firmware
[
2
],
port
->
firmware
[
3
]);
strcpy
(
info
->
bus_info
,
"internal"
);
}
static
int
ixp4xx_get_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
cmd
)
{
struct
port
*
port
=
netdev_priv
(
dev
);
return
phy_ethtool_gset
(
port
->
phydev
,
cmd
);
}
static
int
ixp4xx_set_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
cmd
)
{
struct
port
*
port
=
netdev_priv
(
dev
);
return
phy_ethtool_sset
(
port
->
phydev
,
cmd
);
}
static
int
ixp4xx_nway_reset
(
struct
net_device
*
dev
)
{
struct
port
*
port
=
netdev_priv
(
dev
);
return
phy_start_aneg
(
port
->
phydev
);
}
static
struct
ethtool_ops
ixp4xx_ethtool_ops
=
{
.
get_drvinfo
=
ixp4xx_get_drvinfo
,
.
get_settings
=
ixp4xx_get_settings
,
.
set_settings
=
ixp4xx_set_settings
,
.
nway_reset
=
ixp4xx_nway_reset
,
.
get_link
=
ethtool_op_get_link
,
};
static
int
request_queues
(
struct
port
*
port
)
{
int
err
;
err
=
qmgr_request_queue
(
RXFREE_QUEUE
(
port
->
id
),
RX_DESCS
,
0
,
0
);
err
=
qmgr_request_queue
(
RXFREE_QUEUE
(
port
->
id
),
RX_DESCS
,
0
,
0
,
"%s:RX-free"
,
port
->
netdev
->
name
);
if
(
err
)
return
err
;
err
=
qmgr_request_queue
(
port
->
plat
->
rxq
,
RX_DESCS
,
0
,
0
);
err
=
qmgr_request_queue
(
port
->
plat
->
rxq
,
RX_DESCS
,
0
,
0
,
"%s:RX"
,
port
->
netdev
->
name
);
if
(
err
)
goto
rel_rxfree
;
err
=
qmgr_request_queue
(
TX_QUEUE
(
port
->
id
),
TX_DESCS
,
0
,
0
);
err
=
qmgr_request_queue
(
TX_QUEUE
(
port
->
id
),
TX_DESCS
,
0
,
0
,
"%s:TX"
,
port
->
netdev
->
name
);
if
(
err
)
goto
rel_rx
;
err
=
qmgr_request_queue
(
port
->
plat
->
txreadyq
,
TX_DESCS
,
0
,
0
);
err
=
qmgr_request_queue
(
port
->
plat
->
txreadyq
,
TX_DESCS
,
0
,
0
,
"%s:TX-ready"
,
port
->
netdev
->
name
);
if
(
err
)
goto
rel_tx
;
/* TX-done queue handles skbs sent out by the NPEs */
if
(
!
ports_open
)
{
err
=
qmgr_request_queue
(
TXDONE_QUEUE
,
TXDONE_QUEUE_LEN
,
0
,
0
);
err
=
qmgr_request_queue
(
TXDONE_QUEUE
,
TXDONE_QUEUE_LEN
,
0
,
0
,
"%s:TX-done"
,
DRV_NAME
);
if
(
err
)
goto
rel_txready
;
}
...
...
@@ -943,10 +951,12 @@ static int eth_open(struct net_device *dev)
npe_name
(
npe
));
return
-
EIO
;
}
port
->
firmware
[
0
]
=
msg
.
byte4
;
port
->
firmware
[
1
]
=
msg
.
byte5
;
port
->
firmware
[
2
]
=
msg
.
byte6
;
port
->
firmware
[
3
]
=
msg
.
byte7
;
}
mdio_write
(
dev
,
port
->
plat
->
phy
,
MII_BMCR
,
port
->
mii_bmcr
);
memset
(
&
msg
,
0
,
sizeof
(
msg
));
msg
.
cmd
=
NPE_VLAN_SETRXQOSENTRY
;
msg
.
eth_id
=
port
->
id
;
...
...
@@ -984,6 +994,9 @@ static int eth_open(struct net_device *dev)
return
err
;
}
port
->
speed
=
0
;
/* force "link up" message */
phy_start
(
port
->
phydev
);
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
__raw_writel
(
dev
->
dev_addr
[
i
],
&
port
->
regs
->
hw_addr
[
i
]);
__raw_writel
(
0x08
,
&
port
->
regs
->
random_seed
);
...
...
@@ -1011,10 +1024,8 @@ static int eth_open(struct net_device *dev)
__raw_writel
(
DEFAULT_RX_CNTRL0
,
&
port
->
regs
->
rx_control
[
0
]);
napi_enable
(
&
port
->
napi
);
phy_check_media
(
port
,
1
);
eth_set_mcast_list
(
dev
);
netif_start_queue
(
dev
);
schedule_delayed_work
(
&
port
->
mdio_thread
,
MDIO_INTERVAL
);
qmgr_set_irq
(
port
->
plat
->
rxq
,
QUEUE_IRQ_SRC_NOT_EMPTY
,
eth_rx_irq
,
dev
);
...
...
@@ -1105,25 +1116,31 @@ static int eth_close(struct net_device *dev)
printk
(
KERN_CRIT
"%s: unable to disable loopback
\n
"
,
dev
->
name
);
port
->
mii_bmcr
=
mdio_read
(
dev
,
port
->
plat
->
phy
,
MII_BMCR
)
&
~
(
BMCR_RESET
|
BMCR_PDOWN
);
/* may have been altered */
mdio_write
(
dev
,
port
->
plat
->
phy
,
MII_BMCR
,
port
->
mii_bmcr
|
BMCR_PDOWN
);
phy_stop
(
port
->
phydev
);
if
(
!
ports_open
)
qmgr_disable_irq
(
TXDONE_QUEUE
);
cancel_rearming_delayed_work
(
&
port
->
mdio_thread
);
destroy_queues
(
port
);
release_queues
(
port
);
return
0
;
}
static
const
struct
net_device_ops
ixp4xx_netdev_ops
=
{
.
ndo_open
=
eth_open
,
.
ndo_stop
=
eth_close
,
.
ndo_start_xmit
=
eth_xmit
,
.
ndo_set_multicast_list
=
eth_set_mcast_list
,
.
ndo_do_ioctl
=
eth_ioctl
,
};
static
int
__devinit
eth_init_one
(
struct
platform_device
*
pdev
)
{
struct
port
*
port
;
struct
net_device
*
dev
;
struct
eth_plat_info
*
plat
=
pdev
->
dev
.
platform_data
;
u32
regs_phys
;
char
phy_id
[
BUS_ID_SIZE
];
int
err
;
if
(
!
(
dev
=
alloc_etherdev
(
sizeof
(
struct
port
))))
...
...
@@ -1152,12 +1169,8 @@ static int __devinit eth_init_one(struct platform_device *pdev)
goto
err_free
;
}
dev
->
open
=
eth_open
;
dev
->
hard_start_xmit
=
eth_xmit
;
dev
->
stop
=
eth_close
;
dev
->
get_stats
=
eth_stats
;
dev
->
do_ioctl
=
eth_ioctl
;
dev
->
set_multicast_list
=
eth_set_mcast_list
;
dev
->
netdev_ops
=
&
ixp4xx_netdev_ops
;
dev
->
ethtool_ops
=
&
ixp4xx_ethtool_ops
;
dev
->
tx_queue_len
=
100
;
netif_napi_add
(
dev
,
&
port
->
napi
,
eth_poll
,
NAPI_WEIGHT
);
...
...
@@ -1190,22 +1203,19 @@ static int __devinit eth_init_one(struct platform_device *pdev)
__raw_writel
(
DEFAULT_CORE_CNTRL
,
&
port
->
regs
->
core_control
);
udelay
(
50
);
port
->
mii
.
dev
=
dev
;
port
->
mii
.
mdio_read
=
mdio_read
;
port
->
mii
.
mdio_write
=
mdio_write
;
port
->
mii
.
phy_id
=
plat
->
phy
;
port
->
mii
.
phy_id_mask
=
0x1F
;
port
->
mii
.
reg_num_mask
=
0x1F
;
snprintf
(
phy_id
,
BUS_ID_SIZE
,
PHY_ID_FMT
,
"0"
,
plat
->
phy
);
port
->
phydev
=
phy_connect
(
dev
,
phy_id
,
&
ixp4xx_adjust_link
,
0
,
PHY_INTERFACE_MODE_MII
);
if
(
IS_ERR
(
port
->
phydev
))
{
printk
(
KERN_ERR
"%s: Could not attach to PHY
\n
"
,
dev
->
name
);
return
PTR_ERR
(
port
->
phydev
);
}
port
->
phydev
->
irq
=
PHY_POLL
;
printk
(
KERN_INFO
"%s: MII PHY %i on %s
\n
"
,
dev
->
name
,
plat
->
phy
,
npe_name
(
port
->
npe
));
phy_reset
(
dev
,
plat
->
phy
);
port
->
mii_bmcr
=
mdio_read
(
dev
,
plat
->
phy
,
MII_BMCR
)
&
~
(
BMCR_RESET
|
BMCR_PDOWN
);
mdio_write
(
dev
,
plat
->
phy
,
MII_BMCR
,
port
->
mii_bmcr
|
BMCR_PDOWN
);
INIT_DELAYED_WORK
(
&
port
->
mdio_thread
,
mdio_thread
);
return
0
;
err_unreg:
...
...
@@ -1231,7 +1241,7 @@ static int __devexit eth_remove_one(struct platform_device *pdev)
return
0
;
}
static
struct
platform_driver
drv
=
{
static
struct
platform_driver
ixp4xx_eth_driver
=
{
.
driver
.
name
=
DRV_NAME
,
.
probe
=
eth_init_one
,
.
remove
=
eth_remove_one
,
...
...
@@ -1239,20 +1249,19 @@ static struct platform_driver drv = {
static
int
__init
eth_init_module
(
void
)
{
int
err
;
if
(
!
(
ixp4xx_read_feature_bits
()
&
IXP4XX_FEATURE_NPEB_ETH0
))
return
-
ENOSYS
;
/* All MII PHY accesses use NPE-B Ethernet registers */
spin_lock_init
(
&
mdio_lock
);
mdio_regs
=
(
struct
eth_regs
__iomem
*
)
IXP4XX_EthB_BASE_VIRT
;
__raw_writel
(
DEFAULT_CORE_CNTRL
,
&
mdio_regs
->
core_control
);
return
platform_driver_register
(
&
drv
);
if
((
err
=
ixp4xx_mdio_register
()))
return
err
;
return
platform_driver_register
(
&
ixp4xx_eth_driver
);
}
static
void
__exit
eth_cleanup_module
(
void
)
{
platform_driver_unregister
(
&
drv
);
platform_driver_unregister
(
&
ixp4xx_eth_driver
);
ixp4xx_mdio_remove
();
}
MODULE_AUTHOR
(
"Krzysztof Halasa"
);
...
...
drivers/net/wan/Kconfig
浏览文件 @
e74b3f7d
...
...
@@ -335,6 +335,13 @@ config DSCC4_PCI_RST
Say Y if your card supports this feature.
config IXP4XX_HSS
tristate "Intel IXP4xx HSS (synchronous serial port) support"
depends on HDLC && ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
help
Say Y here if you want to use built-in HSS ports
on IXP4xx processor.
config DLCI
tristate "Frame Relay DLCI support"
---help---
...
...
drivers/net/wan/Makefile
浏览文件 @
e74b3f7d
...
...
@@ -41,6 +41,7 @@ obj-$(CONFIG_C101) += c101.o
obj-$(CONFIG_WANXL)
+=
wanxl.o
obj-$(CONFIG_PCI200SYN)
+=
pci200syn.o
obj-$(CONFIG_PC300TOO)
+=
pc300too.o
obj-$(CONFIG_IXP4XX_HSS)
+=
ixp4xx_hss.o
clean-files
:=
wanxlfw.inc
$(obj)/wanxl.o
:
$(obj)/wanxlfw.inc
...
...
drivers/net/wan/hdlc_ppp.c
浏览文件 @
e74b3f7d
...
...
@@ -303,7 +303,7 @@ static int cp_table[EVENTS][STATES] = {
STA: RTR must supply id
SCJ: RUC must supply CP packet len and data */
static
void
ppp_cp_event
(
struct
net_device
*
dev
,
u16
pid
,
u16
event
,
u8
code
,
u8
id
,
unsigned
int
len
,
void
*
data
)
u8
id
,
unsigned
int
len
,
const
void
*
data
)
{
int
old_state
,
action
;
struct
ppp
*
ppp
=
get_ppp
(
dev
);
...
...
@@ -374,11 +374,12 @@ static void ppp_cp_event(struct net_device *dev, u16 pid, u16 event, u8 code,
static
void
ppp_cp_parse_cr
(
struct
net_device
*
dev
,
u16
pid
,
u8
id
,
unsigned
int
len
,
u8
*
data
)
unsigned
int
req_len
,
const
u8
*
data
)
{
static
u8
const
valid_accm
[
6
]
=
{
LCP_OPTION_ACCM
,
6
,
0
,
0
,
0
,
0
};
u8
*
opt
,
*
out
;
unsigned
int
nak_len
=
0
,
rej_len
=
0
;
const
u8
*
opt
;
u8
*
out
;
unsigned
int
len
=
req_len
,
nak_len
=
0
,
rej_len
=
0
;
if
(
!
(
out
=
kmalloc
(
len
,
GFP_ATOMIC
)))
{
dev
->
stats
.
rx_dropped
++
;
...
...
@@ -423,7 +424,7 @@ static void ppp_cp_parse_cr(struct net_device *dev, u16 pid, u8 id,
else
if
(
nak_len
)
ppp_cp_event
(
dev
,
pid
,
RCR_BAD
,
CP_CONF_NAK
,
id
,
nak_len
,
out
);
else
ppp_cp_event
(
dev
,
pid
,
RCR_GOOD
,
CP_CONF_ACK
,
id
,
len
,
data
);
ppp_cp_event
(
dev
,
pid
,
RCR_GOOD
,
CP_CONF_ACK
,
id
,
req_
len
,
data
);
kfree
(
out
);
}
...
...
drivers/net/wan/ixp4xx_hss.c
0 → 100644
浏览文件 @
e74b3f7d
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录