diff options
Diffstat (limited to 'drivers/net/pasemi_mac.c')
-rw-r--r-- | drivers/net/pasemi_mac.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index bc7f3dee6e5b..8d38425e46c3 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) | |||
85 | { | 85 | { |
86 | struct pci_dev *pdev = mac->pdev; | 86 | struct pci_dev *pdev = mac->pdev; |
87 | struct device_node *dn = pci_device_to_OF_node(pdev); | 87 | struct device_node *dn = pci_device_to_OF_node(pdev); |
88 | int len; | ||
88 | const u8 *maddr; | 89 | const u8 *maddr; |
89 | u8 addr[6]; | 90 | u8 addr[6]; |
90 | 91 | ||
@@ -94,9 +95,17 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) | |||
94 | return -ENOENT; | 95 | return -ENOENT; |
95 | } | 96 | } |
96 | 97 | ||
97 | maddr = of_get_property(dn, "local-mac-address", NULL); | 98 | maddr = of_get_property(dn, "local-mac-address", &len); |
99 | |||
100 | if (maddr && len == 6) { | ||
101 | memcpy(mac->mac_addr, maddr, 6); | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | /* Some old versions of firmware mistakenly uses mac-address | ||
106 | * (and as a string) instead of a byte array in local-mac-address. | ||
107 | */ | ||
98 | 108 | ||
99 | /* Fall back to mac-address for older firmware */ | ||
100 | if (maddr == NULL) | 109 | if (maddr == NULL) |
101 | maddr = of_get_property(dn, "mac-address", NULL); | 110 | maddr = of_get_property(dn, "mac-address", NULL); |
102 | 111 | ||
@@ -106,6 +115,7 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) | |||
106 | return -ENOENT; | 115 | return -ENOENT; |
107 | } | 116 | } |
108 | 117 | ||
118 | |||
109 | if (sscanf(maddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0], | 119 | if (sscanf(maddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0], |
110 | &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) { | 120 | &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) { |
111 | dev_warn(&pdev->dev, | 121 | dev_warn(&pdev->dev, |
@@ -113,7 +123,8 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) | |||
113 | return -EINVAL; | 123 | return -EINVAL; |
114 | } | 124 | } |
115 | 125 | ||
116 | memcpy(mac->mac_addr, addr, sizeof(addr)); | 126 | memcpy(mac->mac_addr, addr, 6); |
127 | |||
117 | return 0; | 128 | return 0; |
118 | } | 129 | } |
119 | 130 | ||
@@ -384,17 +395,14 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) | |||
384 | 395 | ||
385 | static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) | 396 | static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) |
386 | { | 397 | { |
387 | unsigned int reg, stat; | 398 | unsigned int reg, pcnt; |
388 | /* Re-enable packet count interrupts: finally | 399 | /* Re-enable packet count interrupts: finally |
389 | * ack the packet count interrupt we got in rx_intr. | 400 | * ack the packet count interrupt we got in rx_intr. |
390 | */ | 401 | */ |
391 | 402 | ||
392 | pci_read_config_dword(mac->iob_pdev, | 403 | pcnt = *mac->rx_status & PAS_STATUS_PCNT_M; |
393 | PAS_IOB_DMA_RXCH_STAT(mac->dma_rxch), | ||
394 | &stat); | ||
395 | 404 | ||
396 | reg = PAS_IOB_DMA_RXCH_RESET_PCNT(stat & PAS_IOB_DMA_RXCH_STAT_CNTDEL_M) | 405 | reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC; |
397 | | PAS_IOB_DMA_RXCH_RESET_PINTC; | ||
398 | 406 | ||
399 | pci_write_config_dword(mac->iob_pdev, | 407 | pci_write_config_dword(mac->iob_pdev, |
400 | PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), | 408 | PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), |
@@ -403,14 +411,12 @@ static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) | |||
403 | 411 | ||
404 | static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) | 412 | static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) |
405 | { | 413 | { |
406 | unsigned int reg, stat; | 414 | unsigned int reg, pcnt; |
407 | 415 | ||
408 | /* Re-enable packet count interrupts */ | 416 | /* Re-enable packet count interrupts */ |
409 | pci_read_config_dword(mac->iob_pdev, | 417 | pcnt = *mac->tx_status & PAS_STATUS_PCNT_M; |
410 | PAS_IOB_DMA_TXCH_STAT(mac->dma_txch), &stat); | ||
411 | 418 | ||
412 | reg = PAS_IOB_DMA_TXCH_RESET_PCNT(stat & PAS_IOB_DMA_TXCH_STAT_CNTDEL_M) | 419 | reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; |
413 | | PAS_IOB_DMA_TXCH_RESET_PINTC; | ||
414 | 420 | ||
415 | pci_write_config_dword(mac->iob_pdev, | 421 | pci_write_config_dword(mac->iob_pdev, |
416 | PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); | 422 | PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); |
@@ -591,21 +597,24 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) | |||
591 | { | 597 | { |
592 | struct net_device *dev = data; | 598 | struct net_device *dev = data; |
593 | struct pasemi_mac *mac = netdev_priv(dev); | 599 | struct pasemi_mac *mac = netdev_priv(dev); |
594 | unsigned int reg; | 600 | unsigned int reg, pcnt; |
595 | 601 | ||
596 | if (!(*mac->tx_status & PAS_STATUS_CAUSE_M)) | 602 | if (!(*mac->tx_status & PAS_STATUS_CAUSE_M)) |
597 | return IRQ_NONE; | 603 | return IRQ_NONE; |
598 | 604 | ||
599 | pasemi_mac_clean_tx(mac); | 605 | pasemi_mac_clean_tx(mac); |
600 | 606 | ||
601 | reg = PAS_IOB_DMA_TXCH_RESET_PINTC; | 607 | pcnt = *mac->tx_status & PAS_STATUS_PCNT_M; |
608 | |||
609 | reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; | ||
602 | 610 | ||
603 | if (*mac->tx_status & PAS_STATUS_SOFT) | 611 | if (*mac->tx_status & PAS_STATUS_SOFT) |
604 | reg |= PAS_IOB_DMA_TXCH_RESET_SINTC; | 612 | reg |= PAS_IOB_DMA_TXCH_RESET_SINTC; |
605 | if (*mac->tx_status & PAS_STATUS_ERROR) | 613 | if (*mac->tx_status & PAS_STATUS_ERROR) |
606 | reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; | 614 | reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; |
607 | 615 | ||
608 | pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), | 616 | pci_write_config_dword(mac->iob_pdev, |
617 | PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), | ||
609 | reg); | 618 | reg); |
610 | 619 | ||
611 | return IRQ_HANDLED; | 620 | return IRQ_HANDLED; |
@@ -974,6 +983,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) | |||
974 | if (txring->next_to_clean - txring->next_to_use == TX_RING_SIZE) { | 983 | if (txring->next_to_clean - txring->next_to_use == TX_RING_SIZE) { |
975 | spin_unlock_irqrestore(&txring->lock, flags); | 984 | spin_unlock_irqrestore(&txring->lock, flags); |
976 | pasemi_mac_clean_tx(mac); | 985 | pasemi_mac_clean_tx(mac); |
986 | pasemi_mac_restart_tx_intr(mac); | ||
977 | spin_lock_irqsave(&txring->lock, flags); | 987 | spin_lock_irqsave(&txring->lock, flags); |
978 | 988 | ||
979 | if (txring->next_to_clean - txring->next_to_use == | 989 | if (txring->next_to_clean - txring->next_to_use == |
@@ -1210,6 +1220,7 @@ static void __devexit pasemi_mac_remove(struct pci_dev *pdev) | |||
1210 | static struct pci_device_id pasemi_mac_pci_tbl[] = { | 1220 | static struct pci_device_id pasemi_mac_pci_tbl[] = { |
1211 | { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa005) }, | 1221 | { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa005) }, |
1212 | { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa006) }, | 1222 | { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa006) }, |
1223 | { }, | ||
1213 | }; | 1224 | }; |
1214 | 1225 | ||
1215 | MODULE_DEVICE_TABLE(pci, pasemi_mac_pci_tbl); | 1226 | MODULE_DEVICE_TABLE(pci, pasemi_mac_pci_tbl); |