|
@@ -119,7 +119,6 @@ static void prueth_cleanup_tx_chns(struct prueth_emac *emac)
|
|
|
static int prueth_init_tx_chns(struct prueth_emac *emac)
|
|
static int prueth_init_tx_chns(struct prueth_emac *emac)
|
|
|
{
|
|
{
|
|
|
struct net_device *ndev = emac->ndev;
|
|
struct net_device *ndev = emac->ndev;
|
|
|
- struct prueth *prueth = emac->prueth;
|
|
|
|
|
struct device *dev = emac->prueth->dev;
|
|
struct device *dev = emac->prueth->dev;
|
|
|
struct k3_nav_udmax_tx_channel_cfg tx_cfg;
|
|
struct k3_nav_udmax_tx_channel_cfg tx_cfg;
|
|
|
static const struct k3_ring_cfg ring_cfg = {
|
|
static const struct k3_ring_cfg ring_cfg = {
|
|
@@ -129,10 +128,14 @@ static int prueth_init_tx_chns(struct prueth_emac *emac)
|
|
|
.size = PRUETH_MAX_TX_DESC,
|
|
.size = PRUETH_MAX_TX_DESC,
|
|
|
};
|
|
};
|
|
|
u32 hdesc_size;
|
|
u32 hdesc_size;
|
|
|
- int ret;
|
|
|
|
|
|
|
+ int ret, slice;
|
|
|
struct prueth_tx_chn *tx_chn = &emac->tx_chns;
|
|
struct prueth_tx_chn *tx_chn = &emac->tx_chns;
|
|
|
char tx_chn_name[16];
|
|
char tx_chn_name[16];
|
|
|
|
|
|
|
|
|
|
+ slice = prueth_emac_slice(emac);
|
|
|
|
|
+ if (slice < 0)
|
|
|
|
|
+ return slice;
|
|
|
|
|
+
|
|
|
init_completion(&emac->tdown_complete);
|
|
init_completion(&emac->tdown_complete);
|
|
|
|
|
|
|
|
hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE,
|
|
hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE,
|
|
@@ -142,16 +145,8 @@ static int prueth_init_tx_chns(struct prueth_emac *emac)
|
|
|
tx_cfg.tx_cfg = ring_cfg;
|
|
tx_cfg.tx_cfg = ring_cfg;
|
|
|
tx_cfg.txcq_cfg = ring_cfg;
|
|
tx_cfg.txcq_cfg = ring_cfg;
|
|
|
|
|
|
|
|
- /* To differentiate channels. For Single ICSSG case, slice #
|
|
|
|
|
- * is used and for Dual ICSSG case, icssg # used for naming
|
|
|
|
|
- * the channel
|
|
|
|
|
- */
|
|
|
|
|
- if (!prueth->dual_icssg)
|
|
|
|
|
- snprintf(tx_chn_name, sizeof(tx_chn_name), "tx%d-0",
|
|
|
|
|
- emac->egress_slice);
|
|
|
|
|
- else
|
|
|
|
|
- snprintf(tx_chn_name, sizeof(tx_chn_name), "tx%d-0",
|
|
|
|
|
- emac->egress_icssg);
|
|
|
|
|
|
|
+ /* To differentiate channels for SLICE0 vs SLICE1 */
|
|
|
|
|
+ snprintf(tx_chn_name, sizeof(tx_chn_name), "tx%d-0", slice);
|
|
|
|
|
|
|
|
tx_chn->descs_num = PRUETH_MAX_TX_DESC;
|
|
tx_chn->descs_num = PRUETH_MAX_TX_DESC;
|
|
|
spin_lock_init(&tx_chn->lock);
|
|
spin_lock_init(&tx_chn->lock);
|
|
@@ -194,23 +189,18 @@ static int prueth_init_rx_chns(struct prueth_emac *emac,
|
|
|
{
|
|
{
|
|
|
struct net_device *ndev = emac->ndev;
|
|
struct net_device *ndev = emac->ndev;
|
|
|
struct device *dev = emac->prueth->dev;
|
|
struct device *dev = emac->prueth->dev;
|
|
|
- struct prueth *prueth = emac->prueth;
|
|
|
|
|
struct k3_nav_udmax_rx_channel_cfg rx_cfg;
|
|
struct k3_nav_udmax_rx_channel_cfg rx_cfg;
|
|
|
u32 fdqring_id;
|
|
u32 fdqring_id;
|
|
|
u32 hdesc_size;
|
|
u32 hdesc_size;
|
|
|
- int i, ret = 0;
|
|
|
|
|
|
|
+ int i, ret = 0, slice;
|
|
|
char rx_chn_name[16];
|
|
char rx_chn_name[16];
|
|
|
|
|
|
|
|
- /* To differentiate channels. For Single ICSSG case, slice #
|
|
|
|
|
- * is used and for Dual ICSSG case, icssg # used for naming
|
|
|
|
|
- * the channel
|
|
|
|
|
- */
|
|
|
|
|
- if (!prueth->dual_icssg)
|
|
|
|
|
- snprintf(rx_chn_name, sizeof(rx_chn_name), "%s%d",
|
|
|
|
|
- name, emac->ingress_slice);
|
|
|
|
|
- else
|
|
|
|
|
- snprintf(rx_chn_name, sizeof(rx_chn_name), "%s%d",
|
|
|
|
|
- name, emac->ingress_icssg);
|
|
|
|
|
|
|
+ slice = prueth_emac_slice(emac);
|
|
|
|
|
+ if (slice < 0)
|
|
|
|
|
+ return slice;
|
|
|
|
|
+
|
|
|
|
|
+ /* To differentiate channels for SLICE0 vs SLICE1 */
|
|
|
|
|
+ snprintf(rx_chn_name, sizeof(rx_chn_name), "%s%d", name, slice);
|
|
|
|
|
|
|
|
hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE,
|
|
hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE,
|
|
|
PRUETH_NAV_SW_DATA_SIZE);
|
|
PRUETH_NAV_SW_DATA_SIZE);
|
|
@@ -864,37 +854,32 @@ static irqreturn_t prueth_tx_irq(int irq, void *dev_id)
|
|
|
return IRQ_HANDLED;
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void icssg_config_set(struct prueth *prueth, int icssg, int slice)
|
|
|
|
|
|
|
+static void icssg_config_set(struct prueth *prueth, int slice)
|
|
|
{
|
|
{
|
|
|
void __iomem *va;
|
|
void __iomem *va;
|
|
|
|
|
|
|
|
- va = prueth->shram[icssg].va + slice * ICSSG_CONFIG_OFFSET_SLICE1;
|
|
|
|
|
- memcpy_toio(va, &prueth->config[icssg][slice],
|
|
|
|
|
- sizeof(prueth->config[slice]));
|
|
|
|
|
|
|
+ va = prueth->shram.va + slice * ICSSG_CONFIG_OFFSET_SLICE1;
|
|
|
|
|
+ memcpy_toio(va, &prueth->config[slice], sizeof(prueth->config[slice]));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static int prueth_emac_start(struct prueth *prueth,
|
|
|
|
|
- struct prueth_emac *emac,
|
|
|
|
|
- bool ingress)
|
|
|
|
|
|
|
+static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
|
|
|
{
|
|
{
|
|
|
struct device *dev = prueth->dev;
|
|
struct device *dev = prueth->dev;
|
|
|
- int ret, icssg, slice;
|
|
|
|
|
|
|
+ int slice, ret;
|
|
|
struct icssg_config *config;
|
|
struct icssg_config *config;
|
|
|
int i;
|
|
int i;
|
|
|
|
|
|
|
|
- if (ingress) {
|
|
|
|
|
- icssg = emac->ingress_icssg;
|
|
|
|
|
- slice = emac->ingress_slice;
|
|
|
|
|
- } else {
|
|
|
|
|
- icssg = emac->egress_icssg;
|
|
|
|
|
- slice = emac->egress_slice;
|
|
|
|
|
|
|
+ slice = prueth_emac_slice(emac);
|
|
|
|
|
+ if (slice < 0) {
|
|
|
|
|
+ netdev_err(emac->ndev, "invalid port\n");
|
|
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Set Load time configuration */
|
|
/* Set Load time configuration */
|
|
|
- config = &prueth->config[icssg][slice];
|
|
|
|
|
|
|
+ config = &prueth->config[slice];
|
|
|
memset(config, 0, sizeof(*config));
|
|
memset(config, 0, sizeof(*config));
|
|
|
- config->addr_lo = cpu_to_le32(lower_32_bits(prueth->msmcram[icssg].pa));
|
|
|
|
|
- config->addr_hi = cpu_to_le32(upper_32_bits(prueth->msmcram[icssg].pa));
|
|
|
|
|
|
|
+ config->addr_lo = cpu_to_le32(lower_32_bits(prueth->msmcram.pa));
|
|
|
|
|
+ config->addr_hi = cpu_to_le32(upper_32_bits(prueth->msmcram.pa));
|
|
|
config->num_tx_threads = 0;
|
|
config->num_tx_threads = 0;
|
|
|
config->rx_flow_id = emac->rx_flow_id_base; /* flow id for host port */
|
|
config->rx_flow_id = emac->rx_flow_id_base; /* flow id for host port */
|
|
|
config->rx_mgr_flow_id = emac->rx_mgm_flow_id_base; /* for mgm ch */
|
|
config->rx_mgr_flow_id = emac->rx_mgm_flow_id_base; /* for mgm ch */
|
|
@@ -904,50 +889,47 @@ static int prueth_emac_start(struct prueth *prueth,
|
|
|
i < PRUETH_NUM_BUF_POOLS; i++)
|
|
i < PRUETH_NUM_BUF_POOLS; i++)
|
|
|
config->tx_buf_sz[i] = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE);
|
|
config->tx_buf_sz[i] = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE);
|
|
|
|
|
|
|
|
- icssg_config_set(prueth, icssg, slice);
|
|
|
|
|
|
|
+ icssg_config_set(prueth, slice);
|
|
|
|
|
|
|
|
- ret = rproc_boot(prueth->pru[icssg][slice]);
|
|
|
|
|
|
|
+ ret = rproc_boot(prueth->pru[slice]);
|
|
|
if (ret) {
|
|
if (ret) {
|
|
|
- dev_err(dev, "failed to boot ICSSG %d PRU%d: %d\n",
|
|
|
|
|
- icssg, slice, ret);
|
|
|
|
|
|
|
+ dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret);
|
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- ret = rproc_boot(prueth->rtu[icssg][slice]);
|
|
|
|
|
|
|
+ ret = rproc_boot(prueth->rtu[slice]);
|
|
|
if (ret) {
|
|
if (ret) {
|
|
|
- dev_err(dev, "failed to boot ICSSG %d RTU%d: %d\n",
|
|
|
|
|
- icssg, slice, ret);
|
|
|
|
|
|
|
+ dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret);
|
|
|
goto halt_pru;
|
|
goto halt_pru;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
halt_pru:
|
|
halt_pru:
|
|
|
- rproc_shutdown(prueth->pru[icssg][slice]);
|
|
|
|
|
|
|
+ rproc_shutdown(prueth->pru[slice]);
|
|
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void prueth_emac_stop(struct prueth_emac *emac, bool ingress)
|
|
|
|
|
|
|
+static void prueth_emac_stop(struct prueth_emac *emac)
|
|
|
{
|
|
{
|
|
|
struct prueth *prueth = emac->prueth;
|
|
struct prueth *prueth = emac->prueth;
|
|
|
- int icssg, slice;
|
|
|
|
|
|
|
+ int slice;
|
|
|
|
|
|
|
|
- if (!prueth->dual_icssg) {
|
|
|
|
|
- icssg = emac->ingress_icssg;
|
|
|
|
|
- slice = emac->ingress_slice;
|
|
|
|
|
- } else {
|
|
|
|
|
- if (ingress) {
|
|
|
|
|
- icssg = emac->ingress_icssg;
|
|
|
|
|
- slice = emac->ingress_slice;
|
|
|
|
|
- } else {
|
|
|
|
|
- icssg = emac->egress_icssg;
|
|
|
|
|
- slice = emac->egress_slice;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ switch (emac->port_id) {
|
|
|
|
|
+ case PRUETH_PORT_MII0:
|
|
|
|
|
+ slice = ICSS_SLICE0;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case PRUETH_PORT_MII1:
|
|
|
|
|
+ slice = ICSS_SLICE1;
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ netdev_err(emac->ndev, "invalid port\n");
|
|
|
|
|
+ return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- rproc_shutdown(prueth->rtu[icssg][slice]);
|
|
|
|
|
- rproc_shutdown(prueth->pru[icssg][slice]);
|
|
|
|
|
|
|
+ rproc_shutdown(prueth->rtu[slice]);
|
|
|
|
|
+ rproc_shutdown(prueth->pru[slice]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* called back by PHY layer if there is change in link state of hw port*/
|
|
/* called back by PHY layer if there is change in link state of hw port*/
|
|
@@ -956,24 +938,13 @@ static void emac_adjust_link(struct net_device *ndev)
|
|
|
struct prueth_emac *emac = netdev_priv(ndev);
|
|
struct prueth_emac *emac = netdev_priv(ndev);
|
|
|
struct phy_device *phydev = emac->phydev;
|
|
struct phy_device *phydev = emac->phydev;
|
|
|
bool gig_en = false, full_duplex = false;
|
|
bool gig_en = false, full_duplex = false;
|
|
|
- struct regmap *miig_rt, *miig_rt_pair;
|
|
|
|
|
struct prueth *prueth = emac->prueth;
|
|
struct prueth *prueth = emac->prueth;
|
|
|
|
|
+ int slice = prueth_emac_slice(emac);
|
|
|
bool new_state = false;
|
|
bool new_state = false;
|
|
|
- struct regmap *mii_rt;
|
|
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&emac->lock, flags);
|
|
spin_lock_irqsave(&emac->lock, flags);
|
|
|
|
|
|
|
|
- if (!prueth->dual_icssg) {
|
|
|
|
|
- miig_rt = prueth->miig_rt[emac->ingress_icssg];
|
|
|
|
|
- miig_rt_pair = NULL;
|
|
|
|
|
- mii_rt = prueth->mii_rt[emac->egress_icssg];
|
|
|
|
|
- } else {
|
|
|
|
|
- miig_rt = prueth->miig_rt[emac->ingress_icssg];
|
|
|
|
|
- miig_rt_pair = prueth->miig_rt[emac->egress_icssg];
|
|
|
|
|
- mii_rt = prueth->mii_rt[emac->egress_icssg];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (phydev->link) {
|
|
if (phydev->link) {
|
|
|
/* check the mode of operation - full/half duplex */
|
|
/* check the mode of operation - full/half duplex */
|
|
|
if (phydev->duplex != emac->duplex) {
|
|
if (phydev->duplex != emac->duplex) {
|
|
@@ -1014,24 +985,16 @@ static void emac_adjust_link(struct net_device *ndev)
|
|
|
full_duplex = true;
|
|
full_duplex = true;
|
|
|
|
|
|
|
|
/* Set the RGMII cfg for gig en and full duplex */
|
|
/* Set the RGMII cfg for gig en and full duplex */
|
|
|
- icssg_update_rgmii_cfg(miig_rt, gig_en,
|
|
|
|
|
- full_duplex,
|
|
|
|
|
- emac->ingress_slice);
|
|
|
|
|
- if (miig_rt_pair)
|
|
|
|
|
- icssg_update_rgmii_cfg(miig_rt_pair, gig_en,
|
|
|
|
|
- full_duplex,
|
|
|
|
|
- emac->egress_slice);
|
|
|
|
|
|
|
+ icssg_update_rgmii_cfg(prueth->miig_rt, gig_en,
|
|
|
|
|
+ full_duplex, slice);
|
|
|
/* update the Tx IPG based on 100M/1G speed */
|
|
/* update the Tx IPG based on 100M/1G speed */
|
|
|
- icssg_update_mii_rt_cfg(mii_rt, emac->speed,
|
|
|
|
|
- emac->egress_slice);
|
|
|
|
|
|
|
+ icssg_update_mii_rt_cfg(prueth->mii_rt, emac->speed,
|
|
|
|
|
+ slice);
|
|
|
} else {
|
|
} else {
|
|
|
- icssg_update_rgmii_cfg(miig_rt, true, true,
|
|
|
|
|
|
|
+ icssg_update_rgmii_cfg(prueth->miig_rt, true, true,
|
|
|
emac->port_id);
|
|
emac->port_id);
|
|
|
- if (miig_rt_pair)
|
|
|
|
|
- icssg_update_rgmii_cfg(miig_rt_pair, true, true,
|
|
|
|
|
- emac->port_id);
|
|
|
|
|
- icssg_update_mii_rt_cfg(mii_rt, emac->speed,
|
|
|
|
|
- emac->egress_slice);
|
|
|
|
|
|
|
+ icssg_update_mii_rt_cfg(prueth->mii_rt, emac->speed,
|
|
|
|
|
+ slice);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1109,29 +1072,17 @@ static int emac_ndo_open(struct net_device *ndev)
|
|
|
struct device *dev = prueth->dev;
|
|
struct device *dev = prueth->dev;
|
|
|
int ret, i;
|
|
int ret, i;
|
|
|
struct sk_buff *skb;
|
|
struct sk_buff *skb;
|
|
|
|
|
+ int slice = prueth_emac_slice(emac);
|
|
|
|
|
|
|
|
/* clear SMEM of this slice */
|
|
/* clear SMEM of this slice */
|
|
|
- /* clear the shram of correct icssg */
|
|
|
|
|
- if (!prueth->dual_icssg) {
|
|
|
|
|
- memset_io(prueth->shram[emac->ingress_icssg].va +
|
|
|
|
|
- emac->ingress_slice * ICSSG_CONFIG_OFFSET_SLICE1,
|
|
|
|
|
- 0, ICSSG_CONFIG_OFFSET_SLICE1);
|
|
|
|
|
- } else {
|
|
|
|
|
- memset_io(prueth->shram[emac->ingress_icssg].va +
|
|
|
|
|
- emac->ingress_slice * ICSSG_CONFIG_OFFSET_SLICE1,
|
|
|
|
|
- 0, ICSSG_CONFIG_OFFSET_SLICE1);
|
|
|
|
|
- memset_io(prueth->shram[emac->egress_icssg].va +
|
|
|
|
|
- emac->egress_slice * ICSSG_CONFIG_OFFSET_SLICE1,
|
|
|
|
|
- 0, ICSSG_CONFIG_OFFSET_SLICE1);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ memset_io(prueth->shram.va + slice * ICSSG_CONFIG_OFFSET_SLICE1,
|
|
|
|
|
+ 0, ICSSG_CONFIG_OFFSET_SLICE1);
|
|
|
/* set h/w MAC as user might have re-configured */
|
|
/* set h/w MAC as user might have re-configured */
|
|
|
ether_addr_copy(emac->mac_addr, ndev->dev_addr);
|
|
ether_addr_copy(emac->mac_addr, ndev->dev_addr);
|
|
|
|
|
|
|
|
- icssg_class_set_mac_addr(prueth->miig_rt[emac->ingress_icssg],
|
|
|
|
|
- emac->ingress_slice, emac->mac_addr);
|
|
|
|
|
- icssg_class_default(prueth->miig_rt[emac->ingress_icssg],
|
|
|
|
|
- emac->ingress_slice);
|
|
|
|
|
|
|
+ icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
|
|
|
|
|
+ icssg_class_default(prueth->miig_rt, slice);
|
|
|
|
|
+
|
|
|
netif_carrier_off(ndev);
|
|
netif_carrier_off(ndev);
|
|
|
|
|
|
|
|
ret = prueth_init_tx_chns(emac);
|
|
ret = prueth_init_tx_chns(emac);
|
|
@@ -1177,23 +1128,11 @@ static int emac_ndo_open(struct net_device *ndev)
|
|
|
goto free_rx_irq;
|
|
goto free_rx_irq;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /* reset and start PRU firmware at egress. For Single ICSSG
|
|
|
|
|
- * case, both egress and ingress icssg are the same. So just
|
|
|
|
|
- * call it for egress.
|
|
|
|
|
- */
|
|
|
|
|
- ret = prueth_emac_start(prueth, emac, false);
|
|
|
|
|
|
|
+ /* reset and start PRU firmware */
|
|
|
|
|
+ ret = prueth_emac_start(prueth, emac);
|
|
|
if (ret)
|
|
if (ret)
|
|
|
goto free_rx_mgm_irq;
|
|
goto free_rx_mgm_irq;
|
|
|
|
|
|
|
|
- /* reset and start PRU firmware at ingress. For Dual ICSSG
|
|
|
|
|
- * this reset and start the Ingress ICSSG.
|
|
|
|
|
- */
|
|
|
|
|
- if (prueth->dual_icssg) {
|
|
|
|
|
- ret = prueth_emac_start(prueth, emac, true);
|
|
|
|
|
- if (ret)
|
|
|
|
|
- goto error_egress;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
/* start PHY */
|
|
/* start PHY */
|
|
|
phy_start(emac->phydev);
|
|
phy_start(emac->phydev);
|
|
|
|
|
|
|
@@ -1249,9 +1188,7 @@ static int emac_ndo_open(struct net_device *ndev)
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
err:
|
|
err:
|
|
|
- prueth_emac_stop(emac, true);
|
|
|
|
|
-error_egress:
|
|
|
|
|
- prueth_emac_stop(emac, false);
|
|
|
|
|
|
|
+ prueth_emac_stop(emac);
|
|
|
free_rx_mgm_irq:
|
|
free_rx_mgm_irq:
|
|
|
free_irq(emac->rx_mgm_chn.irq, emac);
|
|
free_irq(emac->rx_mgm_chn.irq, emac);
|
|
|
free_rx_irq:
|
|
free_rx_irq:
|
|
@@ -1286,8 +1223,7 @@ static int emac_ndo_stop(struct net_device *ndev)
|
|
|
|
|
|
|
|
/* block packets from wire */
|
|
/* block packets from wire */
|
|
|
phy_stop(emac->phydev);
|
|
phy_stop(emac->phydev);
|
|
|
- icssg_class_disable(prueth->miig_rt[emac->ingress_icssg],
|
|
|
|
|
- emac->ingress_slice);
|
|
|
|
|
|
|
+ icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
|
|
|
|
|
|
|
|
/* tear down and disable UDMA channels */
|
|
/* tear down and disable UDMA channels */
|
|
|
reinit_completion(&emac->tdown_complete);
|
|
reinit_completion(&emac->tdown_complete);
|
|
@@ -1325,9 +1261,7 @@ static int emac_ndo_stop(struct net_device *ndev)
|
|
|
napi_disable(&emac->napi_rx);
|
|
napi_disable(&emac->napi_rx);
|
|
|
|
|
|
|
|
/* stop PRUs */
|
|
/* stop PRUs */
|
|
|
- prueth_emac_stop(emac, false);
|
|
|
|
|
- if (prueth->dual_icssg)
|
|
|
|
|
- prueth_emac_stop(emac, true);
|
|
|
|
|
|
|
+ prueth_emac_stop(emac);
|
|
|
|
|
|
|
|
free_irq(emac->rx_mgm_chn.irq, emac);
|
|
free_irq(emac->rx_mgm_chn.irq, emac);
|
|
|
free_irq(emac->rx_chns.irq, emac);
|
|
free_irq(emac->rx_chns.irq, emac);
|
|
@@ -1375,12 +1309,12 @@ static void emac_ndo_set_rx_mode(struct net_device *ndev)
|
|
|
{
|
|
{
|
|
|
struct prueth_emac *emac = netdev_priv(ndev);
|
|
struct prueth_emac *emac = netdev_priv(ndev);
|
|
|
struct prueth *prueth = emac->prueth;
|
|
struct prueth *prueth = emac->prueth;
|
|
|
- struct regmap *miig_rt = prueth->miig_rt[emac->ingress_icssg];
|
|
|
|
|
|
|
+ int slice = prueth_emac_slice(emac);
|
|
|
|
|
|
|
|
if (ndev->flags & IFF_PROMISC) {
|
|
if (ndev->flags & IFF_PROMISC) {
|
|
|
/* enable promiscuous */
|
|
/* enable promiscuous */
|
|
|
if (!(emac->flags & IFF_PROMISC)) {
|
|
if (!(emac->flags & IFF_PROMISC)) {
|
|
|
- icssg_class_promiscuous(miig_rt, emac->ingress_slice);
|
|
|
|
|
|
|
+ icssg_class_promiscuous(prueth->miig_rt, slice);
|
|
|
emac->flags |= IFF_PROMISC;
|
|
emac->flags |= IFF_PROMISC;
|
|
|
}
|
|
}
|
|
|
return;
|
|
return;
|
|
@@ -1389,7 +1323,7 @@ static void emac_ndo_set_rx_mode(struct net_device *ndev)
|
|
|
} else {
|
|
} else {
|
|
|
if (emac->flags & IFF_PROMISC) {
|
|
if (emac->flags & IFF_PROMISC) {
|
|
|
/* local MAC + BC only */
|
|
/* local MAC + BC only */
|
|
|
- icssg_class_default(miig_rt, emac->ingress_slice);
|
|
|
|
|
|
|
+ icssg_class_default(prueth->miig_rt, slice);
|
|
|
emac->flags &= ~IFF_PROMISC;
|
|
emac->flags &= ~IFF_PROMISC;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1435,9 +1369,6 @@ static int emac_set_ts_config(struct net_device *ndev, struct ifreq *ifr)
|
|
|
struct hwtstamp_config config;
|
|
struct hwtstamp_config config;
|
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
|
|
- if (emac->prueth->dual_icssg)
|
|
|
|
|
- return -ENODEV;
|
|
|
|
|
-
|
|
|
|
|
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
|
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
|
|
return -EFAULT;
|
|
return -EFAULT;
|
|
|
|
|
|
|
@@ -1458,9 +1389,6 @@ static int emac_get_ts_config(struct net_device *ndev, struct ifreq *ifr)
|
|
|
struct prueth_emac *emac = netdev_priv(ndev);
|
|
struct prueth_emac *emac = netdev_priv(ndev);
|
|
|
struct hwtstamp_config *config = &emac->tstamp_config;
|
|
struct hwtstamp_config *config = &emac->tstamp_config;
|
|
|
|
|
|
|
|
- if (emac->prueth->dual_icssg)
|
|
|
|
|
- return -ENODEV;
|
|
|
|
|
-
|
|
|
|
|
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
|
|
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
|
|
|
-EFAULT : 0;
|
|
-EFAULT : 0;
|
|
|
}
|
|
}
|
|
@@ -1527,7 +1455,7 @@ static int prueth_netdev_init(struct prueth *prueth,
|
|
|
const u8 *mac_addr;
|
|
const u8 *mac_addr;
|
|
|
int ret;
|
|
int ret;
|
|
|
u32 refclk_freq;
|
|
u32 refclk_freq;
|
|
|
- struct regmap *iep_map = NULL;
|
|
|
|
|
|
|
+ struct regmap *iep_map;
|
|
|
|
|
|
|
|
port = prueth_node_port(eth_node);
|
|
port = prueth_node_port(eth_node);
|
|
|
if (port < 0)
|
|
if (port < 0)
|
|
@@ -1542,14 +1470,12 @@ static int prueth_netdev_init(struct prueth *prueth,
|
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
emac = netdev_priv(ndev);
|
|
emac = netdev_priv(ndev);
|
|
|
- if (!prueth->dual_icssg) {
|
|
|
|
|
- iep_map = syscon_regmap_lookup_by_phandle(eth_node, "iep");
|
|
|
|
|
- if (IS_ERR(iep_map)) {
|
|
|
|
|
- ret = PTR_ERR(iep_map);
|
|
|
|
|
- if (ret != -EPROBE_DEFER)
|
|
|
|
|
- dev_err(prueth->dev, "couldn't get iep regmap\n");
|
|
|
|
|
- goto free;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ iep_map = syscon_regmap_lookup_by_phandle(eth_node, "iep");
|
|
|
|
|
+ if (IS_ERR(iep_map)) {
|
|
|
|
|
+ ret = PTR_ERR(iep_map);
|
|
|
|
|
+ if (ret != -EPROBE_DEFER)
|
|
|
|
|
+ dev_err(prueth->dev, "couldn't get iep regmap\n");
|
|
|
|
|
+ goto free;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Firmware sets IEP clock to Vbus clk (250MHz) using internal mux.
|
|
/* Firmware sets IEP clock to Vbus clk (250MHz) using internal mux.
|
|
@@ -1562,23 +1488,6 @@ static int prueth_netdev_init(struct prueth *prueth,
|
|
|
emac->prueth = prueth;
|
|
emac->prueth = prueth;
|
|
|
emac->ndev = ndev;
|
|
emac->ndev = ndev;
|
|
|
emac->port_id = port;
|
|
emac->port_id = port;
|
|
|
-
|
|
|
|
|
- if (!prueth->dual_icssg) {
|
|
|
|
|
- emac->egress_icssg = ICSSG0;
|
|
|
|
|
- emac->ingress_icssg = ICSSG0;
|
|
|
|
|
- emac->egress_slice = (port == PRUETH_PORT_MII0) ? ICSS_SLICE0 :
|
|
|
|
|
- ICSS_SLICE1;
|
|
|
|
|
- emac->ingress_slice = emac->egress_slice;
|
|
|
|
|
- } else {
|
|
|
|
|
- /* Dual ICCSG. Mapping of ICSSG/SLICE to port */
|
|
|
|
|
- emac->egress_icssg = (port == PRUETH_PORT_MII0) ?
|
|
|
|
|
- ICSSG1 : ICSSG0;
|
|
|
|
|
- emac->egress_slice = ICSS_SLICE1;
|
|
|
|
|
- emac->ingress_icssg = (port == PRUETH_PORT_MII0) ?
|
|
|
|
|
- ICSSG0 : ICSSG1;
|
|
|
|
|
- emac->ingress_slice = ICSS_SLICE0;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
emac->msg_enable = netif_msg_init(debug_level, PRUETH_EMAC_DEBUG);
|
|
emac->msg_enable = netif_msg_init(debug_level, PRUETH_EMAC_DEBUG);
|
|
|
spin_lock_init(&emac->lock);
|
|
spin_lock_init(&emac->lock);
|
|
|
|
|
|
|
@@ -1633,12 +1542,9 @@ static int prueth_netdev_init(struct prueth *prueth,
|
|
|
ndev->netdev_ops = &emac_netdev_ops;
|
|
ndev->netdev_ops = &emac_netdev_ops;
|
|
|
ndev->ethtool_ops = &icssg_ethtool_ops;
|
|
ndev->ethtool_ops = &icssg_ethtool_ops;
|
|
|
|
|
|
|
|
- if (iep_map) {
|
|
|
|
|
- ret = icssg_iep_init(&emac->iep, prueth->dev, iep_map,
|
|
|
|
|
- refclk_freq);
|
|
|
|
|
- if (ret)
|
|
|
|
|
- goto free;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ret = icssg_iep_init(&emac->iep, prueth->dev, iep_map, refclk_freq);
|
|
|
|
|
+ if (ret)
|
|
|
|
|
+ goto free;
|
|
|
|
|
|
|
|
netif_tx_napi_add(ndev, &emac->napi_tx,
|
|
netif_tx_napi_add(ndev, &emac->napi_tx,
|
|
|
emac_napi_tx_poll, NAPI_POLL_WEIGHT);
|
|
emac_napi_tx_poll, NAPI_POLL_WEIGHT);
|
|
@@ -1675,8 +1581,7 @@ static void prueth_netdev_exit(struct prueth *prueth,
|
|
|
|
|
|
|
|
netif_napi_del(&emac->napi_rx);
|
|
netif_napi_del(&emac->napi_rx);
|
|
|
netif_napi_del(&emac->napi_tx);
|
|
netif_napi_del(&emac->napi_tx);
|
|
|
- if (!prueth->dual_icssg)
|
|
|
|
|
- icssg_iep_exit(&emac->iep);
|
|
|
|
|
|
|
+ icssg_iep_exit(&emac->iep);
|
|
|
free_netdev(emac->ndev);
|
|
free_netdev(emac->ndev);
|
|
|
prueth->emac[mac] = NULL;
|
|
prueth->emac[mac] = NULL;
|
|
|
}
|
|
}
|
|
@@ -1685,71 +1590,36 @@ static int prueth_get_cores(struct prueth *prueth, int slice)
|
|
|
{
|
|
{
|
|
|
struct device *dev = prueth->dev;
|
|
struct device *dev = prueth->dev;
|
|
|
struct device_node *np = dev->of_node;
|
|
struct device_node *np = dev->of_node;
|
|
|
- int pru, rtu, paired_pru = -1, paired_rtu = -1, ret;
|
|
|
|
|
|
|
+ int pru, rtu, ret;
|
|
|
|
|
|
|
|
switch (slice) {
|
|
switch (slice) {
|
|
|
case ICSS_SLICE0:
|
|
case ICSS_SLICE0:
|
|
|
pru = 0;
|
|
pru = 0;
|
|
|
rtu = 1;
|
|
rtu = 1;
|
|
|
- if (prueth->dual_icssg) {
|
|
|
|
|
- paired_pru = 4;
|
|
|
|
|
- paired_rtu = 5;
|
|
|
|
|
- }
|
|
|
|
|
break;
|
|
break;
|
|
|
case ICSS_SLICE1:
|
|
case ICSS_SLICE1:
|
|
|
pru = 2;
|
|
pru = 2;
|
|
|
rtu = 3;
|
|
rtu = 3;
|
|
|
- if (prueth->dual_icssg) {
|
|
|
|
|
- paired_pru = 6;
|
|
|
|
|
- paired_rtu = 7;
|
|
|
|
|
- }
|
|
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- prueth->pru[ICSSG0][slice] = pru_rproc_get(np, pru);
|
|
|
|
|
- if (IS_ERR(prueth->pru[ICSSG0][slice])) {
|
|
|
|
|
- ret = PTR_ERR(prueth->pru[ICSSG0][slice]);
|
|
|
|
|
- prueth->pru[ICSSG0][slice] = NULL;
|
|
|
|
|
- if (ret != -EPROBE_DEFER)
|
|
|
|
|
- dev_err(dev, "unable to get PRU%d slice %d: %d\n",
|
|
|
|
|
- pru, slice, ret);
|
|
|
|
|
- return ret;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- prueth->rtu[ICSSG0][slice] = pru_rproc_get(np, rtu);
|
|
|
|
|
- if (IS_ERR(prueth->rtu[ICSSG0][slice])) {
|
|
|
|
|
- ret = PTR_ERR(prueth->rtu[ICSSG0][slice]);
|
|
|
|
|
- prueth->rtu[ICSSG0][slice] = NULL;
|
|
|
|
|
- if (ret != -EPROBE_DEFER)
|
|
|
|
|
- dev_err(dev, "unable to get RTU%d slice %d: %d\n",
|
|
|
|
|
- rtu, slice, ret);
|
|
|
|
|
- return ret;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!prueth->dual_icssg)
|
|
|
|
|
- return 0;
|
|
|
|
|
-
|
|
|
|
|
- prueth->pru[ICSSG1][slice] = pru_rproc_get(np, paired_pru);
|
|
|
|
|
- if (IS_ERR(prueth->pru[ICSSG1][slice])) {
|
|
|
|
|
- ret = PTR_ERR(prueth->pru[ICSSG1][slice]);
|
|
|
|
|
- prueth->pru[ICSSG1][slice] = NULL;
|
|
|
|
|
|
|
+ prueth->pru[slice] = pru_rproc_get(np, pru);
|
|
|
|
|
+ if (IS_ERR(prueth->pru[slice])) {
|
|
|
|
|
+ ret = PTR_ERR(prueth->pru[slice]);
|
|
|
|
|
+ prueth->pru[slice] = NULL;
|
|
|
if (ret != -EPROBE_DEFER)
|
|
if (ret != -EPROBE_DEFER)
|
|
|
- dev_err(dev,
|
|
|
|
|
- "unable to get Paired PRU%d slice %d: %d\n",
|
|
|
|
|
- paired_pru, slice, ret);
|
|
|
|
|
|
|
+ dev_err(dev, "unable to get PRU%d: %d\n", slice, ret);
|
|
|
return ret;
|
|
return ret;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- prueth->rtu[ICSSG1][slice] = pru_rproc_get(np, paired_rtu);
|
|
|
|
|
- if (IS_ERR(prueth->rtu[ICSSG1][slice])) {
|
|
|
|
|
- ret = PTR_ERR(prueth->rtu[ICSSG1][slice]);
|
|
|
|
|
- prueth->rtu[ICSSG1][slice] = NULL;
|
|
|
|
|
|
|
+ prueth->rtu[slice] = pru_rproc_get(np, rtu);
|
|
|
|
|
+ if (IS_ERR(prueth->rtu[slice])) {
|
|
|
|
|
+ ret = PTR_ERR(prueth->rtu[slice]);
|
|
|
|
|
+ prueth->rtu[slice] = NULL;
|
|
|
if (ret != -EPROBE_DEFER)
|
|
if (ret != -EPROBE_DEFER)
|
|
|
- dev_err(dev,
|
|
|
|
|
- "unable to get Paired RTU%d slice %d: %d\n",
|
|
|
|
|
- paired_rtu, slice, ret);
|
|
|
|
|
|
|
+ dev_err(dev, "unable to get RTU%d: %d\n", slice, ret);
|
|
|
return ret;
|
|
return ret;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1758,15 +1628,11 @@ static int prueth_get_cores(struct prueth *prueth, int slice)
|
|
|
|
|
|
|
|
static void prueth_put_cores(struct prueth *prueth, int slice)
|
|
static void prueth_put_cores(struct prueth *prueth, int slice)
|
|
|
{
|
|
{
|
|
|
- if (prueth->rtu[ICSSG0][slice])
|
|
|
|
|
- pru_rproc_put(prueth->rtu[ICSSG0][slice]);
|
|
|
|
|
- if (prueth->rtu[ICSSG1][slice])
|
|
|
|
|
- pru_rproc_put(prueth->rtu[ICSSG1][slice]);
|
|
|
|
|
-
|
|
|
|
|
- if (prueth->pru[ICSSG0][slice])
|
|
|
|
|
- pru_rproc_put(prueth->pru[ICSSG0][slice]);
|
|
|
|
|
- if (prueth->pru[ICSSG1][slice])
|
|
|
|
|
- pru_rproc_put(prueth->pru[ICSSG1][slice]);
|
|
|
|
|
|
|
+ if (prueth->rtu[slice])
|
|
|
|
|
+ pru_rproc_put(prueth->rtu[slice]);
|
|
|
|
|
+
|
|
|
|
|
+ if (prueth->pru[slice])
|
|
|
|
|
+ pru_rproc_put(prueth->pru[slice]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static int prueth_config_rgmiidelay(struct prueth *prueth,
|
|
static int prueth_config_rgmiidelay(struct prueth *prueth,
|
|
@@ -1777,8 +1643,7 @@ static int prueth_config_rgmiidelay(struct prueth *prueth,
|
|
|
u32 icssgctrl;
|
|
u32 icssgctrl;
|
|
|
struct device_node *np = dev->of_node;
|
|
struct device_node *np = dev->of_node;
|
|
|
|
|
|
|
|
- if (!of_device_is_compatible(np, "ti,am654-icssg-prueth") &&
|
|
|
|
|
- !of_device_is_compatible(np, "ti,am654-dualicssg-prueth"))
|
|
|
|
|
|
|
+ if (!of_device_is_compatible(np, "ti,am654-icssg-prueth"))
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
ctrl_mmr = syscon_regmap_lookup_by_phandle(eth_np, "syscon-rgmii-delay");
|
|
ctrl_mmr = syscon_regmap_lookup_by_phandle(eth_np, "syscon-rgmii-delay");
|
|
@@ -1807,8 +1672,8 @@ static int prueth_probe(struct platform_device *pdev)
|
|
|
struct device_node *np = dev->of_node;
|
|
struct device_node *np = dev->of_node;
|
|
|
struct device_node *eth0_node, *eth1_node;
|
|
struct device_node *eth0_node, *eth1_node;
|
|
|
const struct of_device_id *match;
|
|
const struct of_device_id *match;
|
|
|
- struct pruss *pruss[NUM_ICSSG];
|
|
|
|
|
- int i, ret, msmc_ram_size;
|
|
|
|
|
|
|
+ struct pruss *pruss;
|
|
|
|
|
+ int i, ret;
|
|
|
|
|
|
|
|
if (!np)
|
|
if (!np)
|
|
|
return -ENODEV; /* we don't support non DT */
|
|
return -ENODEV; /* we don't support non DT */
|
|
@@ -1821,9 +1686,6 @@ static int prueth_probe(struct platform_device *pdev)
|
|
|
if (!prueth)
|
|
if (!prueth)
|
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
- if (!strcmp(match->compatible, "ti,am654-dualicssg-prueth"))
|
|
|
|
|
- prueth->dual_icssg = true;
|
|
|
|
|
-
|
|
|
|
|
platform_set_drvdata(pdev, prueth);
|
|
platform_set_drvdata(pdev, prueth);
|
|
|
|
|
|
|
|
prueth->dev = dev;
|
|
prueth->dev = dev;
|
|
@@ -1848,46 +1710,23 @@ static int prueth_probe(struct platform_device *pdev)
|
|
|
prueth->eth_node[PRUETH_MAC0] = eth0_node;
|
|
prueth->eth_node[PRUETH_MAC0] = eth0_node;
|
|
|
prueth->eth_node[PRUETH_MAC1] = eth1_node;
|
|
prueth->eth_node[PRUETH_MAC1] = eth1_node;
|
|
|
|
|
|
|
|
- prueth->miig_rt[ICSSG0] =
|
|
|
|
|
- syscon_regmap_lookup_by_phandle(np, "mii-g-rt");
|
|
|
|
|
- if (IS_ERR(prueth->miig_rt[ICSSG0])) {
|
|
|
|
|
|
|
+ prueth->miig_rt = syscon_regmap_lookup_by_phandle(np, "mii-g-rt");
|
|
|
|
|
+ if (IS_ERR(prueth->miig_rt)) {
|
|
|
dev_err(dev, "couldn't get mii-g-rt syscon regmap\n");
|
|
dev_err(dev, "couldn't get mii-g-rt syscon regmap\n");
|
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (prueth->dual_icssg) {
|
|
|
|
|
- prueth->miig_rt[ICSSG1] =
|
|
|
|
|
- syscon_regmap_lookup_by_phandle(np, "mii-g-rt-paired");
|
|
|
|
|
- if (IS_ERR(prueth->miig_rt[ICSSG1])) {
|
|
|
|
|
- dev_err(dev, "couldn't get mii-g-rt-paired syscon regmap\n");
|
|
|
|
|
- return -ENODEV;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- prueth->mii_rt[ICSSG0] =
|
|
|
|
|
- syscon_regmap_lookup_by_phandle(np, "mii-rt");
|
|
|
|
|
- if (IS_ERR(prueth->mii_rt[ICSSG0])) {
|
|
|
|
|
|
|
+ prueth->mii_rt = syscon_regmap_lookup_by_phandle(np, "mii-rt");
|
|
|
|
|
+ if (IS_ERR(prueth->mii_rt)) {
|
|
|
dev_err(dev, "couldn't get mii-rt syscon regmap\n");
|
|
dev_err(dev, "couldn't get mii-rt syscon regmap\n");
|
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (prueth->dual_icssg) {
|
|
|
|
|
- prueth->mii_rt[ICSSG1] =
|
|
|
|
|
- syscon_regmap_lookup_by_phandle(np, "mii-rt-paired");
|
|
|
|
|
- if (IS_ERR(prueth->mii_rt[ICSSG1])) {
|
|
|
|
|
- dev_err(dev, "couldn't get mii-rt-paired syscon regmap\n");
|
|
|
|
|
- return -ENODEV;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (eth0_node) {
|
|
if (eth0_node) {
|
|
|
ret = prueth_config_rgmiidelay(prueth, eth0_node);
|
|
ret = prueth_config_rgmiidelay(prueth, eth0_node);
|
|
|
if (ret)
|
|
if (ret)
|
|
|
goto put_cores;
|
|
goto put_cores;
|
|
|
|
|
|
|
|
- /* Get SLICE 0 cores. For Dual ICSG, it also gets SLICE0
|
|
|
|
|
- * of second ICSSG as well
|
|
|
|
|
- */
|
|
|
|
|
ret = prueth_get_cores(prueth, ICSS_SLICE0);
|
|
ret = prueth_get_cores(prueth, ICSS_SLICE0);
|
|
|
if (ret)
|
|
if (ret)
|
|
|
goto put_cores;
|
|
goto put_cores;
|
|
@@ -1898,56 +1737,29 @@ static int prueth_probe(struct platform_device *pdev)
|
|
|
if (ret)
|
|
if (ret)
|
|
|
goto put_cores;
|
|
goto put_cores;
|
|
|
|
|
|
|
|
- /* Get SLICE 0 cores. For Dual ICSG, it also gets SLICE0
|
|
|
|
|
- * of second ICSSG as well
|
|
|
|
|
- */
|
|
|
|
|
ret = prueth_get_cores(prueth, ICSS_SLICE1);
|
|
ret = prueth_get_cores(prueth, ICSS_SLICE1);
|
|
|
if (ret)
|
|
if (ret)
|
|
|
goto put_cores;
|
|
goto put_cores;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /* prueth->pruss_id is a dummy id for now */
|
|
|
|
|
- pruss[ICSSG0] = pruss_get(eth0_node ?
|
|
|
|
|
- prueth->pru[ICSSG0][ICSS_SLICE0] :
|
|
|
|
|
- prueth->pru[ICSSG0][ICSS_SLICE1],
|
|
|
|
|
- &prueth->pruss_id[ICSSG0]);
|
|
|
|
|
- if (IS_ERR(pruss[ICSSG0])) {
|
|
|
|
|
- ret = PTR_ERR(pruss[ICSSG0]);
|
|
|
|
|
|
|
+ pruss = pruss_get(eth0_node ?
|
|
|
|
|
+ prueth->pru[ICSS_SLICE0] : prueth->pru[ICSS_SLICE1],
|
|
|
|
|
+ &prueth->pruss_id);
|
|
|
|
|
+ if (IS_ERR(pruss)) {
|
|
|
|
|
+ ret = PTR_ERR(pruss);
|
|
|
dev_err(dev, "unable to get pruss handle\n");
|
|
dev_err(dev, "unable to get pruss handle\n");
|
|
|
goto put_cores;
|
|
goto put_cores;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- prueth->pruss[ICSSG0] = pruss[ICSSG0];
|
|
|
|
|
|
|
+ prueth->pruss = pruss;
|
|
|
|
|
|
|
|
- ret = pruss_request_mem_region(pruss[ICSSG0], PRUSS_MEM_SHRD_RAM2,
|
|
|
|
|
- &prueth->shram[ICSSG0]);
|
|
|
|
|
|
|
+ ret = pruss_request_mem_region(pruss, PRUSS_MEM_SHRD_RAM2,
|
|
|
|
|
+ &prueth->shram);
|
|
|
if (ret) {
|
|
if (ret) {
|
|
|
dev_err(dev, "unable to get PRUSS SHRD RAM2: %d\n", ret);
|
|
dev_err(dev, "unable to get PRUSS SHRD RAM2: %d\n", ret);
|
|
|
goto put_mem;
|
|
goto put_mem;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (prueth->dual_icssg) {
|
|
|
|
|
- pruss[ICSSG1] = pruss_get(eth0_node ?
|
|
|
|
|
- prueth->pru[ICSSG1][ICSS_SLICE0] :
|
|
|
|
|
- prueth->pru[ICSSG1][ICSS_SLICE1],
|
|
|
|
|
- &prueth->pruss_id[ICSSG1]);
|
|
|
|
|
- if (IS_ERR(pruss[ICSSG1])) {
|
|
|
|
|
- ret = PTR_ERR(pruss[ICSSG1]);
|
|
|
|
|
- dev_err(dev, "unable to get pruss handle\n");
|
|
|
|
|
- goto put_cores;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- prueth->pruss[ICSSG1] = pruss[ICSSG1];
|
|
|
|
|
- ret = pruss_request_mem_region(pruss[ICSSG1],
|
|
|
|
|
- PRUSS_MEM_SHRD_RAM2,
|
|
|
|
|
- &prueth->shram[ICSSG1]);
|
|
|
|
|
- if (ret) {
|
|
|
|
|
- dev_err(dev,
|
|
|
|
|
- "unable to get PRUSS SHRD RAM2: %d\n", ret);
|
|
|
|
|
- goto put_mem;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
prueth->sram_pool = of_gen_pool_get(np, "sram", 0);
|
|
prueth->sram_pool = of_gen_pool_get(np, "sram", 0);
|
|
|
if (!prueth->sram_pool) {
|
|
if (!prueth->sram_pool) {
|
|
|
dev_err(dev, "unable to get SRAM pool\n");
|
|
dev_err(dev, "unable to get SRAM pool\n");
|
|
@@ -1955,42 +1767,19 @@ static int prueth_probe(struct platform_device *pdev)
|
|
|
|
|
|
|
|
goto put_mem;
|
|
goto put_mem;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- msmc_ram_size = MSMC_RAM_SIZE;
|
|
|
|
|
- if (prueth->dual_icssg)
|
|
|
|
|
- msmc_ram_size *= 2;
|
|
|
|
|
-
|
|
|
|
|
- /* Get pool for both ICSSG and split it */
|
|
|
|
|
- prueth->msmcram[ICSSG0].va =
|
|
|
|
|
- (void __iomem *)gen_pool_alloc(prueth->sram_pool, msmc_ram_size);
|
|
|
|
|
- if (!prueth->msmcram[ICSSG0].va) {
|
|
|
|
|
|
|
+ prueth->msmcram.va =
|
|
|
|
|
+ (void __iomem *)gen_pool_alloc(prueth->sram_pool,
|
|
|
|
|
+ MSMC_RAM_SIZE);
|
|
|
|
|
+ if (!prueth->msmcram.va) {
|
|
|
ret = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
|
dev_err(dev, "unable to allocate MSMC resource\n");
|
|
dev_err(dev, "unable to allocate MSMC resource\n");
|
|
|
goto put_mem;
|
|
goto put_mem;
|
|
|
}
|
|
}
|
|
|
- prueth->msmcram[ICSSG0].pa =
|
|
|
|
|
- gen_pool_virt_to_phys(prueth->sram_pool,
|
|
|
|
|
- (unsigned long)
|
|
|
|
|
- prueth->msmcram[ICSSG0].va);
|
|
|
|
|
-
|
|
|
|
|
- prueth->msmcram[ICSSG0].size = MSMC_RAM_SIZE;
|
|
|
|
|
- if (prueth->dual_icssg) {
|
|
|
|
|
- prueth->msmcram[ICSSG1].va =
|
|
|
|
|
- prueth->msmcram[ICSSG0].va + MSMC_RAM_SIZE;
|
|
|
|
|
- prueth->msmcram[ICSSG1].pa =
|
|
|
|
|
- prueth->msmcram[ICSSG0].pa + MSMC_RAM_SIZE;
|
|
|
|
|
- prueth->msmcram[ICSSG1].size = MSMC_RAM_SIZE;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- dev_dbg(dev, "sram: ICSSG0 pa %pa va %p size %zx\n",
|
|
|
|
|
- &prueth->msmcram[ICSSG0].pa,
|
|
|
|
|
- prueth->msmcram[ICSSG0].va, prueth->msmcram[ICSSG0].size);
|
|
|
|
|
- if (prueth->dual_icssg) {
|
|
|
|
|
- dev_dbg(dev, "sram: ICSSG0 pa %pa va %p size %zx\n",
|
|
|
|
|
- &prueth->msmcram[ICSSG1].pa,
|
|
|
|
|
- prueth->msmcram[ICSSG1].va,
|
|
|
|
|
- prueth->msmcram[ICSSG1].size);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ prueth->msmcram.pa = gen_pool_virt_to_phys(prueth->sram_pool,
|
|
|
|
|
+ (unsigned long)prueth->msmcram.va);
|
|
|
|
|
+ prueth->msmcram.size = MSMC_RAM_SIZE;
|
|
|
|
|
+ dev_dbg(dev, "sram: pa %llx va %p size %zx\n", prueth->msmcram.pa,
|
|
|
|
|
+ prueth->msmcram.va, prueth->msmcram.size);
|
|
|
|
|
|
|
|
/* setup netdev interfaces */
|
|
/* setup netdev interfaces */
|
|
|
if (eth0_node) {
|
|
if (eth0_node) {
|
|
@@ -2036,10 +1825,8 @@ static int prueth_probe(struct platform_device *pdev)
|
|
|
prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev;
|
|
prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- dev_info(dev,
|
|
|
|
|
- "TI PRU ethernet initialized: %s EMAC mode, dual_icssg %d\n",
|
|
|
|
|
- (!eth0_node || !eth1_node) ? "single" : "dual",
|
|
|
|
|
- prueth->dual_icssg);
|
|
|
|
|
|
|
+ dev_info(dev, "TI PRU ethernet driver initialized: %s EMAC mode\n",
|
|
|
|
|
+ (!eth0_node || !eth1_node) ? "single" : "dual");
|
|
|
|
|
|
|
|
if (eth1_node)
|
|
if (eth1_node)
|
|
|
of_node_put(eth1_node);
|
|
of_node_put(eth1_node);
|
|
@@ -2068,16 +1855,11 @@ netdev_exit:
|
|
|
|
|
|
|
|
free_pool:
|
|
free_pool:
|
|
|
gen_pool_free(prueth->sram_pool,
|
|
gen_pool_free(prueth->sram_pool,
|
|
|
- (unsigned long)prueth->msmcram[0].va, msmc_ram_size);
|
|
|
|
|
|
|
+ (unsigned long)prueth->msmcram.va, MSMC_RAM_SIZE);
|
|
|
|
|
|
|
|
put_mem:
|
|
put_mem:
|
|
|
- pruss_release_mem_region(prueth->pruss[ICSSG0], &prueth->shram[ICSSG0]);
|
|
|
|
|
- pruss_put(prueth->pruss[ICSSG0]);
|
|
|
|
|
- if (prueth->pruss[ICSSG1]) {
|
|
|
|
|
- pruss_release_mem_region(prueth->pruss[ICSSG1],
|
|
|
|
|
- &prueth->shram[ICSSG1]);
|
|
|
|
|
- pruss_put(prueth->pruss[ICSSG1]);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ pruss_release_mem_region(prueth->pruss, &prueth->shram);
|
|
|
|
|
+ pruss_put(prueth->pruss);
|
|
|
|
|
|
|
|
put_cores:
|
|
put_cores:
|
|
|
if (eth1_node) {
|
|
if (eth1_node) {
|
|
@@ -2113,22 +1895,13 @@ static int prueth_remove(struct platform_device *pdev)
|
|
|
prueth_netdev_exit(prueth, eth_node);
|
|
prueth_netdev_exit(prueth, eth_node);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (prueth->dual_icssg)
|
|
|
|
|
- gen_pool_free(prueth->sram_pool,
|
|
|
|
|
- (unsigned long)prueth->msmcram[ICSSG0].va,
|
|
|
|
|
- MSMC_RAM_SIZE * 2);
|
|
|
|
|
- else
|
|
|
|
|
- gen_pool_free(prueth->sram_pool,
|
|
|
|
|
- (unsigned long)prueth->msmcram[ICSSG0].va,
|
|
|
|
|
- MSMC_RAM_SIZE);
|
|
|
|
|
|
|
+ gen_pool_free(prueth->sram_pool,
|
|
|
|
|
+ (unsigned long)prueth->msmcram.va,
|
|
|
|
|
+ MSMC_RAM_SIZE);
|
|
|
|
|
|
|
|
- pruss_release_mem_region(prueth->pruss[ICSSG0], &prueth->shram[ICSSG0]);
|
|
|
|
|
- pruss_put(prueth->pruss[ICSSG0]);
|
|
|
|
|
- if (prueth->dual_icssg) {
|
|
|
|
|
- pruss_release_mem_region(prueth->pruss[ICSSG1],
|
|
|
|
|
- &prueth->shram[ICSSG1]);
|
|
|
|
|
- pruss_put(prueth->pruss[ICSSG1]);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ pruss_release_mem_region(prueth->pruss, &prueth->shram);
|
|
|
|
|
+
|
|
|
|
|
+ pruss_put(prueth->pruss);
|
|
|
|
|
|
|
|
if (prueth->eth_node[PRUETH_MAC1])
|
|
if (prueth->eth_node[PRUETH_MAC1])
|
|
|
prueth_put_cores(prueth, ICSS_SLICE1);
|
|
prueth_put_cores(prueth, ICSS_SLICE1);
|
|
@@ -2197,7 +1970,6 @@ static const struct dev_pm_ops prueth_dev_pm_ops = {
|
|
|
|
|
|
|
|
static const struct of_device_id prueth_dt_match[] = {
|
|
static const struct of_device_id prueth_dt_match[] = {
|
|
|
{ .compatible = "ti,am654-icssg-prueth", },
|
|
{ .compatible = "ti,am654-icssg-prueth", },
|
|
|
- { .compatible = "ti,am654-dualicssg-prueth", },
|
|
|
|
|
{ /* sentinel */ }
|
|
{ /* sentinel */ }
|
|
|
};
|
|
};
|
|
|
MODULE_DEVICE_TABLE(of, prueth_dt_match);
|
|
MODULE_DEVICE_TABLE(of, prueth_dt_match);
|