diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/can/pch_can.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/can/pch_can.c')
-rw-r--r-- | drivers/net/can/pch_can.c | 1290 |
1 files changed, 1290 insertions, 0 deletions
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c new file mode 100644 index 000000000000..d11fbb2b95ff --- /dev/null +++ b/drivers/net/can/pch_can.c | |||
@@ -0,0 +1,1290 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1999 - 2010 Intel Corporation. | ||
3 | * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/netdevice.h> | ||
30 | #include <linux/skbuff.h> | ||
31 | #include <linux/can.h> | ||
32 | #include <linux/can/dev.h> | ||
33 | #include <linux/can/error.h> | ||
34 | |||
35 | #define PCH_CTRL_INIT BIT(0) /* The INIT bit of CANCONT register. */ | ||
36 | #define PCH_CTRL_IE BIT(1) /* The IE bit of CAN control register */ | ||
37 | #define PCH_CTRL_IE_SIE_EIE (BIT(3) | BIT(2) | BIT(1)) | ||
38 | #define PCH_CTRL_CCE BIT(6) | ||
39 | #define PCH_CTRL_OPT BIT(7) /* The OPT bit of CANCONT register. */ | ||
40 | #define PCH_OPT_SILENT BIT(3) /* The Silent bit of CANOPT reg. */ | ||
41 | #define PCH_OPT_LBACK BIT(4) /* The LoopBack bit of CANOPT reg. */ | ||
42 | |||
43 | #define PCH_CMASK_RX_TX_SET 0x00f3 | ||
44 | #define PCH_CMASK_RX_TX_GET 0x0073 | ||
45 | #define PCH_CMASK_ALL 0xff | ||
46 | #define PCH_CMASK_NEWDAT BIT(2) | ||
47 | #define PCH_CMASK_CLRINTPND BIT(3) | ||
48 | #define PCH_CMASK_CTRL BIT(4) | ||
49 | #define PCH_CMASK_ARB BIT(5) | ||
50 | #define PCH_CMASK_MASK BIT(6) | ||
51 | #define PCH_CMASK_RDWR BIT(7) | ||
52 | #define PCH_IF_MCONT_NEWDAT BIT(15) | ||
53 | #define PCH_IF_MCONT_MSGLOST BIT(14) | ||
54 | #define PCH_IF_MCONT_INTPND BIT(13) | ||
55 | #define PCH_IF_MCONT_UMASK BIT(12) | ||
56 | #define PCH_IF_MCONT_TXIE BIT(11) | ||
57 | #define PCH_IF_MCONT_RXIE BIT(10) | ||
58 | #define PCH_IF_MCONT_RMTEN BIT(9) | ||
59 | #define PCH_IF_MCONT_TXRQXT BIT(8) | ||
60 | #define PCH_IF_MCONT_EOB BIT(7) | ||
61 | #define PCH_IF_MCONT_DLC (BIT(0) | BIT(1) | BIT(2) | BIT(3)) | ||
62 | #define PCH_MASK2_MDIR_MXTD (BIT(14) | BIT(15)) | ||
63 | #define PCH_ID2_DIR BIT(13) | ||
64 | #define PCH_ID2_XTD BIT(14) | ||
65 | #define PCH_ID_MSGVAL BIT(15) | ||
66 | #define PCH_IF_CREQ_BUSY BIT(15) | ||
67 | |||
68 | #define PCH_STATUS_INT 0x8000 | ||
69 | #define PCH_REC 0x00007f00 | ||
70 | #define PCH_TEC 0x000000ff | ||
71 | |||
72 | #define PCH_TX_OK BIT(3) | ||
73 | #define PCH_RX_OK BIT(4) | ||
74 | #define PCH_EPASSIV BIT(5) | ||
75 | #define PCH_EWARN BIT(6) | ||
76 | #define PCH_BUS_OFF BIT(7) | ||
77 | |||
78 | /* bit position of certain controller bits. */ | ||
79 | #define PCH_BIT_BRP_SHIFT 0 | ||
80 | #define PCH_BIT_SJW_SHIFT 6 | ||
81 | #define PCH_BIT_TSEG1_SHIFT 8 | ||
82 | #define PCH_BIT_TSEG2_SHIFT 12 | ||
83 | #define PCH_BIT_BRPE_BRPE_SHIFT 6 | ||
84 | |||
85 | #define PCH_MSK_BITT_BRP 0x3f | ||
86 | #define PCH_MSK_BRPE_BRPE 0x3c0 | ||
87 | #define PCH_MSK_CTRL_IE_SIE_EIE 0x07 | ||
88 | #define PCH_COUNTER_LIMIT 10 | ||
89 | |||
90 | #define PCH_CAN_CLK 50000000 /* 50MHz */ | ||
91 | |||
92 | /* | ||
93 | * Define the number of message object. | ||
94 | * PCH CAN communications are done via Message RAM. | ||
95 | * The Message RAM consists of 32 message objects. | ||
96 | */ | ||
97 | #define PCH_RX_OBJ_NUM 26 | ||
98 | #define PCH_TX_OBJ_NUM 6 | ||
99 | #define PCH_RX_OBJ_START 1 | ||
100 | #define PCH_RX_OBJ_END PCH_RX_OBJ_NUM | ||
101 | #define PCH_TX_OBJ_START (PCH_RX_OBJ_END + 1) | ||
102 | #define PCH_TX_OBJ_END (PCH_RX_OBJ_NUM + PCH_TX_OBJ_NUM) | ||
103 | |||
104 | #define PCH_FIFO_THRESH 16 | ||
105 | |||
106 | /* TxRqst2 show status of MsgObjNo.17~32 */ | ||
107 | #define PCH_TREQ2_TX_MASK (((1 << PCH_TX_OBJ_NUM) - 1) <<\ | ||
108 | (PCH_RX_OBJ_END - 16)) | ||
109 | |||
110 | enum pch_ifreg { | ||
111 | PCH_RX_IFREG, | ||
112 | PCH_TX_IFREG, | ||
113 | }; | ||
114 | |||
115 | enum pch_can_err { | ||
116 | PCH_STUF_ERR = 1, | ||
117 | PCH_FORM_ERR, | ||
118 | PCH_ACK_ERR, | ||
119 | PCH_BIT1_ERR, | ||
120 | PCH_BIT0_ERR, | ||
121 | PCH_CRC_ERR, | ||
122 | PCH_LEC_ALL, | ||
123 | }; | ||
124 | |||
125 | enum pch_can_mode { | ||
126 | PCH_CAN_ENABLE, | ||
127 | PCH_CAN_DISABLE, | ||
128 | PCH_CAN_ALL, | ||
129 | PCH_CAN_NONE, | ||
130 | PCH_CAN_STOP, | ||
131 | PCH_CAN_RUN, | ||
132 | }; | ||
133 | |||
134 | struct pch_can_if_regs { | ||
135 | u32 creq; | ||
136 | u32 cmask; | ||
137 | u32 mask1; | ||
138 | u32 mask2; | ||
139 | u32 id1; | ||
140 | u32 id2; | ||
141 | u32 mcont; | ||
142 | u32 data[4]; | ||
143 | u32 rsv[13]; | ||
144 | }; | ||
145 | |||
146 | struct pch_can_regs { | ||
147 | u32 cont; | ||
148 | u32 stat; | ||
149 | u32 errc; | ||
150 | u32 bitt; | ||
151 | u32 intr; | ||
152 | u32 opt; | ||
153 | u32 brpe; | ||
154 | u32 reserve; | ||
155 | struct pch_can_if_regs ifregs[2]; /* [0]=if1 [1]=if2 */ | ||
156 | u32 reserve1[8]; | ||
157 | u32 treq1; | ||
158 | u32 treq2; | ||
159 | u32 reserve2[6]; | ||
160 | u32 data1; | ||
161 | u32 data2; | ||
162 | u32 reserve3[6]; | ||
163 | u32 canipend1; | ||
164 | u32 canipend2; | ||
165 | u32 reserve4[6]; | ||
166 | u32 canmval1; | ||
167 | u32 canmval2; | ||
168 | u32 reserve5[37]; | ||
169 | u32 srst; | ||
170 | }; | ||
171 | |||
172 | struct pch_can_priv { | ||
173 | struct can_priv can; | ||
174 | struct pci_dev *dev; | ||
175 | u32 tx_enable[PCH_TX_OBJ_END]; | ||
176 | u32 rx_enable[PCH_TX_OBJ_END]; | ||
177 | u32 rx_link[PCH_TX_OBJ_END]; | ||
178 | u32 int_enables; | ||
179 | struct net_device *ndev; | ||
180 | struct pch_can_regs __iomem *regs; | ||
181 | struct napi_struct napi; | ||
182 | int tx_obj; /* Point next Tx Obj index */ | ||
183 | int use_msi; | ||
184 | }; | ||
185 | |||
186 | static struct can_bittiming_const pch_can_bittiming_const = { | ||
187 | .name = KBUILD_MODNAME, | ||
188 | .tseg1_min = 2, | ||
189 | .tseg1_max = 16, | ||
190 | .tseg2_min = 1, | ||
191 | .tseg2_max = 8, | ||
192 | .sjw_max = 4, | ||
193 | .brp_min = 1, | ||
194 | .brp_max = 1024, /* 6bit + extended 4bit */ | ||
195 | .brp_inc = 1, | ||
196 | }; | ||
197 | |||
198 | static DEFINE_PCI_DEVICE_TABLE(pch_pci_tbl) = { | ||
199 | {PCI_VENDOR_ID_INTEL, 0x8818, PCI_ANY_ID, PCI_ANY_ID,}, | ||
200 | {0,} | ||
201 | }; | ||
202 | MODULE_DEVICE_TABLE(pci, pch_pci_tbl); | ||
203 | |||
204 | static inline void pch_can_bit_set(void __iomem *addr, u32 mask) | ||
205 | { | ||
206 | iowrite32(ioread32(addr) | mask, addr); | ||
207 | } | ||
208 | |||
209 | static inline void pch_can_bit_clear(void __iomem *addr, u32 mask) | ||
210 | { | ||
211 | iowrite32(ioread32(addr) & ~mask, addr); | ||
212 | } | ||
213 | |||
214 | static void pch_can_set_run_mode(struct pch_can_priv *priv, | ||
215 | enum pch_can_mode mode) | ||
216 | { | ||
217 | switch (mode) { | ||
218 | case PCH_CAN_RUN: | ||
219 | pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_INIT); | ||
220 | break; | ||
221 | |||
222 | case PCH_CAN_STOP: | ||
223 | pch_can_bit_set(&priv->regs->cont, PCH_CTRL_INIT); | ||
224 | break; | ||
225 | |||
226 | default: | ||
227 | netdev_err(priv->ndev, "%s -> Invalid Mode.\n", __func__); | ||
228 | break; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | static void pch_can_set_optmode(struct pch_can_priv *priv) | ||
233 | { | ||
234 | u32 reg_val = ioread32(&priv->regs->opt); | ||
235 | |||
236 | if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) | ||
237 | reg_val |= PCH_OPT_SILENT; | ||
238 | |||
239 | if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) | ||
240 | reg_val |= PCH_OPT_LBACK; | ||
241 | |||
242 | pch_can_bit_set(&priv->regs->cont, PCH_CTRL_OPT); | ||
243 | iowrite32(reg_val, &priv->regs->opt); | ||
244 | } | ||
245 | |||
246 | static void pch_can_rw_msg_obj(void __iomem *creq_addr, u32 num) | ||
247 | { | ||
248 | int counter = PCH_COUNTER_LIMIT; | ||
249 | u32 ifx_creq; | ||
250 | |||
251 | iowrite32(num, creq_addr); | ||
252 | while (counter) { | ||
253 | ifx_creq = ioread32(creq_addr) & PCH_IF_CREQ_BUSY; | ||
254 | if (!ifx_creq) | ||
255 | break; | ||
256 | counter--; | ||
257 | udelay(1); | ||
258 | } | ||
259 | if (!counter) | ||
260 | pr_err("%s:IF1 BUSY Flag is set forever.\n", __func__); | ||
261 | } | ||
262 | |||
263 | static void pch_can_set_int_enables(struct pch_can_priv *priv, | ||
264 | enum pch_can_mode interrupt_no) | ||
265 | { | ||
266 | switch (interrupt_no) { | ||
267 | case PCH_CAN_DISABLE: | ||
268 | pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE); | ||
269 | break; | ||
270 | |||
271 | case PCH_CAN_ALL: | ||
272 | pch_can_bit_set(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); | ||
273 | break; | ||
274 | |||
275 | case PCH_CAN_NONE: | ||
276 | pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); | ||
277 | break; | ||
278 | |||
279 | default: | ||
280 | netdev_err(priv->ndev, "Invalid interrupt number.\n"); | ||
281 | break; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num, | ||
286 | int set, enum pch_ifreg dir) | ||
287 | { | ||
288 | u32 ie; | ||
289 | |||
290 | if (dir) | ||
291 | ie = PCH_IF_MCONT_TXIE; | ||
292 | else | ||
293 | ie = PCH_IF_MCONT_RXIE; | ||
294 | |||
295 | /* Reading the Msg buffer from Message RAM to IF1/2 registers. */ | ||
296 | iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); | ||
297 | pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num); | ||
298 | |||
299 | /* Setting the IF1/2MASK1 register to access MsgVal and RxIE bits */ | ||
300 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL, | ||
301 | &priv->regs->ifregs[dir].cmask); | ||
302 | |||
303 | if (set) { | ||
304 | /* Setting the MsgVal and RxIE/TxIE bits */ | ||
305 | pch_can_bit_set(&priv->regs->ifregs[dir].mcont, ie); | ||
306 | pch_can_bit_set(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL); | ||
307 | } else { | ||
308 | /* Clearing the MsgVal and RxIE/TxIE bits */ | ||
309 | pch_can_bit_clear(&priv->regs->ifregs[dir].mcont, ie); | ||
310 | pch_can_bit_clear(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL); | ||
311 | } | ||
312 | |||
313 | pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num); | ||
314 | } | ||
315 | |||
316 | static void pch_can_set_rx_all(struct pch_can_priv *priv, int set) | ||
317 | { | ||
318 | int i; | ||
319 | |||
320 | /* Traversing to obtain the object configured as receivers. */ | ||
321 | for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) | ||
322 | pch_can_set_rxtx(priv, i, set, PCH_RX_IFREG); | ||
323 | } | ||
324 | |||
325 | static void pch_can_set_tx_all(struct pch_can_priv *priv, int set) | ||
326 | { | ||
327 | int i; | ||
328 | |||
329 | /* Traversing to obtain the object configured as transmit object. */ | ||
330 | for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) | ||
331 | pch_can_set_rxtx(priv, i, set, PCH_TX_IFREG); | ||
332 | } | ||
333 | |||
334 | static u32 pch_can_int_pending(struct pch_can_priv *priv) | ||
335 | { | ||
336 | return ioread32(&priv->regs->intr) & 0xffff; | ||
337 | } | ||
338 | |||
339 | static void pch_can_clear_if_buffers(struct pch_can_priv *priv) | ||
340 | { | ||
341 | int i; /* Msg Obj ID (1~32) */ | ||
342 | |||
343 | for (i = PCH_RX_OBJ_START; i <= PCH_TX_OBJ_END; i++) { | ||
344 | iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[0].cmask); | ||
345 | iowrite32(0xffff, &priv->regs->ifregs[0].mask1); | ||
346 | iowrite32(0xffff, &priv->regs->ifregs[0].mask2); | ||
347 | iowrite32(0x0, &priv->regs->ifregs[0].id1); | ||
348 | iowrite32(0x0, &priv->regs->ifregs[0].id2); | ||
349 | iowrite32(0x0, &priv->regs->ifregs[0].mcont); | ||
350 | iowrite32(0x0, &priv->regs->ifregs[0].data[0]); | ||
351 | iowrite32(0x0, &priv->regs->ifregs[0].data[1]); | ||
352 | iowrite32(0x0, &priv->regs->ifregs[0].data[2]); | ||
353 | iowrite32(0x0, &priv->regs->ifregs[0].data[3]); | ||
354 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | | ||
355 | PCH_CMASK_ARB | PCH_CMASK_CTRL, | ||
356 | &priv->regs->ifregs[0].cmask); | ||
357 | pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i); | ||
358 | } | ||
359 | } | ||
360 | |||
361 | static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) | ||
362 | { | ||
363 | int i; | ||
364 | |||
365 | for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { | ||
366 | iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); | ||
367 | pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i); | ||
368 | |||
369 | iowrite32(0x0, &priv->regs->ifregs[0].id1); | ||
370 | iowrite32(0x0, &priv->regs->ifregs[0].id2); | ||
371 | |||
372 | pch_can_bit_set(&priv->regs->ifregs[0].mcont, | ||
373 | PCH_IF_MCONT_UMASK); | ||
374 | |||
375 | /* In case FIFO mode, Last EoB of Rx Obj must be 1 */ | ||
376 | if (i == PCH_RX_OBJ_END) | ||
377 | pch_can_bit_set(&priv->regs->ifregs[0].mcont, | ||
378 | PCH_IF_MCONT_EOB); | ||
379 | else | ||
380 | pch_can_bit_clear(&priv->regs->ifregs[0].mcont, | ||
381 | PCH_IF_MCONT_EOB); | ||
382 | |||
383 | iowrite32(0, &priv->regs->ifregs[0].mask1); | ||
384 | pch_can_bit_clear(&priv->regs->ifregs[0].mask2, | ||
385 | 0x1fff | PCH_MASK2_MDIR_MXTD); | ||
386 | |||
387 | /* Setting CMASK for writing */ | ||
388 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | | ||
389 | PCH_CMASK_CTRL, &priv->regs->ifregs[0].cmask); | ||
390 | |||
391 | pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i); | ||
392 | } | ||
393 | |||
394 | for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) { | ||
395 | iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask); | ||
396 | pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, i); | ||
397 | |||
398 | /* Resetting DIR bit for reception */ | ||
399 | iowrite32(0x0, &priv->regs->ifregs[1].id1); | ||
400 | iowrite32(PCH_ID2_DIR, &priv->regs->ifregs[1].id2); | ||
401 | |||
402 | /* Setting EOB bit for transmitter */ | ||
403 | iowrite32(PCH_IF_MCONT_EOB | PCH_IF_MCONT_UMASK, | ||
404 | &priv->regs->ifregs[1].mcont); | ||
405 | |||
406 | iowrite32(0, &priv->regs->ifregs[1].mask1); | ||
407 | pch_can_bit_clear(&priv->regs->ifregs[1].mask2, 0x1fff); | ||
408 | |||
409 | /* Setting CMASK for writing */ | ||
410 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB | | ||
411 | PCH_CMASK_CTRL, &priv->regs->ifregs[1].cmask); | ||
412 | |||
413 | pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, i); | ||
414 | } | ||
415 | } | ||
416 | |||
417 | static void pch_can_init(struct pch_can_priv *priv) | ||
418 | { | ||
419 | /* Stopping the Can device. */ | ||
420 | pch_can_set_run_mode(priv, PCH_CAN_STOP); | ||
421 | |||
422 | /* Clearing all the message object buffers. */ | ||
423 | pch_can_clear_if_buffers(priv); | ||
424 | |||
425 | /* Configuring the respective message object as either rx/tx object. */ | ||
426 | pch_can_config_rx_tx_buffers(priv); | ||
427 | |||
428 | /* Enabling the interrupts. */ | ||
429 | pch_can_set_int_enables(priv, PCH_CAN_ALL); | ||
430 | } | ||
431 | |||
432 | static void pch_can_release(struct pch_can_priv *priv) | ||
433 | { | ||
434 | /* Stooping the CAN device. */ | ||
435 | pch_can_set_run_mode(priv, PCH_CAN_STOP); | ||
436 | |||
437 | /* Disabling the interrupts. */ | ||
438 | pch_can_set_int_enables(priv, PCH_CAN_NONE); | ||
439 | |||
440 | /* Disabling all the receive object. */ | ||
441 | pch_can_set_rx_all(priv, 0); | ||
442 | |||
443 | /* Disabling all the transmit object. */ | ||
444 | pch_can_set_tx_all(priv, 0); | ||
445 | } | ||
446 | |||
447 | /* This function clears interrupt(s) from the CAN device. */ | ||
448 | static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) | ||
449 | { | ||
450 | /* Clear interrupt for transmit object */ | ||
451 | if ((mask >= PCH_RX_OBJ_START) && (mask <= PCH_RX_OBJ_END)) { | ||
452 | /* Setting CMASK for clearing the reception interrupts. */ | ||
453 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, | ||
454 | &priv->regs->ifregs[0].cmask); | ||
455 | |||
456 | /* Clearing the Dir bit. */ | ||
457 | pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR); | ||
458 | |||
459 | /* Clearing NewDat & IntPnd */ | ||
460 | pch_can_bit_clear(&priv->regs->ifregs[0].mcont, | ||
461 | PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND); | ||
462 | |||
463 | pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, mask); | ||
464 | } else if ((mask >= PCH_TX_OBJ_START) && (mask <= PCH_TX_OBJ_END)) { | ||
465 | /* | ||
466 | * Setting CMASK for clearing interrupts for frame transmission. | ||
467 | */ | ||
468 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, | ||
469 | &priv->regs->ifregs[1].cmask); | ||
470 | |||
471 | /* Resetting the ID registers. */ | ||
472 | pch_can_bit_set(&priv->regs->ifregs[1].id2, | ||
473 | PCH_ID2_DIR | (0x7ff << 2)); | ||
474 | iowrite32(0x0, &priv->regs->ifregs[1].id1); | ||
475 | |||
476 | /* Claring NewDat, TxRqst & IntPnd */ | ||
477 | pch_can_bit_clear(&priv->regs->ifregs[1].mcont, | ||
478 | PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND | | ||
479 | PCH_IF_MCONT_TXRQXT); | ||
480 | pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, mask); | ||
481 | } | ||
482 | } | ||
483 | |||
484 | static void pch_can_reset(struct pch_can_priv *priv) | ||
485 | { | ||
486 | /* write to sw reset register */ | ||
487 | iowrite32(1, &priv->regs->srst); | ||
488 | iowrite32(0, &priv->regs->srst); | ||
489 | } | ||
490 | |||
491 | static void pch_can_error(struct net_device *ndev, u32 status) | ||
492 | { | ||
493 | struct sk_buff *skb; | ||
494 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
495 | struct can_frame *cf; | ||
496 | u32 errc, lec; | ||
497 | struct net_device_stats *stats = &(priv->ndev->stats); | ||
498 | enum can_state state = priv->can.state; | ||
499 | |||
500 | skb = alloc_can_err_skb(ndev, &cf); | ||
501 | if (!skb) | ||
502 | return; | ||
503 | |||
504 | if (status & PCH_BUS_OFF) { | ||
505 | pch_can_set_tx_all(priv, 0); | ||
506 | pch_can_set_rx_all(priv, 0); | ||
507 | state = CAN_STATE_BUS_OFF; | ||
508 | cf->can_id |= CAN_ERR_BUSOFF; | ||
509 | can_bus_off(ndev); | ||
510 | } | ||
511 | |||
512 | errc = ioread32(&priv->regs->errc); | ||
513 | /* Warning interrupt. */ | ||
514 | if (status & PCH_EWARN) { | ||
515 | state = CAN_STATE_ERROR_WARNING; | ||
516 | priv->can.can_stats.error_warning++; | ||
517 | cf->can_id |= CAN_ERR_CRTL; | ||
518 | if (((errc & PCH_REC) >> 8) > 96) | ||
519 | cf->data[1] |= CAN_ERR_CRTL_RX_WARNING; | ||
520 | if ((errc & PCH_TEC) > 96) | ||
521 | cf->data[1] |= CAN_ERR_CRTL_TX_WARNING; | ||
522 | netdev_dbg(ndev, | ||
523 | "%s -> Error Counter is more than 96.\n", __func__); | ||
524 | } | ||
525 | /* Error passive interrupt. */ | ||
526 | if (status & PCH_EPASSIV) { | ||
527 | priv->can.can_stats.error_passive++; | ||
528 | state = CAN_STATE_ERROR_PASSIVE; | ||
529 | cf->can_id |= CAN_ERR_CRTL; | ||
530 | if (((errc & PCH_REC) >> 8) > 127) | ||
531 | cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; | ||
532 | if ((errc & PCH_TEC) > 127) | ||
533 | cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; | ||
534 | netdev_dbg(ndev, | ||
535 | "%s -> CAN controller is ERROR PASSIVE .\n", __func__); | ||
536 | } | ||
537 | |||
538 | lec = status & PCH_LEC_ALL; | ||
539 | switch (lec) { | ||
540 | case PCH_STUF_ERR: | ||
541 | cf->data[2] |= CAN_ERR_PROT_STUFF; | ||
542 | priv->can.can_stats.bus_error++; | ||
543 | stats->rx_errors++; | ||
544 | break; | ||
545 | case PCH_FORM_ERR: | ||
546 | cf->data[2] |= CAN_ERR_PROT_FORM; | ||
547 | priv->can.can_stats.bus_error++; | ||
548 | stats->rx_errors++; | ||
549 | break; | ||
550 | case PCH_ACK_ERR: | ||
551 | cf->can_id |= CAN_ERR_ACK; | ||
552 | priv->can.can_stats.bus_error++; | ||
553 | stats->rx_errors++; | ||
554 | break; | ||
555 | case PCH_BIT1_ERR: | ||
556 | case PCH_BIT0_ERR: | ||
557 | cf->data[2] |= CAN_ERR_PROT_BIT; | ||
558 | priv->can.can_stats.bus_error++; | ||
559 | stats->rx_errors++; | ||
560 | break; | ||
561 | case PCH_CRC_ERR: | ||
562 | cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ | | ||
563 | CAN_ERR_PROT_LOC_CRC_DEL; | ||
564 | priv->can.can_stats.bus_error++; | ||
565 | stats->rx_errors++; | ||
566 | break; | ||
567 | case PCH_LEC_ALL: /* Written by CPU. No error status */ | ||
568 | break; | ||
569 | } | ||
570 | |||
571 | cf->data[6] = errc & PCH_TEC; | ||
572 | cf->data[7] = (errc & PCH_REC) >> 8; | ||
573 | |||
574 | priv->can.state = state; | ||
575 | netif_receive_skb(skb); | ||
576 | |||
577 | stats->rx_packets++; | ||
578 | stats->rx_bytes += cf->can_dlc; | ||
579 | } | ||
580 | |||
581 | static irqreturn_t pch_can_interrupt(int irq, void *dev_id) | ||
582 | { | ||
583 | struct net_device *ndev = (struct net_device *)dev_id; | ||
584 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
585 | |||
586 | if (!pch_can_int_pending(priv)) | ||
587 | return IRQ_NONE; | ||
588 | |||
589 | pch_can_set_int_enables(priv, PCH_CAN_NONE); | ||
590 | napi_schedule(&priv->napi); | ||
591 | return IRQ_HANDLED; | ||
592 | } | ||
593 | |||
594 | static void pch_fifo_thresh(struct pch_can_priv *priv, int obj_id) | ||
595 | { | ||
596 | if (obj_id < PCH_FIFO_THRESH) { | ||
597 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | | ||
598 | PCH_CMASK_ARB, &priv->regs->ifregs[0].cmask); | ||
599 | |||
600 | /* Clearing the Dir bit. */ | ||
601 | pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR); | ||
602 | |||
603 | /* Clearing NewDat & IntPnd */ | ||
604 | pch_can_bit_clear(&priv->regs->ifregs[0].mcont, | ||
605 | PCH_IF_MCONT_INTPND); | ||
606 | pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_id); | ||
607 | } else if (obj_id > PCH_FIFO_THRESH) { | ||
608 | pch_can_int_clr(priv, obj_id); | ||
609 | } else if (obj_id == PCH_FIFO_THRESH) { | ||
610 | int cnt; | ||
611 | for (cnt = 0; cnt < PCH_FIFO_THRESH; cnt++) | ||
612 | pch_can_int_clr(priv, cnt + 1); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | static void pch_can_rx_msg_lost(struct net_device *ndev, int obj_id) | ||
617 | { | ||
618 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
619 | struct net_device_stats *stats = &(priv->ndev->stats); | ||
620 | struct sk_buff *skb; | ||
621 | struct can_frame *cf; | ||
622 | |||
623 | netdev_dbg(priv->ndev, "Msg Obj is overwritten.\n"); | ||
624 | pch_can_bit_clear(&priv->regs->ifregs[0].mcont, | ||
625 | PCH_IF_MCONT_MSGLOST); | ||
626 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, | ||
627 | &priv->regs->ifregs[0].cmask); | ||
628 | pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_id); | ||
629 | |||
630 | skb = alloc_can_err_skb(ndev, &cf); | ||
631 | if (!skb) | ||
632 | return; | ||
633 | |||
634 | cf->can_id |= CAN_ERR_CRTL; | ||
635 | cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | ||
636 | stats->rx_over_errors++; | ||
637 | stats->rx_errors++; | ||
638 | |||
639 | netif_receive_skb(skb); | ||
640 | } | ||
641 | |||
642 | static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota) | ||
643 | { | ||
644 | u32 reg; | ||
645 | canid_t id; | ||
646 | int rcv_pkts = 0; | ||
647 | struct sk_buff *skb; | ||
648 | struct can_frame *cf; | ||
649 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
650 | struct net_device_stats *stats = &(priv->ndev->stats); | ||
651 | int i; | ||
652 | u32 id2; | ||
653 | u16 data_reg; | ||
654 | |||
655 | do { | ||
656 | /* Reading the message object from the Message RAM */ | ||
657 | iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); | ||
658 | pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_num); | ||
659 | |||
660 | /* Reading the MCONT register. */ | ||
661 | reg = ioread32(&priv->regs->ifregs[0].mcont); | ||
662 | |||
663 | if (reg & PCH_IF_MCONT_EOB) | ||
664 | break; | ||
665 | |||
666 | /* If MsgLost bit set. */ | ||
667 | if (reg & PCH_IF_MCONT_MSGLOST) { | ||
668 | pch_can_rx_msg_lost(ndev, obj_num); | ||
669 | rcv_pkts++; | ||
670 | quota--; | ||
671 | obj_num++; | ||
672 | continue; | ||
673 | } else if (!(reg & PCH_IF_MCONT_NEWDAT)) { | ||
674 | obj_num++; | ||
675 | continue; | ||
676 | } | ||
677 | |||
678 | skb = alloc_can_skb(priv->ndev, &cf); | ||
679 | if (!skb) { | ||
680 | netdev_err(ndev, "alloc_can_skb Failed\n"); | ||
681 | return rcv_pkts; | ||
682 | } | ||
683 | |||
684 | /* Get Received data */ | ||
685 | id2 = ioread32(&priv->regs->ifregs[0].id2); | ||
686 | if (id2 & PCH_ID2_XTD) { | ||
687 | id = (ioread32(&priv->regs->ifregs[0].id1) & 0xffff); | ||
688 | id |= (((id2) & 0x1fff) << 16); | ||
689 | cf->can_id = id | CAN_EFF_FLAG; | ||
690 | } else { | ||
691 | id = (id2 >> 2) & CAN_SFF_MASK; | ||
692 | cf->can_id = id; | ||
693 | } | ||
694 | |||
695 | if (id2 & PCH_ID2_DIR) | ||
696 | cf->can_id |= CAN_RTR_FLAG; | ||
697 | |||
698 | cf->can_dlc = get_can_dlc((ioread32(&priv->regs-> | ||
699 | ifregs[0].mcont)) & 0xF); | ||
700 | |||
701 | for (i = 0; i < cf->can_dlc; i += 2) { | ||
702 | data_reg = ioread16(&priv->regs->ifregs[0].data[i / 2]); | ||
703 | cf->data[i] = data_reg; | ||
704 | cf->data[i + 1] = data_reg >> 8; | ||
705 | } | ||
706 | |||
707 | netif_receive_skb(skb); | ||
708 | rcv_pkts++; | ||
709 | stats->rx_packets++; | ||
710 | quota--; | ||
711 | stats->rx_bytes += cf->can_dlc; | ||
712 | |||
713 | pch_fifo_thresh(priv, obj_num); | ||
714 | obj_num++; | ||
715 | } while (quota > 0); | ||
716 | |||
717 | return rcv_pkts; | ||
718 | } | ||
719 | |||
720 | static void pch_can_tx_complete(struct net_device *ndev, u32 int_stat) | ||
721 | { | ||
722 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
723 | struct net_device_stats *stats = &(priv->ndev->stats); | ||
724 | u32 dlc; | ||
725 | |||
726 | can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_END - 1); | ||
727 | iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, | ||
728 | &priv->regs->ifregs[1].cmask); | ||
729 | pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, int_stat); | ||
730 | dlc = get_can_dlc(ioread32(&priv->regs->ifregs[1].mcont) & | ||
731 | PCH_IF_MCONT_DLC); | ||
732 | stats->tx_bytes += dlc; | ||
733 | stats->tx_packets++; | ||
734 | if (int_stat == PCH_TX_OBJ_END) | ||
735 | netif_wake_queue(ndev); | ||
736 | } | ||
737 | |||
738 | static int pch_can_poll(struct napi_struct *napi, int quota) | ||
739 | { | ||
740 | struct net_device *ndev = napi->dev; | ||
741 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
742 | u32 int_stat; | ||
743 | u32 reg_stat; | ||
744 | int quota_save = quota; | ||
745 | |||
746 | int_stat = pch_can_int_pending(priv); | ||
747 | if (!int_stat) | ||
748 | goto end; | ||
749 | |||
750 | if (int_stat == PCH_STATUS_INT) { | ||
751 | reg_stat = ioread32(&priv->regs->stat); | ||
752 | |||
753 | if ((reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) && | ||
754 | ((reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL)) { | ||
755 | pch_can_error(ndev, reg_stat); | ||
756 | quota--; | ||
757 | } | ||
758 | |||
759 | if (reg_stat & (PCH_TX_OK | PCH_RX_OK)) | ||
760 | pch_can_bit_clear(&priv->regs->stat, | ||
761 | reg_stat & (PCH_TX_OK | PCH_RX_OK)); | ||
762 | |||
763 | int_stat = pch_can_int_pending(priv); | ||
764 | } | ||
765 | |||
766 | if (quota == 0) | ||
767 | goto end; | ||
768 | |||
769 | if ((int_stat >= PCH_RX_OBJ_START) && (int_stat <= PCH_RX_OBJ_END)) { | ||
770 | quota -= pch_can_rx_normal(ndev, int_stat, quota); | ||
771 | } else if ((int_stat >= PCH_TX_OBJ_START) && | ||
772 | (int_stat <= PCH_TX_OBJ_END)) { | ||
773 | /* Handle transmission interrupt */ | ||
774 | pch_can_tx_complete(ndev, int_stat); | ||
775 | } | ||
776 | |||
777 | end: | ||
778 | napi_complete(napi); | ||
779 | pch_can_set_int_enables(priv, PCH_CAN_ALL); | ||
780 | |||
781 | return quota_save - quota; | ||
782 | } | ||
783 | |||
784 | static int pch_set_bittiming(struct net_device *ndev) | ||
785 | { | ||
786 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
787 | const struct can_bittiming *bt = &priv->can.bittiming; | ||
788 | u32 canbit; | ||
789 | u32 bepe; | ||
790 | |||
791 | /* Setting the CCE bit for accessing the Can Timing register. */ | ||
792 | pch_can_bit_set(&priv->regs->cont, PCH_CTRL_CCE); | ||
793 | |||
794 | canbit = (bt->brp - 1) & PCH_MSK_BITT_BRP; | ||
795 | canbit |= (bt->sjw - 1) << PCH_BIT_SJW_SHIFT; | ||
796 | canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << PCH_BIT_TSEG1_SHIFT; | ||
797 | canbit |= (bt->phase_seg2 - 1) << PCH_BIT_TSEG2_SHIFT; | ||
798 | bepe = ((bt->brp - 1) & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE_SHIFT; | ||
799 | iowrite32(canbit, &priv->regs->bitt); | ||
800 | iowrite32(bepe, &priv->regs->brpe); | ||
801 | pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_CCE); | ||
802 | |||
803 | return 0; | ||
804 | } | ||
805 | |||
806 | static void pch_can_start(struct net_device *ndev) | ||
807 | { | ||
808 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
809 | |||
810 | if (priv->can.state != CAN_STATE_STOPPED) | ||
811 | pch_can_reset(priv); | ||
812 | |||
813 | pch_set_bittiming(ndev); | ||
814 | pch_can_set_optmode(priv); | ||
815 | |||
816 | pch_can_set_tx_all(priv, 1); | ||
817 | pch_can_set_rx_all(priv, 1); | ||
818 | |||
819 | /* Setting the CAN to run mode. */ | ||
820 | pch_can_set_run_mode(priv, PCH_CAN_RUN); | ||
821 | |||
822 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
823 | |||
824 | return; | ||
825 | } | ||
826 | |||
827 | static int pch_can_do_set_mode(struct net_device *ndev, enum can_mode mode) | ||
828 | { | ||
829 | int ret = 0; | ||
830 | |||
831 | switch (mode) { | ||
832 | case CAN_MODE_START: | ||
833 | pch_can_start(ndev); | ||
834 | netif_wake_queue(ndev); | ||
835 | break; | ||
836 | default: | ||
837 | ret = -EOPNOTSUPP; | ||
838 | break; | ||
839 | } | ||
840 | |||
841 | return ret; | ||
842 | } | ||
843 | |||
844 | static int pch_can_open(struct net_device *ndev) | ||
845 | { | ||
846 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
847 | int retval; | ||
848 | |||
849 | /* Regstering the interrupt. */ | ||
850 | retval = request_irq(priv->dev->irq, pch_can_interrupt, IRQF_SHARED, | ||
851 | ndev->name, ndev); | ||
852 | if (retval) { | ||
853 | netdev_err(ndev, "request_irq failed.\n"); | ||
854 | goto req_irq_err; | ||
855 | } | ||
856 | |||
857 | /* Open common can device */ | ||
858 | retval = open_candev(ndev); | ||
859 | if (retval) { | ||
860 | netdev_err(ndev, "open_candev() failed %d\n", retval); | ||
861 | goto err_open_candev; | ||
862 | } | ||
863 | |||
864 | pch_can_init(priv); | ||
865 | pch_can_start(ndev); | ||
866 | napi_enable(&priv->napi); | ||
867 | netif_start_queue(ndev); | ||
868 | |||
869 | return 0; | ||
870 | |||
871 | err_open_candev: | ||
872 | free_irq(priv->dev->irq, ndev); | ||
873 | req_irq_err: | ||
874 | pch_can_release(priv); | ||
875 | |||
876 | return retval; | ||
877 | } | ||
878 | |||
879 | static int pch_close(struct net_device *ndev) | ||
880 | { | ||
881 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
882 | |||
883 | netif_stop_queue(ndev); | ||
884 | napi_disable(&priv->napi); | ||
885 | pch_can_release(priv); | ||
886 | free_irq(priv->dev->irq, ndev); | ||
887 | close_candev(ndev); | ||
888 | priv->can.state = CAN_STATE_STOPPED; | ||
889 | return 0; | ||
890 | } | ||
891 | |||
892 | static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) | ||
893 | { | ||
894 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
895 | struct can_frame *cf = (struct can_frame *)skb->data; | ||
896 | int tx_obj_no; | ||
897 | int i; | ||
898 | u32 id2; | ||
899 | |||
900 | if (can_dropped_invalid_skb(ndev, skb)) | ||
901 | return NETDEV_TX_OK; | ||
902 | |||
903 | tx_obj_no = priv->tx_obj; | ||
904 | if (priv->tx_obj == PCH_TX_OBJ_END) { | ||
905 | if (ioread32(&priv->regs->treq2) & PCH_TREQ2_TX_MASK) | ||
906 | netif_stop_queue(ndev); | ||
907 | |||
908 | priv->tx_obj = PCH_TX_OBJ_START; | ||
909 | } else { | ||
910 | priv->tx_obj++; | ||
911 | } | ||
912 | |||
913 | /* Setting the CMASK register. */ | ||
914 | pch_can_bit_set(&priv->regs->ifregs[1].cmask, PCH_CMASK_ALL); | ||
915 | |||
916 | /* If ID extended is set. */ | ||
917 | if (cf->can_id & CAN_EFF_FLAG) { | ||
918 | iowrite32(cf->can_id & 0xffff, &priv->regs->ifregs[1].id1); | ||
919 | id2 = ((cf->can_id >> 16) & 0x1fff) | PCH_ID2_XTD; | ||
920 | } else { | ||
921 | iowrite32(0, &priv->regs->ifregs[1].id1); | ||
922 | id2 = (cf->can_id & CAN_SFF_MASK) << 2; | ||
923 | } | ||
924 | |||
925 | id2 |= PCH_ID_MSGVAL; | ||
926 | |||
927 | /* If remote frame has to be transmitted.. */ | ||
928 | if (!(cf->can_id & CAN_RTR_FLAG)) | ||
929 | id2 |= PCH_ID2_DIR; | ||
930 | |||
931 | iowrite32(id2, &priv->regs->ifregs[1].id2); | ||
932 | |||
933 | /* Copy data to register */ | ||
934 | for (i = 0; i < cf->can_dlc; i += 2) { | ||
935 | iowrite16(cf->data[i] | (cf->data[i + 1] << 8), | ||
936 | &priv->regs->ifregs[1].data[i / 2]); | ||
937 | } | ||
938 | |||
939 | can_put_echo_skb(skb, ndev, tx_obj_no - PCH_RX_OBJ_END - 1); | ||
940 | |||
941 | /* Set the size of the data. Update if2_mcont */ | ||
942 | iowrite32(cf->can_dlc | PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT | | ||
943 | PCH_IF_MCONT_TXIE, &priv->regs->ifregs[1].mcont); | ||
944 | |||
945 | pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, tx_obj_no); | ||
946 | |||
947 | return NETDEV_TX_OK; | ||
948 | } | ||
949 | |||
950 | static const struct net_device_ops pch_can_netdev_ops = { | ||
951 | .ndo_open = pch_can_open, | ||
952 | .ndo_stop = pch_close, | ||
953 | .ndo_start_xmit = pch_xmit, | ||
954 | }; | ||
955 | |||
956 | static void __devexit pch_can_remove(struct pci_dev *pdev) | ||
957 | { | ||
958 | struct net_device *ndev = pci_get_drvdata(pdev); | ||
959 | struct pch_can_priv *priv = netdev_priv(ndev); | ||
960 | |||
961 | unregister_candev(priv->ndev); | ||
962 | if (priv->use_msi) | ||
963 | pci_disable_msi(priv->dev); | ||
964 | pci_release_regions(pdev); | ||
965 | pci_disable_device(pdev); | ||
966 | pci_set_drvdata(pdev, NULL); | ||
967 | pch_can_reset(priv); | ||
968 | pci_iounmap(pdev, priv->regs); | ||
969 | free_candev(priv->ndev); | ||
970 | } | ||
971 | |||
972 | #ifdef CONFIG_PM | ||
973 | static void pch_can_set_int_custom(struct pch_can_priv *priv) | ||
974 | { | ||
975 | /* Clearing the IE, SIE and EIE bits of Can control register. */ | ||
976 | pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); | ||
977 | |||
978 | /* Appropriately setting them. */ | ||
979 | pch_can_bit_set(&priv->regs->cont, | ||
980 | ((priv->int_enables & PCH_MSK_CTRL_IE_SIE_EIE) << 1)); | ||
981 | } | ||
982 | |||
983 | /* This function retrieves interrupt enabled for the CAN device. */ | ||
984 | static u32 pch_can_get_int_enables(struct pch_can_priv *priv) | ||
985 | { | ||
986 | /* Obtaining the status of IE, SIE and EIE interrupt bits. */ | ||
987 | return (ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1; | ||
988 | } | ||
989 | |||
990 | static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, | ||
991 | enum pch_ifreg dir) | ||
992 | { | ||
993 | u32 ie, enable; | ||
994 | |||
995 | if (dir) | ||
996 | ie = PCH_IF_MCONT_RXIE; | ||
997 | else | ||
998 | ie = PCH_IF_MCONT_TXIE; | ||
999 | |||
1000 | iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask); | ||
1001 | pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num); | ||
1002 | |||
1003 | if (((ioread32(&priv->regs->ifregs[dir].id2)) & PCH_ID_MSGVAL) && | ||
1004 | ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie)) | ||
1005 | enable = 1; | ||
1006 | else | ||
1007 | enable = 0; | ||
1008 | |||
1009 | return enable; | ||
1010 | } | ||
1011 | |||
1012 | static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, | ||
1013 | u32 buffer_num, int set) | ||
1014 | { | ||
1015 | iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); | ||
1016 | pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num); | ||
1017 | iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, | ||
1018 | &priv->regs->ifregs[0].cmask); | ||
1019 | if (set) | ||
1020 | pch_can_bit_clear(&priv->regs->ifregs[0].mcont, | ||
1021 | PCH_IF_MCONT_EOB); | ||
1022 | else | ||
1023 | pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB); | ||
1024 | |||
1025 | pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num); | ||
1026 | } | ||
1027 | |||
1028 | static u32 pch_can_get_rx_buffer_link(struct pch_can_priv *priv, u32 buffer_num) | ||
1029 | { | ||
1030 | u32 link; | ||
1031 | |||
1032 | iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); | ||
1033 | pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num); | ||
1034 | |||
1035 | if (ioread32(&priv->regs->ifregs[0].mcont) & PCH_IF_MCONT_EOB) | ||
1036 | link = 0; | ||
1037 | else | ||
1038 | link = 1; | ||
1039 | return link; | ||
1040 | } | ||
1041 | |||
1042 | static int pch_can_get_buffer_status(struct pch_can_priv *priv) | ||
1043 | { | ||
1044 | return (ioread32(&priv->regs->treq1) & 0xffff) | | ||
1045 | (ioread32(&priv->regs->treq2) << 16); | ||
1046 | } | ||
1047 | |||
1048 | static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1049 | { | ||
1050 | int i; | ||
1051 | int retval; | ||
1052 | u32 buf_stat; /* Variable for reading the transmit buffer status. */ | ||
1053 | int counter = PCH_COUNTER_LIMIT; | ||
1054 | |||
1055 | struct net_device *dev = pci_get_drvdata(pdev); | ||
1056 | struct pch_can_priv *priv = netdev_priv(dev); | ||
1057 | |||
1058 | /* Stop the CAN controller */ | ||
1059 | pch_can_set_run_mode(priv, PCH_CAN_STOP); | ||
1060 | |||
1061 | /* Indicate that we are aboutto/in suspend */ | ||
1062 | priv->can.state = CAN_STATE_STOPPED; | ||
1063 | |||
1064 | /* Waiting for all transmission to complete. */ | ||
1065 | while (counter) { | ||
1066 | buf_stat = pch_can_get_buffer_status(priv); | ||
1067 | if (!buf_stat) | ||
1068 | break; | ||
1069 | counter--; | ||
1070 | udelay(1); | ||
1071 | } | ||
1072 | if (!counter) | ||
1073 | dev_err(&pdev->dev, "%s -> Transmission time out.\n", __func__); | ||
1074 | |||
1075 | /* Save interrupt configuration and then disable them */ | ||
1076 | priv->int_enables = pch_can_get_int_enables(priv); | ||
1077 | pch_can_set_int_enables(priv, PCH_CAN_DISABLE); | ||
1078 | |||
1079 | /* Save Tx buffer enable state */ | ||
1080 | for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) | ||
1081 | priv->tx_enable[i - 1] = pch_can_get_rxtx_ir(priv, i, | ||
1082 | PCH_TX_IFREG); | ||
1083 | |||
1084 | /* Disable all Transmit buffers */ | ||
1085 | pch_can_set_tx_all(priv, 0); | ||
1086 | |||
1087 | /* Save Rx buffer enable state */ | ||
1088 | for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { | ||
1089 | priv->rx_enable[i - 1] = pch_can_get_rxtx_ir(priv, i, | ||
1090 | PCH_RX_IFREG); | ||
1091 | priv->rx_link[i - 1] = pch_can_get_rx_buffer_link(priv, i); | ||
1092 | } | ||
1093 | |||
1094 | /* Disable all Receive buffers */ | ||
1095 | pch_can_set_rx_all(priv, 0); | ||
1096 | retval = pci_save_state(pdev); | ||
1097 | if (retval) { | ||
1098 | dev_err(&pdev->dev, "pci_save_state failed.\n"); | ||
1099 | } else { | ||
1100 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
1101 | pci_disable_device(pdev); | ||
1102 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1103 | } | ||
1104 | |||
1105 | return retval; | ||
1106 | } | ||
1107 | |||
1108 | static int pch_can_resume(struct pci_dev *pdev) | ||
1109 | { | ||
1110 | int i; | ||
1111 | int retval; | ||
1112 | struct net_device *dev = pci_get_drvdata(pdev); | ||
1113 | struct pch_can_priv *priv = netdev_priv(dev); | ||
1114 | |||
1115 | pci_set_power_state(pdev, PCI_D0); | ||
1116 | pci_restore_state(pdev); | ||
1117 | retval = pci_enable_device(pdev); | ||
1118 | if (retval) { | ||
1119 | dev_err(&pdev->dev, "pci_enable_device failed.\n"); | ||
1120 | return retval; | ||
1121 | } | ||
1122 | |||
1123 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
1124 | |||
1125 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
1126 | |||
1127 | /* Disabling all interrupts. */ | ||
1128 | pch_can_set_int_enables(priv, PCH_CAN_DISABLE); | ||
1129 | |||
1130 | /* Setting the CAN device in Stop Mode. */ | ||
1131 | pch_can_set_run_mode(priv, PCH_CAN_STOP); | ||
1132 | |||
1133 | /* Configuring the transmit and receive buffers. */ | ||
1134 | pch_can_config_rx_tx_buffers(priv); | ||
1135 | |||
1136 | /* Restore the CAN state */ | ||
1137 | pch_set_bittiming(dev); | ||
1138 | |||
1139 | /* Listen/Active */ | ||
1140 | pch_can_set_optmode(priv); | ||
1141 | |||
1142 | /* Enabling the transmit buffer. */ | ||
1143 | for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) | ||
1144 | pch_can_set_rxtx(priv, i, priv->tx_enable[i - 1], PCH_TX_IFREG); | ||
1145 | |||
1146 | /* Configuring the receive buffer and enabling them. */ | ||
1147 | for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) { | ||
1148 | /* Restore buffer link */ | ||
1149 | pch_can_set_rx_buffer_link(priv, i, priv->rx_link[i - 1]); | ||
1150 | |||
1151 | /* Restore buffer enables */ | ||
1152 | pch_can_set_rxtx(priv, i, priv->rx_enable[i - 1], PCH_RX_IFREG); | ||
1153 | } | ||
1154 | |||
1155 | /* Enable CAN Interrupts */ | ||
1156 | pch_can_set_int_custom(priv); | ||
1157 | |||
1158 | /* Restore Run Mode */ | ||
1159 | pch_can_set_run_mode(priv, PCH_CAN_RUN); | ||
1160 | |||
1161 | return retval; | ||
1162 | } | ||
1163 | #else | ||
1164 | #define pch_can_suspend NULL | ||
1165 | #define pch_can_resume NULL | ||
1166 | #endif | ||
1167 | |||
1168 | static int pch_can_get_berr_counter(const struct net_device *dev, | ||
1169 | struct can_berr_counter *bec) | ||
1170 | { | ||
1171 | struct pch_can_priv *priv = netdev_priv(dev); | ||
1172 | u32 errc = ioread32(&priv->regs->errc); | ||
1173 | |||
1174 | bec->txerr = errc & PCH_TEC; | ||
1175 | bec->rxerr = (errc & PCH_REC) >> 8; | ||
1176 | |||
1177 | return 0; | ||
1178 | } | ||
1179 | |||
1180 | static int __devinit pch_can_probe(struct pci_dev *pdev, | ||
1181 | const struct pci_device_id *id) | ||
1182 | { | ||
1183 | struct net_device *ndev; | ||
1184 | struct pch_can_priv *priv; | ||
1185 | int rc; | ||
1186 | void __iomem *addr; | ||
1187 | |||
1188 | rc = pci_enable_device(pdev); | ||
1189 | if (rc) { | ||
1190 | dev_err(&pdev->dev, "Failed pci_enable_device %d\n", rc); | ||
1191 | goto probe_exit_endev; | ||
1192 | } | ||
1193 | |||
1194 | rc = pci_request_regions(pdev, KBUILD_MODNAME); | ||
1195 | if (rc) { | ||
1196 | dev_err(&pdev->dev, "Failed pci_request_regions %d\n", rc); | ||
1197 | goto probe_exit_pcireq; | ||
1198 | } | ||
1199 | |||
1200 | addr = pci_iomap(pdev, 1, 0); | ||
1201 | if (!addr) { | ||
1202 | rc = -EIO; | ||
1203 | dev_err(&pdev->dev, "Failed pci_iomap\n"); | ||
1204 | goto probe_exit_ipmap; | ||
1205 | } | ||
1206 | |||
1207 | ndev = alloc_candev(sizeof(struct pch_can_priv), PCH_TX_OBJ_END); | ||
1208 | if (!ndev) { | ||
1209 | rc = -ENOMEM; | ||
1210 | dev_err(&pdev->dev, "Failed alloc_candev\n"); | ||
1211 | goto probe_exit_alloc_candev; | ||
1212 | } | ||
1213 | |||
1214 | priv = netdev_priv(ndev); | ||
1215 | priv->ndev = ndev; | ||
1216 | priv->regs = addr; | ||
1217 | priv->dev = pdev; | ||
1218 | priv->can.bittiming_const = &pch_can_bittiming_const; | ||
1219 | priv->can.do_set_mode = pch_can_do_set_mode; | ||
1220 | priv->can.do_get_berr_counter = pch_can_get_berr_counter; | ||
1221 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY | | ||
1222 | CAN_CTRLMODE_LOOPBACK; | ||
1223 | priv->tx_obj = PCH_TX_OBJ_START; /* Point head of Tx Obj */ | ||
1224 | |||
1225 | ndev->irq = pdev->irq; | ||
1226 | ndev->flags |= IFF_ECHO; | ||
1227 | |||
1228 | pci_set_drvdata(pdev, ndev); | ||
1229 | SET_NETDEV_DEV(ndev, &pdev->dev); | ||
1230 | ndev->netdev_ops = &pch_can_netdev_ops; | ||
1231 | priv->can.clock.freq = PCH_CAN_CLK; /* Hz */ | ||
1232 | |||
1233 | netif_napi_add(ndev, &priv->napi, pch_can_poll, PCH_RX_OBJ_END); | ||
1234 | |||
1235 | rc = pci_enable_msi(priv->dev); | ||
1236 | if (rc) { | ||
1237 | netdev_err(ndev, "PCH CAN opened without MSI\n"); | ||
1238 | priv->use_msi = 0; | ||
1239 | } else { | ||
1240 | netdev_err(ndev, "PCH CAN opened with MSI\n"); | ||
1241 | pci_set_master(pdev); | ||
1242 | priv->use_msi = 1; | ||
1243 | } | ||
1244 | |||
1245 | rc = register_candev(ndev); | ||
1246 | if (rc) { | ||
1247 | dev_err(&pdev->dev, "Failed register_candev %d\n", rc); | ||
1248 | goto probe_exit_reg_candev; | ||
1249 | } | ||
1250 | |||
1251 | return 0; | ||
1252 | |||
1253 | probe_exit_reg_candev: | ||
1254 | if (priv->use_msi) | ||
1255 | pci_disable_msi(priv->dev); | ||
1256 | free_candev(ndev); | ||
1257 | probe_exit_alloc_candev: | ||
1258 | pci_iounmap(pdev, addr); | ||
1259 | probe_exit_ipmap: | ||
1260 | pci_release_regions(pdev); | ||
1261 | probe_exit_pcireq: | ||
1262 | pci_disable_device(pdev); | ||
1263 | probe_exit_endev: | ||
1264 | return rc; | ||
1265 | } | ||
1266 | |||
1267 | static struct pci_driver pch_can_pci_driver = { | ||
1268 | .name = "pch_can", | ||
1269 | .id_table = pch_pci_tbl, | ||
1270 | .probe = pch_can_probe, | ||
1271 | .remove = __devexit_p(pch_can_remove), | ||
1272 | .suspend = pch_can_suspend, | ||
1273 | .resume = pch_can_resume, | ||
1274 | }; | ||
1275 | |||
1276 | static int __init pch_can_pci_init(void) | ||
1277 | { | ||
1278 | return pci_register_driver(&pch_can_pci_driver); | ||
1279 | } | ||
1280 | module_init(pch_can_pci_init); | ||
1281 | |||
1282 | static void __exit pch_can_pci_exit(void) | ||
1283 | { | ||
1284 | pci_unregister_driver(&pch_can_pci_driver); | ||
1285 | } | ||
1286 | module_exit(pch_can_pci_exit); | ||
1287 | |||
1288 | MODULE_DESCRIPTION("Intel EG20T PCH CAN(Controller Area Network) Driver"); | ||
1289 | MODULE_LICENSE("GPL v2"); | ||
1290 | MODULE_VERSION("0.94"); | ||