Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Simple PCIe FMC carrier SPEC - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Simple PCIe FMC carrier SPEC - Software
Commits
e04e06e4
Commit
e04e06e4
authored
Sep 06, 2012
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wr-nic: completed eth_init
Signed-off-by:
Alessandro Rubini
<
rubini@gnudd.com
>
parent
0e7d41b5
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
124 additions
and
33 deletions
+124
-33
wr-nic-core.c
kernel/wr-nic-core.c
+17
-33
wr-nic-eth.c
kernel/wr-nic-eth.c
+107
-0
No files found.
kernel/wr-nic-core.c
View file @
e04e06e4
...
...
@@ -9,26 +9,19 @@
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/fmc.h>
#include <linux/fmc-sdb.h>
#include "spec-nic.h"
#include "spec.h"
#include "spec-nic.h"
#include "wr_nic/wr-nic.h"
static
struct
fmc_driver
wrn_drv
;
static
char
*
wrn_filename
=
WRN_GATEWARE_DEFAULT_NAME
;
module_param_named
(
file
,
wrn_filename
,
charp
,
0444
);
irqreturn_t
wrn_handler
(
int
irq
,
void
*
dev_id
)
{
struct
fmc_device
*
fmc
=
dev_id
;
fmc
->
op
->
irq_ack
(
fmc
);
printk
(
"%s: irq %i
\n
"
,
__func__
,
irq
);
return
IRQ_HANDLED
;
}
int
wrn_probe
(
struct
fmc_device
*
fmc
)
int
wrn_fmc_probe
(
struct
fmc_device
*
fmc
)
{
int
ret
=
0
;
struct
device
*
dev
=
fmc
->
hwdev
;
...
...
@@ -56,7 +49,7 @@ int wrn_probe(struct fmc_device *fmc)
}
dev_info
(
dev
,
"Gateware successfully loaded
\n
"
);
if
(
(
ret
=
fmc_scan_sdb_tree
(
fmc
,
0x63000
))
<
0
)
{
if
(
(
ret
=
fmc_scan_sdb_tree
(
fmc
,
WRN_SDB_ADDR
))
<
0
)
{
dev_err
(
dev
,
"scan fmc failed %i
\n
"
,
ret
);
goto
out
;
}
...
...
@@ -72,37 +65,23 @@ int wrn_probe(struct fmc_device *fmc)
/* The netword device */
ret
=
wrn_eth_init
(
fmc
);
if
(
ret
<
0
)
goto
out_gpio
;
/* The interrupt */
ret
=
fmc
->
op
->
irq_request
(
fmc
,
wrn_handler
,
"wr-nic"
,
0
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"Can't request interrupt
\n
"
);
goto
out_nic
;
}
return
0
;
out_nic:
wrn_eth_exit
(
fmc
);
out_gpio:
wrn_gpio_exit
(
fmc
);
wrn_gpio_exit
(
fmc
);
out:
return
ret
;
}
int
wrn_remove
(
struct
fmc_device
*
fmc
)
int
wrn_
fmc_
remove
(
struct
fmc_device
*
fmc
)
{
fmc
->
op
->
irq_free
(
fmc
);
wrn_eth_exit
(
fmc
);
wrn_gpio_exit
(
fmc
);
fmc_free_sdb_tree
(
fmc
);
return
0
;
}
static
struct
fmc_driver
wrn_drv
=
{
static
struct
fmc_driver
wrn_
fmc_
drv
=
{
.
driver
.
name
=
KBUILD_MODNAME
,
.
probe
=
wrn_probe
,
.
remove
=
wrn_remove
,
.
probe
=
wrn_
fmc_
probe
,
.
remove
=
wrn_
fmc_
remove
,
/* no table, as the current match just matches everything */
};
...
...
@@ -110,13 +89,18 @@ static int wrn_init(void)
{
int
ret
;
ret
=
fmc_driver_register
(
&
wrn_drv
);
ret
=
platform_driver_register
(
&
wrn_driver
);
/* nic-device.c */
if
(
!
ret
)
ret
=
fmc_driver_register
(
&
wrn_fmc_drv
);
if
(
ret
<
0
)
platform_driver_unregister
(
&
wrn_driver
);
return
ret
;
}
static
void
wrn_exit
(
void
)
{
fmc_driver_unregister
(
&
wrn_drv
);
fmc_driver_unregister
(
&
wrn_fmc_drv
);
platform_driver_unregister
(
&
wrn_driver
);
}
module_init
(
wrn_init
);
...
...
kernel/wr-nic-eth.c
View file @
e04e06e4
...
...
@@ -17,11 +17,118 @@
#include "wr_nic/wr-nic.h"
#include "spec.h"
/*
* nic-device.c defines a platform driver. We need to allocate
* a platform device each time this init function is called
* (part of the code is from wr_nic/module.c).
*/
static
void
wrn_release
(
struct
device
*
dev
)
{
/* nothing to do, but mandatory function */
pr_debug
(
"%s
\n
"
,
__func__
);
}
static
struct
platform_device
wrn_pdev
=
{
/* other fields filled after it's copied: see wrn_eth_init() */
.
name
=
KBUILD_MODNAME
,
.
dev
.
release
=
&
wrn_release
,
};
irqreturn_t
wrn_handler
(
int
irq
,
void
*
dev_id
)
{
struct
fmc_device
*
fmc
=
dev_id
;
fmc
->
op
->
irq_ack
(
fmc
);
printk
(
"%s: irq %i
\n
"
,
__func__
,
irq
);
return
IRQ_HANDLED
;
}
static
struct
wrn_core
{
const
char
*
name
;
uint64_t
vendor
;
uint32_t
device
;
}
wrn_cores
[]
=
{
[
WRN_FB_NIC
]
=
{
"NIC"
,
SDB_CERN
,
WRN_SDB_NIC
},
[
WRN_FB_EP
]
=
{
"Endpoint"
,
SDB_CERN
,
WRN_SDB_EP
},
[
WRN_FB_PPSG
]
=
{
"PPS-Gen"
,
SDB_CERN
,
WRN_SDB_PPSG
},
[
WRN_FB_TS
]
=
{
"Tx-Stamp"
,
SDB_CERN
,
WRN_SDB_TS
},
};
int
wrn_eth_init
(
struct
fmc_device
*
fmc
)
{
struct
device
*
dev
=
fmc
->
hwdev
;
struct
resource
*
resarr
;
struct
platform_device
*
pdev
;
struct
wrn_drvdata
*
drvdata
;
struct
wrn_dev
*
wrn
;
struct
wrn_core
*
c
;
int
i
,
ret
;
ret
=
fmc
->
op
->
irq_request
(
fmc
,
wrn_handler
,
"wr-nic"
,
0
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"Can't request interrupt
\n
"
);
return
ret
;
}
/* Make a copy of the platform device and register it */
ret
=
-
ENOMEM
;
pdev
=
kmemdup
(
&
wrn_pdev
,
sizeof
(
wrn_pdev
),
GFP_KERNEL
);
resarr
=
kzalloc
(
sizeof
(
*
resarr
)
*
ARRAY_SIZE
(
wrn_cores
),
GFP_KERNEL
);
drvdata
=
kzalloc
(
sizeof
(
*
drvdata
),
GFP_KERNEL
);
wrn
=
kzalloc
(
sizeof
(
*
wrn
),
GFP_KERNEL
);
if
(
!
pdev
||
!
resarr
||
!
drvdata
||
!
wrn
)
goto
out_mem
;
for
(
i
=
0
,
c
=
wrn_cores
;
i
<
ARRAY_SIZE
(
wrn_cores
);
i
++
,
c
++
)
{
signed
long
start
;
unsigned
long
size
;
start
=
fmc_find_sdb_device
(
fmc
->
sdb
,
c
->
vendor
,
c
->
device
,
&
size
);
if
(
start
<
0
)
{
dev_err
(
dev
,
"Can't find sdb core
\"
%s
\"\n
"
,
c
->
name
);
goto
out_mem
;
}
dev_info
(
dev
,
"core
\"
%s
\"
: offset %08lx
\n
"
,
c
->
name
,
start
);
resarr
[
i
].
name
=
c
->
name
;
resarr
[
i
].
flags
=
IORESOURCE_MEM
;
resarr
[
i
].
start
=
(
unsigned
long
)
fmc
->
base
+
start
;
resarr
[
i
].
end
=
resarr
[
i
].
start
+
size
-
1
;
}
pdev
->
resource
=
resarr
;
pdev
->
num_resources
=
ARRAY_SIZE
(
wrn_cores
);
drvdata
->
wrn
=
wrn
;
drvdata
->
fmc
=
fmc
;
/* FIXME: drvdata->gpio_base etc */
pdev
->
dev
.
platform_data
=
drvdata
;
fmc
->
mezzanine_data
=
pdev
;
platform_device_register
(
pdev
);
wrn_pdev
.
id
++
;
/* for the next one */
return
0
;
out_mem:
kfree
(
wrn
);
kfree
(
drvdata
);
kfree
(
resarr
);
kfree
(
pdev
);
fmc
->
op
->
irq_free
(
fmc
);
return
ret
;
}
void
wrn_eth_exit
(
struct
fmc_device
*
fmc
)
{
struct
platform_device
*
pdev
=
fmc
->
mezzanine_data
;
struct
wrn_drvdata
*
drvdata
=
pdev
->
dev
.
platform_data
;
platform_device_unregister
(
pdev
);
kfree
(
drvdata
->
wrn
);
kfree
(
drvdata
);
kfree
(
pdev
->
resource
);
kfree
(
pdev
);
fmc
->
mezzanine_data
=
NULL
;
fmc
->
op
->
irq_free
(
fmc
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment