|
@@ -42,6 +42,16 @@
|
|
|
NETIF_MSG_RX_ERR | \
|
|
NETIF_MSG_RX_ERR | \
|
|
|
NETIF_MSG_TX_ERR)
|
|
NETIF_MSG_TX_ERR)
|
|
|
|
|
|
|
|
|
|
+static const char *ravb_rx_irqs[NUM_RX_QUEUE] = {
|
|
|
|
|
+ "ch0", /* RAVB_BE */
|
|
|
|
|
+ "ch1", /* RAVB_NC */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+static const char *ravb_tx_irqs[NUM_TX_QUEUE] = {
|
|
|
|
|
+ "ch18", /* RAVB_BE */
|
|
|
|
|
+ "ch19", /* RAVB_NC */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
void ravb_modify(struct net_device *ndev, enum ravb_reg reg, u32 clear,
|
|
void ravb_modify(struct net_device *ndev, enum ravb_reg reg, u32 clear,
|
|
|
u32 set)
|
|
u32 set)
|
|
|
{
|
|
{
|
|
@@ -365,6 +375,7 @@ static void ravb_emac_init(struct net_device *ndev)
|
|
|
/* Device init function for Ethernet AVB */
|
|
/* Device init function for Ethernet AVB */
|
|
|
static int ravb_dmac_init(struct net_device *ndev)
|
|
static int ravb_dmac_init(struct net_device *ndev)
|
|
|
{
|
|
{
|
|
|
|
|
+ struct ravb_private *priv = netdev_priv(ndev);
|
|
|
int error;
|
|
int error;
|
|
|
|
|
|
|
|
/* Set CONFIG mode */
|
|
/* Set CONFIG mode */
|
|
@@ -401,6 +412,12 @@ static int ravb_dmac_init(struct net_device *ndev)
|
|
|
ravb_write(ndev, TCCR_TFEN, TCCR);
|
|
ravb_write(ndev, TCCR_TFEN, TCCR);
|
|
|
|
|
|
|
|
/* Interrupt init: */
|
|
/* Interrupt init: */
|
|
|
|
|
+ if (priv->chip_id == RCAR_GEN3) {
|
|
|
|
|
+ /* Clear DIL.DPLx */
|
|
|
|
|
+ ravb_write(ndev, 0, DIL);
|
|
|
|
|
+ /* Set queue specific interrupt */
|
|
|
|
|
+ ravb_write(ndev, CIE_CRIE | CIE_CTIE | CIE_CL0M, CIE);
|
|
|
|
|
+ }
|
|
|
/* Frame receive */
|
|
/* Frame receive */
|
|
|
ravb_write(ndev, RIC0_FRE0 | RIC0_FRE1, RIC0);
|
|
ravb_write(ndev, RIC0_FRE0 | RIC0_FRE1, RIC0);
|
|
|
/* Disable FIFO full warning */
|
|
/* Disable FIFO full warning */
|
|
@@ -643,7 +660,7 @@ static int ravb_stop_dma(struct net_device *ndev)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* E-MAC interrupt handler */
|
|
/* E-MAC interrupt handler */
|
|
|
-static void ravb_emac_interrupt(struct net_device *ndev)
|
|
|
|
|
|
|
+static void ravb_emac_interrupt_unlocked(struct net_device *ndev)
|
|
|
{
|
|
{
|
|
|
struct ravb_private *priv = netdev_priv(ndev);
|
|
struct ravb_private *priv = netdev_priv(ndev);
|
|
|
u32 ecsr, psr;
|
|
u32 ecsr, psr;
|
|
@@ -669,6 +686,18 @@ static void ravb_emac_interrupt(struct net_device *ndev)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static irqreturn_t ravb_emac_interrupt(int irq, void *dev_id)
|
|
|
|
|
+{
|
|
|
|
|
+ struct net_device *ndev = dev_id;
|
|
|
|
|
+ struct ravb_private *priv = netdev_priv(ndev);
|
|
|
|
|
+
|
|
|
|
|
+ spin_lock(&priv->lock);
|
|
|
|
|
+ ravb_emac_interrupt_unlocked(ndev);
|
|
|
|
|
+ mmiowb();
|
|
|
|
|
+ spin_unlock(&priv->lock);
|
|
|
|
|
+ return IRQ_HANDLED;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* Error interrupt handler */
|
|
/* Error interrupt handler */
|
|
|
static void ravb_error_interrupt(struct net_device *ndev)
|
|
static void ravb_error_interrupt(struct net_device *ndev)
|
|
|
{
|
|
{
|
|
@@ -695,6 +724,50 @@ static void ravb_error_interrupt(struct net_device *ndev)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static bool ravb_queue_interrupt(struct net_device *ndev, int q)
|
|
|
|
|
+{
|
|
|
|
|
+ struct ravb_private *priv = netdev_priv(ndev);
|
|
|
|
|
+ u32 ris0 = ravb_read(ndev, RIS0);
|
|
|
|
|
+ u32 ric0 = ravb_read(ndev, RIC0);
|
|
|
|
|
+ u32 tis = ravb_read(ndev, TIS);
|
|
|
|
|
+ u32 tic = ravb_read(ndev, TIC);
|
|
|
|
|
+
|
|
|
|
|
+ if (((ris0 & ric0) & BIT(q)) || ((tis & tic) & BIT(q))) {
|
|
|
|
|
+ if (napi_schedule_prep(&priv->napi[q])) {
|
|
|
|
|
+ /* Mask RX and TX interrupts */
|
|
|
|
|
+ if (priv->chip_id == RCAR_GEN2) {
|
|
|
|
|
+ ravb_write(ndev, ric0 & ~BIT(q), RIC0);
|
|
|
|
|
+ ravb_write(ndev, tic & ~BIT(q), TIC);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ravb_write(ndev, BIT(q), RID0);
|
|
|
|
|
+ ravb_write(ndev, BIT(q), TID);
|
|
|
|
|
+ }
|
|
|
|
|
+ __napi_schedule(&priv->napi[q]);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ netdev_warn(ndev,
|
|
|
|
|
+ "ignoring interrupt, rx status 0x%08x, rx mask 0x%08x,\n",
|
|
|
|
|
+ ris0, ric0);
|
|
|
|
|
+ netdev_warn(ndev,
|
|
|
|
|
+ " tx status 0x%08x, tx mask 0x%08x.\n",
|
|
|
|
|
+ tis, tic);
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static bool ravb_timestamp_interrupt(struct net_device *ndev)
|
|
|
|
|
+{
|
|
|
|
|
+ u32 tis = ravb_read(ndev, TIS);
|
|
|
|
|
+
|
|
|
|
|
+ if (tis & TIS_TFUF) {
|
|
|
|
|
+ ravb_write(ndev, ~TIS_TFUF, TIS);
|
|
|
|
|
+ ravb_get_tx_tstamp(ndev);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static irqreturn_t ravb_interrupt(int irq, void *dev_id)
|
|
static irqreturn_t ravb_interrupt(int irq, void *dev_id)
|
|
|
{
|
|
{
|
|
|
struct net_device *ndev = dev_id;
|
|
struct net_device *ndev = dev_id;
|
|
@@ -708,46 +781,22 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
|
|
|
|
|
|
|
|
/* Received and transmitted interrupts */
|
|
/* Received and transmitted interrupts */
|
|
|
if (iss & (ISS_FRS | ISS_FTS | ISS_TFUS)) {
|
|
if (iss & (ISS_FRS | ISS_FTS | ISS_TFUS)) {
|
|
|
- u32 ris0 = ravb_read(ndev, RIS0);
|
|
|
|
|
- u32 ric0 = ravb_read(ndev, RIC0);
|
|
|
|
|
- u32 tis = ravb_read(ndev, TIS);
|
|
|
|
|
- u32 tic = ravb_read(ndev, TIC);
|
|
|
|
|
int q;
|
|
int q;
|
|
|
|
|
|
|
|
/* Timestamp updated */
|
|
/* Timestamp updated */
|
|
|
- if (tis & TIS_TFUF) {
|
|
|
|
|
- ravb_write(ndev, ~TIS_TFUF, TIS);
|
|
|
|
|
- ravb_get_tx_tstamp(ndev);
|
|
|
|
|
|
|
+ if (ravb_timestamp_interrupt(ndev))
|
|
|
result = IRQ_HANDLED;
|
|
result = IRQ_HANDLED;
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
/* Network control and best effort queue RX/TX */
|
|
/* Network control and best effort queue RX/TX */
|
|
|
for (q = RAVB_NC; q >= RAVB_BE; q--) {
|
|
for (q = RAVB_NC; q >= RAVB_BE; q--) {
|
|
|
- if (((ris0 & ric0) & BIT(q)) ||
|
|
|
|
|
- ((tis & tic) & BIT(q))) {
|
|
|
|
|
- if (napi_schedule_prep(&priv->napi[q])) {
|
|
|
|
|
- /* Mask RX and TX interrupts */
|
|
|
|
|
- ric0 &= ~BIT(q);
|
|
|
|
|
- tic &= ~BIT(q);
|
|
|
|
|
- ravb_write(ndev, ric0, RIC0);
|
|
|
|
|
- ravb_write(ndev, tic, TIC);
|
|
|
|
|
- __napi_schedule(&priv->napi[q]);
|
|
|
|
|
- } else {
|
|
|
|
|
- netdev_warn(ndev,
|
|
|
|
|
- "ignoring interrupt, rx status 0x%08x, rx mask 0x%08x,\n",
|
|
|
|
|
- ris0, ric0);
|
|
|
|
|
- netdev_warn(ndev,
|
|
|
|
|
- " tx status 0x%08x, tx mask 0x%08x.\n",
|
|
|
|
|
- tis, tic);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (ravb_queue_interrupt(ndev, q))
|
|
|
result = IRQ_HANDLED;
|
|
result = IRQ_HANDLED;
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* E-MAC status summary */
|
|
/* E-MAC status summary */
|
|
|
if (iss & ISS_MS) {
|
|
if (iss & ISS_MS) {
|
|
|
- ravb_emac_interrupt(ndev);
|
|
|
|
|
|
|
+ ravb_emac_interrupt_unlocked(ndev);
|
|
|
result = IRQ_HANDLED;
|
|
result = IRQ_HANDLED;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -757,6 +806,7 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
|
|
|
result = IRQ_HANDLED;
|
|
result = IRQ_HANDLED;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /* gPTP interrupt status summary */
|
|
|
if ((iss & ISS_CGIS) && ravb_ptp_interrupt(ndev) == IRQ_HANDLED)
|
|
if ((iss & ISS_CGIS) && ravb_ptp_interrupt(ndev) == IRQ_HANDLED)
|
|
|
result = IRQ_HANDLED;
|
|
result = IRQ_HANDLED;
|
|
|
|
|
|
|
@@ -765,6 +815,64 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* Timestamp/Error/gPTP interrupt handler */
|
|
|
|
|
+static irqreturn_t ravb_multi_interrupt(int irq, void *dev_id)
|
|
|
|
|
+{
|
|
|
|
|
+ struct net_device *ndev = dev_id;
|
|
|
|
|
+ struct ravb_private *priv = netdev_priv(ndev);
|
|
|
|
|
+ irqreturn_t result = IRQ_NONE;
|
|
|
|
|
+ u32 iss;
|
|
|
|
|
+
|
|
|
|
|
+ spin_lock(&priv->lock);
|
|
|
|
|
+ /* Get interrupt status */
|
|
|
|
|
+ iss = ravb_read(ndev, ISS);
|
|
|
|
|
+
|
|
|
|
|
+ /* Timestamp updated */
|
|
|
|
|
+ if ((iss & ISS_TFUS) && ravb_timestamp_interrupt(ndev))
|
|
|
|
|
+ result = IRQ_HANDLED;
|
|
|
|
|
+
|
|
|
|
|
+ /* Error status summary */
|
|
|
|
|
+ if (iss & ISS_ES) {
|
|
|
|
|
+ ravb_error_interrupt(ndev);
|
|
|
|
|
+ result = IRQ_HANDLED;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* gPTP interrupt status summary */
|
|
|
|
|
+ if ((iss & ISS_CGIS) && ravb_ptp_interrupt(ndev) == IRQ_HANDLED)
|
|
|
|
|
+ result = IRQ_HANDLED;
|
|
|
|
|
+
|
|
|
|
|
+ mmiowb();
|
|
|
|
|
+ spin_unlock(&priv->lock);
|
|
|
|
|
+ return result;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static irqreturn_t ravb_dma_interrupt(int irq, void *dev_id, int q)
|
|
|
|
|
+{
|
|
|
|
|
+ struct net_device *ndev = dev_id;
|
|
|
|
|
+ struct ravb_private *priv = netdev_priv(ndev);
|
|
|
|
|
+ irqreturn_t result = IRQ_NONE;
|
|
|
|
|
+
|
|
|
|
|
+ spin_lock(&priv->lock);
|
|
|
|
|
+
|
|
|
|
|
+ /* Network control/Best effort queue RX/TX */
|
|
|
|
|
+ if (ravb_queue_interrupt(ndev, q))
|
|
|
|
|
+ result = IRQ_HANDLED;
|
|
|
|
|
+
|
|
|
|
|
+ mmiowb();
|
|
|
|
|
+ spin_unlock(&priv->lock);
|
|
|
|
|
+ return result;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static irqreturn_t ravb_be_interrupt(int irq, void *dev_id)
|
|
|
|
|
+{
|
|
|
|
|
+ return ravb_dma_interrupt(irq, dev_id, RAVB_BE);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static irqreturn_t ravb_nc_interrupt(int irq, void *dev_id)
|
|
|
|
|
+{
|
|
|
|
|
+ return ravb_dma_interrupt(irq, dev_id, RAVB_NC);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static int ravb_poll(struct napi_struct *napi, int budget)
|
|
static int ravb_poll(struct napi_struct *napi, int budget)
|
|
|
{
|
|
{
|
|
|
struct net_device *ndev = napi->dev;
|
|
struct net_device *ndev = napi->dev;
|
|
@@ -804,8 +912,13 @@ static int ravb_poll(struct napi_struct *napi, int budget)
|
|
|
|
|
|
|
|
/* Re-enable RX/TX interrupts */
|
|
/* Re-enable RX/TX interrupts */
|
|
|
spin_lock_irqsave(&priv->lock, flags);
|
|
spin_lock_irqsave(&priv->lock, flags);
|
|
|
- ravb_modify(ndev, RIC0, mask, mask);
|
|
|
|
|
- ravb_modify(ndev, TIC, mask, mask);
|
|
|
|
|
|
|
+ if (priv->chip_id == RCAR_GEN2) {
|
|
|
|
|
+ ravb_modify(ndev, RIC0, mask, mask);
|
|
|
|
|
+ ravb_modify(ndev, TIC, mask, mask);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ravb_write(ndev, mask, RIE0);
|
|
|
|
|
+ ravb_write(ndev, mask, TIE);
|
|
|
|
|
+ }
|
|
|
mmiowb();
|
|
mmiowb();
|
|
|
spin_unlock_irqrestore(&priv->lock, flags);
|
|
spin_unlock_irqrestore(&priv->lock, flags);
|
|
|
|
|
|
|
@@ -1208,35 +1321,72 @@ static const struct ethtool_ops ravb_ethtool_ops = {
|
|
|
.get_ts_info = ravb_get_ts_info,
|
|
.get_ts_info = ravb_get_ts_info,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+static inline int ravb_hook_irq(unsigned int irq, irq_handler_t handler,
|
|
|
|
|
+ struct net_device *ndev, struct device *dev,
|
|
|
|
|
+ const char *ch)
|
|
|
|
|
+{
|
|
|
|
|
+ char *name;
|
|
|
|
|
+ int error;
|
|
|
|
|
+
|
|
|
|
|
+ name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s", ndev->name, ch);
|
|
|
|
|
+ if (!name)
|
|
|
|
|
+ return -ENOMEM;
|
|
|
|
|
+ error = request_irq(irq, handler, 0, name, ndev);
|
|
|
|
|
+ if (error)
|
|
|
|
|
+ netdev_err(ndev, "cannot request IRQ %s\n", name);
|
|
|
|
|
+
|
|
|
|
|
+ return error;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* Network device open function for Ethernet AVB */
|
|
/* Network device open function for Ethernet AVB */
|
|
|
static int ravb_open(struct net_device *ndev)
|
|
static int ravb_open(struct net_device *ndev)
|
|
|
{
|
|
{
|
|
|
struct ravb_private *priv = netdev_priv(ndev);
|
|
struct ravb_private *priv = netdev_priv(ndev);
|
|
|
|
|
+ struct platform_device *pdev = priv->pdev;
|
|
|
|
|
+ struct device *dev = &pdev->dev;
|
|
|
int error;
|
|
int error;
|
|
|
|
|
|
|
|
napi_enable(&priv->napi[RAVB_BE]);
|
|
napi_enable(&priv->napi[RAVB_BE]);
|
|
|
napi_enable(&priv->napi[RAVB_NC]);
|
|
napi_enable(&priv->napi[RAVB_NC]);
|
|
|
|
|
|
|
|
- error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED, ndev->name,
|
|
|
|
|
- ndev);
|
|
|
|
|
- if (error) {
|
|
|
|
|
- netdev_err(ndev, "cannot request IRQ\n");
|
|
|
|
|
- goto out_napi_off;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (priv->chip_id == RCAR_GEN3) {
|
|
|
|
|
- error = request_irq(priv->emac_irq, ravb_interrupt,
|
|
|
|
|
- IRQF_SHARED, ndev->name, ndev);
|
|
|
|
|
|
|
+ if (priv->chip_id == RCAR_GEN2) {
|
|
|
|
|
+ error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED,
|
|
|
|
|
+ ndev->name, ndev);
|
|
|
if (error) {
|
|
if (error) {
|
|
|
netdev_err(ndev, "cannot request IRQ\n");
|
|
netdev_err(ndev, "cannot request IRQ\n");
|
|
|
- goto out_free_irq;
|
|
|
|
|
|
|
+ goto out_napi_off;
|
|
|
}
|
|
}
|
|
|
|
|
+ } else {
|
|
|
|
|
+ error = ravb_hook_irq(ndev->irq, ravb_multi_interrupt, ndev,
|
|
|
|
|
+ dev, "ch22:multi");
|
|
|
|
|
+ if (error)
|
|
|
|
|
+ goto out_napi_off;
|
|
|
|
|
+ error = ravb_hook_irq(priv->emac_irq, ravb_emac_interrupt, ndev,
|
|
|
|
|
+ dev, "ch24:emac");
|
|
|
|
|
+ if (error)
|
|
|
|
|
+ goto out_free_irq;
|
|
|
|
|
+ error = ravb_hook_irq(priv->rx_irqs[RAVB_BE], ravb_be_interrupt,
|
|
|
|
|
+ ndev, dev, "ch0:rx_be");
|
|
|
|
|
+ if (error)
|
|
|
|
|
+ goto out_free_irq_emac;
|
|
|
|
|
+ error = ravb_hook_irq(priv->tx_irqs[RAVB_BE], ravb_be_interrupt,
|
|
|
|
|
+ ndev, dev, "ch18:tx_be");
|
|
|
|
|
+ if (error)
|
|
|
|
|
+ goto out_free_irq_be_rx;
|
|
|
|
|
+ error = ravb_hook_irq(priv->rx_irqs[RAVB_NC], ravb_nc_interrupt,
|
|
|
|
|
+ ndev, dev, "ch1:rx_nc");
|
|
|
|
|
+ if (error)
|
|
|
|
|
+ goto out_free_irq_be_tx;
|
|
|
|
|
+ error = ravb_hook_irq(priv->tx_irqs[RAVB_NC], ravb_nc_interrupt,
|
|
|
|
|
+ ndev, dev, "ch19:tx_nc");
|
|
|
|
|
+ if (error)
|
|
|
|
|
+ goto out_free_irq_nc_rx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Device init */
|
|
/* Device init */
|
|
|
error = ravb_dmac_init(ndev);
|
|
error = ravb_dmac_init(ndev);
|
|
|
if (error)
|
|
if (error)
|
|
|
- goto out_free_irq2;
|
|
|
|
|
|
|
+ goto out_free_irq_nc_tx;
|
|
|
ravb_emac_init(ndev);
|
|
ravb_emac_init(ndev);
|
|
|
|
|
|
|
|
/* Initialise PTP Clock driver */
|
|
/* Initialise PTP Clock driver */
|
|
@@ -1256,9 +1406,18 @@ out_ptp_stop:
|
|
|
/* Stop PTP Clock driver */
|
|
/* Stop PTP Clock driver */
|
|
|
if (priv->chip_id == RCAR_GEN2)
|
|
if (priv->chip_id == RCAR_GEN2)
|
|
|
ravb_ptp_stop(ndev);
|
|
ravb_ptp_stop(ndev);
|
|
|
-out_free_irq2:
|
|
|
|
|
- if (priv->chip_id == RCAR_GEN3)
|
|
|
|
|
- free_irq(priv->emac_irq, ndev);
|
|
|
|
|
|
|
+out_free_irq_nc_tx:
|
|
|
|
|
+ if (priv->chip_id == RCAR_GEN2)
|
|
|
|
|
+ goto out_free_irq;
|
|
|
|
|
+ free_irq(priv->tx_irqs[RAVB_NC], ndev);
|
|
|
|
|
+out_free_irq_nc_rx:
|
|
|
|
|
+ free_irq(priv->rx_irqs[RAVB_NC], ndev);
|
|
|
|
|
+out_free_irq_be_tx:
|
|
|
|
|
+ free_irq(priv->tx_irqs[RAVB_BE], ndev);
|
|
|
|
|
+out_free_irq_be_rx:
|
|
|
|
|
+ free_irq(priv->rx_irqs[RAVB_BE], ndev);
|
|
|
|
|
+out_free_irq_emac:
|
|
|
|
|
+ free_irq(priv->emac_irq, ndev);
|
|
|
out_free_irq:
|
|
out_free_irq:
|
|
|
free_irq(ndev->irq, ndev);
|
|
free_irq(ndev->irq, ndev);
|
|
|
out_napi_off:
|
|
out_napi_off:
|
|
@@ -1713,6 +1872,7 @@ static int ravb_probe(struct platform_device *pdev)
|
|
|
struct net_device *ndev;
|
|
struct net_device *ndev;
|
|
|
int error, irq, q;
|
|
int error, irq, q;
|
|
|
struct resource *res;
|
|
struct resource *res;
|
|
|
|
|
+ int i;
|
|
|
|
|
|
|
|
if (!np) {
|
|
if (!np) {
|
|
|
dev_err(&pdev->dev,
|
|
dev_err(&pdev->dev,
|
|
@@ -1782,6 +1942,22 @@ static int ravb_probe(struct platform_device *pdev)
|
|
|
goto out_release;
|
|
goto out_release;
|
|
|
}
|
|
}
|
|
|
priv->emac_irq = irq;
|
|
priv->emac_irq = irq;
|
|
|
|
|
+ for (i = 0; i < NUM_RX_QUEUE; i++) {
|
|
|
|
|
+ irq = platform_get_irq_byname(pdev, ravb_rx_irqs[i]);
|
|
|
|
|
+ if (irq < 0) {
|
|
|
|
|
+ error = irq;
|
|
|
|
|
+ goto out_release;
|
|
|
|
|
+ }
|
|
|
|
|
+ priv->rx_irqs[i] = irq;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (i = 0; i < NUM_TX_QUEUE; i++) {
|
|
|
|
|
+ irq = platform_get_irq_byname(pdev, ravb_tx_irqs[i]);
|
|
|
|
|
+ if (irq < 0) {
|
|
|
|
|
+ error = irq;
|
|
|
|
|
+ goto out_release;
|
|
|
|
|
+ }
|
|
|
|
|
+ priv->tx_irqs[i] = irq;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
priv->chip_id = chip_id;
|
|
priv->chip_id = chip_id;
|