aboutsummaryrefslogtreecommitdiffstats
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.c132
1 files changed, 91 insertions, 41 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index c3a0fc64de0c..be311e9404b4 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -83,44 +83,35 @@ static struct pasdma_status *dma_status;
83 83
84static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg) 84static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
85{ 85{
86 unsigned int val; 86 return in_le32(mac->iob_regs+reg);
87
88 pci_read_config_dword(mac->iob_pdev, reg, &val);
89 return val;
90} 87}
91 88
92static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg, 89static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
93 unsigned int val) 90 unsigned int val)
94{ 91{
95 pci_write_config_dword(mac->iob_pdev, reg, val); 92 out_le32(mac->iob_regs+reg, val);
96} 93}
97 94
98static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg) 95static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg)
99{ 96{
100 unsigned int val; 97 return in_le32(mac->regs+reg);
101
102 pci_read_config_dword(mac->pdev, reg, &val);
103 return val;
104} 98}
105 99
106static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg, 100static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg,
107 unsigned int val) 101 unsigned int val)
108{ 102{
109 pci_write_config_dword(mac->pdev, reg, val); 103 out_le32(mac->regs+reg, val);
110} 104}
111 105
112static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg) 106static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg)
113{ 107{
114 unsigned int val; 108 return in_le32(mac->dma_regs+reg);
115
116 pci_read_config_dword(mac->dma_pdev, reg, &val);
117 return val;
118} 109}
119 110
120static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg, 111static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg,
121 unsigned int val) 112 unsigned int val)
122{ 113{
123 pci_write_config_dword(mac->dma_pdev, reg, val); 114 out_le32(mac->dma_regs+reg, val);
124} 115}
125 116
126static int pasemi_get_mac_addr(struct pasemi_mac *mac) 117static int pasemi_get_mac_addr(struct pasemi_mac *mac)
@@ -585,7 +576,6 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
585 } 576 }
586 mac->tx->next_to_clean += count; 577 mac->tx->next_to_clean += count;
587 spin_unlock_irqrestore(&mac->tx->lock, flags); 578 spin_unlock_irqrestore(&mac->tx->lock, flags);
588
589 netif_wake_queue(mac->netdev); 579 netif_wake_queue(mac->netdev);
590 580
591 return count; 581 return count;
@@ -1071,6 +1061,73 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget)
1071 return pkts; 1061 return pkts;
1072} 1062}
1073 1063
1064static void __iomem * __devinit map_onedev(struct pci_dev *p, int index)
1065{
1066 struct device_node *dn;
1067 void __iomem *ret;
1068
1069 dn = pci_device_to_OF_node(p);
1070 if (!dn)
1071 goto fallback;
1072
1073 ret = of_iomap(dn, index);
1074 if (!ret)
1075 goto fallback;
1076
1077 return ret;
1078fallback:
1079 /* This is hardcoded and ugly, but we have some firmware versions
1080 * that don't provide the register space in the device tree. Luckily
1081 * they are at well-known locations so we can just do the math here.
1082 */
1083 return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
1084}
1085
1086static int __devinit pasemi_mac_map_regs(struct pasemi_mac *mac)
1087{
1088 struct resource res;
1089 struct device_node *dn;
1090 int err;
1091
1092 mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
1093 if (!mac->dma_pdev) {
1094 dev_err(&mac->pdev->dev, "Can't find DMA Controller\n");
1095 return -ENODEV;
1096 }
1097
1098 mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
1099 if (!mac->iob_pdev) {
1100 dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n");
1101 return -ENODEV;
1102 }
1103
1104 mac->regs = map_onedev(mac->pdev, 0);
1105 mac->dma_regs = map_onedev(mac->dma_pdev, 0);
1106 mac->iob_regs = map_onedev(mac->iob_pdev, 0);
1107
1108 if (!mac->regs || !mac->dma_regs || !mac->iob_regs) {
1109 dev_err(&mac->pdev->dev, "Can't map registers\n");
1110 return -ENODEV;
1111 }
1112
1113 /* The dma status structure is located in the I/O bridge, and
1114 * is cache coherent.
1115 */
1116 if (!dma_status) {
1117 dn = pci_device_to_OF_node(mac->iob_pdev);
1118 if (dn)
1119 err = of_address_to_resource(dn, 1, &res);
1120 if (!dn || err) {
1121 /* Fallback for old firmware */
1122 res.start = 0xfd800000;
1123 res.end = res.start + 0x1000;
1124 }
1125 dma_status = __ioremap(res.start, res.end-res.start, 0);
1126 }
1127
1128 return 0;
1129}
1130
1074static int __devinit 1131static int __devinit
1075pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 1132pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1076{ 1133{
@@ -1099,26 +1156,11 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1099 1156
1100 mac->pdev = pdev; 1157 mac->pdev = pdev;
1101 mac->netdev = dev; 1158 mac->netdev = dev;
1102 mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
1103 1159
1104 netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64); 1160 netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);
1105 1161
1106 dev->features = NETIF_F_HW_CSUM; 1162 dev->features = NETIF_F_HW_CSUM;
1107 1163
1108 if (!mac->dma_pdev) {
1109 dev_err(&pdev->dev, "Can't find DMA Controller\n");
1110 err = -ENODEV;
1111 goto out_free_netdev;
1112 }
1113
1114 mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
1115
1116 if (!mac->iob_pdev) {
1117 dev_err(&pdev->dev, "Can't find I/O Bridge\n");
1118 err = -ENODEV;
1119 goto out_put_dma_pdev;
1120 }
1121
1122 /* These should come out of the device tree eventually */ 1164 /* These should come out of the device tree eventually */
1123 mac->dma_txch = index; 1165 mac->dma_txch = index;
1124 mac->dma_rxch = index; 1166 mac->dma_rxch = index;
@@ -1157,12 +1199,9 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1157 dev->get_stats = pasemi_mac_get_stats; 1199 dev->get_stats = pasemi_mac_get_stats;
1158 dev->set_multicast_list = pasemi_mac_set_rx_mode; 1200 dev->set_multicast_list = pasemi_mac_set_rx_mode;
1159 1201
1160 /* The dma status structure is located in the I/O bridge, and 1202 err = pasemi_mac_map_regs(mac);
1161 * is cache coherent. 1203 if (err)
1162 */ 1204 goto out;
1163 if (!dma_status)
1164 /* XXXOJN This should come from the device tree */
1165 dma_status = __ioremap(0xfd800000, 0x1000, 0);
1166 1205
1167 mac->rx_status = &dma_status->rx_sta[mac->dma_rxch]; 1206 mac->rx_status = &dma_status->rx_sta[mac->dma_rxch];
1168 mac->tx_status = &dma_status->tx_sta[mac->dma_txch]; 1207 mac->tx_status = &dma_status->tx_sta[mac->dma_txch];
@@ -1189,10 +1228,17 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1189 return err; 1228 return err;
1190 1229
1191out: 1230out:
1192 pci_dev_put(mac->iob_pdev); 1231 if (mac->iob_pdev)
1193out_put_dma_pdev: 1232 pci_dev_put(mac->iob_pdev);
1194 pci_dev_put(mac->dma_pdev); 1233 if (mac->dma_pdev)
1195out_free_netdev: 1234 pci_dev_put(mac->dma_pdev);
1235 if (mac->dma_regs)
1236 iounmap(mac->dma_regs);
1237 if (mac->iob_regs)
1238 iounmap(mac->iob_regs);
1239 if (mac->regs)
1240 iounmap(mac->regs);
1241
1196 free_netdev(dev); 1242 free_netdev(dev);
1197out_disable_device: 1243out_disable_device:
1198 pci_disable_device(pdev); 1244 pci_disable_device(pdev);
@@ -1216,6 +1262,10 @@ static void __devexit pasemi_mac_remove(struct pci_dev *pdev)
1216 pci_dev_put(mac->dma_pdev); 1262 pci_dev_put(mac->dma_pdev);
1217 pci_dev_put(mac->iob_pdev); 1263 pci_dev_put(mac->iob_pdev);
1218 1264
1265 iounmap(mac->regs);
1266 iounmap(mac->dma_regs);
1267 iounmap(mac->iob_regs);
1268
1219 pci_set_drvdata(pdev, NULL); 1269 pci_set_drvdata(pdev, NULL);
1220 free_netdev(netdev); 1270 free_netdev(netdev);
1221} 1271}