Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
03965cfa
Commit
03965cfa
authored
Apr 03, 2002
by
Dave Jones
Committed by
Jeff Garzik
Apr 03, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge ioc3-eth net drvr changes from 2.4.x:
- Improved MAC address discovery. - endian fixes
parent
cefa7b19
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
135 additions
and
23 deletions
+135
-23
drivers/net/ioc3-eth.c
drivers/net/ioc3-eth.c
+135
-23
No files found.
drivers/net/ioc3-eth.c
View file @
03965cfa
...
@@ -341,14 +341,15 @@ static int nic_init(struct ioc3 *ioc3)
...
@@ -341,14 +341,15 @@ static int nic_init(struct ioc3 *ioc3)
}
}
/*
/*
* Read the NIC (Number-In-a-Can) device.
* Read the NIC (Number-In-a-Can) device used to store the MAC address on
* SN0 / SN00 nodeboards and PCI cards.
*/
*/
static
void
ioc3_get_eaddr
(
struct
ioc3_private
*
ip
)
static
void
ioc3_get_eaddr
_nic
(
struct
ioc3_private
*
ip
)
{
{
struct
ioc3
*
ioc3
=
ip
->
regs
;
struct
ioc3
*
ioc3
=
ip
->
regs
;
u8
nic
[
14
];
u8
nic
[
14
];
int
i
;
int
tries
=
2
;
/* There may be some problem with the battery? */
int
tries
=
2
;
/* There may be some problem with the battery? */
int
i
;
ioc3_w
(
gpcr_s
,
(
1
<<
21
));
ioc3_w
(
gpcr_s
,
(
1
<<
21
));
...
@@ -371,16 +372,123 @@ static void ioc3_get_eaddr(struct ioc3_private *ip)
...
@@ -371,16 +372,123 @@ static void ioc3_get_eaddr(struct ioc3_private *ip)
for
(
i
=
13
;
i
>=
0
;
i
--
)
for
(
i
=
13
;
i
>=
0
;
i
--
)
nic
[
i
]
=
nic_read_byte
(
ioc3
);
nic
[
i
]
=
nic_read_byte
(
ioc3
);
printk
(
"Ethernet address is "
);
for
(
i
=
2
;
i
<
8
;
i
++
)
for
(
i
=
2
;
i
<
8
;
i
++
)
{
ip
->
dev
->
dev_addr
[
i
-
2
]
=
nic
[
i
];
ip
->
dev
->
dev_addr
[
i
-
2
]
=
nic
[
i
];
printk
(
"%02x"
,
nic
[
i
]);
}
#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2)
/*
* Get the ether-address on SN1 nodes
*/
static
void
ioc3_get_eaddr_sn
(
struct
ioc3_private
*
ip
)
{
int
ibrick_mac_addr_get
(
nasid_t
,
char
*
);
struct
ioc3
*
ioc3
=
ip
->
regs
;
nasid_t
nasid_of_ioc3
;
char
io7eaddr
[
20
];
long
mac
;
int
err_val
;
/*
* err_val = ibrick_mac_addr_get(get_nasid(), io7eaddr );
*
* BAD!! The above call uses get_nasid() and assumes that
* the ioc3 pointed to by struct ioc3 is hooked up to the
* cbrick that we're running on. The proper way to make this call
* is to figure out which nasid the ioc3 is connected to
* and use that to call ibrick_mac_addr_get. Below is
* a hack to do just that.
*/
/*
* Get the nasid of the ioc3 from the ioc3's base addr.
* FIXME: the 8 at the end assumes we're in memory mode,
* not node mode (for that, we'd change it to a 9).
* Is there a call to extract this info from a physical
* addr somewhere in an sn header file already? If so,
* we should probably use that, or restructure this routine
* to use pci_dev and generic numa nodeid getting stuff.
*/
nasid_of_ioc3
=
(((
unsigned
long
)
ioc3
>>
33
)
&
~
(
-
1
<<
8
));
err_val
=
ibrick_mac_addr_get
(
nasid_of_ioc3
,
io7eaddr
);
if
(
err_val
)
{
/* Couldn't read the eeprom; try OSLoadOptions. */
printk
(
"WARNING: ibrick_mac_addr_get failed: %d
\n
"
,
err_val
);
/* this is where we hardwire the mac address
* 1st ibrick had 08:00:69:11:34:75
* 2nd ibrick had 08:00:69:11:35:35
*
* Eagan Machines:
* mankato1 08:00:69:11:BE:95
* warroad 08:00:69:11:bd:60
* duron 08:00:69:11:34:60
*
* an easy way to get the mac address is to hook
* up an ip35, then from L1 do 'cti serial'
* and then look for MAC line XXX THIS DOESN"T QUITE WORK!!
*/
printk
(
"ioc3_get_eaddr: setting ethernet address to:
\n
-----> "
);
ip
->
dev
->
dev_addr
[
0
]
=
0x8
;
ip
->
dev
->
dev_addr
[
1
]
=
0x0
;
ip
->
dev
->
dev_addr
[
2
]
=
0x69
;
ip
->
dev
->
dev_addr
[
3
]
=
0x11
;
ip
->
dev
->
dev_addr
[
4
]
=
0x34
;
ip
->
dev
->
dev_addr
[
5
]
=
0x60
;
}
else
{
long
simple_strtol
(
const
char
*
,
char
**
,
unsigned
int
);
mac
=
simple_strtol
(
io7eaddr
,
(
char
**
)
0
,
16
);
ip
->
dev
->
dev_addr
[
0
]
=
(
mac
>>
40
)
&
0xff
;
ip
->
dev
->
dev_addr
[
1
]
=
(
mac
>>
32
)
&
0xff
;
ip
->
dev
->
dev_addr
[
2
]
=
(
mac
>>
24
)
&
0xff
;
ip
->
dev
->
dev_addr
[
3
]
=
(
mac
>>
16
)
&
0xff
;
ip
->
dev
->
dev_addr
[
4
]
=
(
mac
>>
8
)
&
0xff
;
ip
->
dev
->
dev_addr
[
5
]
=
mac
&
0xff
;
}
}
#endif
/*
* Ok, this is hosed by design. It's necessary to know what machine the
* NIC is in in order to know how to read the NIC address. We also have
* to know if it's a PCI card or a NIC in on the node board ...
*/
static
void
ioc3_get_eaddr
(
struct
ioc3_private
*
ip
)
{
void
(
*
do_get_eaddr
)(
struct
ioc3_private
*
ip
)
=
NULL
;
int
i
;
/*
* We should also use this code for PCI cards, no matter what host
* machine but how to know that we're a PCI card?
*/
#ifdef CONFIG_SGI_IP27
do_get_eaddr
=
ioc3_get_eaddr_nic
;
#endif
#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2)
do_get_eaddr
=
ioc3_get_eaddr_sn
;
#endif
if
(
!
do_get_eaddr
)
{
printk
(
KERN_ERR
"Don't know how to read MAC address of this "
"IOC3 NIC
\n
"
);
return
;
}
printk
(
"Ethernet address is "
);
for
(
i
=
0
;
i
<
6
;
i
++
)
{
printk
(
"%02x"
,
ip
->
dev
->
dev_addr
[
i
]);
if
(
i
<
7
)
if
(
i
<
7
)
printk
(
":"
);
printk
(
":"
);
}
}
printk
(
".
\n
"
);
printk
(
".
\n
"
);
}
}
/*
/*
* Caller must hold the ioc3_lock ever for MII readers. This is also
* Caller must hold the ioc3_lock ever for MII readers. This is also
* used to protect the transmitter side but it's low contention.
* used to protect the transmitter side but it's low contention.
...
@@ -435,10 +543,10 @@ ioc3_rx(struct ioc3_private *ip)
...
@@ -435,10 +543,10 @@ ioc3_rx(struct ioc3_private *ip)
skb
=
ip
->
rx_skbs
[
rx_entry
];
skb
=
ip
->
rx_skbs
[
rx_entry
];
rxb
=
(
struct
ioc3_erxbuf
*
)
(
skb
->
data
-
RX_OFFSET
);
rxb
=
(
struct
ioc3_erxbuf
*
)
(
skb
->
data
-
RX_OFFSET
);
w0
=
rxb
->
w0
;
w0
=
be32_to_cpu
(
rxb
->
w0
)
;
while
(
w0
&
ERXBUF_V
)
{
while
(
w0
&
ERXBUF_V
)
{
err
=
rxb
->
err
;
/* It's valid ... */
err
=
be32_to_cpu
(
rxb
->
err
);
/* It's valid ... */
if
(
err
&
ERXBUF_GOODPKT
)
{
if
(
err
&
ERXBUF_GOODPKT
)
{
len
=
((
w0
>>
ERXBUF_BYTECNT_SHIFT
)
&
0x7ff
)
-
4
;
len
=
((
w0
>>
ERXBUF_BYTECNT_SHIFT
)
&
0x7ff
)
-
4
;
skb_trim
(
skb
,
len
);
skb_trim
(
skb
,
len
);
...
@@ -479,8 +587,8 @@ ioc3_rx(struct ioc3_private *ip)
...
@@ -479,8 +587,8 @@ ioc3_rx(struct ioc3_private *ip)
ip
->
stats
.
rx_frame_errors
++
;
ip
->
stats
.
rx_frame_errors
++
;
next:
next:
ip
->
rx_skbs
[
n_entry
]
=
new_skb
;
ip
->
rx_skbs
[
n_entry
]
=
new_skb
;
rxr
[
n_entry
]
=
(
0xa5UL
<<
56
)
|
rxr
[
n_entry
]
=
cpu_to_be32
(
(
0xa5UL
<<
56
)
|
((
unsigned
long
)
rxb
&
TO_PHYS_MASK
);
((
unsigned
long
)
rxb
&
TO_PHYS_MASK
)
);
rxb
->
w0
=
0
;
/* Clear valid flag */
rxb
->
w0
=
0
;
/* Clear valid flag */
n_entry
=
(
n_entry
+
1
)
&
511
;
/* Update erpir */
n_entry
=
(
n_entry
+
1
)
&
511
;
/* Update erpir */
...
@@ -488,7 +596,7 @@ ioc3_rx(struct ioc3_private *ip)
...
@@ -488,7 +596,7 @@ ioc3_rx(struct ioc3_private *ip)
rx_entry
=
(
rx_entry
+
1
)
&
511
;
rx_entry
=
(
rx_entry
+
1
)
&
511
;
skb
=
ip
->
rx_skbs
[
rx_entry
];
skb
=
ip
->
rx_skbs
[
rx_entry
];
rxb
=
(
struct
ioc3_erxbuf
*
)
(
skb
->
data
-
RX_OFFSET
);
rxb
=
(
struct
ioc3_erxbuf
*
)
(
skb
->
data
-
RX_OFFSET
);
w0
=
rxb
->
w0
;
w0
=
be32_to_cpu
(
rxb
->
w0
)
;
}
}
ioc3
->
erpir
=
(
n_entry
<<
3
)
|
ERPIR_ARM
;
ioc3
->
erpir
=
(
n_entry
<<
3
)
|
ERPIR_ARM
;
ip
->
rx_pi
=
n_entry
;
ip
->
rx_pi
=
n_entry
;
...
@@ -1190,8 +1298,8 @@ ioc3_alloc_rings(struct net_device *dev, struct ioc3_private *ip,
...
@@ -1190,8 +1298,8 @@ ioc3_alloc_rings(struct net_device *dev, struct ioc3_private *ip,
/* Because we reserve afterwards. */
/* Because we reserve afterwards. */
skb_put
(
skb
,
(
1664
+
RX_OFFSET
));
skb_put
(
skb
,
(
1664
+
RX_OFFSET
));
rxb
=
(
struct
ioc3_erxbuf
*
)
skb
->
data
;
rxb
=
(
struct
ioc3_erxbuf
*
)
skb
->
data
;
rxr
[
i
]
=
(
0xa5UL
<<
56
)
rxr
[
i
]
=
cpu_to_be64
((
0xa5UL
<<
56
)
|
|
((
unsigned
long
)
rxb
&
TO_PHYS_MASK
);
((
unsigned
long
)
rxb
&
TO_PHYS_MASK
)
);
skb_reserve
(
skb
,
RX_OFFSET
);
skb_reserve
(
skb
,
RX_OFFSET
);
}
}
ip
->
rx_ci
=
0
;
ip
->
rx_ci
=
0
;
...
@@ -1555,8 +1663,8 @@ ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -1555,8 +1663,8 @@ ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
memset
(
desc
->
data
+
len
,
0
,
ETH_ZLEN
-
len
);
memset
(
desc
->
data
+
len
,
0
,
ETH_ZLEN
-
len
);
len
=
ETH_ZLEN
;
len
=
ETH_ZLEN
;
}
}
desc
->
cmd
=
len
|
ETXD_INTWHENDONE
|
ETXD_D0V
;
desc
->
cmd
=
cpu_to_be32
(
len
|
ETXD_INTWHENDONE
|
ETXD_D0V
)
;
desc
->
bufcnt
=
len
;
desc
->
bufcnt
=
cpu_to_be32
(
len
)
;
}
else
if
((
data
^
(
data
+
len
))
&
0x4000
)
{
}
else
if
((
data
^
(
data
+
len
))
&
0x4000
)
{
unsigned
long
b2
,
s1
,
s2
;
unsigned
long
b2
,
s1
,
s2
;
...
@@ -1564,16 +1672,20 @@ ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -1564,16 +1672,20 @@ ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
s1
=
b2
-
data
;
s1
=
b2
-
data
;
s2
=
data
+
len
-
b2
;
s2
=
data
+
len
-
b2
;
desc
->
cmd
=
len
|
ETXD_INTWHENDONE
|
ETXD_B1V
|
ETXD_B2V
;
desc
->
cmd
=
cpu_to_be32
(
len
|
ETXD_INTWHENDONE
|
desc
->
bufcnt
=
(
s1
<<
ETXD_B1CNT_SHIFT
)
|
ETXD_B1V
|
ETXD_B2V
);
(
s2
<<
ETXD_B2CNT_SHIFT
);
desc
->
bufcnt
=
cpu_to_be32
((
s1
<<
ETXD_B1CNT_SHIFT
)
desc
->
p1
=
(
0xa5UL
<<
56
)
|
(
data
&
TO_PHYS_MASK
);
|
(
s2
<<
ETXD_B2CNT_SHIFT
));
desc
->
p2
=
(
0xa5UL
<<
56
)
|
(
data
&
TO_PHYS_MASK
);
desc
->
p1
=
cpu_to_be64
((
0xa5UL
<<
56
)
|
(
data
&
TO_PHYS_MASK
));
desc
->
p2
=
cpu_to_be64
((
0xa5UL
<<
56
)
|
(
data
&
TO_PHYS_MASK
));
}
else
{
}
else
{
/* Normal sized packet that doesn't cross a page boundary. */
/* Normal sized packet that doesn't cross a page boundary. */
desc
->
cmd
=
len
|
ETXD_INTWHENDONE
|
ETXD_B1V
;
desc
->
cmd
=
cpu_to_be32
(
len
|
ETXD_INTWHENDONE
|
ETXD_B1V
);
desc
->
bufcnt
=
len
<<
ETXD_B1CNT_SHIFT
;
desc
->
bufcnt
=
cpu_to_be32
(
len
<<
ETXD_B1CNT_SHIFT
);
desc
->
p1
=
(
0xa5UL
<<
56
)
|
(
data
&
TO_PHYS_MASK
);
desc
->
p1
=
cpu_to_be64
((
0xa5UL
<<
56
)
|
(
data
&
TO_PHYS_MASK
));
}
}
BARRIER
();
BARRIER
();
...
...
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