aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMatthias Fuchs <matthias.fuchs@esd.eu>2010-04-06 21:09:56 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-13 04:23:26 -0400
commit82e381775f6da6b29ae625e73a2ea18844eb4825 (patch)
tree365f8d81cbabada143734883b42e2ace938ceeb1 /drivers/net
parent2e8e18ef52e7dd1af0a3bd1f7d990a1d0b249586 (diff)
can: Add esd board support to plx_pci CAN driver
This patch adds support for SJA1000 based PCI CAN interface cards from electronic system design gmbh. Some changes have been done on the common code: - esd boards must not have the 2nd local interupt enabled (PLX9030/9050) - a new path for PLX9056/PEX8311 chips has been added - new plx9056 reset function has been implemented - struct plx_card_info got a reset function entry In detail the following additional boards are now supported: CAN-PCI/200 (PCI) CAN-PCI/266 (PCI) CAN-PMC266 (PMC module) CAN-PCIe/2000 (PCI Express) CAN-CPCI/200 (Compact PCI, 3U) CAN-PCI104 (PCI104) Signed-off-by: Matthias Fuchs <matthias.fuchs@esd.eu> Acked-by: Wolfgang Grandegger <wg@grandegger.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/can/sja1000/Kconfig4
-rw-r--r--drivers/net/can/sja1000/plx_pci.c153
2 files changed, 145 insertions, 12 deletions
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
index 9e277d64a318..ae3505afd682 100644
--- a/drivers/net/can/sja1000/Kconfig
+++ b/drivers/net/can/sja1000/Kconfig
@@ -53,7 +53,9 @@ config CAN_PLX_PCI
53 Driver supports now: 53 Driver supports now:
54 - Adlink PCI-7841/cPCI-7841 card (http://www.adlinktech.com/) 54 - Adlink PCI-7841/cPCI-7841 card (http://www.adlinktech.com/)
55 - Adlink PCI-7841/cPCI-7841 SE card 55 - Adlink PCI-7841/cPCI-7841 SE card
56 - esd CAN-PCI/CPCI/PCI104/200 (http://www.esd.eu/)
57 - esd CAN-PCI/PMC/266
58 - esd CAN-PCIe/2000
56 - Marathon CAN-bus-PCI card (http://www.marathon.ru/) 59 - Marathon CAN-bus-PCI card (http://www.marathon.ru/)
57 - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/) 60 - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
58
59endif 61endif
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
index 4aff4070db96..d5efd68085fd 100644
--- a/drivers/net/can/sja1000/plx_pci.c
+++ b/drivers/net/can/sja1000/plx_pci.c
@@ -41,7 +41,10 @@ MODULE_DESCRIPTION("Socket-CAN driver for PLX90xx PCI-bridge cards with "
41MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, " 41MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, "
42 "Adlink PCI-7841/cPCI-7841 SE, " 42 "Adlink PCI-7841/cPCI-7841 SE, "
43 "Marathon CAN-bus-PCI, " 43 "Marathon CAN-bus-PCI, "
44 "TEWS TECHNOLOGIES TPMC810"); 44 "TEWS TECHNOLOGIES TPMC810, "
45 "esd CAN-PCI/CPCI/PCI104/200, "
46 "esd CAN-PCI/PMC/266, "
47 "esd CAN-PCIe/2000")
45MODULE_LICENSE("GPL v2"); 48MODULE_LICENSE("GPL v2");
46 49
47#define PLX_PCI_MAX_CHAN 2 50#define PLX_PCI_MAX_CHAN 2
@@ -50,11 +53,14 @@ struct plx_pci_card {
50 int channels; /* detected channels count */ 53 int channels; /* detected channels count */
51 struct net_device *net_dev[PLX_PCI_MAX_CHAN]; 54 struct net_device *net_dev[PLX_PCI_MAX_CHAN];
52 void __iomem *conf_addr; 55 void __iomem *conf_addr;
56
57 /* Pointer to device-dependent reset function */
58 void (*reset_func)(struct pci_dev *pdev);
53}; 59};
54 60
55#define PLX_PCI_CAN_CLOCK (16000000 / 2) 61#define PLX_PCI_CAN_CLOCK (16000000 / 2)
56 62
57/* PLX90xx registers */ 63/* PLX9030/9050/9052 registers */
58#define PLX_INTCSR 0x4c /* Interrupt Control/Status */ 64#define PLX_INTCSR 0x4c /* Interrupt Control/Status */
59#define PLX_CNTRL 0x50 /* User I/O, Direct Slave Response, 65#define PLX_CNTRL 0x50 /* User I/O, Direct Slave Response,
60 * Serial EEPROM, and Initialization 66 * Serial EEPROM, and Initialization
@@ -66,6 +72,14 @@ struct plx_pci_card {
66#define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */ 72#define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */
67#define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */ 73#define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */
68 74
75/* PLX9056 registers */
76#define PLX9056_INTCSR 0x68 /* Interrupt Control/Status */
77#define PLX9056_CNTRL 0x6c /* Control / Software Reset */
78
79#define PLX9056_LINTI (1 << 11)
80#define PLX9056_PCI_INT_EN (1 << 8)
81#define PLX9056_PCI_RCR (1 << 29) /* Read Configuration Registers */
82
69/* 83/*
70 * The board configuration is probably following: 84 * The board configuration is probably following:
71 * RX1 is connected to ground. 85 * RX1 is connected to ground.
@@ -101,6 +115,13 @@ struct plx_pci_card {
101#define ADLINK_PCI_VENDOR_ID 0x144A 115#define ADLINK_PCI_VENDOR_ID 0x144A
102#define ADLINK_PCI_DEVICE_ID 0x7841 116#define ADLINK_PCI_DEVICE_ID 0x7841
103 117
118#define ESD_PCI_SUB_SYS_ID_PCI200 0x0004
119#define ESD_PCI_SUB_SYS_ID_PCI266 0x0009
120#define ESD_PCI_SUB_SYS_ID_PMC266 0x000e
121#define ESD_PCI_SUB_SYS_ID_CPCI200 0x010b
122#define ESD_PCI_SUB_SYS_ID_PCIE2000 0x0200
123#define ESD_PCI_SUB_SYS_ID_PCI104200 0x0501
124
104#define MARATHON_PCI_DEVICE_ID 0x2715 125#define MARATHON_PCI_DEVICE_ID 0x2715
105 126
106#define TEWS_PCI_VENDOR_ID 0x1498 127#define TEWS_PCI_VENDOR_ID 0x1498
@@ -108,6 +129,7 @@ struct plx_pci_card {
108 129
109static void plx_pci_reset_common(struct pci_dev *pdev); 130static void plx_pci_reset_common(struct pci_dev *pdev);
110static void plx_pci_reset_marathon(struct pci_dev *pdev); 131static void plx_pci_reset_marathon(struct pci_dev *pdev);
132static void plx9056_pci_reset_common(struct pci_dev *pdev);
111 133
112struct plx_pci_channel_map { 134struct plx_pci_channel_map {
113 u32 bar; 135 u32 bar;
@@ -148,6 +170,30 @@ static struct plx_pci_card_info plx_pci_card_info_adlink_se __devinitdata = {
148 /* based on PLX9052 */ 170 /* based on PLX9052 */
149}; 171};
150 172
173static struct plx_pci_card_info plx_pci_card_info_esd200 __devinitdata = {
174 "esd CAN-PCI/CPCI/PCI104/200", 2,
175 PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
176 {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} },
177 &plx_pci_reset_common
178 /* based on PLX9030/9050 */
179};
180
181static struct plx_pci_card_info plx_pci_card_info_esd266 __devinitdata = {
182 "esd CAN-PCI/PMC/266", 2,
183 PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
184 {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} },
185 &plx9056_pci_reset_common
186 /* based on PLX9056 */
187};
188
189static struct plx_pci_card_info plx_pci_card_info_esd2000 __devinitdata = {
190 "esd CAN-PCIe/2000", 2,
191 PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
192 {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} },
193 &plx9056_pci_reset_common
194 /* based on PEX8311 */
195};
196
151static struct plx_pci_card_info plx_pci_card_info_marathon __devinitdata = { 197static struct plx_pci_card_info plx_pci_card_info_marathon __devinitdata = {
152 "Marathon CAN-bus-PCI", 2, 198 "Marathon CAN-bus-PCI", 2,
153 PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, 199 PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
@@ -180,6 +226,48 @@ static DEFINE_PCI_DEVICE_TABLE(plx_pci_tbl) = {
180 (kernel_ulong_t)&plx_pci_card_info_adlink_se 226 (kernel_ulong_t)&plx_pci_card_info_adlink_se
181 }, 227 },
182 { 228 {
229 /* esd CAN-PCI/200 */
230 PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
231 PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI200,
232 0, 0,
233 (kernel_ulong_t)&plx_pci_card_info_esd200
234 },
235 {
236 /* esd CAN-CPCI/200 */
237 PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
238 PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_CPCI200,
239 0, 0,
240 (kernel_ulong_t)&plx_pci_card_info_esd200
241 },
242 {
243 /* esd CAN-PCI104/200 */
244 PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
245 PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI104200,
246 0, 0,
247 (kernel_ulong_t)&plx_pci_card_info_esd200
248 },
249 {
250 /* esd CAN-PCI/266 */
251 PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056,
252 PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI266,
253 0, 0,
254 (kernel_ulong_t)&plx_pci_card_info_esd266
255 },
256 {
257 /* esd CAN-PMC/266 */
258 PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056,
259 PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PMC266,
260 0, 0,
261 (kernel_ulong_t)&plx_pci_card_info_esd266
262 },
263 {
264 /* esd CAN-PCIE/2000 */
265 PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056,
266 PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCIE2000,
267 0, 0,
268 (kernel_ulong_t)&plx_pci_card_info_esd2000
269 },
270 {
183 /* Marathon CAN-bus-PCI card */ 271 /* Marathon CAN-bus-PCI card */
184 PCI_VENDOR_ID_PLX, MARATHON_PCI_DEVICE_ID, 272 PCI_VENDOR_ID_PLX, MARATHON_PCI_DEVICE_ID,
185 PCI_ANY_ID, PCI_ANY_ID, 273 PCI_ANY_ID, PCI_ANY_ID,
@@ -242,7 +330,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv)
242} 330}
243 331
244/* 332/*
245 * PLX90xx software reset 333 * PLX9030/50/52 software reset
246 * Also LRESET# asserts and brings to reset device on the Local Bus (if wired). 334 * Also LRESET# asserts and brings to reset device on the Local Bus (if wired).
247 * For most cards it's enough for reset the SJA1000 chips. 335 * For most cards it's enough for reset the SJA1000 chips.
248 */ 336 */
@@ -259,6 +347,38 @@ static void plx_pci_reset_common(struct pci_dev *pdev)
259 iowrite32(cntrl, card->conf_addr + PLX_CNTRL); 347 iowrite32(cntrl, card->conf_addr + PLX_CNTRL);
260}; 348};
261 349
350/*
351 * PLX9056 software reset
352 * Assert LRESET# and reset device(s) on the Local Bus (if wired).
353 */
354static void plx9056_pci_reset_common(struct pci_dev *pdev)
355{
356 struct plx_pci_card *card = pci_get_drvdata(pdev);
357 u32 cntrl;
358
359 /* issue a local bus reset */
360 cntrl = ioread32(card->conf_addr + PLX9056_CNTRL);
361 cntrl |= PLX_PCI_RESET;
362 iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL);
363 udelay(100);
364 cntrl ^= PLX_PCI_RESET;
365 iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL);
366
367 /* reload local configuration from EEPROM */
368 cntrl |= PLX9056_PCI_RCR;
369 iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL);
370
371 /*
372 * There is no safe way to poll for the end
373 * of reconfiguration process. Waiting for 10ms
374 * is safe.
375 */
376 mdelay(10);
377
378 cntrl ^= PLX9056_PCI_RCR;
379 iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL);
380};
381
262/* Special reset function for Marathon card */ 382/* Special reset function for Marathon card */
263static void plx_pci_reset_marathon(struct pci_dev *pdev) 383static void plx_pci_reset_marathon(struct pci_dev *pdev)
264{ 384{
@@ -302,13 +422,16 @@ static void plx_pci_del_card(struct pci_dev *pdev)
302 free_sja1000dev(dev); 422 free_sja1000dev(dev);
303 } 423 }
304 424
305 plx_pci_reset_common(pdev); 425 card->reset_func(pdev);
306 426
307 /* 427 /*
308 * Disable interrupts from PCI-card (PLX90xx) and disable Local_1, 428 * Disable interrupts from PCI-card and disable local
309 * Local_2 interrupts 429 * interrupts
310 */ 430 */
311 iowrite32(0x0, card->conf_addr + PLX_INTCSR); 431 if (pdev->device != PCI_DEVICE_ID_PLX_9056)
432 iowrite32(0x0, card->conf_addr + PLX_INTCSR);
433 else
434 iowrite32(0x0, card->conf_addr + PLX9056_INTCSR);
312 435
313 if (card->conf_addr) 436 if (card->conf_addr)
314 pci_iounmap(pdev, card->conf_addr); 437 pci_iounmap(pdev, card->conf_addr);
@@ -367,6 +490,7 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev,
367 card->conf_addr = addr + ci->conf_map.offset; 490 card->conf_addr = addr + ci->conf_map.offset;
368 491
369 ci->reset_func(pdev); 492 ci->reset_func(pdev);
493 card->reset_func = ci->reset_func;
370 494
371 /* Detect available channels */ 495 /* Detect available channels */
372 for (i = 0; i < ci->channel_count; i++) { 496 for (i = 0; i < ci->channel_count; i++) {
@@ -438,10 +562,17 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev,
438 * Enable interrupts from PCI-card (PLX90xx) and enable Local_1, 562 * Enable interrupts from PCI-card (PLX90xx) and enable Local_1,
439 * Local_2 interrupts from the SJA1000 chips 563 * Local_2 interrupts from the SJA1000 chips
440 */ 564 */
441 val = ioread32(card->conf_addr + PLX_INTCSR); 565 if (pdev->device != PCI_DEVICE_ID_PLX_9056) {
442 val |= PLX_LINT1_EN | PLX_LINT2_EN | PLX_PCI_INT_EN; 566 val = ioread32(card->conf_addr + PLX_INTCSR);
443 iowrite32(val, card->conf_addr + PLX_INTCSR); 567 if (pdev->subsystem_vendor == PCI_VENDOR_ID_ESDGMBH)
444 568 val |= PLX_LINT1_EN | PLX_PCI_INT_EN;
569 else
570 val |= PLX_LINT1_EN | PLX_LINT2_EN | PLX_PCI_INT_EN;
571 iowrite32(val, card->conf_addr + PLX_INTCSR);
572 } else {
573 iowrite32(PLX9056_LINTI | PLX9056_PCI_INT_EN,
574 card->conf_addr + PLX9056_INTCSR);
575 }
445 return 0; 576 return 0;
446 577
447failure_cleanup: 578failure_cleanup: