summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorCristian Bercaru <cristian.bercaru@freescale.com>2013-04-18 16:08:33 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-04-19 22:34:00 (GMT)
commit3308f15e4a74e33e8ccf7237b7842fdaf1b320ad (patch)
treeda3e742bec1bcc7700f44676f116b94a533a4325 /drivers
parent6c53cea1d6b8be0d68e10ac1fb7bd1383da24c40 (diff)
downloadlinux-fsl-qoriq-3308f15e4a74e33e8ccf7237b7842fdaf1b320ad.tar.xz
dpaa_eth: add ethtool PAUSE frame support
Change-Id: I52222f0bf60bb073bb3b77bf935a31e84b4939c0 Reviewed-on: http://git.am.freescale.net:8181/1545 Reviewed-by: Bucur Madalin-Cristian-B32716 <madalin.bucur@freescale.com> Reviewed-by: Sovaiala Cristian-Constantin-B39531 <Cristian.Sovaiala@freescale.com> Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpa-ethtool.c24
-rw-r--r--drivers/net/ethernet/freescale/dpa/mac-api.c50
-rw-r--r--drivers/net/ethernet/freescale/dpa/mac.c7
-rw-r--r--drivers/net/ethernet/freescale/dpa/mac.h12
4 files changed, 90 insertions, 3 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpa-ethtool.c b/drivers/net/ethernet/freescale/dpa/dpa-ethtool.c
index 1bdd8d2..2ba6966 100644
--- a/drivers/net/ethernet/freescale/dpa/dpa-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpa/dpa-ethtool.c
@@ -168,12 +168,16 @@ void __cold dpa_get_pauseparam(struct net_device *net_dev, struct ethtool_pausep
return;
}
- et_pauseparam->autoneg = priv->mac_dev->phy_dev->autoneg;
+ et_pauseparam->autoneg = priv->mac_dev->autoneg_pause;
+ et_pauseparam->rx_pause = priv->mac_dev->rx_pause;
+ et_pauseparam->tx_pause = priv->mac_dev->tx_pause;
}
int __cold dpa_set_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *et_pauseparam)
{
struct dpa_priv_s *priv;
+ int _errno;
+ bool en;
priv = netdev_priv(net_dev);
@@ -186,7 +190,23 @@ int __cold dpa_set_pauseparam(struct net_device *net_dev, struct ethtool_pausepa
return -ENODEV;
}
- priv->mac_dev->phy_dev->autoneg = et_pauseparam->autoneg;
+ en = et_pauseparam->rx_pause ? true : false;
+ _errno = priv->mac_dev->set_rx_pause(priv->mac_dev, en);
+ if (unlikely(_errno < 0)) {
+ netdev_err(net_dev, "set_rx_pause() = %d\n", _errno);
+ return _errno;
+ }
+
+ en = et_pauseparam->tx_pause ? true : false;
+ _errno = priv->mac_dev->set_tx_pause(priv->mac_dev, en);
+ if (unlikely(_errno < 0)) {
+ netdev_err(net_dev, "set_tx_pause() = %d\n", _errno);
+ return _errno;
+ }
+
+ priv->mac_dev->autoneg_pause = et_pauseparam->autoneg;
+ priv->mac_dev->rx_pause = et_pauseparam->rx_pause;
+ priv->mac_dev->tx_pause = et_pauseparam->tx_pause;
return 0;
}
diff --git a/drivers/net/ethernet/freescale/dpa/mac-api.c b/drivers/net/ethernet/freescale/dpa/mac-api.c
index b7987fa..717e005 100644
--- a/drivers/net/ethernet/freescale/dpa/mac-api.c
+++ b/drivers/net/ethernet/freescale/dpa/mac-api.c
@@ -624,6 +624,49 @@ static void *get_mac_handle(struct mac_device *mac_dev)
return (void*)priv->mac;
}
+static int __cold set_rx_pause(struct mac_device *mac_dev, bool en)
+{
+ int _errno;
+ t_Error err;
+
+ /* if rx pause is enabled, do NOT ignore pause frames */
+ err = FM_MAC_SetRxIgnorePauseFrames(
+ ((struct mac_priv_s *)macdev_priv(mac_dev))->mac, !en);
+
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0)
+ dev_err(mac_dev->dev,
+ "FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err);
+
+ return _errno;
+}
+
+static int __cold set_tx_pause(struct mac_device *mac_dev, bool en)
+{
+ int _errno;
+ t_Error err;
+
+ if (en)
+ err = FM_MAC_SetTxPauseFrames(
+ ((struct mac_priv_s *)macdev_priv(mac_dev))->mac,
+ TX_PAUSE_PRIO_ENABLE,
+ TX_PAUSE_TIME_ENABLE,
+ TX_PAUSE_THRESH_DEFAULT);
+ else
+ err = FM_MAC_SetTxPauseFrames(
+ ((struct mac_priv_s *)macdev_priv(mac_dev))->mac,
+ TX_PAUSE_PRIO_DISABLE,
+ TX_PAUSE_TIME_DISABLE,
+ TX_PAUSE_THRESH_DEFAULT);
+
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0)
+ dev_err(mac_dev->dev,
+ "FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
+
+ return _errno;
+}
+
static int __cold fm_rtc_enable(struct net_device *net_dev)
{
struct dpa_priv_s *priv = netdev_priv(net_dev);
@@ -763,7 +806,6 @@ static int __cold fm_rtc_set_fiper(struct net_device *net_dev, uint32_t id,
return _errno;
}
-
void fm_mac_dump_regs(struct mac_device *mac_dev)
{
struct mac_priv_s *mac_priv = macdev_priv(mac_dev);
@@ -784,6 +826,8 @@ static void __cold setup_dtsec(struct mac_device *mac_dev)
mac_dev->ptp_enable = ptp_enable;
mac_dev->ptp_disable = ptp_disable;
mac_dev->get_mac_handle = get_mac_handle;
+ mac_dev->set_tx_pause = set_tx_pause;
+ mac_dev->set_rx_pause = set_rx_pause;
mac_dev->fm_rtc_enable = fm_rtc_enable;
mac_dev->fm_rtc_disable = fm_rtc_disable;
mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
@@ -804,6 +848,8 @@ static void __cold setup_xgmac(struct mac_device *mac_dev)
mac_dev->change_addr = change_addr;
mac_dev->set_multi = set_multi;
mac_dev->uninit = uninit;
+ mac_dev->set_tx_pause = set_tx_pause;
+ mac_dev->set_rx_pause = set_rx_pause;
}
static void __cold setup_memac(struct mac_device *mac_dev)
@@ -816,6 +862,8 @@ static void __cold setup_memac(struct mac_device *mac_dev)
mac_dev->change_addr = change_addr;
mac_dev->set_multi = set_multi;
mac_dev->uninit = uninit;
+ mac_dev->set_tx_pause = set_tx_pause;
+ mac_dev->set_rx_pause = set_rx_pause;
mac_dev->fm_rtc_enable = fm_rtc_enable;
mac_dev->fm_rtc_disable = fm_rtc_disable;
mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
diff --git a/drivers/net/ethernet/freescale/dpa/mac.c b/drivers/net/ethernet/freescale/dpa/mac.c
index 310b2a8..87739e9 100644
--- a/drivers/net/ethernet/freescale/dpa/mac.c
+++ b/drivers/net/ethernet/freescale/dpa/mac.c
@@ -166,6 +166,13 @@ static int __cold mac_probe(struct platform_device *_of_dev)
INIT_LIST_HEAD(&mac_dev->mc_addr_list);
+ /* pause frame autonegotiation enabled*/
+ mac_dev->autoneg_pause = true;
+ /* does not ignore PAUSE frames */
+ mac_dev->rx_pause = true;
+ /* transmits PAUSE frames when congested */
+ mac_dev->tx_pause = true;
+
/* Get the FM node */
dev_node = of_get_parent(mac_node);
if (unlikely(dev_node == NULL)) {
diff --git a/drivers/net/ethernet/freescale/dpa/mac.h b/drivers/net/ethernet/freescale/dpa/mac.h
index 5cdb57c..9cf1740 100644
--- a/drivers/net/ethernet/freescale/dpa/mac.h
+++ b/drivers/net/ethernet/freescale/dpa/mac.h
@@ -67,6 +67,10 @@ struct mac_device {
/* List of multicast addresses */
struct list_head mc_addr_list;
+ u32 autoneg_pause;
+ u32 rx_pause;
+ u32 tx_pause;
+
int (*init_phy)(struct net_device *net_dev);
int (*init)(struct mac_device *mac_dev);
int (*start)(struct mac_device *mac_dev);
@@ -78,6 +82,8 @@ struct mac_device {
int (*ptp_enable)(struct mac_device *mac_dev);
int (*ptp_disable)(struct mac_device *mac_dev);
void *(*get_mac_handle)(struct mac_device *mac_dev);
+ int (*set_rx_pause)(struct mac_device *mac_dev, bool en);
+ int (*set_tx_pause)(struct mac_device *mac_dev, bool en);
int (*fm_rtc_enable)(struct net_device *net_dev);
int (*fm_rtc_disable)(struct net_device *net_dev);
int (*fm_rtc_get_cnt)(struct net_device *net_dev, uint64_t *ts);
@@ -107,4 +113,10 @@ extern const char *mac_driver_description;
extern const size_t mac_sizeof_priv[];
extern void (*const mac_setup[])(struct mac_device *mac_dev);
+#define TX_PAUSE_PRIO_ENABLE 0
+#define TX_PAUSE_PRIO_DISABLE 0xff
+#define TX_PAUSE_TIME_ENABLE 0xf000
+#define TX_PAUSE_TIME_DISABLE 0
+#define TX_PAUSE_THRESH_DEFAULT 0
+
#endif /* __MAC_H */