forked from Minki/linux
Merge branch 'dpaa-cleanups'
Sean Anderson says: ==================== net: dpaa: Cleanups in preparation for phylink conversion (part 2) This series contains several cleanup patches for dpaa/fman. While they are intended to prepare for a phylink conversion, they stand on their own. This series was originally submitted as part of [1]. [1] https://lore.kernel.org/netdev/20220715215954.1449214-1-sean.anderson@seco.com Changes in v5: - Reduce line length of tgec_config - Reduce line length of qman_update_cgr_safe - Rebase onto net-next/master Changes in v4: - weer -> were - tricy -> tricky - Use mac_dev for calling change_addr - qman_cgr_create -> qman_create_cgr Changes in v2: - Fix prototype for dtsec_initialization - Fix warning if sizeof(void *) != sizeof(resource_size_t) - Specify type of mac_dev for exception_cb - Add helper for sanity checking cgr ops - Add CGR update function - Adjust queue depth on rate change ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
ab526eaa84
@ -197,12 +197,15 @@ static int dpaa_rx_extra_headroom;
|
||||
#define dpaa_get_max_mtu() \
|
||||
(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,
|
||||
const struct net_device_ops *dpaa_ops,
|
||||
u16 tx_timeout)
|
||||
{
|
||||
struct dpaa_priv *priv = netdev_priv(net_dev);
|
||||
struct device *dev = net_dev->dev.parent;
|
||||
struct mac_device *mac_dev = priv->mac_dev;
|
||||
struct dpaa_percpu_priv *percpu_priv;
|
||||
const u8 *mac_addr;
|
||||
int i, err;
|
||||
@ -216,10 +219,10 @@ static int dpaa_netdev_init(struct net_device *net_dev,
|
||||
}
|
||||
|
||||
net_dev->netdev_ops = dpaa_ops;
|
||||
mac_addr = priv->mac_dev->addr;
|
||||
mac_addr = mac_dev->addr;
|
||||
|
||||
net_dev->mem_start = priv->mac_dev->res->start;
|
||||
net_dev->mem_end = priv->mac_dev->res->end;
|
||||
net_dev->mem_start = (unsigned long)mac_dev->vaddr;
|
||||
net_dev->mem_end = (unsigned long)mac_dev->vaddr_end;
|
||||
|
||||
net_dev->min_mtu = ETH_MIN_MTU;
|
||||
net_dev->max_mtu = dpaa_get_max_mtu();
|
||||
@ -246,7 +249,7 @@ static int dpaa_netdev_init(struct net_device *net_dev,
|
||||
eth_hw_addr_set(net_dev, mac_addr);
|
||||
} else {
|
||||
eth_hw_addr_random(net_dev);
|
||||
err = priv->mac_dev->change_addr(priv->mac_dev->fman_mac,
|
||||
err = mac_dev->change_addr(mac_dev->fman_mac,
|
||||
(const enet_addr_t *)net_dev->dev_addr);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to set random MAC address\n");
|
||||
@ -261,6 +264,9 @@ static int dpaa_netdev_init(struct net_device *net_dev,
|
||||
net_dev->needed_headroom = priv->tx_headroom;
|
||||
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 */
|
||||
netif_carrier_off(net_dev);
|
||||
|
||||
@ -290,10 +296,7 @@ static int dpaa_stop(struct net_device *net_dev)
|
||||
|
||||
if (mac_dev->phy_dev)
|
||||
phy_stop(mac_dev->phy_dev);
|
||||
err = mac_dev->disable(mac_dev->fman_mac);
|
||||
if (err < 0)
|
||||
netif_err(priv, ifdown, net_dev, "mac_dev->disable() = %d\n",
|
||||
err);
|
||||
mac_dev->disable(mac_dev->fman_mac);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
|
||||
error = fman_port_disable(mac_dev->port[i]);
|
||||
@ -828,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.cgr.cscn_en = QM_CGR_EN;
|
||||
|
||||
/* Set different thresholds based on the MAC speed.
|
||||
* This may turn suboptimal if the MAC is reconfigured at a speed
|
||||
* lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
|
||||
* In such cases, we ought to reconfigure the threshold, too.
|
||||
/* Set different thresholds based on the configured MAC speed.
|
||||
* This may turn suboptimal if the MAC is reconfigured at another
|
||||
* speed, so MACs must call dpaa_eth_cgr_set_speed in their adjust_link
|
||||
* callback.
|
||||
*/
|
||||
if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
|
||||
cs_th = DPAA_CS_THRESHOLD_10G;
|
||||
@ -860,6 +863,31 @@ out_error:
|
||||
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,
|
||||
struct dpaa_fq *fq,
|
||||
const struct qman_fq *template)
|
||||
|
@ -18,7 +18,7 @@ static ssize_t dpaa_eth_show_addr(struct device *dev,
|
||||
|
||||
if (mac_dev)
|
||||
return sprintf(buf, "%llx",
|
||||
(unsigned long long)mac_dev->res->start);
|
||||
(unsigned long long)mac_dev->vaddr);
|
||||
else
|
||||
return sprintf(buf, "none");
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "fman_dtsec.h"
|
||||
#include "fman.h"
|
||||
#include "mac.h"
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/bitrev.h>
|
||||
@ -300,7 +301,7 @@ struct fman_mac {
|
||||
/* Ethernet physical interface */
|
||||
phy_interface_t phy_if;
|
||||
u16 max_speed;
|
||||
void *dev_id; /* device cookie used by the exception cbs */
|
||||
struct mac_device *dev_id; /* device cookie used by the exception cbs */
|
||||
fman_mac_exception_cb *exception_cb;
|
||||
fman_mac_exception_cb *event_cb;
|
||||
/* Number of individual addresses in registers for this station */
|
||||
@ -813,26 +814,6 @@ static void free_init_resources(struct fman_mac *dtsec)
|
||||
dtsec->unicast_addr_hash = NULL;
|
||||
}
|
||||
|
||||
int dtsec_cfg_max_frame_len(struct fman_mac *dtsec, u16 new_val)
|
||||
{
|
||||
if (is_init_done(dtsec->dtsec_drv_param))
|
||||
return -EINVAL;
|
||||
|
||||
dtsec->dtsec_drv_param->maximum_frame = new_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_cfg_pad_and_crc(struct fman_mac *dtsec, bool new_val)
|
||||
{
|
||||
if (is_init_done(dtsec->dtsec_drv_param))
|
||||
return -EINVAL;
|
||||
|
||||
dtsec->dtsec_drv_param->tx_pad_crc = new_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void graceful_start(struct fman_mac *dtsec)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
@ -871,7 +852,7 @@ static void graceful_stop(struct fman_mac *dtsec)
|
||||
}
|
||||
}
|
||||
|
||||
int dtsec_enable(struct fman_mac *dtsec)
|
||||
static int dtsec_enable(struct fman_mac *dtsec)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
u32 tmp;
|
||||
@ -890,13 +871,12 @@ int dtsec_enable(struct fman_mac *dtsec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_disable(struct fman_mac *dtsec)
|
||||
static void dtsec_disable(struct fman_mac *dtsec)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
u32 tmp;
|
||||
|
||||
if (!is_init_done(dtsec->dtsec_drv_param))
|
||||
return -EINVAL;
|
||||
WARN_ON_ONCE(!is_init_done(dtsec->dtsec_drv_param));
|
||||
|
||||
/* Graceful stop - Assert the graceful Rx/Tx stop bit */
|
||||
graceful_stop(dtsec);
|
||||
@ -904,13 +884,12 @@ int dtsec_disable(struct fman_mac *dtsec)
|
||||
tmp = ioread32be(®s->maccfg1);
|
||||
tmp &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
|
||||
iowrite32be(tmp, ®s->maccfg1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_set_tx_pause_frames(struct fman_mac *dtsec,
|
||||
u8 __maybe_unused priority,
|
||||
u16 pause_time, u16 __maybe_unused thresh_time)
|
||||
static int dtsec_set_tx_pause_frames(struct fman_mac *dtsec,
|
||||
u8 __maybe_unused priority,
|
||||
u16 pause_time,
|
||||
u16 __maybe_unused thresh_time)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
u32 ptv = 0;
|
||||
@ -945,7 +924,7 @@ int dtsec_set_tx_pause_frames(struct fman_mac *dtsec,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_accept_rx_pause_frames(struct fman_mac *dtsec, bool en)
|
||||
static int dtsec_accept_rx_pause_frames(struct fman_mac *dtsec, bool en)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
u32 tmp;
|
||||
@ -967,7 +946,8 @@ int dtsec_accept_rx_pause_frames(struct fman_mac *dtsec, bool en)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_modify_mac_address(struct fman_mac *dtsec, const enet_addr_t *enet_addr)
|
||||
static int dtsec_modify_mac_address(struct fman_mac *dtsec,
|
||||
const enet_addr_t *enet_addr)
|
||||
{
|
||||
if (!is_init_done(dtsec->dtsec_drv_param))
|
||||
return -EINVAL;
|
||||
@ -985,7 +965,8 @@ int dtsec_modify_mac_address(struct fman_mac *dtsec, const enet_addr_t *enet_add
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
|
||||
static int dtsec_add_hash_mac_address(struct fman_mac *dtsec,
|
||||
enet_addr_t *eth_addr)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
struct eth_hash_entry *hash_entry;
|
||||
@ -1051,7 +1032,7 @@ int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
|
||||
static int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
|
||||
{
|
||||
u32 tmp;
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
@ -1070,7 +1051,7 @@ int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable)
|
||||
static int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
u32 rctrl, tctrl;
|
||||
@ -1095,7 +1076,8 @@ int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
|
||||
static int dtsec_del_hash_mac_address(struct fman_mac *dtsec,
|
||||
enet_addr_t *eth_addr)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
struct list_head *pos;
|
||||
@ -1166,7 +1148,7 @@ int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_set_promiscuous(struct fman_mac *dtsec, bool new_val)
|
||||
static int dtsec_set_promiscuous(struct fman_mac *dtsec, bool new_val)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
u32 tmp;
|
||||
@ -1195,7 +1177,7 @@ int dtsec_set_promiscuous(struct fman_mac *dtsec, bool new_val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed)
|
||||
static int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
u32 tmp;
|
||||
@ -1229,7 +1211,7 @@ int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_restart_autoneg(struct fman_mac *dtsec)
|
||||
static int dtsec_restart_autoneg(struct fman_mac *dtsec)
|
||||
{
|
||||
u16 tmp_reg16;
|
||||
|
||||
@ -1247,20 +1229,31 @@ int dtsec_restart_autoneg(struct fman_mac *dtsec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version)
|
||||
static void adjust_link_dtsec(struct mac_device *mac_dev)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
struct phy_device *phy_dev = mac_dev->phy_dev;
|
||||
struct fman_mac *fman_mac;
|
||||
bool rx_pause, tx_pause;
|
||||
int err;
|
||||
|
||||
if (!is_init_done(dtsec->dtsec_drv_param))
|
||||
return -EINVAL;
|
||||
fman_mac = mac_dev->fman_mac;
|
||||
if (!phy_dev->link) {
|
||||
dtsec_restart_autoneg(fman_mac);
|
||||
|
||||
*mac_version = ioread32be(®s->tsec_id);
|
||||
return;
|
||||
}
|
||||
|
||||
return 0;
|
||||
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);
|
||||
err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
|
||||
if (err < 0)
|
||||
dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
|
||||
err);
|
||||
}
|
||||
|
||||
int dtsec_set_exception(struct fman_mac *dtsec,
|
||||
enum fman_mac_exceptions exception, bool enable)
|
||||
static int dtsec_set_exception(struct fman_mac *dtsec,
|
||||
enum fman_mac_exceptions exception, bool enable)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
u32 bit_mask = 0;
|
||||
@ -1313,7 +1306,7 @@ int dtsec_set_exception(struct fman_mac *dtsec,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_init(struct fman_mac *dtsec)
|
||||
static int dtsec_init(struct fman_mac *dtsec)
|
||||
{
|
||||
struct dtsec_regs __iomem *regs = dtsec->regs;
|
||||
struct dtsec_cfg *dtsec_drv_param;
|
||||
@ -1407,7 +1400,7 @@ int dtsec_init(struct fman_mac *dtsec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtsec_free(struct fman_mac *dtsec)
|
||||
static int dtsec_free(struct fman_mac *dtsec)
|
||||
{
|
||||
free_init_resources(dtsec);
|
||||
|
||||
@ -1418,13 +1411,11 @@ int dtsec_free(struct fman_mac *dtsec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct fman_mac *dtsec_config(struct fman_mac_params *params)
|
||||
static struct fman_mac *dtsec_config(struct mac_device *mac_dev,
|
||||
struct fman_mac_params *params)
|
||||
{
|
||||
struct fman_mac *dtsec;
|
||||
struct dtsec_cfg *dtsec_drv_param;
|
||||
void __iomem *base_addr;
|
||||
|
||||
base_addr = params->base_addr;
|
||||
|
||||
/* allocate memory for the UCC GETH data structure. */
|
||||
dtsec = kzalloc(sizeof(*dtsec), GFP_KERNEL);
|
||||
@ -1441,10 +1432,10 @@ struct fman_mac *dtsec_config(struct fman_mac_params *params)
|
||||
|
||||
set_dflts(dtsec_drv_param);
|
||||
|
||||
dtsec->regs = base_addr;
|
||||
dtsec->addr = ENET_ADDR_TO_UINT64(params->addr);
|
||||
dtsec->regs = mac_dev->vaddr;
|
||||
dtsec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
|
||||
dtsec->max_speed = params->max_speed;
|
||||
dtsec->phy_if = params->phy_if;
|
||||
dtsec->phy_if = mac_dev->phy_if;
|
||||
dtsec->mac_id = params->mac_id;
|
||||
dtsec->exceptions = (DTSEC_IMASK_BREN |
|
||||
DTSEC_IMASK_RXCEN |
|
||||
@ -1461,34 +1452,87 @@ struct fman_mac *dtsec_config(struct fman_mac_params *params)
|
||||
DTSEC_IMASK_RDPEEN);
|
||||
dtsec->exception_cb = params->exception_cb;
|
||||
dtsec->event_cb = params->event_cb;
|
||||
dtsec->dev_id = params->dev_id;
|
||||
dtsec->dev_id = mac_dev;
|
||||
dtsec->ptp_tsu_enabled = dtsec->dtsec_drv_param->ptp_tsu_en;
|
||||
dtsec->en_tsu_err_exception = dtsec->dtsec_drv_param->ptp_exception_en;
|
||||
|
||||
dtsec->fm = params->fm;
|
||||
dtsec->basex_if = params->basex_if;
|
||||
|
||||
if (!params->internal_phy_node) {
|
||||
pr_err("TBI PHY node is not available\n");
|
||||
goto err_dtsec_drv_param;
|
||||
}
|
||||
|
||||
dtsec->tbiphy = of_phy_find_device(params->internal_phy_node);
|
||||
if (!dtsec->tbiphy) {
|
||||
pr_err("of_phy_find_device (TBI PHY) failed\n");
|
||||
goto err_dtsec_drv_param;
|
||||
}
|
||||
|
||||
put_device(&dtsec->tbiphy->mdio.dev);
|
||||
|
||||
/* Save FMan revision */
|
||||
fman_get_revision(dtsec->fm, &dtsec->fm_rev_info);
|
||||
|
||||
return dtsec;
|
||||
|
||||
err_dtsec_drv_param:
|
||||
kfree(dtsec_drv_param);
|
||||
err_dtsec:
|
||||
kfree(dtsec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int dtsec_initialization(struct mac_device *mac_dev,
|
||||
struct device_node *mac_node,
|
||||
struct fman_mac_params *params)
|
||||
{
|
||||
int err;
|
||||
struct fman_mac *dtsec;
|
||||
struct device_node *phy_node;
|
||||
|
||||
mac_dev->set_promisc = dtsec_set_promiscuous;
|
||||
mac_dev->change_addr = dtsec_modify_mac_address;
|
||||
mac_dev->add_hash_mac_addr = dtsec_add_hash_mac_address;
|
||||
mac_dev->remove_hash_mac_addr = dtsec_del_hash_mac_address;
|
||||
mac_dev->set_tx_pause = dtsec_set_tx_pause_frames;
|
||||
mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames;
|
||||
mac_dev->set_exception = dtsec_set_exception;
|
||||
mac_dev->set_allmulti = dtsec_set_allmulti;
|
||||
mac_dev->set_tstamp = dtsec_set_tstamp;
|
||||
mac_dev->set_multi = fman_set_multi;
|
||||
mac_dev->adjust_link = adjust_link_dtsec;
|
||||
mac_dev->enable = dtsec_enable;
|
||||
mac_dev->disable = dtsec_disable;
|
||||
|
||||
mac_dev->fman_mac = dtsec_config(mac_dev, params);
|
||||
if (!mac_dev->fman_mac) {
|
||||
err = -EINVAL;
|
||||
goto _return;
|
||||
}
|
||||
|
||||
dtsec = mac_dev->fman_mac;
|
||||
dtsec->dtsec_drv_param->maximum_frame = fman_get_max_frm();
|
||||
dtsec->dtsec_drv_param->tx_pad_crc = true;
|
||||
|
||||
phy_node = of_parse_phandle(mac_node, "tbi-handle", 0);
|
||||
if (!phy_node) {
|
||||
pr_err("TBI PHY node is not available\n");
|
||||
err = -EINVAL;
|
||||
goto _return_fm_mac_free;
|
||||
}
|
||||
|
||||
dtsec->tbiphy = of_phy_find_device(phy_node);
|
||||
if (!dtsec->tbiphy) {
|
||||
pr_err("of_phy_find_device (TBI PHY) failed\n");
|
||||
err = -EINVAL;
|
||||
goto _return_fm_mac_free;
|
||||
}
|
||||
put_device(&dtsec->tbiphy->mdio.dev);
|
||||
|
||||
err = dtsec_init(dtsec);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
/* For 1G MAC, disable by default the MIB counters overflow interrupt */
|
||||
err = dtsec_set_exception(dtsec, FM_MAC_EX_1G_RX_MIB_CNT_OVFL, false);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
dev_info(mac_dev->dev, "FMan dTSEC version: 0x%08x\n",
|
||||
ioread32be(&dtsec->regs->tsec_id));
|
||||
|
||||
goto _return;
|
||||
|
||||
_return_fm_mac_free:
|
||||
dtsec_free(dtsec);
|
||||
|
||||
_return:
|
||||
return err;
|
||||
}
|
||||
|
@ -8,27 +8,10 @@
|
||||
|
||||
#include "fman_mac.h"
|
||||
|
||||
struct fman_mac *dtsec_config(struct fman_mac_params *params);
|
||||
int dtsec_set_promiscuous(struct fman_mac *dtsec, bool new_val);
|
||||
int dtsec_modify_mac_address(struct fman_mac *dtsec, const enet_addr_t *enet_addr);
|
||||
int dtsec_adjust_link(struct fman_mac *dtsec,
|
||||
u16 speed);
|
||||
int dtsec_restart_autoneg(struct fman_mac *dtsec);
|
||||
int dtsec_cfg_max_frame_len(struct fman_mac *dtsec, u16 new_val);
|
||||
int dtsec_cfg_pad_and_crc(struct fman_mac *dtsec, bool new_val);
|
||||
int dtsec_enable(struct fman_mac *dtsec);
|
||||
int dtsec_disable(struct fman_mac *dtsec);
|
||||
int dtsec_init(struct fman_mac *dtsec);
|
||||
int dtsec_free(struct fman_mac *dtsec);
|
||||
int dtsec_accept_rx_pause_frames(struct fman_mac *dtsec, bool en);
|
||||
int dtsec_set_tx_pause_frames(struct fman_mac *dtsec, u8 priority,
|
||||
u16 pause_time, u16 thresh_time);
|
||||
int dtsec_set_exception(struct fman_mac *dtsec,
|
||||
enum fman_mac_exceptions exception, bool enable);
|
||||
int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
|
||||
int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
|
||||
int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version);
|
||||
int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable);
|
||||
int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable);
|
||||
struct mac_device;
|
||||
|
||||
int dtsec_initialization(struct mac_device *mac_dev,
|
||||
struct device_node *mac_node,
|
||||
struct fman_mac_params *params);
|
||||
|
||||
#endif /* __DTSEC_H */
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
struct fman_mac;
|
||||
struct mac_device;
|
||||
|
||||
/* Ethernet Address */
|
||||
typedef u8 enet_addr_t[ETH_ALEN];
|
||||
@ -158,30 +159,23 @@ struct eth_hash_entry {
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
typedef void (fman_mac_exception_cb)(void *dev_id,
|
||||
enum fman_mac_exceptions exceptions);
|
||||
typedef void (fman_mac_exception_cb)(struct mac_device *dev_id,
|
||||
enum fman_mac_exceptions exceptions);
|
||||
|
||||
/* FMan MAC config input */
|
||||
struct fman_mac_params {
|
||||
/* Base of memory mapped FM MAC registers */
|
||||
void __iomem *base_addr;
|
||||
/* MAC address of device; First octet is sent first */
|
||||
enet_addr_t addr;
|
||||
/* MAC ID; numbering of dTSEC and 1G-mEMAC:
|
||||
* 0 - FM_MAX_NUM_OF_1G_MACS;
|
||||
* numbering of 10G-MAC (TGEC) and 10G-mEMAC:
|
||||
* 0 - FM_MAX_NUM_OF_10G_MACS
|
||||
*/
|
||||
u8 mac_id;
|
||||
/* PHY interface */
|
||||
phy_interface_t phy_if;
|
||||
/* Note that the speed should indicate the maximum rate that
|
||||
* this MAC should support rather than the actual speed;
|
||||
*/
|
||||
u16 max_speed;
|
||||
/* A handle to the FM object this port related to */
|
||||
void *fm;
|
||||
void *dev_id; /* device cookie used by the exception cbs */
|
||||
fman_mac_exception_cb *event_cb; /* MDIO Events Callback Routine */
|
||||
fman_mac_exception_cb *exception_cb;/* Exception Callback Routine */
|
||||
/* SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
|
||||
@ -190,8 +184,6 @@ struct fman_mac_params {
|
||||
* synchronize with far-end phy at 10Mbps, 100Mbps or 1000Mbps
|
||||
*/
|
||||
bool basex_if;
|
||||
/* Pointer to TBI/PCS PHY node, used for TBI/PCS PHY access */
|
||||
struct device_node *internal_phy_node;
|
||||
};
|
||||
|
||||
struct eth_hash_t {
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "fman_memac.h"
|
||||
#include "fman.h"
|
||||
#include "mac.h"
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
@ -310,7 +311,7 @@ struct fman_mac {
|
||||
/* Ethernet physical interface */
|
||||
phy_interface_t phy_if;
|
||||
u16 max_speed;
|
||||
void *dev_id; /* device cookie used by the exception cbs */
|
||||
struct mac_device *dev_id; /* device cookie used by the exception cbs */
|
||||
fman_mac_exception_cb *exception_cb;
|
||||
fman_mac_exception_cb *event_cb;
|
||||
/* Pointer to driver's global address hash table */
|
||||
@ -685,7 +686,7 @@ static bool is_init_done(struct memac_cfg *memac_drv_params)
|
||||
return false;
|
||||
}
|
||||
|
||||
int memac_enable(struct fman_mac *memac)
|
||||
static int memac_enable(struct fman_mac *memac)
|
||||
{
|
||||
struct memac_regs __iomem *regs = memac->regs;
|
||||
u32 tmp;
|
||||
@ -700,22 +701,20 @@ int memac_enable(struct fman_mac *memac)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_disable(struct fman_mac *memac)
|
||||
static void memac_disable(struct fman_mac *memac)
|
||||
|
||||
{
|
||||
struct memac_regs __iomem *regs = memac->regs;
|
||||
u32 tmp;
|
||||
|
||||
if (!is_init_done(memac->memac_drv_param))
|
||||
return -EINVAL;
|
||||
WARN_ON_ONCE(!is_init_done(memac->memac_drv_param));
|
||||
|
||||
tmp = ioread32be(®s->command_config);
|
||||
tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
|
||||
iowrite32be(tmp, ®s->command_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_set_promiscuous(struct fman_mac *memac, bool new_val)
|
||||
static int memac_set_promiscuous(struct fman_mac *memac, bool new_val)
|
||||
{
|
||||
struct memac_regs __iomem *regs = memac->regs;
|
||||
u32 tmp;
|
||||
@ -734,7 +733,7 @@ int memac_set_promiscuous(struct fman_mac *memac, bool new_val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_adjust_link(struct fman_mac *memac, u16 speed)
|
||||
static int memac_adjust_link(struct fman_mac *memac, u16 speed)
|
||||
{
|
||||
struct memac_regs __iomem *regs = memac->regs;
|
||||
u32 tmp;
|
||||
@ -774,39 +773,26 @@ int memac_adjust_link(struct fman_mac *memac, u16 speed)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_cfg_max_frame_len(struct fman_mac *memac, u16 new_val)
|
||||
static void adjust_link_memac(struct mac_device *mac_dev)
|
||||
{
|
||||
if (is_init_done(memac->memac_drv_param))
|
||||
return -EINVAL;
|
||||
struct phy_device *phy_dev = mac_dev->phy_dev;
|
||||
struct fman_mac *fman_mac;
|
||||
bool rx_pause, tx_pause;
|
||||
int err;
|
||||
|
||||
memac->memac_drv_param->max_frame_length = new_val;
|
||||
fman_mac = mac_dev->fman_mac;
|
||||
memac_adjust_link(fman_mac, phy_dev->speed);
|
||||
mac_dev->update_speed(mac_dev, phy_dev->speed);
|
||||
|
||||
return 0;
|
||||
fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
|
||||
err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
|
||||
if (err < 0)
|
||||
dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
|
||||
err);
|
||||
}
|
||||
|
||||
int memac_cfg_reset_on_init(struct fman_mac *memac, bool enable)
|
||||
{
|
||||
if (is_init_done(memac->memac_drv_param))
|
||||
return -EINVAL;
|
||||
|
||||
memac->memac_drv_param->reset_on_init = enable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_cfg_fixed_link(struct fman_mac *memac,
|
||||
struct fixed_phy_status *fixed_link)
|
||||
{
|
||||
if (is_init_done(memac->memac_drv_param))
|
||||
return -EINVAL;
|
||||
|
||||
memac->memac_drv_param->fixed_link = fixed_link;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
|
||||
u16 pause_time, u16 thresh_time)
|
||||
static int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
|
||||
u16 pause_time, u16 thresh_time)
|
||||
{
|
||||
struct memac_regs __iomem *regs = memac->regs;
|
||||
u32 tmp;
|
||||
@ -843,7 +829,7 @@ int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_accept_rx_pause_frames(struct fman_mac *memac, bool en)
|
||||
static int memac_accept_rx_pause_frames(struct fman_mac *memac, bool en)
|
||||
{
|
||||
struct memac_regs __iomem *regs = memac->regs;
|
||||
u32 tmp;
|
||||
@ -862,7 +848,8 @@ int memac_accept_rx_pause_frames(struct fman_mac *memac, bool en)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_modify_mac_address(struct fman_mac *memac, const enet_addr_t *enet_addr)
|
||||
static int memac_modify_mac_address(struct fman_mac *memac,
|
||||
const enet_addr_t *enet_addr)
|
||||
{
|
||||
if (!is_init_done(memac->memac_drv_param))
|
||||
return -EINVAL;
|
||||
@ -872,7 +859,8 @@ int memac_modify_mac_address(struct fman_mac *memac, const enet_addr_t *enet_add
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
|
||||
static int memac_add_hash_mac_address(struct fman_mac *memac,
|
||||
enet_addr_t *eth_addr)
|
||||
{
|
||||
struct memac_regs __iomem *regs = memac->regs;
|
||||
struct eth_hash_entry *hash_entry;
|
||||
@ -905,7 +893,7 @@ int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_set_allmulti(struct fman_mac *memac, bool enable)
|
||||
static int memac_set_allmulti(struct fman_mac *memac, bool enable)
|
||||
{
|
||||
u32 entry;
|
||||
struct memac_regs __iomem *regs = memac->regs;
|
||||
@ -928,12 +916,13 @@ int memac_set_allmulti(struct fman_mac *memac, bool enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_set_tstamp(struct fman_mac *memac, bool enable)
|
||||
static int memac_set_tstamp(struct fman_mac *memac, bool enable)
|
||||
{
|
||||
return 0; /* Always enabled. */
|
||||
}
|
||||
|
||||
int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
|
||||
static int memac_del_hash_mac_address(struct fman_mac *memac,
|
||||
enet_addr_t *eth_addr)
|
||||
{
|
||||
struct memac_regs __iomem *regs = memac->regs;
|
||||
struct eth_hash_entry *hash_entry = NULL;
|
||||
@ -966,8 +955,8 @@ int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_set_exception(struct fman_mac *memac,
|
||||
enum fman_mac_exceptions exception, bool enable)
|
||||
static int memac_set_exception(struct fman_mac *memac,
|
||||
enum fman_mac_exceptions exception, bool enable)
|
||||
{
|
||||
u32 bit_mask = 0;
|
||||
|
||||
@ -989,13 +978,13 @@ int memac_set_exception(struct fman_mac *memac,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_init(struct fman_mac *memac)
|
||||
static int memac_init(struct fman_mac *memac)
|
||||
{
|
||||
struct memac_cfg *memac_drv_param;
|
||||
u8 i;
|
||||
enet_addr_t eth_addr;
|
||||
bool slow_10g_if = false;
|
||||
struct fixed_phy_status *fixed_link;
|
||||
struct fixed_phy_status *fixed_link = NULL;
|
||||
int err;
|
||||
u32 reg32 = 0;
|
||||
|
||||
@ -1106,7 +1095,7 @@ int memac_init(struct fman_mac *memac)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memac_free(struct fman_mac *memac)
|
||||
static int memac_free(struct fman_mac *memac)
|
||||
{
|
||||
free_init_resources(memac);
|
||||
|
||||
@ -1119,13 +1108,12 @@ int memac_free(struct fman_mac *memac)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct fman_mac *memac_config(struct fman_mac_params *params)
|
||||
static struct fman_mac *memac_config(struct mac_device *mac_dev,
|
||||
struct fman_mac_params *params)
|
||||
{
|
||||
struct fman_mac *memac;
|
||||
struct memac_cfg *memac_drv_param;
|
||||
void __iomem *base_addr;
|
||||
|
||||
base_addr = params->base_addr;
|
||||
/* allocate memory for the m_emac data structure */
|
||||
memac = kzalloc(sizeof(*memac), GFP_KERNEL);
|
||||
if (!memac)
|
||||
@ -1143,38 +1131,121 @@ struct fman_mac *memac_config(struct fman_mac_params *params)
|
||||
|
||||
set_dflts(memac_drv_param);
|
||||
|
||||
memac->addr = ENET_ADDR_TO_UINT64(params->addr);
|
||||
memac->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
|
||||
|
||||
memac->regs = base_addr;
|
||||
memac->regs = mac_dev->vaddr;
|
||||
memac->max_speed = params->max_speed;
|
||||
memac->phy_if = params->phy_if;
|
||||
memac->phy_if = mac_dev->phy_if;
|
||||
memac->mac_id = params->mac_id;
|
||||
memac->exceptions = (MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER |
|
||||
MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI);
|
||||
memac->exception_cb = params->exception_cb;
|
||||
memac->event_cb = params->event_cb;
|
||||
memac->dev_id = params->dev_id;
|
||||
memac->dev_id = mac_dev;
|
||||
memac->fm = params->fm;
|
||||
memac->basex_if = params->basex_if;
|
||||
|
||||
/* Save FMan revision */
|
||||
fman_get_revision(memac->fm, &memac->fm_rev_info);
|
||||
|
||||
return memac;
|
||||
}
|
||||
|
||||
int memac_initialization(struct mac_device *mac_dev,
|
||||
struct device_node *mac_node,
|
||||
struct fman_mac_params *params)
|
||||
{
|
||||
int err;
|
||||
struct device_node *phy_node;
|
||||
struct fixed_phy_status *fixed_link;
|
||||
struct fman_mac *memac;
|
||||
|
||||
mac_dev->set_promisc = memac_set_promiscuous;
|
||||
mac_dev->change_addr = memac_modify_mac_address;
|
||||
mac_dev->add_hash_mac_addr = memac_add_hash_mac_address;
|
||||
mac_dev->remove_hash_mac_addr = memac_del_hash_mac_address;
|
||||
mac_dev->set_tx_pause = memac_set_tx_pause_frames;
|
||||
mac_dev->set_rx_pause = memac_accept_rx_pause_frames;
|
||||
mac_dev->set_exception = memac_set_exception;
|
||||
mac_dev->set_allmulti = memac_set_allmulti;
|
||||
mac_dev->set_tstamp = memac_set_tstamp;
|
||||
mac_dev->set_multi = fman_set_multi;
|
||||
mac_dev->adjust_link = adjust_link_memac;
|
||||
mac_dev->enable = memac_enable;
|
||||
mac_dev->disable = memac_disable;
|
||||
|
||||
if (params->max_speed == SPEED_10000)
|
||||
mac_dev->phy_if = PHY_INTERFACE_MODE_XGMII;
|
||||
|
||||
mac_dev->fman_mac = memac_config(mac_dev, params);
|
||||
if (!mac_dev->fman_mac) {
|
||||
err = -EINVAL;
|
||||
goto _return;
|
||||
}
|
||||
|
||||
memac = mac_dev->fman_mac;
|
||||
memac->memac_drv_param->max_frame_length = fman_get_max_frm();
|
||||
memac->memac_drv_param->reset_on_init = true;
|
||||
if (memac->phy_if == PHY_INTERFACE_MODE_SGMII ||
|
||||
memac->phy_if == PHY_INTERFACE_MODE_QSGMII) {
|
||||
if (!params->internal_phy_node) {
|
||||
phy_node = of_parse_phandle(mac_node, "pcsphy-handle", 0);
|
||||
if (!phy_node) {
|
||||
pr_err("PCS PHY node is not available\n");
|
||||
memac_free(memac);
|
||||
return NULL;
|
||||
err = -EINVAL;
|
||||
goto _return_fm_mac_free;
|
||||
}
|
||||
|
||||
memac->pcsphy = of_phy_find_device(params->internal_phy_node);
|
||||
memac->pcsphy = of_phy_find_device(phy_node);
|
||||
if (!memac->pcsphy) {
|
||||
pr_err("of_phy_find_device (PCS PHY) failed\n");
|
||||
memac_free(memac);
|
||||
return NULL;
|
||||
err = -EINVAL;
|
||||
goto _return_fm_mac_free;
|
||||
}
|
||||
}
|
||||
|
||||
return memac;
|
||||
if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
|
||||
struct phy_device *phy;
|
||||
|
||||
err = of_phy_register_fixed_link(mac_node);
|
||||
if (err)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL);
|
||||
if (!fixed_link) {
|
||||
err = -ENOMEM;
|
||||
goto _return_fm_mac_free;
|
||||
}
|
||||
|
||||
mac_dev->phy_node = of_node_get(mac_node);
|
||||
phy = of_phy_find_device(mac_dev->phy_node);
|
||||
if (!phy) {
|
||||
err = -EINVAL;
|
||||
of_node_put(mac_dev->phy_node);
|
||||
goto _return_fixed_link_free;
|
||||
}
|
||||
|
||||
fixed_link->link = phy->link;
|
||||
fixed_link->speed = phy->speed;
|
||||
fixed_link->duplex = phy->duplex;
|
||||
fixed_link->pause = phy->pause;
|
||||
fixed_link->asym_pause = phy->asym_pause;
|
||||
|
||||
put_device(&phy->mdio.dev);
|
||||
memac->memac_drv_param->fixed_link = fixed_link;
|
||||
}
|
||||
|
||||
err = memac_init(mac_dev->fman_mac);
|
||||
if (err < 0)
|
||||
goto _return_fixed_link_free;
|
||||
|
||||
dev_info(mac_dev->dev, "FMan MEMAC\n");
|
||||
|
||||
goto _return;
|
||||
|
||||
_return_fixed_link_free:
|
||||
kfree(fixed_link);
|
||||
_return_fm_mac_free:
|
||||
memac_free(mac_dev->fman_mac);
|
||||
_return:
|
||||
return err;
|
||||
}
|
||||
|
@ -11,26 +11,10 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/phy_fixed.h>
|
||||
|
||||
struct fman_mac *memac_config(struct fman_mac_params *params);
|
||||
int memac_set_promiscuous(struct fman_mac *memac, bool new_val);
|
||||
int memac_modify_mac_address(struct fman_mac *memac, const enet_addr_t *enet_addr);
|
||||
int memac_adjust_link(struct fman_mac *memac, u16 speed);
|
||||
int memac_cfg_max_frame_len(struct fman_mac *memac, u16 new_val);
|
||||
int memac_cfg_reset_on_init(struct fman_mac *memac, bool enable);
|
||||
int memac_cfg_fixed_link(struct fman_mac *memac,
|
||||
struct fixed_phy_status *fixed_link);
|
||||
int memac_enable(struct fman_mac *memac);
|
||||
int memac_disable(struct fman_mac *memac);
|
||||
int memac_init(struct fman_mac *memac);
|
||||
int memac_free(struct fman_mac *memac);
|
||||
int memac_accept_rx_pause_frames(struct fman_mac *memac, bool en);
|
||||
int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
|
||||
u16 pause_time, u16 thresh_time);
|
||||
int memac_set_exception(struct fman_mac *memac,
|
||||
enum fman_mac_exceptions exception, bool enable);
|
||||
int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
|
||||
int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
|
||||
int memac_set_allmulti(struct fman_mac *memac, bool enable);
|
||||
int memac_set_tstamp(struct fman_mac *memac, bool enable);
|
||||
struct mac_device;
|
||||
|
||||
int memac_initialization(struct mac_device *mac_dev,
|
||||
struct device_node *mac_node,
|
||||
struct fman_mac_params *params);
|
||||
|
||||
#endif /* __MEMAC_H */
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "fman_tgec.h"
|
||||
#include "fman.h"
|
||||
#include "mac.h"
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/bitrev.h>
|
||||
@ -179,7 +180,7 @@ struct fman_mac {
|
||||
/* MAC address of device; */
|
||||
u64 addr;
|
||||
u16 max_speed;
|
||||
void *dev_id; /* device cookie used by the exception cbs */
|
||||
struct mac_device *dev_id; /* device cookie used by the exception cbs */
|
||||
fman_mac_exception_cb *exception_cb;
|
||||
fman_mac_exception_cb *event_cb;
|
||||
/* pointer to driver's global address hash table */
|
||||
@ -392,7 +393,7 @@ static bool is_init_done(struct tgec_cfg *cfg)
|
||||
return false;
|
||||
}
|
||||
|
||||
int tgec_enable(struct fman_mac *tgec)
|
||||
static int tgec_enable(struct fman_mac *tgec)
|
||||
{
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
u32 tmp;
|
||||
@ -407,22 +408,19 @@ int tgec_enable(struct fman_mac *tgec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_disable(struct fman_mac *tgec)
|
||||
static void tgec_disable(struct fman_mac *tgec)
|
||||
{
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
u32 tmp;
|
||||
|
||||
if (!is_init_done(tgec->cfg))
|
||||
return -EINVAL;
|
||||
WARN_ON_ONCE(!is_init_done(tgec->cfg));
|
||||
|
||||
tmp = ioread32be(®s->command_config);
|
||||
tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
|
||||
iowrite32be(tmp, ®s->command_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val)
|
||||
static int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val)
|
||||
{
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
u32 tmp;
|
||||
@ -440,18 +438,9 @@ int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_cfg_max_frame_len(struct fman_mac *tgec, u16 new_val)
|
||||
{
|
||||
if (is_init_done(tgec->cfg))
|
||||
return -EINVAL;
|
||||
|
||||
tgec->cfg->max_frame_length = new_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_set_tx_pause_frames(struct fman_mac *tgec, u8 __maybe_unused priority,
|
||||
u16 pause_time, u16 __maybe_unused thresh_time)
|
||||
static int tgec_set_tx_pause_frames(struct fman_mac *tgec,
|
||||
u8 __maybe_unused priority, u16 pause_time,
|
||||
u16 __maybe_unused thresh_time)
|
||||
{
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
|
||||
@ -463,7 +452,7 @@ int tgec_set_tx_pause_frames(struct fman_mac *tgec, u8 __maybe_unused priority,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_accept_rx_pause_frames(struct fman_mac *tgec, bool en)
|
||||
static int tgec_accept_rx_pause_frames(struct fman_mac *tgec, bool en)
|
||||
{
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
u32 tmp;
|
||||
@ -481,7 +470,8 @@ int tgec_accept_rx_pause_frames(struct fman_mac *tgec, bool en)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_modify_mac_address(struct fman_mac *tgec, const enet_addr_t *p_enet_addr)
|
||||
static int tgec_modify_mac_address(struct fman_mac *tgec,
|
||||
const enet_addr_t *p_enet_addr)
|
||||
{
|
||||
if (!is_init_done(tgec->cfg))
|
||||
return -EINVAL;
|
||||
@ -492,7 +482,8 @@ int tgec_modify_mac_address(struct fman_mac *tgec, const enet_addr_t *p_enet_add
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
|
||||
static int tgec_add_hash_mac_address(struct fman_mac *tgec,
|
||||
enet_addr_t *eth_addr)
|
||||
{
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
struct eth_hash_entry *hash_entry;
|
||||
@ -529,7 +520,7 @@ int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_set_allmulti(struct fman_mac *tgec, bool enable)
|
||||
static int tgec_set_allmulti(struct fman_mac *tgec, bool enable)
|
||||
{
|
||||
u32 entry;
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
@ -552,7 +543,7 @@ int tgec_set_allmulti(struct fman_mac *tgec, bool enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_set_tstamp(struct fman_mac *tgec, bool enable)
|
||||
static int tgec_set_tstamp(struct fman_mac *tgec, bool enable)
|
||||
{
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
u32 tmp;
|
||||
@ -572,7 +563,8 @@ int tgec_set_tstamp(struct fman_mac *tgec, bool enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
|
||||
static int tgec_del_hash_mac_address(struct fman_mac *tgec,
|
||||
enet_addr_t *eth_addr)
|
||||
{
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
struct eth_hash_entry *hash_entry = NULL;
|
||||
@ -609,20 +601,15 @@ int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_get_version(struct fman_mac *tgec, u32 *mac_version)
|
||||
static void tgec_adjust_link(struct mac_device *mac_dev)
|
||||
{
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
struct phy_device *phy_dev = mac_dev->phy_dev;
|
||||
|
||||
if (!is_init_done(tgec->cfg))
|
||||
return -EINVAL;
|
||||
|
||||
*mac_version = ioread32be(®s->tgec_id);
|
||||
|
||||
return 0;
|
||||
mac_dev->update_speed(mac_dev, phy_dev->speed);
|
||||
}
|
||||
|
||||
int tgec_set_exception(struct fman_mac *tgec,
|
||||
enum fman_mac_exceptions exception, bool enable)
|
||||
static int tgec_set_exception(struct fman_mac *tgec,
|
||||
enum fman_mac_exceptions exception, bool enable)
|
||||
{
|
||||
struct tgec_regs __iomem *regs = tgec->regs;
|
||||
u32 bit_mask = 0;
|
||||
@ -648,7 +635,7 @@ int tgec_set_exception(struct fman_mac *tgec,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_init(struct fman_mac *tgec)
|
||||
static int tgec_init(struct fman_mac *tgec)
|
||||
{
|
||||
struct tgec_cfg *cfg;
|
||||
enet_addr_t eth_addr;
|
||||
@ -731,7 +718,7 @@ int tgec_init(struct fman_mac *tgec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tgec_free(struct fman_mac *tgec)
|
||||
static int tgec_free(struct fman_mac *tgec)
|
||||
{
|
||||
free_init_resources(tgec);
|
||||
|
||||
@ -741,13 +728,12 @@ int tgec_free(struct fman_mac *tgec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct fman_mac *tgec_config(struct fman_mac_params *params)
|
||||
static struct fman_mac *tgec_config(struct mac_device *mac_dev,
|
||||
struct fman_mac_params *params)
|
||||
{
|
||||
struct fman_mac *tgec;
|
||||
struct tgec_cfg *cfg;
|
||||
void __iomem *base_addr;
|
||||
|
||||
base_addr = params->base_addr;
|
||||
/* allocate memory for the UCC GETH data structure. */
|
||||
tgec = kzalloc(sizeof(*tgec), GFP_KERNEL);
|
||||
if (!tgec)
|
||||
@ -765,8 +751,8 @@ struct fman_mac *tgec_config(struct fman_mac_params *params)
|
||||
|
||||
set_dflts(cfg);
|
||||
|
||||
tgec->regs = base_addr;
|
||||
tgec->addr = ENET_ADDR_TO_UINT64(params->addr);
|
||||
tgec->regs = mac_dev->vaddr;
|
||||
tgec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
|
||||
tgec->max_speed = params->max_speed;
|
||||
tgec->mac_id = params->mac_id;
|
||||
tgec->exceptions = (TGEC_IMASK_MDIO_SCAN_EVENT |
|
||||
@ -786,7 +772,7 @@ struct fman_mac *tgec_config(struct fman_mac_params *params)
|
||||
TGEC_IMASK_RX_ALIGN_ER);
|
||||
tgec->exception_cb = params->exception_cb;
|
||||
tgec->event_cb = params->event_cb;
|
||||
tgec->dev_id = params->dev_id;
|
||||
tgec->dev_id = mac_dev;
|
||||
tgec->fm = params->fm;
|
||||
|
||||
/* Save FMan revision */
|
||||
@ -794,3 +780,52 @@ struct fman_mac *tgec_config(struct fman_mac_params *params)
|
||||
|
||||
return tgec;
|
||||
}
|
||||
|
||||
int tgec_initialization(struct mac_device *mac_dev,
|
||||
struct device_node *mac_node,
|
||||
struct fman_mac_params *params)
|
||||
{
|
||||
int err;
|
||||
struct fman_mac *tgec;
|
||||
|
||||
mac_dev->set_promisc = tgec_set_promiscuous;
|
||||
mac_dev->change_addr = tgec_modify_mac_address;
|
||||
mac_dev->add_hash_mac_addr = tgec_add_hash_mac_address;
|
||||
mac_dev->remove_hash_mac_addr = tgec_del_hash_mac_address;
|
||||
mac_dev->set_tx_pause = tgec_set_tx_pause_frames;
|
||||
mac_dev->set_rx_pause = tgec_accept_rx_pause_frames;
|
||||
mac_dev->set_exception = tgec_set_exception;
|
||||
mac_dev->set_allmulti = tgec_set_allmulti;
|
||||
mac_dev->set_tstamp = tgec_set_tstamp;
|
||||
mac_dev->set_multi = fman_set_multi;
|
||||
mac_dev->adjust_link = tgec_adjust_link;
|
||||
mac_dev->enable = tgec_enable;
|
||||
mac_dev->disable = tgec_disable;
|
||||
|
||||
mac_dev->fman_mac = tgec_config(mac_dev, params);
|
||||
if (!mac_dev->fman_mac) {
|
||||
err = -EINVAL;
|
||||
goto _return;
|
||||
}
|
||||
|
||||
tgec = mac_dev->fman_mac;
|
||||
tgec->cfg->max_frame_length = fman_get_max_frm();
|
||||
err = tgec_init(tgec);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
/* For 10G MAC, disable Tx ECC exception */
|
||||
err = tgec_set_exception(tgec, FM_MAC_EX_10G_TX_ECC_ER, false);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
pr_info("FMan XGEC version: 0x%08x\n",
|
||||
ioread32be(&tgec->regs->tgec_id));
|
||||
goto _return;
|
||||
|
||||
_return_fm_mac_free:
|
||||
tgec_free(mac_dev->fman_mac);
|
||||
|
||||
_return:
|
||||
return err;
|
||||
}
|
||||
|
@ -8,23 +8,10 @@
|
||||
|
||||
#include "fman_mac.h"
|
||||
|
||||
struct fman_mac *tgec_config(struct fman_mac_params *params);
|
||||
int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val);
|
||||
int tgec_modify_mac_address(struct fman_mac *tgec, const enet_addr_t *enet_addr);
|
||||
int tgec_cfg_max_frame_len(struct fman_mac *tgec, u16 new_val);
|
||||
int tgec_enable(struct fman_mac *tgec);
|
||||
int tgec_disable(struct fman_mac *tgec);
|
||||
int tgec_init(struct fman_mac *tgec);
|
||||
int tgec_free(struct fman_mac *tgec);
|
||||
int tgec_accept_rx_pause_frames(struct fman_mac *tgec, bool en);
|
||||
int tgec_set_tx_pause_frames(struct fman_mac *tgec, u8 priority,
|
||||
u16 pause_time, u16 thresh_time);
|
||||
int tgec_set_exception(struct fman_mac *tgec,
|
||||
enum fman_mac_exceptions exception, bool enable);
|
||||
int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
|
||||
int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
|
||||
int tgec_get_version(struct fman_mac *tgec, u32 *mac_version);
|
||||
int tgec_set_allmulti(struct fman_mac *tgec, bool enable);
|
||||
int tgec_set_tstamp(struct fman_mac *tgec, bool enable);
|
||||
struct mac_device;
|
||||
|
||||
int tgec_initialization(struct mac_device *mac_dev,
|
||||
struct device_node *mac_node,
|
||||
struct fman_mac_params *params);
|
||||
|
||||
#endif /* __TGEC_H */
|
||||
|
@ -28,14 +28,12 @@ MODULE_LICENSE("Dual BSD/GPL");
|
||||
MODULE_DESCRIPTION("FSL FMan MAC API based driver");
|
||||
|
||||
struct mac_priv_s {
|
||||
void __iomem *vaddr;
|
||||
u8 cell_index;
|
||||
struct fman *fman;
|
||||
/* List of multicast addresses */
|
||||
struct list_head mc_addr_list;
|
||||
struct platform_device *eth_dev;
|
||||
u16 speed;
|
||||
u16 max_speed;
|
||||
};
|
||||
|
||||
struct mac_address {
|
||||
@ -43,10 +41,9 @@ struct mac_address {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static void mac_exception(void *handle, enum fman_mac_exceptions ex)
|
||||
static void mac_exception(struct mac_device *mac_dev,
|
||||
enum fman_mac_exceptions ex)
|
||||
{
|
||||
struct mac_device *mac_dev = handle;
|
||||
|
||||
if (ex == FM_MAC_EX_10G_RX_FIFO_OVFL) {
|
||||
/* don't flag RX FIFO after the first */
|
||||
mac_dev->set_exception(mac_dev->fman_mac,
|
||||
@ -58,30 +55,6 @@ static void mac_exception(void *handle, enum fman_mac_exceptions ex)
|
||||
__func__, ex);
|
||||
}
|
||||
|
||||
int set_fman_mac_params(struct mac_device *mac_dev,
|
||||
struct fman_mac_params *params)
|
||||
{
|
||||
struct mac_priv_s *priv = mac_dev->priv;
|
||||
|
||||
params->base_addr = (typeof(params->base_addr))
|
||||
devm_ioremap(mac_dev->dev, mac_dev->res->start,
|
||||
resource_size(mac_dev->res));
|
||||
if (!params->base_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(¶ms->addr, mac_dev->addr, sizeof(mac_dev->addr));
|
||||
params->max_speed = priv->max_speed;
|
||||
params->phy_if = mac_dev->phy_if;
|
||||
params->basex_if = false;
|
||||
params->mac_id = priv->cell_index;
|
||||
params->fm = (void *)priv->fman;
|
||||
params->exception_cb = mac_exception;
|
||||
params->event_cb = mac_exception;
|
||||
params->dev_id = mac_dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fman_set_multi(struct net_device *net_dev, struct mac_device *mac_dev)
|
||||
{
|
||||
struct mac_priv_s *priv;
|
||||
@ -216,267 +189,6 @@ void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
|
||||
}
|
||||
EXPORT_SYMBOL(fman_get_pause_cfg);
|
||||
|
||||
static void adjust_link_void(struct mac_device *mac_dev)
|
||||
{
|
||||
}
|
||||
|
||||
static void adjust_link_dtsec(struct mac_device *mac_dev)
|
||||
{
|
||||
struct phy_device *phy_dev = mac_dev->phy_dev;
|
||||
struct fman_mac *fman_mac;
|
||||
bool rx_pause, tx_pause;
|
||||
int err;
|
||||
|
||||
fman_mac = mac_dev->fman_mac;
|
||||
if (!phy_dev->link) {
|
||||
dtsec_restart_autoneg(fman_mac);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dtsec_adjust_link(fman_mac, phy_dev->speed);
|
||||
fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
|
||||
err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
|
||||
if (err < 0)
|
||||
dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
|
||||
err);
|
||||
}
|
||||
|
||||
static void adjust_link_memac(struct mac_device *mac_dev)
|
||||
{
|
||||
struct phy_device *phy_dev = mac_dev->phy_dev;
|
||||
struct fman_mac *fman_mac;
|
||||
bool rx_pause, tx_pause;
|
||||
int err;
|
||||
|
||||
fman_mac = mac_dev->fman_mac;
|
||||
memac_adjust_link(fman_mac, phy_dev->speed);
|
||||
|
||||
fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
|
||||
err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
|
||||
if (err < 0)
|
||||
dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
|
||||
err);
|
||||
}
|
||||
|
||||
static int tgec_initialization(struct mac_device *mac_dev,
|
||||
struct device_node *mac_node)
|
||||
{
|
||||
int err;
|
||||
struct fman_mac_params params;
|
||||
u32 version;
|
||||
|
||||
mac_dev->set_promisc = tgec_set_promiscuous;
|
||||
mac_dev->change_addr = tgec_modify_mac_address;
|
||||
mac_dev->add_hash_mac_addr = tgec_add_hash_mac_address;
|
||||
mac_dev->remove_hash_mac_addr = tgec_del_hash_mac_address;
|
||||
mac_dev->set_tx_pause = tgec_set_tx_pause_frames;
|
||||
mac_dev->set_rx_pause = tgec_accept_rx_pause_frames;
|
||||
mac_dev->set_exception = tgec_set_exception;
|
||||
mac_dev->set_allmulti = tgec_set_allmulti;
|
||||
mac_dev->set_tstamp = tgec_set_tstamp;
|
||||
mac_dev->set_multi = fman_set_multi;
|
||||
mac_dev->adjust_link = adjust_link_void;
|
||||
mac_dev->enable = tgec_enable;
|
||||
mac_dev->disable = tgec_disable;
|
||||
|
||||
err = set_fman_mac_params(mac_dev, ¶ms);
|
||||
if (err)
|
||||
goto _return;
|
||||
|
||||
mac_dev->fman_mac = tgec_config(¶ms);
|
||||
if (!mac_dev->fman_mac) {
|
||||
err = -EINVAL;
|
||||
goto _return;
|
||||
}
|
||||
|
||||
err = tgec_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
err = tgec_init(mac_dev->fman_mac);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
/* For 10G MAC, disable Tx ECC exception */
|
||||
err = mac_dev->set_exception(mac_dev->fman_mac,
|
||||
FM_MAC_EX_10G_TX_ECC_ER, false);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
err = tgec_get_version(mac_dev->fman_mac, &version);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
dev_info(mac_dev->dev, "FMan XGEC version: 0x%08x\n", version);
|
||||
|
||||
goto _return;
|
||||
|
||||
_return_fm_mac_free:
|
||||
tgec_free(mac_dev->fman_mac);
|
||||
|
||||
_return:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dtsec_initialization(struct mac_device *mac_dev,
|
||||
struct device_node *mac_node)
|
||||
{
|
||||
int err;
|
||||
struct fman_mac_params params;
|
||||
u32 version;
|
||||
|
||||
mac_dev->set_promisc = dtsec_set_promiscuous;
|
||||
mac_dev->change_addr = dtsec_modify_mac_address;
|
||||
mac_dev->add_hash_mac_addr = dtsec_add_hash_mac_address;
|
||||
mac_dev->remove_hash_mac_addr = dtsec_del_hash_mac_address;
|
||||
mac_dev->set_tx_pause = dtsec_set_tx_pause_frames;
|
||||
mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames;
|
||||
mac_dev->set_exception = dtsec_set_exception;
|
||||
mac_dev->set_allmulti = dtsec_set_allmulti;
|
||||
mac_dev->set_tstamp = dtsec_set_tstamp;
|
||||
mac_dev->set_multi = fman_set_multi;
|
||||
mac_dev->adjust_link = adjust_link_dtsec;
|
||||
mac_dev->enable = dtsec_enable;
|
||||
mac_dev->disable = dtsec_disable;
|
||||
|
||||
err = set_fman_mac_params(mac_dev, ¶ms);
|
||||
if (err)
|
||||
goto _return;
|
||||
params.internal_phy_node = of_parse_phandle(mac_node, "tbi-handle", 0);
|
||||
|
||||
mac_dev->fman_mac = dtsec_config(¶ms);
|
||||
if (!mac_dev->fman_mac) {
|
||||
err = -EINVAL;
|
||||
goto _return;
|
||||
}
|
||||
|
||||
err = dtsec_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
err = dtsec_cfg_pad_and_crc(mac_dev->fman_mac, true);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
err = dtsec_init(mac_dev->fman_mac);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
/* For 1G MAC, disable by default the MIB counters overflow interrupt */
|
||||
err = mac_dev->set_exception(mac_dev->fman_mac,
|
||||
FM_MAC_EX_1G_RX_MIB_CNT_OVFL, false);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
err = dtsec_get_version(mac_dev->fman_mac, &version);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
dev_info(mac_dev->dev, "FMan dTSEC version: 0x%08x\n", version);
|
||||
|
||||
goto _return;
|
||||
|
||||
_return_fm_mac_free:
|
||||
dtsec_free(mac_dev->fman_mac);
|
||||
|
||||
_return:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int memac_initialization(struct mac_device *mac_dev,
|
||||
struct device_node *mac_node)
|
||||
{
|
||||
int err;
|
||||
struct fman_mac_params params;
|
||||
struct fixed_phy_status *fixed_link = NULL;
|
||||
|
||||
mac_dev->set_promisc = memac_set_promiscuous;
|
||||
mac_dev->change_addr = memac_modify_mac_address;
|
||||
mac_dev->add_hash_mac_addr = memac_add_hash_mac_address;
|
||||
mac_dev->remove_hash_mac_addr = memac_del_hash_mac_address;
|
||||
mac_dev->set_tx_pause = memac_set_tx_pause_frames;
|
||||
mac_dev->set_rx_pause = memac_accept_rx_pause_frames;
|
||||
mac_dev->set_exception = memac_set_exception;
|
||||
mac_dev->set_allmulti = memac_set_allmulti;
|
||||
mac_dev->set_tstamp = memac_set_tstamp;
|
||||
mac_dev->set_multi = fman_set_multi;
|
||||
mac_dev->adjust_link = adjust_link_memac;
|
||||
mac_dev->enable = memac_enable;
|
||||
mac_dev->disable = memac_disable;
|
||||
|
||||
err = set_fman_mac_params(mac_dev, ¶ms);
|
||||
if (err)
|
||||
goto _return;
|
||||
params.internal_phy_node = of_parse_phandle(mac_node, "pcsphy-handle", 0);
|
||||
|
||||
if (params.max_speed == SPEED_10000)
|
||||
params.phy_if = PHY_INTERFACE_MODE_XGMII;
|
||||
|
||||
mac_dev->fman_mac = memac_config(¶ms);
|
||||
if (!mac_dev->fman_mac) {
|
||||
err = -EINVAL;
|
||||
goto _return;
|
||||
}
|
||||
|
||||
err = memac_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
err = memac_cfg_reset_on_init(mac_dev->fman_mac, true);
|
||||
if (err < 0)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
|
||||
struct phy_device *phy;
|
||||
|
||||
err = of_phy_register_fixed_link(mac_node);
|
||||
if (err)
|
||||
goto _return_fm_mac_free;
|
||||
|
||||
fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL);
|
||||
if (!fixed_link) {
|
||||
err = -ENOMEM;
|
||||
goto _return_fm_mac_free;
|
||||
}
|
||||
|
||||
mac_dev->phy_node = of_node_get(mac_node);
|
||||
phy = of_phy_find_device(mac_dev->phy_node);
|
||||
if (!phy) {
|
||||
err = -EINVAL;
|
||||
of_node_put(mac_dev->phy_node);
|
||||
goto _return_fixed_link_free;
|
||||
}
|
||||
|
||||
fixed_link->link = phy->link;
|
||||
fixed_link->speed = phy->speed;
|
||||
fixed_link->duplex = phy->duplex;
|
||||
fixed_link->pause = phy->pause;
|
||||
fixed_link->asym_pause = phy->asym_pause;
|
||||
|
||||
put_device(&phy->mdio.dev);
|
||||
|
||||
err = memac_cfg_fixed_link(mac_dev->fman_mac, fixed_link);
|
||||
if (err < 0)
|
||||
goto _return_fixed_link_free;
|
||||
}
|
||||
|
||||
err = memac_init(mac_dev->fman_mac);
|
||||
if (err < 0)
|
||||
goto _return_fixed_link_free;
|
||||
|
||||
dev_info(mac_dev->dev, "FMan MEMAC\n");
|
||||
|
||||
goto _return;
|
||||
|
||||
_return_fixed_link_free:
|
||||
kfree(fixed_link);
|
||||
_return_fm_mac_free:
|
||||
memac_free(mac_dev->fman_mac);
|
||||
_return:
|
||||
return err;
|
||||
}
|
||||
|
||||
#define DTSEC_SUPPORTED \
|
||||
(SUPPORTED_10baseT_Half \
|
||||
| SUPPORTED_10baseT_Full \
|
||||
@ -561,13 +273,15 @@ MODULE_DEVICE_TABLE(of, mac_match);
|
||||
static int mac_probe(struct platform_device *_of_dev)
|
||||
{
|
||||
int err, i, nph;
|
||||
int (*init)(struct mac_device *mac_dev, struct device_node *mac_node);
|
||||
int (*init)(struct mac_device *mac_dev, struct device_node *mac_node,
|
||||
struct fman_mac_params *params);
|
||||
struct device *dev;
|
||||
struct device_node *mac_node, *dev_node;
|
||||
struct mac_device *mac_dev;
|
||||
struct platform_device *of_dev;
|
||||
struct resource res;
|
||||
struct resource *res;
|
||||
struct mac_priv_s *priv;
|
||||
struct fman_mac_params params;
|
||||
u32 val;
|
||||
u8 fman_id;
|
||||
phy_interface_t phy_if;
|
||||
@ -577,15 +291,11 @@ static int mac_probe(struct platform_device *_of_dev)
|
||||
init = of_device_get_match_data(dev);
|
||||
|
||||
mac_dev = devm_kzalloc(dev, sizeof(*mac_dev), GFP_KERNEL);
|
||||
if (!mac_dev) {
|
||||
err = -ENOMEM;
|
||||
goto _return;
|
||||
}
|
||||
if (!mac_dev)
|
||||
return -ENOMEM;
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv) {
|
||||
err = -ENOMEM;
|
||||
goto _return;
|
||||
}
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Save private information */
|
||||
mac_dev->priv = priv;
|
||||
@ -598,8 +308,7 @@ static int mac_probe(struct platform_device *_of_dev)
|
||||
if (!dev_node) {
|
||||
dev_err(dev, "of_get_parent(%pOF) failed\n",
|
||||
mac_node);
|
||||
err = -EINVAL;
|
||||
goto _return_of_node_put;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
of_dev = of_find_device_by_node(dev_node);
|
||||
@ -629,42 +338,33 @@ static int mac_probe(struct platform_device *_of_dev)
|
||||
of_node_put(dev_node);
|
||||
|
||||
/* Get the address of the memory mapped registers */
|
||||
err = of_address_to_resource(mac_node, 0, &res);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "of_address_to_resource(%pOF) = %d\n",
|
||||
mac_node, err);
|
||||
goto _return_of_node_put;
|
||||
res = platform_get_mem_or_io(_of_dev, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "could not get registers\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mac_dev->res = __devm_request_region(dev,
|
||||
fman_get_mem_region(priv->fman),
|
||||
res.start, resource_size(&res),
|
||||
"mac");
|
||||
if (!mac_dev->res) {
|
||||
dev_err(dev, "__devm_request_mem_region(mac) failed\n");
|
||||
err = -EBUSY;
|
||||
goto _return_of_node_put;
|
||||
err = devm_request_resource(dev, fman_get_mem_region(priv->fman), res);
|
||||
if (err) {
|
||||
dev_err_probe(dev, err, "could not request resource\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
priv->vaddr = devm_ioremap(dev, mac_dev->res->start,
|
||||
resource_size(mac_dev->res));
|
||||
if (!priv->vaddr) {
|
||||
mac_dev->vaddr = devm_ioremap(dev, res->start, resource_size(res));
|
||||
if (!mac_dev->vaddr) {
|
||||
dev_err(dev, "devm_ioremap() failed\n");
|
||||
err = -EIO;
|
||||
goto _return_of_node_put;
|
||||
return -EIO;
|
||||
}
|
||||
mac_dev->vaddr_end = mac_dev->vaddr + resource_size(res);
|
||||
|
||||
if (!of_device_is_available(mac_node)) {
|
||||
err = -ENODEV;
|
||||
goto _return_of_node_put;
|
||||
}
|
||||
if (!of_device_is_available(mac_node))
|
||||
return -ENODEV;
|
||||
|
||||
/* Get the cell-index */
|
||||
err = of_property_read_u32(mac_node, "cell-index", &val);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to read cell-index for %pOF\n", mac_node);
|
||||
err = -EINVAL;
|
||||
goto _return_of_node_put;
|
||||
return -EINVAL;
|
||||
}
|
||||
priv->cell_index = (u8)val;
|
||||
|
||||
@ -678,15 +378,13 @@ static int mac_probe(struct platform_device *_of_dev)
|
||||
if (unlikely(nph < 0)) {
|
||||
dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n",
|
||||
mac_node);
|
||||
err = nph;
|
||||
goto _return_of_node_put;
|
||||
return nph;
|
||||
}
|
||||
|
||||
if (nph != ARRAY_SIZE(mac_dev->port)) {
|
||||
dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n",
|
||||
mac_node);
|
||||
err = -EINVAL;
|
||||
goto _return_of_node_put;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
|
||||
@ -695,8 +393,7 @@ static int mac_probe(struct platform_device *_of_dev)
|
||||
if (!dev_node) {
|
||||
dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n",
|
||||
mac_node);
|
||||
err = -EINVAL;
|
||||
goto _return_of_node_put;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
of_dev = of_find_device_by_node(dev_node);
|
||||
@ -728,7 +425,7 @@ static int mac_probe(struct platform_device *_of_dev)
|
||||
mac_dev->phy_if = phy_if;
|
||||
|
||||
priv->speed = phy2speed[mac_dev->phy_if];
|
||||
priv->max_speed = priv->speed;
|
||||
params.max_speed = priv->speed;
|
||||
mac_dev->if_support = DTSEC_SUPPORTED;
|
||||
/* We don't support half-duplex in SGMII mode */
|
||||
if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII)
|
||||
@ -736,7 +433,7 @@ static int mac_probe(struct platform_device *_of_dev)
|
||||
SUPPORTED_100baseT_Half);
|
||||
|
||||
/* Gigabit support (no half-duplex) */
|
||||
if (priv->max_speed == 1000)
|
||||
if (params.max_speed == 1000)
|
||||
mac_dev->if_support |= SUPPORTED_1000baseT_Full;
|
||||
|
||||
/* The 10G interface only supports one mode */
|
||||
@ -746,11 +443,17 @@ static int mac_probe(struct platform_device *_of_dev)
|
||||
/* Get the rest of the PHY information */
|
||||
mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
|
||||
|
||||
err = init(mac_dev, mac_node);
|
||||
params.basex_if = false;
|
||||
params.mac_id = priv->cell_index;
|
||||
params.fm = (void *)priv->fman;
|
||||
params.exception_cb = mac_exception;
|
||||
params.event_cb = mac_exception;
|
||||
|
||||
err = init(mac_dev, mac_node, ¶ms);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "mac_dev->init() = %d\n", err);
|
||||
of_node_put(mac_dev->phy_node);
|
||||
goto _return_of_node_put;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* pause frame autonegotiation enabled */
|
||||
@ -777,11 +480,10 @@ static int mac_probe(struct platform_device *_of_dev)
|
||||
priv->eth_dev = NULL;
|
||||
}
|
||||
|
||||
goto _return;
|
||||
return err;
|
||||
|
||||
_return_of_node_put:
|
||||
of_node_put(dev_node);
|
||||
_return:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -19,14 +19,16 @@ struct fman_mac;
|
||||
struct mac_priv_s;
|
||||
|
||||
struct mac_device {
|
||||
void __iomem *vaddr;
|
||||
void __iomem *vaddr_end;
|
||||
struct device *dev;
|
||||
struct resource *res;
|
||||
u8 addr[ETH_ALEN];
|
||||
struct fman_port *port[2];
|
||||
u32 if_support;
|
||||
struct phy_device *phy_dev;
|
||||
phy_interface_t phy_if;
|
||||
struct device_node *phy_node;
|
||||
struct net_device *net_dev;
|
||||
|
||||
bool autoneg_pause;
|
||||
bool rx_pause_req;
|
||||
@ -37,7 +39,7 @@ struct mac_device {
|
||||
bool allmulti;
|
||||
|
||||
int (*enable)(struct fman_mac *mac_dev);
|
||||
int (*disable)(struct fman_mac *mac_dev);
|
||||
void (*disable)(struct fman_mac *mac_dev);
|
||||
void (*adjust_link)(struct mac_device *mac_dev);
|
||||
int (*set_promisc)(struct fman_mac *mac_dev, bool enable);
|
||||
int (*change_addr)(struct fman_mac *mac_dev, const enet_addr_t *enet_addr);
|
||||
@ -55,6 +57,8 @@ struct mac_device {
|
||||
int (*remove_hash_mac_addr)(struct fman_mac *mac_dev,
|
||||
enet_addr_t *eth_addr);
|
||||
|
||||
void (*update_speed)(struct mac_device *mac_dev, int speed);
|
||||
|
||||
struct fman_mac *fman_mac;
|
||||
struct mac_priv_s *priv;
|
||||
};
|
||||
@ -71,8 +75,6 @@ int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx);
|
||||
|
||||
void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
|
||||
bool *tx_pause);
|
||||
int set_fman_mac_params(struct mac_device *mac_dev,
|
||||
struct fman_mac_params *params);
|
||||
int fman_set_multi(struct net_device *net_dev, struct mac_device *mac_dev);
|
||||
|
||||
#endif /* __MAC_H */
|
||||
|
@ -2483,13 +2483,8 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL(qman_create_cgr);
|
||||
|
||||
int qman_delete_cgr(struct qman_cgr *cgr)
|
||||
static struct qman_portal *qman_cgr_get_affine_portal(struct qman_cgr *cgr)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
struct qm_mcr_querycgr cgr_state;
|
||||
struct qm_mcc_initcgr local_opts;
|
||||
int ret = 0;
|
||||
struct qman_cgr *i;
|
||||
struct qman_portal *p = get_affine_portal();
|
||||
|
||||
if (cgr->chan != p->config->channel) {
|
||||
@ -2497,10 +2492,25 @@ int qman_delete_cgr(struct qman_cgr *cgr)
|
||||
dev_err(p->config->dev, "CGR not owned by current portal");
|
||||
dev_dbg(p->config->dev, " create 0x%x, delete 0x%x\n",
|
||||
cgr->chan, p->config->channel);
|
||||
|
||||
ret = -EINVAL;
|
||||
goto put_portal;
|
||||
put_affine_portal();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int qman_delete_cgr(struct qman_cgr *cgr)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
struct qm_mcr_querycgr cgr_state;
|
||||
struct qm_mcc_initcgr local_opts;
|
||||
int ret = 0;
|
||||
struct qman_cgr *i;
|
||||
struct qman_portal *p = qman_cgr_get_affine_portal(cgr);
|
||||
|
||||
if (!p)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
|
||||
spin_lock_irqsave(&p->cgr_lock, irqflags);
|
||||
list_del(&cgr->node);
|
||||
@ -2528,7 +2538,6 @@ int qman_delete_cgr(struct qman_cgr *cgr)
|
||||
list_add(&cgr->node, &p->cgr_cbs);
|
||||
release_lock:
|
||||
spin_unlock_irqrestore(&p->cgr_lock, irqflags);
|
||||
put_portal:
|
||||
put_affine_portal();
|
||||
return ret;
|
||||
}
|
||||
@ -2559,6 +2568,54 @@ void qman_delete_cgr_safe(struct qman_cgr *cgr)
|
||||
}
|
||||
EXPORT_SYMBOL(qman_delete_cgr_safe);
|
||||
|
||||
static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
|
||||
{
|
||||
int ret;
|
||||
unsigned long irqflags;
|
||||
struct qman_portal *p = qman_cgr_get_affine_portal(cgr);
|
||||
|
||||
if (!p)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&p->cgr_lock, irqflags);
|
||||
ret = qm_modify_cgr(cgr, 0, opts);
|
||||
spin_unlock_irqrestore(&p->cgr_lock, irqflags);
|
||||
put_affine_portal();
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct update_cgr_params {
|
||||
struct qman_cgr *cgr;
|
||||
struct qm_mcc_initcgr *opts;
|
||||
int ret;
|
||||
};
|
||||
|
||||
static void qman_update_cgr_smp_call(void *p)
|
||||
{
|
||||
struct update_cgr_params *params = p;
|
||||
|
||||
params->ret = qman_update_cgr(params->cgr, params->opts);
|
||||
}
|
||||
|
||||
int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
|
||||
{
|
||||
struct update_cgr_params params = {
|
||||
.cgr = cgr,
|
||||
.opts = opts,
|
||||
};
|
||||
|
||||
preempt_disable();
|
||||
if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id())
|
||||
smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
|
||||
qman_update_cgr_smp_call, ¶ms,
|
||||
true);
|
||||
else
|
||||
params.ret = qman_update_cgr(cgr, opts);
|
||||
preempt_enable();
|
||||
return params.ret;
|
||||
}
|
||||
EXPORT_SYMBOL(qman_update_cgr_safe);
|
||||
|
||||
/* Cleanup FQs */
|
||||
|
||||
static int _qm_mr_consume_and_match_verb(struct qm_portal *p, int v)
|
||||
|
@ -1171,6 +1171,15 @@ int qman_delete_cgr(struct qman_cgr *cgr);
|
||||
*/
|
||||
void qman_delete_cgr_safe(struct qman_cgr *cgr);
|
||||
|
||||
/**
|
||||
* qman_update_cgr_safe - Modifies a congestion group object from any CPU
|
||||
* @cgr: the 'cgr' object to modify
|
||||
* @opts: state of the CGR settings
|
||||
*
|
||||
* This will select the proper CPU and modify the CGR settings.
|
||||
*/
|
||||
int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts);
|
||||
|
||||
/**
|
||||
* qman_query_cgr_congested - Queries CGR's congestion status
|
||||
* @cgr: the 'cgr' object to query
|
||||
|
Loading…
Reference in New Issue
Block a user