Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 351461
b: refs/heads/master
c: baa70a5
h: refs/heads/master
i:
  351459: 115c515
v: v3
  • Loading branch information
Frank Li authored and David S. Miller committed Jan 18, 2013
1 parent 65cec50 commit 7d96224
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8b5b6f5413e97c3e8bafcdd67553d508f4f698cd
refs/heads/master: baa70a5c48a01ea02e32270eb96eb19bd3b76667
87 changes: 86 additions & 1 deletion trunk/drivers/net/ethernet/freescale/fec.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@

#define DRIVER_NAME "fec"

/* Pause frame feild and FIFO threshold */
#define FEC_ENET_FCE (1 << 5)
#define FEC_ENET_RSEM_V 0x84
#define FEC_ENET_RSFL_V 16
#define FEC_ENET_RAEM_V 0x8
#define FEC_ENET_RAFL_V 0x8
#define FEC_ENET_OPD_V 0xFFF0

/* Controller is ENET-MAC */
#define FEC_QUIRK_ENET_MAC (1 << 0)
/* Controller needs driver to swap frame */
Expand Down Expand Up @@ -193,6 +201,9 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
/* Transmitter timeout */
#define TX_TIMEOUT (2 * HZ)

#define FEC_PAUSE_FLAG_AUTONEG 0x1
#define FEC_PAUSE_FLAG_ENABLE 0x2

static int mii_cnt;

static struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp, int is_ex)
Expand Down Expand Up @@ -470,6 +481,25 @@ fec_restart(struct net_device *ndev, int duplex)
}
#endif
}

/* enable pause frame*/
if ((fep->pause_flag & FEC_PAUSE_FLAG_ENABLE) ||
((fep->pause_flag & FEC_PAUSE_FLAG_AUTONEG) &&
fep->phy_dev && fep->phy_dev->pause)) {
rcntl |= FEC_ENET_FCE;

/* set FIFO thresh hold parameter to reduce overrun */
writel(FEC_ENET_RSEM_V, fep->hwp + FEC_R_FIFO_RSEM);
writel(FEC_ENET_RSFL_V, fep->hwp + FEC_R_FIFO_RSFL);
writel(FEC_ENET_RAEM_V, fep->hwp + FEC_R_FIFO_RAEM);
writel(FEC_ENET_RAFL_V, fep->hwp + FEC_R_FIFO_RAFL);

/* OPD */
writel(FEC_ENET_OPD_V, fep->hwp + FEC_OPD);
} else {
rcntl &= ~FEC_ENET_FCE;
}

writel(rcntl, fep->hwp + FEC_R_CNTRL);

if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
Expand Down Expand Up @@ -1016,8 +1046,10 @@ static int fec_enet_mii_probe(struct net_device *ndev)
}

/* mask with MAC supported features */
if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT)
if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) {
phy_dev->supported &= PHY_GBIT_FEATURES;
phy_dev->supported |= SUPPORTED_Pause;
}
else
phy_dev->supported &= PHY_BASIC_FEATURES;

Expand Down Expand Up @@ -1203,7 +1235,55 @@ static int fec_enet_get_ts_info(struct net_device *ndev,
}
}

static void fec_enet_get_pauseparam(struct net_device *ndev,
struct ethtool_pauseparam *pause)
{
struct fec_enet_private *fep = netdev_priv(ndev);

pause->autoneg = (fep->pause_flag & FEC_PAUSE_FLAG_AUTONEG) != 0;
pause->tx_pause = (fep->pause_flag & FEC_PAUSE_FLAG_ENABLE) != 0;
pause->rx_pause = pause->tx_pause;
}

static int fec_enet_set_pauseparam(struct net_device *ndev,
struct ethtool_pauseparam *pause)
{
struct fec_enet_private *fep = netdev_priv(ndev);

if (pause->tx_pause != pause->rx_pause) {
netdev_info(ndev,
"hardware only support enable/disable both tx and rx");
return -EINVAL;
}

fep->pause_flag = 0;

/* tx pause must be same as rx pause */
fep->pause_flag |= pause->rx_pause ? FEC_PAUSE_FLAG_ENABLE : 0;
fep->pause_flag |= pause->autoneg ? FEC_PAUSE_FLAG_AUTONEG : 0;

if (pause->rx_pause || pause->autoneg) {
fep->phy_dev->supported |= ADVERTISED_Pause;
fep->phy_dev->advertising |= ADVERTISED_Pause;
} else {
fep->phy_dev->supported &= ~ADVERTISED_Pause;
fep->phy_dev->advertising &= ~ADVERTISED_Pause;
}

if (pause->autoneg) {
if (netif_running(ndev))
fec_stop(ndev);
phy_start_aneg(fep->phy_dev);
}
if (netif_running(ndev))
fec_restart(ndev, 0);

return 0;
}

static const struct ethtool_ops fec_enet_ethtool_ops = {
.get_pauseparam = fec_enet_get_pauseparam,
.set_pauseparam = fec_enet_set_pauseparam,
.get_settings = fec_enet_get_settings,
.set_settings = fec_enet_set_settings,
.get_drvinfo = fec_enet_get_drvinfo,
Expand Down Expand Up @@ -1643,6 +1723,11 @@ fec_probe(struct platform_device *pdev)
/* setup board info structure */
fep = netdev_priv(ndev);

/* default enable pause frame auto negotiation */
if (pdev->id_entry &&
(pdev->id_entry->driver_data & FEC_QUIRK_HAS_GBIT))
fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG;

fep->hwp = ioremap(r->start, resource_size(r));
fep->pdev = pdev;
fep->dev_id = dev_id++;
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/net/ethernet/freescale/fec.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
#define FEC_R_DES_START 0x180 /* Receive descriptor ring */
#define FEC_X_DES_START 0x184 /* Transmit descriptor ring */
#define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */
#define FEC_R_FIFO_RSFL 0x190 /* Receive FIFO section full threshold */
#define FEC_R_FIFO_RSEM 0x194 /* Receive FIFO section empty threshold */
#define FEC_R_FIFO_RAEM 0x198 /* Receive FIFO almost empty threshold */
#define FEC_R_FIFO_RAFL 0x19c /* Receive FIFO almost full threshold */
#define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */
#define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */

Expand Down Expand Up @@ -243,6 +247,7 @@ struct fec_enet_private {
struct completion mdio_done;
int irq[FEC_IRQ_NUM];
int bufdesc_ex;
int pause_flag;

struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps;
Expand Down

0 comments on commit 7d96224

Please sign in to comment.