Commit ef2a8d54 authored by Sean Anderson's avatar Sean Anderson Committed by David S. Miller

net: dpaa: Adjust queue depth on rate change

Instead of setting the queue depth once during probe, adjust it on the
fly whenever we configure the link. This is a bit unusal, since usually
the DPAA driver calls into the FMAN driver, but here we do the opposite.
We need to add a netdev to struct mac_device for this, but it will soon
live in the phylink config.

I haven't tested this extensively, but it doesn't seem to break
anything. We could possibly optimize this a bit by keeping track of the
last rate, but for now we just update every time. 10GEC probably doesn't
need to call into this at all, but I've added it for consistency.
Signed-off-by: default avatarSean Anderson <sean.anderson@seco.com>
Acked-by: default avatarCamelia Groza <camelia.groza@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 914f8b22
...@@ -197,6 +197,8 @@ static int dpaa_rx_extra_headroom; ...@@ -197,6 +197,8 @@ static int dpaa_rx_extra_headroom;
#define dpaa_get_max_mtu() \ #define dpaa_get_max_mtu() \
(dpaa_max_frm - (VLAN_ETH_HLEN + ETH_FCS_LEN)) (dpaa_max_frm - (VLAN_ETH_HLEN + ETH_FCS_LEN))
static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed);
static int dpaa_netdev_init(struct net_device *net_dev, static int dpaa_netdev_init(struct net_device *net_dev,
const struct net_device_ops *dpaa_ops, const struct net_device_ops *dpaa_ops,
u16 tx_timeout) u16 tx_timeout)
...@@ -262,6 +264,9 @@ static int dpaa_netdev_init(struct net_device *net_dev, ...@@ -262,6 +264,9 @@ static int dpaa_netdev_init(struct net_device *net_dev,
net_dev->needed_headroom = priv->tx_headroom; net_dev->needed_headroom = priv->tx_headroom;
net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout); net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
mac_dev->net_dev = net_dev;
mac_dev->update_speed = dpaa_eth_cgr_set_speed;
/* start without the RUNNING flag, phylib controls it later */ /* start without the RUNNING flag, phylib controls it later */
netif_carrier_off(net_dev); netif_carrier_off(net_dev);
...@@ -826,10 +831,10 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv) ...@@ -826,10 +831,10 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv)
initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES); initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES);
initcgr.cgr.cscn_en = QM_CGR_EN; initcgr.cgr.cscn_en = QM_CGR_EN;
/* Set different thresholds based on the MAC speed. /* Set different thresholds based on the configured MAC speed.
* This may turn suboptimal if the MAC is reconfigured at a speed * This may turn suboptimal if the MAC is reconfigured at another
* lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link. * speed, so MACs must call dpaa_eth_cgr_set_speed in their adjust_link
* In such cases, we ought to reconfigure the threshold, too. * callback.
*/ */
if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full) if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
cs_th = DPAA_CS_THRESHOLD_10G; cs_th = DPAA_CS_THRESHOLD_10G;
...@@ -858,6 +863,31 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv) ...@@ -858,6 +863,31 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv)
return err; return err;
} }
static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed)
{
struct net_device *net_dev = mac_dev->net_dev;
struct dpaa_priv *priv = netdev_priv(net_dev);
struct qm_mcc_initcgr opts = { };
u32 cs_th;
int err;
opts.we_mask = cpu_to_be16(QM_CGR_WE_CS_THRES);
switch (speed) {
case SPEED_10000:
cs_th = DPAA_CS_THRESHOLD_10G;
break;
case SPEED_1000:
default:
cs_th = DPAA_CS_THRESHOLD_1G;
break;
}
qm_cgr_cs_thres_set64(&opts.cgr.cs_thres, cs_th, 1);
err = qman_update_cgr_safe(&priv->cgr_data.cgr, &opts);
if (err)
netdev_err(net_dev, "could not update speed: %d\n", err);
}
static inline void dpaa_setup_ingress(const struct dpaa_priv *priv, static inline void dpaa_setup_ingress(const struct dpaa_priv *priv,
struct dpaa_fq *fq, struct dpaa_fq *fq,
const struct qman_fq *template) const struct qman_fq *template)
......
...@@ -1244,6 +1244,7 @@ static void adjust_link_dtsec(struct mac_device *mac_dev) ...@@ -1244,6 +1244,7 @@ static void adjust_link_dtsec(struct mac_device *mac_dev)
} }
dtsec_adjust_link(fman_mac, phy_dev->speed); dtsec_adjust_link(fman_mac, phy_dev->speed);
mac_dev->update_speed(mac_dev, phy_dev->speed);
fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause); fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause); err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
if (err < 0) if (err < 0)
......
...@@ -782,6 +782,7 @@ static void adjust_link_memac(struct mac_device *mac_dev) ...@@ -782,6 +782,7 @@ static void adjust_link_memac(struct mac_device *mac_dev)
fman_mac = mac_dev->fman_mac; fman_mac = mac_dev->fman_mac;
memac_adjust_link(fman_mac, phy_dev->speed); memac_adjust_link(fman_mac, phy_dev->speed);
mac_dev->update_speed(mac_dev, phy_dev->speed);
fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause); fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause); err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
......
...@@ -601,8 +601,11 @@ static int tgec_del_hash_mac_address(struct fman_mac *tgec, ...@@ -601,8 +601,11 @@ static int tgec_del_hash_mac_address(struct fman_mac *tgec,
return 0; return 0;
} }
static void adjust_link_void(struct mac_device *mac_dev) static void tgec_adjust_link(struct mac_device *mac_dev)
{ {
struct phy_device *phy_dev = mac_dev->phy_dev;
mac_dev->update_speed(mac_dev, phy_dev->speed);
} }
static int tgec_set_exception(struct fman_mac *tgec, static int tgec_set_exception(struct fman_mac *tgec,
...@@ -795,7 +798,7 @@ int tgec_initialization(struct mac_device *mac_dev, ...@@ -795,7 +798,7 @@ int tgec_initialization(struct mac_device *mac_dev,
mac_dev->set_allmulti = tgec_set_allmulti; mac_dev->set_allmulti = tgec_set_allmulti;
mac_dev->set_tstamp = tgec_set_tstamp; mac_dev->set_tstamp = tgec_set_tstamp;
mac_dev->set_multi = fman_set_multi; mac_dev->set_multi = fman_set_multi;
mac_dev->adjust_link = adjust_link_void; mac_dev->adjust_link = tgec_adjust_link;
mac_dev->enable = tgec_enable; mac_dev->enable = tgec_enable;
mac_dev->disable = tgec_disable; mac_dev->disable = tgec_disable;
......
...@@ -28,6 +28,7 @@ struct mac_device { ...@@ -28,6 +28,7 @@ struct mac_device {
struct phy_device *phy_dev; struct phy_device *phy_dev;
phy_interface_t phy_if; phy_interface_t phy_if;
struct device_node *phy_node; struct device_node *phy_node;
struct net_device *net_dev;
bool autoneg_pause; bool autoneg_pause;
bool rx_pause_req; bool rx_pause_req;
...@@ -56,6 +57,8 @@ struct mac_device { ...@@ -56,6 +57,8 @@ struct mac_device {
int (*remove_hash_mac_addr)(struct fman_mac *mac_dev, int (*remove_hash_mac_addr)(struct fman_mac *mac_dev,
enet_addr_t *eth_addr); enet_addr_t *eth_addr);
void (*update_speed)(struct mac_device *mac_dev, int speed);
struct fman_mac *fman_mac; struct fman_mac *fman_mac;
struct mac_priv_s *priv; struct mac_priv_s *priv;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment