aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/pasemi_mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pasemi_mac.c')
-rw-r--r--drivers/net/pasemi_mac.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index bc7f3dee6e5..8d38425e46c 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -85,6 +85,7 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
{
struct pci_dev *pdev = mac->pdev;
struct device_node *dn = pci_device_to_OF_node(pdev);
+ int len;
const u8 *maddr;
u8 addr[6];
@@ -94,9 +95,17 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
return -ENOENT;
}
- maddr = of_get_property(dn, "local-mac-address", NULL);
+ maddr = of_get_property(dn, "local-mac-address", &len);
+
+ if (maddr && len == 6) {
+ memcpy(mac->mac_addr, maddr, 6);
+ return 0;
+ }
+
+ /* Some old versions of firmware mistakenly uses mac-address
+ * (and as a string) instead of a byte array in local-mac-address.
+ */
- /* Fall back to mac-address for older firmware */
if (maddr == NULL)
maddr = of_get_property(dn, "mac-address", NULL);
@@ -106,6 +115,7 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
return -ENOENT;
}
+
if (sscanf(maddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0],
&addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) {
dev_warn(&pdev->dev,
@@ -113,7 +123,8 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
return -EINVAL;
}
- memcpy(mac->mac_addr, addr, sizeof(addr));
+ memcpy(mac->mac_addr, addr, 6);
+
return 0;
}
@@ -384,17 +395,14 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
{
- unsigned int reg, stat;
+ unsigned int reg, pcnt;
/* Re-enable packet count interrupts: finally
* ack the packet count interrupt we got in rx_intr.
*/
- pci_read_config_dword(mac->iob_pdev,
- PAS_IOB_DMA_RXCH_STAT(mac->dma_rxch),
- &stat);
+ pcnt = *mac->rx_status & PAS_STATUS_PCNT_M;
- reg = PAS_IOB_DMA_RXCH_RESET_PCNT(stat & PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
- | PAS_IOB_DMA_RXCH_RESET_PINTC;
+ reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC;
pci_write_config_dword(mac->iob_pdev,
PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch),
@@ -403,14 +411,12 @@ static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
{
- unsigned int reg, stat;
+ unsigned int reg, pcnt;
/* Re-enable packet count interrupts */
- pci_read_config_dword(mac->iob_pdev,
- PAS_IOB_DMA_TXCH_STAT(mac->dma_txch), &stat);
+ pcnt = *mac->tx_status & PAS_STATUS_PCNT_M;
- reg = PAS_IOB_DMA_TXCH_RESET_PCNT(stat & PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
- | PAS_IOB_DMA_TXCH_RESET_PINTC;
+ reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC;
pci_write_config_dword(mac->iob_pdev,
PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
@@ -591,21 +597,24 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
{
struct net_device *dev = data;
struct pasemi_mac *mac = netdev_priv(dev);
- unsigned int reg;
+ unsigned int reg, pcnt;
if (!(*mac->tx_status & PAS_STATUS_CAUSE_M))
return IRQ_NONE;
pasemi_mac_clean_tx(mac);
- reg = PAS_IOB_DMA_TXCH_RESET_PINTC;
+ pcnt = *mac->tx_status & PAS_STATUS_PCNT_M;
+
+ reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC;
if (*mac->tx_status & PAS_STATUS_SOFT)
reg |= PAS_IOB_DMA_TXCH_RESET_SINTC;
if (*mac->tx_status & PAS_STATUS_ERROR)
reg |= PAS_IOB_DMA_TXCH_RESET_DINTC;
- pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch),
+ pci_write_config_dword(mac->iob_pdev,
+ PAS_IOB_DMA_TXCH_RESET(mac->dma_txch),
reg);
return IRQ_HANDLED;
@@ -974,6 +983,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
if (txring->next_to_clean - txring->next_to_use == TX_RING_SIZE) {
spin_unlock_irqrestore(&txring->lock, flags);
pasemi_mac_clean_tx(mac);
+ pasemi_mac_restart_tx_intr(mac);
spin_lock_irqsave(&txring->lock, flags);
if (txring->next_to_clean - txring->next_to_use ==
@@ -1210,6 +1220,7 @@ static void __devexit pasemi_mac_remove(struct pci_dev *pdev)
static struct pci_device_id pasemi_mac_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa005) },
{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa006) },
+ { },
};
MODULE_DEVICE_TABLE(pci, pasemi_mac_pci_tbl);