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
17c5cde7
Commit
17c5cde7
authored
May 04, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[netdrvr b44] ethtool_ops support
parent
4003ce2e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
199 additions
and
214 deletions
+199
-214
drivers/net/b44.c
drivers/net/b44.c
+199
-214
No files found.
drivers/net/b44.c
View file @
17c5cde7
...
...
@@ -27,8 +27,8 @@
#define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.9
3
"
#define DRV_MODULE_RELDATE "Ma
r
, 2004"
#define DRV_MODULE_VERSION "0.9
4
"
#define DRV_MODULE_RELDATE "Ma
y 4
, 2004"
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
...
...
@@ -1373,247 +1373,234 @@ static void b44_set_rx_mode(struct net_device *dev)
spin_unlock_irq
(
&
bp
->
lock
);
}
static
int
b44_ethtool_ioctl
(
struct
net_device
*
dev
,
void
__user
*
useraddr
)
static
u32
b44_get_msglevel
(
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
);
return
bp
->
msg_enable
;
}
static
void
b44_set_msglevel
(
struct
net_device
*
dev
,
u32
value
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
bp
->
msg_enable
=
value
;
}
static
void
b44_get_drvinfo
(
struct
net_device
*
dev
,
struct
ethtool_drvinfo
*
info
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
struct
pci_dev
*
pci_dev
=
bp
->
pdev
;
u32
ethcmd
;
if
(
copy_from_user
(
&
ethcmd
,
useraddr
,
sizeof
(
ethcmd
)))
return
-
EFAULT
;
switch
(
ethcmd
)
{
case
ETHTOOL_GDRVINFO
:
{
struct
ethtool_drvinfo
info
=
{
ETHTOOL_GDRVINFO
};
strcpy
(
info
.
driver
,
DRV_MODULE_NAME
);
strcpy
(
info
.
version
,
DRV_MODULE_VERSION
);
memset
(
&
info
.
fw_version
,
0
,
sizeof
(
info
.
fw_version
));
strcpy
(
info
.
bus_info
,
pci_name
(
pci_dev
));
info
.
eedump_len
=
0
;
info
.
regdump_len
=
0
;
if
(
copy_to_user
(
useraddr
,
&
info
,
sizeof
(
info
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_GSET
:
{
struct
ethtool_cmd
cmd
=
{
ETHTOOL_GSET
};
strcpy
(
info
->
driver
,
DRV_MODULE_NAME
);
strcpy
(
info
->
version
,
DRV_MODULE_VERSION
);
strcpy
(
info
->
bus_info
,
pci_name
(
pci_dev
));
}
if
(
!
(
bp
->
flags
&
B44_FLAG_INIT_COMPLETE
))
return
-
EAGAIN
;
cmd
.
supported
=
(
SUPPORTED_Autoneg
);
cmd
.
supported
|=
(
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
|
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
SUPPORTED_MII
);
static
int
b44_nway_reset
(
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
u32
bmcr
;
int
r
;
cmd
.
advertising
=
0
;
if
(
bp
->
flags
&
B44_FLAG_ADV_10HALF
)
cmd
.
advertising
|=
ADVERTISE_10HALF
;
if
(
bp
->
flags
&
B44_FLAG_ADV_10FULL
)
cmd
.
advertising
|=
ADVERTISE_10FULL
;
if
(
bp
->
flags
&
B44_FLAG_ADV_100HALF
)
cmd
.
advertising
|=
ADVERTISE_100HALF
;
if
(
bp
->
flags
&
B44_FLAG_ADV_100FULL
)
cmd
.
advertising
|=
ADVERTISE_100FULL
;
cmd
.
advertising
|=
ADVERTISE_PAUSE_CAP
|
ADVERTISE_PAUSE_ASYM
;
cmd
.
speed
=
(
bp
->
flags
&
B44_FLAG_100_BASE_T
)
?
SPEED_100
:
SPEED_10
;
cmd
.
duplex
=
(
bp
->
flags
&
B44_FLAG_FULL_DUPLEX
)
?
DUPLEX_FULL
:
DUPLEX_HALF
;
cmd
.
port
=
0
;
cmd
.
phy_address
=
bp
->
phy_addr
;
cmd
.
transceiver
=
(
bp
->
flags
&
B44_FLAG_INTERNAL_PHY
)
?
XCVR_INTERNAL
:
XCVR_EXTERNAL
;
cmd
.
autoneg
=
(
bp
->
flags
&
B44_FLAG_FORCE_LINK
)
?
AUTONEG_DISABLE
:
AUTONEG_ENABLE
;
cmd
.
maxtxpkt
=
0
;
cmd
.
maxrxpkt
=
0
;
if
(
copy_to_user
(
useraddr
,
&
cmd
,
sizeof
(
cmd
)))
return
-
EFAULT
;
return
0
;
spin_lock_irq
(
&
bp
->
lock
);
b44_readphy
(
bp
,
MII_BMCR
,
&
bmcr
);
b44_readphy
(
bp
,
MII_BMCR
,
&
bmcr
);
r
=
-
EINVAL
;
if
(
bmcr
&
BMCR_ANENABLE
)
{
b44_writephy
(
bp
,
MII_BMCR
,
bmcr
|
BMCR_ANRESTART
);
r
=
0
;
}
case
ETHTOOL_SSET
:
{
struct
ethtool_cmd
cmd
;
if
(
!
(
bp
->
flags
&
B44_FLAG_INIT_COMPLETE
))
return
-
EAGAIN
;
if
(
copy_from_user
(
&
cmd
,
useraddr
,
sizeof
(
cmd
)))
return
-
EFAULT
;
/* We do not support gigabit. */
if
(
cmd
.
autoneg
==
AUTONEG_ENABLE
)
{
if
(
cmd
.
advertising
&
(
ADVERTISED_1000baseT_Half
|
ADVERTISED_1000baseT_Full
))
return
-
EINVAL
;
}
else
if
((
cmd
.
speed
!=
SPEED_100
&&
cmd
.
speed
!=
SPEED_10
)
||
(
cmd
.
duplex
!=
DUPLEX_HALF
&&
cmd
.
duplex
!=
DUPLEX_FULL
))
{
return
-
EINVAL
;
}
spin_unlock_irq
(
&
bp
->
lock
);
spin_lock_irq
(
&
bp
->
lock
);
return
r
;
}
if
(
cmd
.
autoneg
==
AUTONEG_ENABLE
)
{
bp
->
flags
&=
~
B44_FLAG_FORCE_LINK
;
bp
->
flags
&=
~
(
B44_FLAG_ADV_10HALF
|
B44_FLAG_ADV_10FULL
|
B44_FLAG_ADV_100HALF
|
B44_FLAG_ADV_100FULL
);
if
(
cmd
.
advertising
&
ADVERTISE_10HALF
)
bp
->
flags
|=
B44_FLAG_ADV_10HALF
;
if
(
cmd
.
advertising
&
ADVERTISE_10FULL
)
bp
->
flags
|=
B44_FLAG_ADV_10FULL
;
if
(
cmd
.
advertising
&
ADVERTISE_100HALF
)
bp
->
flags
|=
B44_FLAG_ADV_100HALF
;
if
(
cmd
.
advertising
&
ADVERTISE_100FULL
)
bp
->
flags
|=
B44_FLAG_ADV_100FULL
;
}
else
{
bp
->
flags
|=
B44_FLAG_FORCE_LINK
;
if
(
cmd
.
speed
==
SPEED_100
)
bp
->
flags
|=
B44_FLAG_100_BASE_T
;
if
(
cmd
.
duplex
==
DUPLEX_FULL
)
bp
->
flags
|=
B44_FLAG_FULL_DUPLEX
;
}
static
int
b44_get_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
cmd
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
if
(
!
(
bp
->
flags
&
B44_FLAG_INIT_COMPLETE
))
return
-
EAGAIN
;
cmd
->
supported
=
(
SUPPORTED_Autoneg
);
cmd
->
supported
|=
(
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
|
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
SUPPORTED_MII
);
cmd
->
advertising
=
0
;
if
(
bp
->
flags
&
B44_FLAG_ADV_10HALF
)
cmd
->
advertising
|=
ADVERTISE_10HALF
;
if
(
bp
->
flags
&
B44_FLAG_ADV_10FULL
)
cmd
->
advertising
|=
ADVERTISE_10FULL
;
if
(
bp
->
flags
&
B44_FLAG_ADV_100HALF
)
cmd
->
advertising
|=
ADVERTISE_100HALF
;
if
(
bp
->
flags
&
B44_FLAG_ADV_100FULL
)
cmd
->
advertising
|=
ADVERTISE_100FULL
;
cmd
->
advertising
|=
ADVERTISE_PAUSE_CAP
|
ADVERTISE_PAUSE_ASYM
;
cmd
->
speed
=
(
bp
->
flags
&
B44_FLAG_100_BASE_T
)
?
SPEED_100
:
SPEED_10
;
cmd
->
duplex
=
(
bp
->
flags
&
B44_FLAG_FULL_DUPLEX
)
?
DUPLEX_FULL
:
DUPLEX_HALF
;
cmd
->
port
=
0
;
cmd
->
phy_address
=
bp
->
phy_addr
;
cmd
->
transceiver
=
(
bp
->
flags
&
B44_FLAG_INTERNAL_PHY
)
?
XCVR_INTERNAL
:
XCVR_EXTERNAL
;
cmd
->
autoneg
=
(
bp
->
flags
&
B44_FLAG_FORCE_LINK
)
?
AUTONEG_DISABLE
:
AUTONEG_ENABLE
;
cmd
->
maxtxpkt
=
0
;
cmd
->
maxrxpkt
=
0
;
return
0
;
}
b44_setup_phy
(
bp
);
static
int
b44_set_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
cmd
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
spin_unlock_irq
(
&
bp
->
lock
);
if
(
!
(
bp
->
flags
&
B44_FLAG_INIT_COMPLETE
))
return
-
EAGAIN
;
return
0
;
/* We do not support gigabit. */
if
(
cmd
->
autoneg
==
AUTONEG_ENABLE
)
{
if
(
cmd
->
advertising
&
(
ADVERTISED_1000baseT_Half
|
ADVERTISED_1000baseT_Full
))
return
-
EINVAL
;
}
else
if
((
cmd
->
speed
!=
SPEED_100
&&
cmd
->
speed
!=
SPEED_10
)
||
(
cmd
->
duplex
!=
DUPLEX_HALF
&&
cmd
->
duplex
!=
DUPLEX_FULL
))
{
return
-
EINVAL
;
}
case
ETHTOOL_GMSGLVL
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GMSGLVL
};
edata
.
data
=
bp
->
msg_enable
;
if
(
copy_to_user
(
useraddr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SMSGLVL
:
{
struct
ethtool_value
edata
;
if
(
copy_from_user
(
&
edata
,
useraddr
,
sizeof
(
edata
)))
return
-
EFAULT
;
bp
->
msg_enable
=
edata
.
data
;
return
0
;
spin_lock_irq
(
&
bp
->
lock
);
if
(
cmd
->
autoneg
==
AUTONEG_ENABLE
)
{
bp
->
flags
&=
~
B44_FLAG_FORCE_LINK
;
bp
->
flags
&=
~
(
B44_FLAG_ADV_10HALF
|
B44_FLAG_ADV_10FULL
|
B44_FLAG_ADV_100HALF
|
B44_FLAG_ADV_100FULL
);
if
(
cmd
->
advertising
&
ADVERTISE_10HALF
)
bp
->
flags
|=
B44_FLAG_ADV_10HALF
;
if
(
cmd
->
advertising
&
ADVERTISE_10FULL
)
bp
->
flags
|=
B44_FLAG_ADV_10FULL
;
if
(
cmd
->
advertising
&
ADVERTISE_100HALF
)
bp
->
flags
|=
B44_FLAG_ADV_100HALF
;
if
(
cmd
->
advertising
&
ADVERTISE_100FULL
)
bp
->
flags
|=
B44_FLAG_ADV_100FULL
;
}
else
{
bp
->
flags
|=
B44_FLAG_FORCE_LINK
;
if
(
cmd
->
speed
==
SPEED_100
)
bp
->
flags
|=
B44_FLAG_100_BASE_T
;
if
(
cmd
->
duplex
==
DUPLEX_FULL
)
bp
->
flags
|=
B44_FLAG_FULL_DUPLEX
;
}
case
ETHTOOL_NWAY_RST
:
{
u32
bmcr
;
int
r
;
spin_lock_irq
(
&
bp
->
lock
);
b44_readphy
(
bp
,
MII_BMCR
,
&
bmcr
);
b44_readphy
(
bp
,
MII_BMCR
,
&
bmcr
);
r
=
-
EINVAL
;
if
(
bmcr
&
BMCR_ANENABLE
)
{
b44_writephy
(
bp
,
MII_BMCR
,
bmcr
|
BMCR_ANRESTART
);
r
=
0
;
}
spin_unlock_irq
(
&
bp
->
lock
);
b44_setup_phy
(
bp
);
return
r
;
}
case
ETHTOOL_GLINK
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GLINK
};
edata
.
data
=
netif_carrier_ok
(
bp
->
dev
)
?
1
:
0
;
if
(
copy_to_user
(
useraddr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_GRINGPARAM
:
{
struct
ethtool_ringparam
ering
=
{
ETHTOOL_GRINGPARAM
};
spin_unlock_irq
(
&
bp
->
lock
);
ering
.
rx_max_pending
=
B44_RX_RING_SIZE
-
1
;
ering
.
rx_pending
=
bp
->
rx_pending
;
return
0
;
}
/* XXX ethtool lacks a tx_max_pending, oops... */
static
void
b44_get_ringparam
(
struct
net_device
*
dev
,
struct
ethtool_ringparam
*
ering
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
if
(
copy_to_user
(
useraddr
,
&
ering
,
sizeof
(
ering
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SRINGPARAM
:
{
struct
ethtool_ringparam
ering
;
ering
->
rx_max_pending
=
B44_RX_RING_SIZE
-
1
;
ering
->
rx_pending
=
bp
->
rx_pending
;
if
(
copy_from_user
(
&
ering
,
useraddr
,
sizeof
(
ering
)))
return
-
EFAULT
;
/* XXX ethtool lacks a tx_max_pending, oops... */
}
if
((
ering
.
rx_pending
>
B44_RX_RING_SIZE
-
1
)
||
(
ering
.
rx_mini_pending
!=
0
)
||
(
ering
.
rx_jumbo_pending
!=
0
)
||
(
ering
.
tx_pending
>
B44_TX_RING_SIZE
-
1
))
return
-
EINVAL
;
static
int
b44_set_ringparam
(
struct
net_device
*
dev
,
struct
ethtool_ringparam
*
ering
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
spin_lock_irq
(
&
bp
->
lock
);
if
((
ering
->
rx_pending
>
B44_RX_RING_SIZE
-
1
)
||
(
ering
->
rx_mini_pending
!=
0
)
||
(
ering
->
rx_jumbo_pending
!=
0
)
||
(
ering
->
tx_pending
>
B44_TX_RING_SIZE
-
1
))
return
-
EINVAL
;
bp
->
rx_pending
=
ering
.
rx_pending
;
bp
->
tx_pending
=
ering
.
tx_pending
;
spin_lock_irq
(
&
bp
->
lock
);
b44_halt
(
bp
);
b44_init_rings
(
bp
);
b44_init_hw
(
bp
);
netif_wake_queue
(
bp
->
dev
);
spin_unlock_irq
(
&
bp
->
lock
);
bp
->
rx_pending
=
ering
->
rx_pending
;
bp
->
tx_pending
=
ering
->
tx_pending
;
b44_enable_ints
(
bp
);
return
0
;
}
case
ETHTOOL_GPAUSEPARAM
:
{
struct
ethtool_pauseparam
epause
=
{
ETHTOOL_GPAUSEPARAM
};
epause
.
autoneg
=
(
bp
->
flags
&
B44_FLAG_PAUSE_AUTO
)
!=
0
;
epause
.
rx_pause
=
(
bp
->
flags
&
B44_FLAG_RX_PAUSE
)
!=
0
;
epause
.
tx_pause
=
(
bp
->
flags
&
B44_FLAG_TX_PAUSE
)
!=
0
;
if
(
copy_to_user
(
useraddr
,
&
epause
,
sizeof
(
epause
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SPAUSEPARAM
:
{
struct
ethtool_pauseparam
epause
;
b44_halt
(
bp
);
b44_init_rings
(
bp
);
b44_init_hw
(
bp
);
netif_wake_queue
(
bp
->
dev
);
spin_unlock_irq
(
&
bp
->
lock
);
if
(
copy_from_user
(
&
epause
,
useraddr
,
sizeof
(
epause
)))
return
-
EFAULT
;
b44_enable_ints
(
bp
);
return
0
;
}
spin_lock_irq
(
&
bp
->
lock
);
if
(
epause
.
autoneg
)
bp
->
flags
|=
B44_FLAG_PAUSE_AUTO
;
else
bp
->
flags
&=
~
B44_FLAG_PAUSE_AUTO
;
if
(
epause
.
rx_pause
)
bp
->
flags
|=
B44_FLAG_RX_PAUSE
;
else
bp
->
flags
&=
~
B44_FLAG_RX_PAUSE
;
if
(
epause
.
tx_pause
)
bp
->
flags
|=
B44_FLAG_TX_PAUSE
;
else
bp
->
flags
&=
~
B44_FLAG_TX_PAUSE
;
if
(
bp
->
flags
&
B44_FLAG_PAUSE_AUTO
)
{
b44_halt
(
bp
);
b44_init_rings
(
bp
);
b44_init_hw
(
bp
);
}
else
{
__b44_set_flow_ctrl
(
bp
,
bp
->
flags
);
}
spin_unlock_irq
(
&
bp
->
lock
);
static
void
b44_get_pauseparam
(
struct
net_device
*
dev
,
struct
ethtool_pauseparam
*
epause
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
epause
->
autoneg
=
(
bp
->
flags
&
B44_FLAG_PAUSE_AUTO
)
!=
0
;
epause
->
rx_pause
=
(
bp
->
flags
&
B44_FLAG_RX_PAUSE
)
!=
0
;
epause
->
tx_pause
=
(
bp
->
flags
&
B44_FLAG_TX_PAUSE
)
!=
0
;
}
b44_enable_ints
(
bp
);
return
0
;
static
int
b44_set_pauseparam
(
struct
net_device
*
dev
,
struct
ethtool_pauseparam
*
epause
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
spin_lock_irq
(
&
bp
->
lock
);
if
(
epause
->
autoneg
)
bp
->
flags
|=
B44_FLAG_PAUSE_AUTO
;
else
bp
->
flags
&=
~
B44_FLAG_PAUSE_AUTO
;
if
(
epause
->
rx_pause
)
bp
->
flags
|=
B44_FLAG_RX_PAUSE
;
else
bp
->
flags
&=
~
B44_FLAG_RX_PAUSE
;
if
(
epause
->
tx_pause
)
bp
->
flags
|=
B44_FLAG_TX_PAUSE
;
else
bp
->
flags
&=
~
B44_FLAG_TX_PAUSE
;
if
(
bp
->
flags
&
B44_FLAG_PAUSE_AUTO
)
{
b44_halt
(
bp
);
b44_init_rings
(
bp
);
b44_init_hw
(
bp
);
}
else
{
__b44_set_flow_ctrl
(
bp
,
bp
->
flags
);
}
}
;
spin_unlock_irq
(
&
bp
->
lock
)
;
return
-
EOPNOTSUPP
;
b44_enable_ints
(
bp
);
return
0
;
}
static
struct
ethtool_ops
b44_ethtool_ops
=
{
.
get_drvinfo
=
b44_get_drvinfo
,
.
get_settings
=
b44_get_settings
,
.
set_settings
=
b44_set_settings
,
.
nway_reset
=
b44_nway_reset
,
.
get_link
=
ethtool_op_get_link
,
.
get_ringparam
=
b44_get_ringparam
,
.
set_ringparam
=
b44_set_ringparam
,
.
get_pauseparam
=
b44_get_pauseparam
,
.
set_pauseparam
=
b44_set_pauseparam
,
.
get_msglevel
=
b44_get_msglevel
,
.
set_msglevel
=
b44_set_msglevel
,
};
static
int
b44_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
ifr
,
int
cmd
)
{
struct
mii_ioctl_data
__user
*
data
=
(
struct
mii_ioctl_data
__user
*
)
&
ifr
->
ifr_data
;
...
...
@@ -1621,9 +1608,6 @@ static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
int
err
;
switch
(
cmd
)
{
case
SIOCETHTOOL
:
return
b44_ethtool_ioctl
(
dev
,
(
void
__user
*
)
ifr
->
ifr_data
);
case
SIOCGMIIPHY
:
data
->
phy_id
=
bp
->
phy_addr
;
...
...
@@ -1797,6 +1781,7 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
dev
->
watchdog_timeo
=
B44_TX_TIMEOUT
;
dev
->
change_mtu
=
b44_change_mtu
;
dev
->
irq
=
pdev
->
irq
;
SET_ETHTOOL_OPS
(
dev
,
&
b44_ethtool_ops
);
err
=
b44_get_invariants
(
bp
);
if
(
err
)
{
...
...
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