189 |
189 |
#define RXBEID0_OFF 4
|
190 |
190 |
#define RXBDLC_OFF 5
|
191 |
191 |
#define RXBDAT_OFF 6
|
192 |
|
#define RXFSIDH(n) ((n) * 4)
|
193 |
|
#define RXFSIDL(n) ((n) * 4 + 1)
|
194 |
|
#define RXFEID8(n) ((n) * 4 + 2)
|
195 |
|
#define RXFEID0(n) ((n) * 4 + 3)
|
|
192 |
const u8 RXFSIDH[6] = {
|
|
193 |
0x00,
|
|
194 |
0x04,
|
|
195 |
0x08,
|
|
196 |
0x10,
|
|
197 |
0x14,
|
|
198 |
0x18
|
|
199 |
};
|
|
200 |
const u8 RXFSIDL[6] = {
|
|
201 |
0x01,
|
|
202 |
0x05,
|
|
203 |
0x09,
|
|
204 |
0x11,
|
|
205 |
0x15,
|
|
206 |
0x19
|
|
207 |
};
|
|
208 |
const u8 RXFEID8[6] = {
|
|
209 |
0x02,
|
|
210 |
0x06,
|
|
211 |
0x0A,
|
|
212 |
0x12,
|
|
213 |
0x16,
|
|
214 |
0x1A
|
|
215 |
};
|
|
216 |
const u8 RXFEID0[6] = {
|
|
217 |
0x03,
|
|
218 |
0x07,
|
|
219 |
0x0B,
|
|
220 |
0x13,
|
|
221 |
0x17,
|
|
222 |
0x1B
|
|
223 |
};
|
196 |
224 |
#define RXMSIDH(n) ((n) * 4 + 0x20)
|
197 |
225 |
#define RXMSIDL(n) ((n) * 4 + 0x21)
|
198 |
226 |
#define RXMEID8(n) ((n) * 4 + 0x22)
|
... | ... | |
230 |
258 |
"oscillator_frequency_override will be used in place of "
|
231 |
259 |
"mcp251x_platform_data.oscillator_frequency.");
|
232 |
260 |
|
|
261 |
static int rxbn_op_mode[2] = {0, 0};
|
|
262 |
module_param_array(rxbn_op_mode, int, NULL, S_IRUGO);
|
|
263 |
MODULE_PARM_DESC(rxbn_op_mode, "0 = (default) MCP2515 hardware filtering will"
|
|
264 |
" be disabled for receive buffer n (0 or 1)."
|
|
265 |
" rxb0 controls filters 0 and 1, rxb1 controls filters 2-5"
|
|
266 |
" Note there is kernel level filtering, but for high traffic scenarios"
|
|
267 |
" kernel may not be able to keep up."
|
|
268 |
" 1 = use rxbn_mask and rxbn filters, but only accept std CAN ids."
|
|
269 |
" 2 = use rxbn_mask and rxbn filters, but only accept ext CAN ids."
|
|
270 |
" 3 = use rxbn_mask and rxbn filters, and accept ext or std CAN ids.");
|
|
271 |
|
|
272 |
static int rxbn_mask[2];
|
|
273 |
module_param_array(rxbn_mask, int, NULL, S_IRUGO);
|
|
274 |
MODULE_PARM_DESC(rxbn_mask, "Mask used for receive buffer n if rxbn_op_mode "
|
|
275 |
" is 1, 2 or 3. Bits 10-0 for std ids. Bits 29-11 for ext ids.");
|
|
276 |
|
|
277 |
static int rxbn_filters[6];
|
|
278 |
module_param_array(rxbn_filters, int, NULL, S_IRUGO);
|
|
279 |
MODULE_PARM_DESC(rxbn_filters, "Filter used for receive buffer n if "
|
|
280 |
"rxbn_op_mode is 1, 2 or 3. Bits 10-0 for std ids. Bits 29-11 for ext "
|
|
281 |
"ids (also need to set bit 30 for ext id filtering). Note that filters "
|
|
282 |
"0 and 1 correspond to rxbn_op_mode[0] and rxbn_mask[0], while filters "
|
|
283 |
"2-5 corresponds to rxbn_op_mode[1] and rxbn_mask[1]");
|
|
284 |
|
233 |
285 |
static struct can_bittiming_const mcp251x_bittiming_const = {
|
234 |
286 |
.name = DEVICE_NAME,
|
235 |
287 |
.tseg1_min = 3,
|
... | ... | |
617 |
669 |
static int mcp251x_setup(struct net_device *net, struct mcp251x_priv *priv,
|
618 |
670 |
struct spi_device *spi)
|
619 |
671 |
{
|
|
672 |
int i = 0;
|
|
673 |
uint8_t reg_val = 0;
|
|
674 |
|
620 |
675 |
mcp251x_do_set_bittiming(net);
|
621 |
676 |
|
622 |
|
mcp251x_write_reg(spi, RXBCTRL(0),
|
623 |
|
RXBCTRL_BUKT | RXBCTRL_RXM0 | RXBCTRL_RXM1);
|
624 |
|
mcp251x_write_reg(spi, RXBCTRL(1),
|
625 |
|
RXBCTRL_RXM0 | RXBCTRL_RXM1);
|
|
677 |
/* Setup recv buffer 0 control. default no hw filtering */
|
|
678 |
reg_val = RXBCTRL_BUKT | RXBCTRL_RXM1 | RXBCTRL_RXM0;
|
|
679 |
if (1 == rxbn_op_mode[0]) {
|
|
680 |
/* std ids only */
|
|
681 |
reg_val = RXBCTRL_BUKT | RXBCTRL_RXM0 ;
|
|
682 |
} else if (2 == rxbn_op_mode[0]) {
|
|
683 |
/* ext ids only */
|
|
684 |
reg_val = RXBCTRL_BUKT | RXBCTRL_RXM1;
|
|
685 |
} else if (3 == rxbn_op_mode[0]) {
|
|
686 |
/* std or ext ids */
|
|
687 |
reg_val = RXBCTRL_BUKT;
|
|
688 |
}
|
|
689 |
mcp251x_write_reg(spi, RXBCTRL(0), reg_val);
|
|
690 |
|
|
691 |
/* Setup recv buffer 1 control. default no hw filtering */
|
|
692 |
reg_val = RXBCTRL_RXM1 | RXBCTRL_RXM0;
|
|
693 |
if (1 == rxbn_op_mode[1]) {
|
|
694 |
/* std ids only */
|
|
695 |
reg_val = RXBCTRL_RXM0 ;
|
|
696 |
} else if (2 == rxbn_op_mode[1]) {
|
|
697 |
/* ext ids only */
|
|
698 |
reg_val = RXBCTRL_RXM1;
|
|
699 |
} else if (3 == rxbn_op_mode[1]) {
|
|
700 |
/* std or ext ids */
|
|
701 |
reg_val = 0;
|
|
702 |
}
|
|
703 |
mcp251x_write_reg(spi, RXBCTRL(1), reg_val);
|
|
704 |
|
|
705 |
/* Fill out mask registers */
|
|
706 |
for (i = 0; i < ARRAY_SIZE(rxbn_mask); i++) {
|
|
707 |
mcp251x_write_reg(spi, RXMSIDH(i), (uint8_t)(rxbn_mask[i]>>3));
|
|
708 |
mcp251x_write_reg(spi, RXMSIDL(i), (uint8_t)((rxbn_mask[i]<<5) |
|
|
709 |
(0x3 & (rxbn_mask[i]>>27))));
|
|
710 |
mcp251x_write_reg(spi, RXMEID8(i), (uint8_t)(rxbn_mask[i]>>19));
|
|
711 |
mcp251x_write_reg(spi, RXMEID0(i), (uint8_t)(rxbn_mask[i]>>11));
|
|
712 |
}
|
|
713 |
|
|
714 |
/* Fill out filter registers */
|
|
715 |
for (i = 0; i < ARRAY_SIZE(rxbn_filters); i++) {
|
|
716 |
mcp251x_write_reg(spi, RXFSIDH[i], (uint8_t)(
|
|
717 |
rxbn_filters[i]>>3));
|
|
718 |
mcp251x_write_reg(spi, RXFSIDL[i], (uint8_t)(
|
|
719 |
(rxbn_filters[i]<<5) | (0x3 & (rxbn_filters[i]>>27)) |
|
|
720 |
(0x8 & (rxbn_filters[i]>>29))));
|
|
721 |
mcp251x_write_reg(spi, RXFEID8[i], (uint8_t)(
|
|
722 |
rxbn_filters[i]>>19));
|
|
723 |
mcp251x_write_reg(spi, RXFEID0[i], (uint8_t)(
|
|
724 |
rxbn_filters[i]>>11));
|
|
725 |
}
|
|
726 |
|
626 |
727 |
return 0;
|
627 |
728 |
}
|
628 |
729 |
|