diff options
Diffstat (limited to 'drivers/net/pasemi_mac.c')
-rw-r--r-- | drivers/net/pasemi_mac.c | 132 |
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 | ||
84 | static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg) | 84 | static 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 | ||
92 | static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg, | 89 | static 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 | ||
98 | static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg) | 95 | static 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 | ||
106 | static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg, | 100 | static 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 | ||
112 | static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg) | 106 | static 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 | ||
120 | static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg, | 111 | static 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 | ||
126 | static int pasemi_get_mac_addr(struct pasemi_mac *mac) | 117 | static 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 | ||
1064 | static 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; | ||
1078 | fallback: | ||
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 | |||
1086 | static 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 | |||
1074 | static int __devinit | 1131 | static int __devinit |
1075 | pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 1132 | pasemi_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 | ||
1191 | out: | 1230 | out: |
1192 | pci_dev_put(mac->iob_pdev); | 1231 | if (mac->iob_pdev) |
1193 | out_put_dma_pdev: | 1232 | pci_dev_put(mac->iob_pdev); |
1194 | pci_dev_put(mac->dma_pdev); | 1233 | if (mac->dma_pdev) |
1195 | out_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); |
1197 | out_disable_device: | 1243 | out_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 | } |