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
1d0c1d0b
Commit
1d0c1d0b
authored
Jun 18, 2002
by
Chad N. Tindel
Committed by
David S. Miller
Jun 18, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drivers/net/bonding.c: Check ethtool then mii ioctl to determine link status.
parent
32a352e6
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
107 additions
and
18 deletions
+107
-18
drivers/net/bonding.c
drivers/net/bonding.c
+107
-18
No files found.
drivers/net/bonding.c
View file @
1d0c1d0b
...
@@ -176,6 +176,16 @@
...
@@ -176,6 +176,16 @@
* Steve Mead <steve.mead at comdev dot cc>
* Steve Mead <steve.mead at comdev dot cc>
* - Port Gleb Natapov's multicast support patchs from 2.4.12
* - Port Gleb Natapov's multicast support patchs from 2.4.12
* to 2.4.18 adding support for multicast.
* to 2.4.18 adding support for multicast.
*
* 2002/06/17 - Tony Cureington <tony.cureington * hp_com>
* - corrected uninitialized pointer (ifr.ifr_data) in bond_check_dev_link;
* actually changed function to use ETHTOOL, then MIIPHY, and finally
* MIIREG to determine the link status
* - fixed bad ifr_data pointer assignments in bond_ioctl
* - corrected mode 1 being reported as active-backup in bond_get_info;
* also added text to distinguish type of load balancing (rr or xor)
* - change arp_ip_target module param from "1-12s" (array of 12 ptrs)
* to "s" (a single ptr)
*/
*/
#include <linux/config.h>
#include <linux/config.h>
...
@@ -210,6 +220,9 @@
...
@@ -210,6 +220,9 @@
#include <linux/smp.h>
#include <linux/smp.h>
#include <linux/if_ether.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/if_arp.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
/* monitor all links that often (in milliseconds). <=0 disables monitoring */
/* monitor all links that often (in milliseconds). <=0 disables monitoring */
#ifndef BOND_LINK_MON_INTERV
#ifndef BOND_LINK_MON_INTERV
...
@@ -253,7 +266,7 @@ MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
...
@@ -253,7 +266,7 @@ MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
MODULE_PARM
(
mode
,
"i"
);
MODULE_PARM
(
mode
,
"i"
);
MODULE_PARM
(
arp_interval
,
"i"
);
MODULE_PARM
(
arp_interval
,
"i"
);
MODULE_PARM_DESC
(
arp_interval
,
"arp interval in milliseconds"
);
MODULE_PARM_DESC
(
arp_interval
,
"arp interval in milliseconds"
);
MODULE_PARM
(
arp_ip_target
,
"
1-12
s"
);
MODULE_PARM
(
arp_ip_target
,
"s"
);
MODULE_PARM_DESC
(
arp_ip_target
,
"arp target in n.n.n.n form"
);
MODULE_PARM_DESC
(
arp_ip_target
,
"arp target in n.n.n.n form"
);
MODULE_PARM_DESC
(
mode
,
"Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor"
);
MODULE_PARM_DESC
(
mode
,
"Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor"
);
MODULE_PARM
(
updelay
,
"i"
);
MODULE_PARM
(
updelay
,
"i"
);
...
@@ -386,21 +399,51 @@ static u16 bond_check_dev_link(struct net_device *dev)
...
@@ -386,21 +399,51 @@ static u16 bond_check_dev_link(struct net_device *dev)
{
{
static
int
(
*
ioctl
)(
struct
net_device
*
,
struct
ifreq
*
,
int
);
static
int
(
*
ioctl
)(
struct
net_device
*
,
struct
ifreq
*
,
int
);
struct
ifreq
ifr
;
struct
ifreq
ifr
;
u16
*
data
=
(
u16
*
)
&
ifr
.
ifr_data
;
struct
mii_ioctl_data
mii
;
struct
ethtool_value
etool
;
/* data[0] automagically filled by the ioctl */
data
[
1
]
=
1
;
/* MII location 1 reports Link Status */
if
((
ioctl
=
dev
->
do_ioctl
)
!=
NULL
)
{
/* ioctl to access MII */
/* TODO: set pointer to correct ioctl on a per team member */
/* bases to make this more efficient. that is, once */
/* we determine the correct ioctl, we will always */
/* call it and not the others for that team */
/* member. */
/* try SOICETHTOOL ioctl, some drivers cache ETHTOOL_GLINK */
/* for a period of time; we need to encourage link status */
/* be reported by network drivers in real time; if the */
/* value is cached, the mmimon module parm may have no */
/* effect... */
etool
.
cmd
=
ETHTOOL_GLINK
;
ifr
.
ifr_data
=
(
char
*
)
&
etool
;
if
(
ioctl
(
dev
,
&
ifr
,
SIOCETHTOOL
)
==
0
)
{
if
(
etool
.
data
==
1
)
{
return
(
MII_LINK_READY
);
}
else
{
return
(
0
);
}
}
if
(((
ioctl
=
dev
->
do_ioctl
)
!=
NULL
)
&&
/* ioctl to access MII */
ifr
.
ifr_data
=
(
char
*
)
&
mii
;
(
ioctl
(
dev
,
&
ifr
,
SIOCGMIIPHY
)
==
0
))
{
/* try MIIPHY first then, if that doesn't work, try MIIREG */
/* now, data[3] contains info about link status :
if
(
ioctl
(
dev
,
&
ifr
,
SIOCGMIIPHY
)
==
0
)
{
- data[3] & 0x04 means link up
/* now, mii.phy_id contains info about link status :
- data[3] & 0x20 means end of auto-negociation
- mii.phy_id & 0x04 means link up
- mii.phy_id & 0x20 means end of auto-negociation
*/
*/
return
data
[
3
];
return
mii
.
phy_id
;
}
else
{
return
MII_LINK_READY
;
/* spoof link up ( we can't check it) */
}
}
mii
.
reg_num
=
1
;
/* the MII register we want to read */
if
(
ioctl
(
dev
,
&
ifr
,
SIOCGMIIREG
)
==
0
)
{
/* mii.val_out contians the same link info as phy_id */
/* above */
return
mii
.
val_out
;
}
}
return
MII_LINK_READY
;
/* spoof link up ( we can't check it) */
}
}
static
u16
bond_check_mii_link
(
bonding_t
*
bond
)
static
u16
bond_check_mii_link
(
bonding_t
*
bond
)
...
@@ -1707,7 +1750,7 @@ static int bond_ioctl(struct net_device *master_dev, struct ifreq *ifr, int cmd)
...
@@ -1707,7 +1750,7 @@ static int bond_ioctl(struct net_device *master_dev, struct ifreq *ifr, int cmd)
switch
(
cmd
)
{
switch
(
cmd
)
{
case
SIOCGMIIPHY
:
case
SIOCGMIIPHY
:
data
=
(
u16
*
)
&
ifr
->
ifr_data
;
data
=
(
u16
*
)
ifr
->
ifr_data
;
if
(
data
==
NULL
)
{
if
(
data
==
NULL
)
{
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -1718,7 +1761,7 @@ static int bond_ioctl(struct net_device *master_dev, struct ifreq *ifr, int cmd)
...
@@ -1718,7 +1761,7 @@ static int bond_ioctl(struct net_device *master_dev, struct ifreq *ifr, int cmd)
* We do this again just in case we were called by SIOCGMIIREG
* We do this again just in case we were called by SIOCGMIIREG
* instead of SIOCGMIIPHY.
* instead of SIOCGMIIPHY.
*/
*/
data
=
(
u16
*
)
&
ifr
->
ifr_data
;
data
=
(
u16
*
)
ifr
->
ifr_data
;
if
(
data
==
NULL
)
{
if
(
data
==
NULL
)
{
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -2035,7 +2078,28 @@ static int bond_get_info(char *buf, char **start, off_t offset, int length)
...
@@ -2035,7 +2078,28 @@ static int bond_get_info(char *buf, char **start, off_t offset, int length)
link
=
bond_check_mii_link
(
bond
);
link
=
bond_check_mii_link
(
bond
);
len
+=
sprintf
(
buf
+
len
,
"Bonding Mode: "
);
len
+=
sprintf
(
buf
+
len
,
"Bonding Mode: "
);
len
+=
sprintf
(
buf
+
len
,
"%s
\n
"
,
mode
?
"active-backup"
:
"load balancing"
);
switch
(
mode
)
{
case
BOND_MODE_ACTIVEBACKUP
:
len
+=
sprintf
(
buf
+
len
,
"%s
\n
"
,
"active-backup"
);
break
;
case
BOND_MODE_ROUNDROBIN
:
len
+=
sprintf
(
buf
+
len
,
"%s
\n
"
,
"load balancing (round-robin)"
);
break
;
case
BOND_MODE_XOR
:
len
+=
sprintf
(
buf
+
len
,
"%s
\n
"
,
"load balancing (xor)"
);
break
;
default:
len
+=
sprintf
(
buf
+
len
,
"%s
\n
"
,
"unknown"
);
break
;
}
if
(
mode
==
BOND_MODE_ACTIVEBACKUP
)
{
if
(
mode
==
BOND_MODE_ACTIVEBACKUP
)
{
read_lock_irqsave
(
&
bond
->
lock
,
flags
);
read_lock_irqsave
(
&
bond
->
lock
,
flags
);
...
@@ -2282,7 +2346,32 @@ static int __init bonding_init(void)
...
@@ -2282,7 +2346,32 @@ static int __init bonding_init(void)
}
}
memset
(
dev_bonds
,
0
,
max_bonds
*
sizeof
(
struct
net_device
));
memset
(
dev_bonds
,
0
,
max_bonds
*
sizeof
(
struct
net_device
));
if
(
updelay
<
0
)
{
printk
(
KERN_WARNING
"bonding_init(): updelay module parameter (%d), "
"not in range 0-%d, so it was reset to 0
\n
"
,
updelay
,
INT_MAX
);
updelay
=
0
;
}
if
(
downdelay
<
0
)
{
printk
(
KERN_WARNING
"bonding_init(): downdelay module parameter (%d), "
"not in range 0-%d, so it was reset to 0
\n
"
,
downdelay
,
INT_MAX
);
downdelay
=
0
;
}
if
(
arp_interval
<
0
)
{
printk
(
KERN_WARNING
"bonding_init(): arp_interval module parameter (%d), "
"not in range 0-%d, so it was reset to %d
\n
"
,
arp_interval
,
INT_MAX
,
BOND_LINK_ARP_INTERV
);
arp_interval
=
BOND_LINK_ARP_INTERV
;
}
if
(
arp_ip_target
)
{
if
(
arp_ip_target
)
{
/* TODO: check and log bad ip address */
if
(
my_inet_aton
(
arp_ip_target
,
&
arp_target
)
==
0
)
{
if
(
my_inet_aton
(
arp_ip_target
,
&
arp_target
)
==
0
)
{
arp_interval
=
0
;
arp_interval
=
0
;
}
}
...
...
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