Skip to content

Commit 163d01c

Browse files
hayesorzdavem330
authored andcommitted
r8152: support pauseparam of ethtool_ops
Support get_pauseparam and set_pauseparam of ethtool_ops. Signed-off-by: Hayes Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 68b8c55 commit 163d01c

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

drivers/net/usb/r8152.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8967,6 +8967,79 @@ static int rtl8152_set_ringparam(struct net_device *netdev,
89678967
return 0;
89688968
}
89698969

8970+
static void rtl8152_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
8971+
{
8972+
struct r8152 *tp = netdev_priv(netdev);
8973+
u16 bmcr, lcladv, rmtadv;
8974+
u8 cap;
8975+
8976+
if (usb_autopm_get_interface(tp->intf) < 0)
8977+
return;
8978+
8979+
mutex_lock(&tp->control);
8980+
8981+
bmcr = r8152_mdio_read(tp, MII_BMCR);
8982+
lcladv = r8152_mdio_read(tp, MII_ADVERTISE);
8983+
rmtadv = r8152_mdio_read(tp, MII_LPA);
8984+
8985+
mutex_unlock(&tp->control);
8986+
8987+
usb_autopm_put_interface(tp->intf);
8988+
8989+
if (!(bmcr & BMCR_ANENABLE)) {
8990+
pause->autoneg = 0;
8991+
pause->rx_pause = 0;
8992+
pause->tx_pause = 0;
8993+
return;
8994+
}
8995+
8996+
pause->autoneg = 1;
8997+
8998+
cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
8999+
9000+
if (cap & FLOW_CTRL_RX)
9001+
pause->rx_pause = 1;
9002+
9003+
if (cap & FLOW_CTRL_TX)
9004+
pause->tx_pause = 1;
9005+
}
9006+
9007+
static int rtl8152_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
9008+
{
9009+
struct r8152 *tp = netdev_priv(netdev);
9010+
u16 old, new1;
9011+
u8 cap = 0;
9012+
int ret;
9013+
9014+
ret = usb_autopm_get_interface(tp->intf);
9015+
if (ret < 0)
9016+
return ret;
9017+
9018+
mutex_lock(&tp->control);
9019+
9020+
if (pause->autoneg && !(r8152_mdio_read(tp, MII_BMCR) & BMCR_ANENABLE)) {
9021+
ret = -EINVAL;
9022+
goto out;
9023+
}
9024+
9025+
if (pause->rx_pause)
9026+
cap |= FLOW_CTRL_RX;
9027+
9028+
if (pause->tx_pause)
9029+
cap |= FLOW_CTRL_TX;
9030+
9031+
old = r8152_mdio_read(tp, MII_ADVERTISE);
9032+
new1 = (old & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)) | mii_advertise_flowctrl(cap);
9033+
if (old != new1)
9034+
r8152_mdio_write(tp, MII_ADVERTISE, new1);
9035+
9036+
out:
9037+
mutex_unlock(&tp->control);
9038+
usb_autopm_put_interface(tp->intf);
9039+
9040+
return ret;
9041+
}
9042+
89709043
static const struct ethtool_ops ops = {
89719044
.supported_coalesce_params = ETHTOOL_COALESCE_USECS,
89729045
.get_drvinfo = rtl8152_get_drvinfo,
@@ -8989,6 +9062,8 @@ static const struct ethtool_ops ops = {
89899062
.set_tunable = rtl8152_set_tunable,
89909063
.get_ringparam = rtl8152_get_ringparam,
89919064
.set_ringparam = rtl8152_set_ringparam,
9065+
.get_pauseparam = rtl8152_get_pauseparam,
9066+
.set_pauseparam = rtl8152_set_pauseparam,
89929067
};
89939068

89949069
static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)

0 commit comments

Comments
 (0)