Skip to content

Instantly share code, notes, and snippets.

@vstk
Created February 6, 2016 23:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vstk/9c4307bb9ae0a6ae0208 to your computer and use it in GitHub Desktop.
Save vstk/9c4307bb9ae0a6ae0208 to your computer and use it in GitHub Desktop.
c_can.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <c_can_irq_control>:
if (priv->raminit)
priv->raminit(priv, enable);
}
static void c_can_irq_control(struct c_can_priv *priv, bool enable)
{
0: e1a0c00d mov ip, sp
4: e92dd830 push {r4, r5, fp, ip, lr, pc}
8: e24cb004 sub fp, ip, #4
c: e52de004 push {lr} ; (str lr, [sp, #-4]!)
10: ebfffffe bl 0 <__gnu_mcount_nc>
14: e1a05001 mov r5, r1
u32 ctrl = priv->read_reg(priv, C_CAN_CTRL_REG) & ~CONTROL_IRQMSK;
18: e3a01000 mov r1, #0
1c: e5903134 ldr r3, [r0, #308] ; 0x134
if (priv->raminit)
priv->raminit(priv, enable);
}
static void c_can_irq_control(struct c_can_priv *priv, bool enable)
{
20: e1a04000 mov r4, r0
u32 ctrl = priv->read_reg(priv, C_CAN_CTRL_REG) & ~CONTROL_IRQMSK;
24: e12fff33 blx r3
if (enable)
28: e3550000 cmp r5, #0
priv->raminit(priv, enable);
}
static void c_can_irq_control(struct c_can_priv *priv, bool enable)
{
u32 ctrl = priv->read_reg(priv, C_CAN_CTRL_REG) & ~CONTROL_IRQMSK;
2c: e3c0200e bic r2, r0, #14
if (enable)
ctrl |= CONTROL_IRQMSK;
30: 1382200e orrne r2, r2, #14
priv->write_reg(priv, C_CAN_CTRL_REG, ctrl);
34: e5943138 ldr r3, [r4, #312] ; 0x138
38: e6ff2072 uxth r2, r2
3c: e1a00004 mov r0, r4
40: e3a01000 mov r1, #0
44: e12fff33 blx r3
48: e89da830 ldm sp, {r4, r5, fp, sp, pc}
0000004c <c_can_stop>:
return 0;
}
static void c_can_stop(struct net_device *dev)
{
4c: e1a0c00d mov ip, sp
50: e92dd830 push {r4, r5, fp, ip, lr, pc}
54: e24cb004 sub fp, ip, #4
58: e52de004 push {lr} ; (str lr, [sp, #-4]!)
5c: ebfffffe bl 0 <__gnu_mcount_nc>
struct c_can_priv *priv = netdev_priv(dev);
60: e2805d13 add r5, r0, #1216 ; 0x4c0
return 0;
}
static void c_can_stop(struct net_device *dev)
{
64: e1a04000 mov r4, r0
struct c_can_priv *priv = netdev_priv(dev);
c_can_irq_control(priv, false);
68: e3a01000 mov r1, #0
6c: e1a00005 mov r0, r5
70: ebffffe2 bl 0 <c_can_irq_control>
/* put ctrl to init on stop to end ongoing transmission */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_INIT);
74: e59435f8 ldr r3, [r4, #1528] ; 0x5f8
78: e1a00005 mov r0, r5
7c: e3a01000 mov r1, #0
80: e3a02001 mov r2, #1
84: e12fff33 blx r3
/* deactivate pins */
pinctrl_pm_select_sleep_state(dev->dev.parent);
priv->can.state = CAN_STATE_STOPPED;
88: e3a03004 mov r3, #4
8c: e5843524 str r3, [r4, #1316] ; 0x524
90: e89da830 ldm sp, {r4, r5, fp, sp, pc}
00000094 <alloc_c_can_dev>:
return 0;
}
struct net_device *alloc_c_can_dev(void)
{
94: e1a0c00d mov ip, sp
98: e92dd818 push {r3, r4, fp, ip, lr, pc}
9c: e24cb004 sub fp, ip, #4
a0: e52de004 push {lr} ; (str lr, [sp, #-4]!)
a4: ebfffffe bl 0 <__gnu_mcount_nc>
struct net_device *dev;
struct c_can_priv *priv;
dev = alloc_candev(sizeof(struct c_can_priv), C_CAN_MSG_OBJ_TX_NUM);
a8: e3a00e1b mov r0, #432 ; 0x1b0
ac: e3a01010 mov r1, #16
b0: ebfffffe bl 0 <alloc_candev>
if (!dev)
b4: e2504000 subs r4, r0, #0
b8: 0a000010 beq 100 <alloc_c_can_dev+0x6c>
return NULL;
priv = netdev_priv(dev);
netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT);
bc: e3002000 movw r2, #0
c0: e2841e57 add r1, r4, #1392 ; 0x570
c4: e3402000 movt r2, #0
c8: e3a03010 mov r3, #16
cc: ebfffffe bl 0 <netif_napi_add>
priv->dev = dev;
priv->can.bittiming_const = &c_can_bittiming_const;
d0: e3001000 movw r1, #0
priv->can.do_set_mode = c_can_set_mode;
d4: e3002000 movw r2, #0
priv->can.do_get_berr_counter = c_can_get_berr_counter;
d8: e3003000 movw r3, #0
priv = netdev_priv(dev);
netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT);
priv->dev = dev;
priv->can.bittiming_const = &c_can_bittiming_const;
dc: e3401000 movt r1, #0
priv->can.do_set_mode = c_can_set_mode;
e0: e3402000 movt r2, #0
priv->can.do_get_berr_counter = c_can_get_berr_counter;
e4: e3403000 movt r3, #0
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
e8: e3a00013 mov r0, #19
return NULL;
priv = netdev_priv(dev);
netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT);
priv->dev = dev;
ec: e58445e0 str r4, [r4, #1504] ; 0x5e0
priv->can.bittiming_const = &c_can_bittiming_const;
f0: e5841518 str r1, [r4, #1304] ; 0x518
priv->can.do_set_mode = c_can_set_mode;
f4: e5842558 str r2, [r4, #1368] ; 0x558
priv->can.do_get_berr_counter = c_can_get_berr_counter;
f8: e5843560 str r3, [r4, #1376] ; 0x560
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
fc: e584052c str r0, [r4, #1324] ; 0x52c
CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_BERR_REPORTING;
return dev;
}
100: e1a00004 mov r0, r4
104: e89da818 ldm sp, {r3, r4, fp, sp, pc}
00000108 <c_can_get_berr_counter>:
return 0;
}
static int c_can_get_berr_counter(const struct net_device *dev,
struct can_berr_counter *bec)
{
108: e1a0c00d mov ip, sp
10c: e92dd830 push {r4, r5, fp, ip, lr, pc}
110: e24cb004 sub fp, ip, #4
114: e52de004 push {lr} ; (str lr, [sp, #-4]!)
118: ebfffffe bl 0 <__gnu_mcount_nc>
11c: e1a04000 mov r4, r0
120: e1a05001 mov r5, r1
pm_runtime_disable(priv->device);
}
static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv)
{
if (priv->device)
124: e59005e4 ldr r0, [r0, #1508] ; 0x5e4
128: e3500000 cmp r0, #0
12c: 0a000001 beq 138 <c_can_get_berr_counter+0x30>
return __pm_runtime_resume(dev, RPM_GET_PUT | RPM_ASYNC);
}
static inline int pm_runtime_get_sync(struct device *dev)
{
return __pm_runtime_resume(dev, RPM_GET_PUT);
130: e3a01004 mov r1, #4
134: ebfffffe bl 0 <__pm_runtime_resume>
struct can_berr_counter *bec)
{
unsigned int reg_err_counter;
struct c_can_priv *priv = netdev_priv(dev);
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
138: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
13c: e2840d13 add r0, r4, #1216 ; 0x4c0
140: e3a01003 mov r1, #3
144: e12fff33 blx r3
bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
ERR_CNT_REC_SHIFT;
bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK;
148: e6ef3070 uxtb r3, r0
{
unsigned int reg_err_counter;
struct c_can_priv *priv = netdev_priv(dev);
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
14c: e7e60450 ubfx r0, r0, #8, #7
150: e1c500b2 strh r0, [r5, #2]
ERR_CNT_REC_SHIFT;
bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK;
154: e1c530b0 strh r3, [r5]
pm_runtime_get_sync(priv->device);
}
static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv)
{
if (priv->device)
158: e59405e4 ldr r0, [r4, #1508] ; 0x5e4
15c: e3500000 cmp r0, #0
160: 0a000001 beq 16c <c_can_get_berr_counter+0x64>
RPM_GET_PUT | RPM_ASYNC | RPM_AUTO);
}
static inline int pm_runtime_put_sync(struct device *dev)
{
return __pm_runtime_idle(dev, RPM_GET_PUT);
164: e3a01004 mov r1, #4
168: ebfffffe bl 0 <__pm_runtime_idle>
c_can_pm_runtime_get_sync(priv);
err = __c_can_get_berr_counter(dev, bec);
c_can_pm_runtime_put_sync(priv);
return err;
}
16c: e3a00000 mov r0, #0
170: e89da830 ldm sp, {r4, r5, fp, sp, pc}
00000174 <c_can_obj_update>:
priv->write_reg(priv, C_CAN_CTRL_REG, ctrl);
}
static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj)
{
174: e1a0c00d mov ip, sp
178: e92dd9f8 push {r3, r4, r5, r6, r7, r8, fp, ip, lr, pc}
17c: e24cb004 sub fp, ip, #4
180: e52de004 push {lr} ; (str lr, [sp, #-4]!)
184: ebfffffe bl 0 <__gnu_mcount_nc>
struct c_can_priv *priv = netdev_priv(dev);
int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
188: e0818101 add r8, r1, r1, lsl #2
priv->write_reg(priv, C_CAN_CTRL_REG, ctrl);
}
static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj)
{
struct c_can_priv *priv = netdev_priv(dev);
18c: e2807d13 add r7, r0, #1216 ; 0x4c0
priv->write_reg(priv, C_CAN_CTRL_REG, ctrl);
}
static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj)
{
190: e1a05000 mov r5, r0
struct c_can_priv *priv = netdev_priv(dev);
int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
priv->write_reg32(priv, reg, (cmd << 16) | obj);
194: e1832802 orr r2, r3, r2, lsl #16
}
static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj)
{
struct c_can_priv *priv = netdev_priv(dev);
int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
198: e0811088 add r1, r1, r8, lsl #1
priv->write_reg32(priv, reg, (cmd << 16) | obj);
for (cnt = MIN_TIMEOUT_VALUE; cnt; cnt--) {
if (!(priv->read_reg(priv, reg) & IF_COMR_BUSY))
return;
udelay(1);
19c: e3006000 movw r6, #0
static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj)
{
struct c_can_priv *priv = netdev_priv(dev);
int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
priv->write_reg32(priv, reg, (cmd << 16) | obj);
1a0: e5903600 ldr r3, [r0, #1536] ; 0x600
1a4: e1a00007 mov r0, r7
}
static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj)
{
struct c_can_priv *priv = netdev_priv(dev);
int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
1a8: e2818008 add r8, r1, #8
priv->write_reg32(priv, reg, (cmd << 16) | obj);
for (cnt = MIN_TIMEOUT_VALUE; cnt; cnt--) {
if (!(priv->read_reg(priv, reg) & IF_COMR_BUSY))
return;
udelay(1);
1ac: e3406000 movt r6, #0
static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj)
{
struct c_can_priv *priv = netdev_priv(dev);
int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
priv->write_reg32(priv, reg, (cmd << 16) | obj);
1b0: e1a01008 mov r1, r8
1b4: e3a04006 mov r4, #6
1b8: e12fff33 blx r3
for (cnt = MIN_TIMEOUT_VALUE; cnt; cnt--) {
if (!(priv->read_reg(priv, reg) & IF_COMR_BUSY))
1bc: e59535f4 ldr r3, [r5, #1524] ; 0x5f4
1c0: e1a00007 mov r0, r7
1c4: e1a01008 mov r1, r8
1c8: e12fff33 blx r3
1cc: e3100902 tst r0, #32768 ; 0x8000
return;
udelay(1);
1d0: e30a036e movw r0, #41838 ; 0xa36e
1d4: e3400001 movt r0, #1
int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
priv->write_reg32(priv, reg, (cmd << 16) | obj);
for (cnt = MIN_TIMEOUT_VALUE; cnt; cnt--) {
if (!(priv->read_reg(priv, reg) & IF_COMR_BUSY))
1d8: 089da9f8 ldmeq sp, {r3, r4, r5, r6, r7, r8, fp, sp, pc}
return;
udelay(1);
1dc: e5963004 ldr r3, [r6, #4]
1e0: e12fff33 blx r3
struct c_can_priv *priv = netdev_priv(dev);
int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
priv->write_reg32(priv, reg, (cmd << 16) | obj);
for (cnt = MIN_TIMEOUT_VALUE; cnt; cnt--) {
1e4: e2544001 subs r4, r4, #1
1e8: 1afffff3 bne 1bc <c_can_obj_update+0x48>
if (!(priv->read_reg(priv, reg) & IF_COMR_BUSY))
return;
udelay(1);
}
netdev_err(dev, "Updating object timed out\n");
1ec: e3001000 movw r1, #0
1f0: e1a00005 mov r0, r5
1f4: e3401000 movt r1, #0
1f8: ebfffffe bl 0 <netdev_err>
1fc: e89da9f8 ldm sp, {r3, r4, r5, r6, r7, r8, fp, sp, pc}
00000200 <c_can_inval_tx_object>:
* Note: According to documentation clearing TXIE while MSGVAL is set
* is not allowed, but works nicely on C/DCAN. And that lowers the I/O
* load significantly.
*/
static void c_can_inval_tx_object(struct net_device *dev, int iface, int obj)
{
200: e1a0c00d mov ip, sp
204: e92dd878 push {r3, r4, r5, r6, fp, ip, lr, pc}
208: e24cb004 sub fp, ip, #4
20c: e52de004 push {lr} ; (str lr, [sp, #-4]!)
210: ebfffffe bl 0 <__gnu_mcount_nc>
214: e1a04001 mov r4, r1
struct c_can_priv *priv = netdev_priv(dev);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
218: e0811101 add r1, r1, r1, lsl #2
21c: e59035f8 ldr r3, [r0, #1528] ; 0x5f8
* Note: According to documentation clearing TXIE while MSGVAL is set
* is not allowed, but works nicely on C/DCAN. And that lowers the I/O
* load significantly.
*/
static void c_can_inval_tx_object(struct net_device *dev, int iface, int obj)
{
220: e1a05000 mov r5, r0
struct c_can_priv *priv = netdev_priv(dev);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
224: e0841081 add r1, r4, r1, lsl #1
* Note: According to documentation clearing TXIE while MSGVAL is set
* is not allowed, but works nicely on C/DCAN. And that lowers the I/O
* load significantly.
*/
static void c_can_inval_tx_object(struct net_device *dev, int iface, int obj)
{
228: e1a06002 mov r6, r2
struct c_can_priv *priv = netdev_priv(dev);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
22c: e2800d13 add r0, r0, #1216 ; 0x4c0
230: e3a02000 mov r2, #0
234: e281100e add r1, r1, #14
238: e12fff33 blx r3
}
static inline void c_can_object_put(struct net_device *dev, int iface,
u32 obj, u32 cmd)
{
c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj);
23c: e1a00005 mov r0, r5
240: e1a01004 mov r1, r4
244: e1a03006 mov r3, r6
248: e3a020b0 mov r2, #176 ; 0xb0
24c: ebffffc8 bl 174 <c_can_obj_update>
250: e89da878 ldm sp, {r3, r4, r5, r6, fp, sp, pc}
00000254 <c_can_inval_msg_object>:
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
c_can_object_put(dev, iface, obj, IF_COMM_INVAL);
}
static void c_can_inval_msg_object(struct net_device *dev, int iface, int obj)
{
254: e1a0c00d mov ip, sp
258: e92dd9f8 push {r3, r4, r5, r6, r7, r8, fp, ip, lr, pc}
25c: e24cb004 sub fp, ip, #4
260: e52de004 push {lr} ; (str lr, [sp, #-4]!)
264: ebfffffe bl 0 <__gnu_mcount_nc>
struct c_can_priv *priv = netdev_priv(dev);
priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0);
268: e0817101 add r7, r1, r1, lsl #2
c_can_object_put(dev, iface, obj, IF_COMM_INVAL);
}
static void c_can_inval_msg_object(struct net_device *dev, int iface, int obj)
{
struct c_can_priv *priv = netdev_priv(dev);
26c: e2806d13 add r6, r0, #1216 ; 0x4c0
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
c_can_object_put(dev, iface, obj, IF_COMM_INVAL);
}
static void c_can_inval_msg_object(struct net_device *dev, int iface, int obj)
{
270: e1a05000 mov r5, r0
struct c_can_priv *priv = netdev_priv(dev);
priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0);
274: e59035f8 ldr r3, [r0, #1528] ; 0x5f8
278: e0817087 add r7, r1, r7, lsl #1
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
c_can_object_put(dev, iface, obj, IF_COMM_INVAL);
}
static void c_can_inval_msg_object(struct net_device *dev, int iface, int obj)
{
27c: e1a04001 mov r4, r1
280: e1a08002 mov r8, r2
struct c_can_priv *priv = netdev_priv(dev);
priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0);
284: e1a00006 mov r0, r6
288: e287100c add r1, r7, #12
28c: e3a02000 mov r2, #0
290: e12fff33 blx r3
priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0);
294: e287100d add r1, r7, #13
298: e1a00006 mov r0, r6
29c: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
2a0: e3a02000 mov r2, #0
2a4: e12fff33 blx r3
c_can_inval_tx_object(dev, iface, obj);
2a8: e1a00005 mov r0, r5
2ac: e1a01004 mov r1, r4
2b0: e1a02008 mov r2, r8
2b4: ebffffd1 bl 200 <c_can_inval_tx_object>
2b8: e89da9f8 ldm sp, {r3, r4, r5, r6, r7, r8, fp, sp, pc}
000002bc <c_can_wait_for_ctrl_init>:
return NETDEV_TX_OK;
}
static int c_can_wait_for_ctrl_init(struct net_device *dev,
struct c_can_priv *priv, u32 init)
{
2bc: e1a0c00d mov ip, sp
2c0: e92dd9f8 push {r3, r4, r5, r6, r7, r8, fp, ip, lr, pc}
2c4: e24cb004 sub fp, ip, #4
2c8: e52de004 push {lr} ; (str lr, [sp, #-4]!)
2cc: ebfffffe bl 0 <__gnu_mcount_nc>
int retry = 0;
while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) {
udelay(10);
2d0: e3006000 movw r6, #0
return NETDEV_TX_OK;
}
static int c_can_wait_for_ctrl_init(struct net_device *dev,
struct c_can_priv *priv, u32 init)
{
2d4: e1a08000 mov r8, r0
2d8: e1a05001 mov r5, r1
2dc: e1a07002 mov r7, r2
int retry = 0;
while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) {
udelay(10);
2e0: e3406000 movt r6, #0
static int c_can_wait_for_ctrl_init(struct net_device *dev,
struct c_can_priv *priv, u32 init)
{
int retry = 0;
while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) {
2e4: e30043ea movw r4, #1002 ; 0x3ea
2e8: ea000003 b 2fc <c_can_wait_for_ctrl_init+0x40>
udelay(10);
2ec: e5963004 ldr r3, [r6, #4]
2f0: e12fff33 blx r3
if (retry++ > 1000) {
2f4: e2544001 subs r4, r4, #1
2f8: 0a00000a beq 328 <c_can_wait_for_ctrl_init+0x6c>
static int c_can_wait_for_ctrl_init(struct net_device *dev,
struct c_can_priv *priv, u32 init)
{
int retry = 0;
while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) {
2fc: e5953134 ldr r3, [r5, #308] ; 0x134
300: e1a00005 mov r0, r5
304: e3a01000 mov r1, #0
308: e12fff33 blx r3
30c: e2003001 and r3, r0, #1
udelay(10);
310: e306024c movw r0, #25164 ; 0x624c
static int c_can_wait_for_ctrl_init(struct net_device *dev,
struct c_can_priv *priv, u32 init)
{
int retry = 0;
while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) {
314: e1530007 cmp r3, r7
udelay(10);
318: e3400010 movt r0, #16
static int c_can_wait_for_ctrl_init(struct net_device *dev,
struct c_can_priv *priv, u32 init)
{
int retry = 0;
while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) {
31c: 1afffff2 bne 2ec <c_can_wait_for_ctrl_init+0x30>
if (retry++ > 1000) {
netdev_err(dev, "CCTRL: set CONTROL_INIT failed\n");
return -EIO;
}
}
return 0;
320: e3a00000 mov r0, #0
}
324: e89da9f8 ldm sp, {r3, r4, r5, r6, r7, r8, fp, sp, pc}
int retry = 0;
while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) {
udelay(10);
if (retry++ > 1000) {
netdev_err(dev, "CCTRL: set CONTROL_INIT failed\n");
328: e3001000 movw r1, #0
32c: e1a00008 mov r0, r8
330: e3401000 movt r1, #0
334: ebfffffe bl 0 <netdev_err>
return -EIO;
338: e3e00004 mvn r0, #4
33c: e89da9f8 ldm sp, {r3, r4, r5, r6, r7, r8, fp, sp, pc}
00000340 <c_can_handle_state_change>:
return pkts;
}
static int c_can_handle_state_change(struct net_device *dev,
enum c_can_bus_error_types error_type)
{
340: e1a0c00d mov ip, sp
344: e92dd9f0 push {r4, r5, r6, r7, r8, fp, ip, lr, pc}
348: e24cb004 sub fp, ip, #4
34c: e24dd00c sub sp, sp, #12
350: e52de004 push {lr} ; (str lr, [sp, #-4]!)
354: ebfffffe bl 0 <__gnu_mcount_nc>
struct net_device_stats *stats = &dev->stats;
struct can_frame *cf;
struct sk_buff *skb;
struct can_berr_counter bec;
switch (error_type) {
358: e3510002 cmp r1, #2
return pkts;
}
static int c_can_handle_state_change(struct net_device *dev,
enum c_can_bus_error_types error_type)
{
35c: e1a05001 mov r5, r1
360: e1a04000 mov r4, r0
unsigned int reg_err_counter;
unsigned int rx_err_passive;
struct c_can_priv *priv = netdev_priv(dev);
364: e2807d13 add r7, r0, #1216 ; 0x4c0
struct net_device_stats *stats = &dev->stats;
struct can_frame *cf;
struct sk_buff *skb;
struct can_berr_counter bec;
switch (error_type) {
368: 0a00004b beq 49c <c_can_handle_state_change+0x15c>
36c: e3510003 cmp r1, #3
370: 0a000043 beq 484 <c_can_handle_state_change+0x144>
374: e3510001 cmp r1, #1
378: 0a00003b beq 46c <c_can_handle_state_change+0x12c>
default:
break;
}
/* propagate the error condition to the CAN stack */
skb = alloc_can_err_skb(dev, &cf);
37c: e1a00004 mov r0, r4
380: e24b1028 sub r1, fp, #40 ; 0x28
384: ebfffffe bl 0 <alloc_can_err_skb>
if (unlikely(!skb))
388: e2506000 subs r6, r0, #0
38c: 0a000055 beq 4e8 <c_can_handle_state_change+0x1a8>
struct can_berr_counter *bec)
{
unsigned int reg_err_counter;
struct c_can_priv *priv = netdev_priv(dev);
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
390: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
394: e1a00007 mov r0, r7
398: e3a01003 mov r1, #3
39c: e12fff33 blx r3
skb = alloc_can_err_skb(dev, &cf);
if (unlikely(!skb))
return 0;
__c_can_get_berr_counter(dev, &bec);
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
3a0: e59425f4 ldr r2, [r4, #1524] ; 0x5f4
struct can_berr_counter *bec)
{
unsigned int reg_err_counter;
struct c_can_priv *priv = netdev_priv(dev);
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
3a4: e1a03000 mov r3, r0
skb = alloc_can_err_skb(dev, &cf);
if (unlikely(!skb))
return 0;
__c_can_get_berr_counter(dev, &bec);
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
3a8: e3a01003 mov r1, #3
3ac: e1a00007 mov r0, r7
struct c_can_priv *priv = netdev_priv(dev);
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
ERR_CNT_REC_SHIFT;
bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK;
3b0: e6ef8073 uxtb r8, r3
{
unsigned int reg_err_counter;
struct c_can_priv *priv = netdev_priv(dev);
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
3b4: e7e67453 ubfx r7, r3, #8, #7
skb = alloc_can_err_skb(dev, &cf);
if (unlikely(!skb))
return 0;
__c_can_get_berr_counter(dev, &bec);
reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
3b8: e12fff32 blx r2
rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >>
ERR_CNT_RP_SHIFT;
switch (error_type) {
3bc: e3550002 cmp r5, #2
3c0: 0a00003b beq 4b4 <c_can_handle_state_change+0x174>
3c4: e3550003 cmp r5, #3
3c8: 0a000015 beq 424 <c_can_handle_state_change+0xe4>
3cc: e3550001 cmp r5, #1
3d0: 1a000005 bne 3ec <c_can_handle_state_change+0xac>
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
break;
case C_CAN_BUS_OFF:
/* bus-off state */
cf->can_id |= CAN_ERR_BUSOFF;
3d4: e51b3028 ldr r3, [fp, #-40] ; 0x28
can_bus_off(dev);
3d8: e1a00004 mov r0, r4
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
break;
case C_CAN_BUS_OFF:
/* bus-off state */
cf->can_id |= CAN_ERR_BUSOFF;
3dc: e5932000 ldr r2, [r3]
3e0: e3822040 orr r2, r2, #64 ; 0x40
3e4: e5832000 str r2, [r3]
can_bus_off(dev);
3e8: ebfffffe bl 0 <can_bus_off>
3ec: e51b2028 ldr r2, [fp, #-40] ; 0x28
break;
default:
break;
}
stats->rx_packets++;
3f0: e59430c0 ldr r3, [r4, #192] ; 0xc0
int netif_rx(struct sk_buff *skb);
int netif_rx_ni(struct sk_buff *skb);
int netif_receive_skb_sk(struct sock *sk, struct sk_buff *skb);
static inline int netif_receive_skb(struct sk_buff *skb)
{
return netif_receive_skb_sk(skb->sk, skb);
3f4: e1a01006 mov r1, r6
stats->rx_bytes += cf->can_dlc;
3f8: e59400c8 ldr r0, [r4, #200] ; 0xc8
break;
default:
break;
}
stats->rx_packets++;
3fc: e2833001 add r3, r3, #1
400: e58430c0 str r3, [r4, #192] ; 0xc0
stats->rx_bytes += cf->can_dlc;
404: e5d23004 ldrb r3, [r2, #4]
408: e0803003 add r3, r0, r3
40c: e58430c8 str r3, [r4, #200] ; 0xc8
410: e5960010 ldr r0, [r6, #16]
414: ebfffffe bl 0 <netif_receive_skb_sk>
netif_receive_skb(skb);
return 1;
418: e3a00001 mov r0, #1
}
41c: e24bd020 sub sp, fp, #32
420: e89da9f0 ldm sp, {r4, r5, r6, r7, r8, fp, sp, pc}
cf->data[7] = bec.rxerr;
break;
case C_CAN_ERROR_PASSIVE:
/* error passive state */
cf->can_id |= CAN_ERR_CRTL;
424: e51b3028 ldr r3, [fp, #-40] ; 0x28
if (rx_err_passive)
428: e3100902 tst r0, #32768 ; 0x8000
cf->data[7] = bec.rxerr;
break;
case C_CAN_ERROR_PASSIVE:
/* error passive state */
cf->can_id |= CAN_ERR_CRTL;
42c: e5932000 ldr r2, [r3]
430: e3822004 orr r2, r2, #4
434: e5832000 str r2, [r3]
if (rx_err_passive)
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
438: 151b3028 ldrne r3, [fp, #-40] ; 0x28
43c: 051b2028 ldreq r2, [fp, #-40] ; 0x28
440: 15d31009 ldrbne r1, [r3, #9]
444: 11a02003 movne r2, r3
448: 13811010 orrne r1, r1, #16
44c: 15c31009 strbne r1, [r3, #9]
if (bec.txerr > 127)
450: e358007f cmp r8, #127 ; 0x7f
cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
454: 85d23009 ldrbhi r3, [r2, #9]
cf->data[6] = bec.txerr;
458: e5c2800e strb r8, [r2, #14]
cf->data[7] = bec.rxerr;
45c: e5c2700f strb r7, [r2, #15]
/* error passive state */
cf->can_id |= CAN_ERR_CRTL;
if (rx_err_passive)
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
if (bec.txerr > 127)
cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
460: 83833020 orrhi r3, r3, #32
464: 85c23009 strbhi r3, [r2, #9]
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
break;
468: eaffffe0 b 3f0 <c_can_handle_state_change+0xb0>
priv->can.state = CAN_STATE_ERROR_PASSIVE;
break;
case C_CAN_BUS_OFF:
/* bus-off state */
priv->can.state = CAN_STATE_BUS_OFF;
priv->can.can_stats.bus_off++;
46c: e59034cc ldr r3, [r0, #1228] ; 0x4cc
priv->can.can_stats.error_passive++;
priv->can.state = CAN_STATE_ERROR_PASSIVE;
break;
case C_CAN_BUS_OFF:
/* bus-off state */
priv->can.state = CAN_STATE_BUS_OFF;
470: e3a02003 mov r2, #3
474: e5802524 str r2, [r0, #1316] ; 0x524
priv->can.can_stats.bus_off++;
478: e2833001 add r3, r3, #1
47c: e58034cc str r3, [r0, #1228] ; 0x4cc
break;
480: eaffffbd b 37c <c_can_handle_state_change+0x3c>
priv->can.can_stats.error_warning++;
priv->can.state = CAN_STATE_ERROR_WARNING;
break;
case C_CAN_ERROR_PASSIVE:
/* error passive state */
priv->can.can_stats.error_passive++;
484: e59034c8 ldr r3, [r0, #1224] ; 0x4c8
priv->can.state = CAN_STATE_ERROR_PASSIVE;
488: e3a02002 mov r2, #2
48c: e5802524 str r2, [r0, #1316] ; 0x524
priv->can.can_stats.error_warning++;
priv->can.state = CAN_STATE_ERROR_WARNING;
break;
case C_CAN_ERROR_PASSIVE:
/* error passive state */
priv->can.can_stats.error_passive++;
490: e2833001 add r3, r3, #1
494: e58034c8 str r3, [r0, #1224] ; 0x4c8
priv->can.state = CAN_STATE_ERROR_PASSIVE;
break;
498: eaffffb7 b 37c <c_can_handle_state_change+0x3c>
struct can_berr_counter bec;
switch (error_type) {
case C_CAN_ERROR_WARNING:
/* error warning state */
priv->can.can_stats.error_warning++;
49c: e59034c4 ldr r3, [r0, #1220] ; 0x4c4
priv->can.state = CAN_STATE_ERROR_WARNING;
4a0: e3a02001 mov r2, #1
4a4: e5802524 str r2, [r0, #1316] ; 0x524
struct can_berr_counter bec;
switch (error_type) {
case C_CAN_ERROR_WARNING:
/* error warning state */
priv->can.can_stats.error_warning++;
4a8: e0833002 add r3, r3, r2
4ac: e58034c4 str r3, [r0, #1220] ; 0x4c4
priv->can.state = CAN_STATE_ERROR_WARNING;
break;
4b0: eaffffb1 b 37c <c_can_handle_state_change+0x3c>
ERR_CNT_RP_SHIFT;
switch (error_type) {
case C_CAN_ERROR_WARNING:
/* error warning state */
cf->can_id |= CAN_ERR_CRTL;
4b4: e51b3028 ldr r3, [fp, #-40] ; 0x28
cf->data[1] = (bec.txerr > bec.rxerr) ?
4b8: e1570008 cmp r7, r8
4bc: 23a01004 movcs r1, #4
4c0: 33a01008 movcc r1, #8
ERR_CNT_RP_SHIFT;
switch (error_type) {
case C_CAN_ERROR_WARNING:
/* error warning state */
cf->can_id |= CAN_ERR_CRTL;
4c4: e5932000 ldr r2, [r3]
4c8: e3822004 orr r2, r2, #4
4cc: e5832000 str r2, [r3]
cf->data[1] = (bec.txerr > bec.rxerr) ?
4d0: e51b3028 ldr r3, [fp, #-40] ; 0x28
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
cf->data[6] = bec.txerr;
4d4: e5c3800e strb r8, [r3, #14]
cf->data[7] = bec.rxerr;
break;
4d8: e1a02003 mov r2, r3
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] = (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
4dc: e5c3700f strb r7, [r3, #15]
switch (error_type) {
case C_CAN_ERROR_WARNING:
/* error warning state */
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] = (bec.txerr > bec.rxerr) ?
4e0: e5c31009 strb r1, [r3, #9]
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
break;
4e4: eaffffc1 b 3f0 <c_can_handle_state_change+0xb0>
}
/* propagate the error condition to the CAN stack */
skb = alloc_can_err_skb(dev, &cf);
if (unlikely(!skb))
return 0;
4e8: e1a00006 mov r0, r6
4ec: eaffffca b 41c <c_can_handle_state_change+0xdc>
000004f0 <c_can_power_down>:
}
EXPORT_SYMBOL_GPL(alloc_c_can_dev);
#ifdef CONFIG_PM
int c_can_power_down(struct net_device *dev)
{
4f0: e1a0c00d mov ip, sp
4f4: e92dd8f0 push {r4, r5, r6, r7, fp, ip, lr, pc}
4f8: e24cb004 sub fp, ip, #4
4fc: e52de004 push {lr} ; (str lr, [sp, #-4]!)
500: ebfffffe bl 0 <__gnu_mcount_nc>
504: e1a04000 mov r4, r0
u32 val;
unsigned long time_out;
struct c_can_priv *priv = netdev_priv(dev);
if (!(dev->flags & IFF_UP))
508: e5903130 ldr r3, [r0, #304] ; 0x130
50c: e3130001 tst r3, #1
510: 0a00002d beq 5cc <c_can_power_down+0xdc>
return 0;
WARN_ON(priv->type != BOSCH_D_CAN);
514: e5903610 ldr r3, [r0, #1552] ; 0x610
518: e3530002 cmp r3, #2
51c: 1a00002e bne 5dc <c_can_power_down+0xec>
#ifdef CONFIG_PM
int c_can_power_down(struct net_device *dev)
{
u32 val;
unsigned long time_out;
struct c_can_priv *priv = netdev_priv(dev);
520: e2846d13 add r6, r4, #1216 ; 0x4c0
return 0;
WARN_ON(priv->type != BOSCH_D_CAN);
/* set PDR value so the device goes to power down mode */
val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
524: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
528: e3a01001 mov r1, #1
52c: e1a00006 mov r0, r6
530: e12fff33 blx r3
val |= CONTROL_EX_PDR;
priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
/* Wait for the PDA bit to get set */
time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
534: e3005000 movw r5, #0
WARN_ON(priv->type != BOSCH_D_CAN);
/* set PDR value so the device goes to power down mode */
val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
val |= CONTROL_EX_PDR;
538: e3802c01 orr r2, r0, #256 ; 0x100
priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
53c: e6ff2072 uxth r2, r2
540: e1a00006 mov r0, r6
544: e59435f8 ldr r3, [r4, #1528] ; 0x5f8
548: e3a01001 mov r1, #1
/* Wait for the PDA bit to get set */
time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
54c: e3405000 movt r5, #0
WARN_ON(priv->type != BOSCH_D_CAN);
/* set PDR value so the device goes to power down mode */
val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
val |= CONTROL_EX_PDR;
priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
550: e12fff33 blx r3
/* Wait for the PDA bit to get set */
time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
554: e5957000 ldr r7, [r5]
558: e2877064 add r7, r7, #100 ; 0x64
while (!(priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
55c: ea000003 b 570 <c_can_power_down+0x80>
time_after(time_out, jiffies))
560: e5953000 ldr r3, [r5]
564: e0673003 rsb r3, r7, r3
568: e3530000 cmp r3, #0
56c: aa000005 bge 588 <c_can_power_down+0x98>
val |= CONTROL_EX_PDR;
priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
/* Wait for the PDA bit to get set */
time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
while (!(priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
570: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
574: e1a00006 mov r0, r6
578: e3a01002 mov r1, #2
57c: e12fff33 blx r3
580: e3100b01 tst r0, #1024 ; 0x400
584: 0afffff5 beq 560 <c_can_power_down+0x70>
time_after(time_out, jiffies))
cpu_relax();
if (time_after(jiffies, time_out))
588: e5953000 ldr r3, [r5]
58c: e0637007 rsb r7, r3, r7
590: e3570000 cmp r7, #0
594: ba00000e blt 5d4 <c_can_power_down+0xe4>
return -ETIMEDOUT;
c_can_stop(dev);
598: e1a00004 mov r0, r4
59c: ebfffeaa bl 4c <c_can_stop>
pm_runtime_put_sync(priv->device);
}
static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable)
{
if (priv->raminit)
5a0: e5943620 ldr r3, [r4, #1568] ; 0x620
5a4: e3530000 cmp r3, #0
5a8: 0a000002 beq 5b8 <c_can_power_down+0xc8>
priv->raminit(priv, enable);
5ac: e1a00006 mov r0, r6
5b0: e3a01000 mov r1, #0
5b4: e12fff33 blx r3
pm_runtime_get_sync(priv->device);
}
static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv)
{
if (priv->device)
5b8: e59405e4 ldr r0, [r4, #1508] ; 0x5e4
5bc: e3500000 cmp r0, #0
5c0: 0a000001 beq 5cc <c_can_power_down+0xdc>
5c4: e3a01004 mov r1, #4
5c8: ebfffffe bl 0 <__pm_runtime_idle>
c_can_stop(dev);
c_can_reset_ram(priv, false);
c_can_pm_runtime_put_sync(priv);
return 0;
5cc: e3a00000 mov r0, #0
5d0: e89da8f0 ldm sp, {r4, r5, r6, r7, fp, sp, pc}
while (!(priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
time_after(time_out, jiffies))
cpu_relax();
if (time_after(jiffies, time_out))
return -ETIMEDOUT;
5d4: e3e0006d mvn r0, #109 ; 0x6d
c_can_reset_ram(priv, false);
c_can_pm_runtime_put_sync(priv);
return 0;
}
5d8: e89da8f0 ldm sp, {r4, r5, r6, r7, fp, sp, pc}
struct c_can_priv *priv = netdev_priv(dev);
if (!(dev->flags & IFF_UP))
return 0;
WARN_ON(priv->type != BOSCH_D_CAN);
5dc: e3000000 movw r0, #0
5e0: e3001497 movw r1, #1175 ; 0x497
5e4: e3400000 movt r0, #0
5e8: ebfffffe bl 0 <warn_slowpath_null>
5ec: eaffffcb b 520 <c_can_power_down+0x30>
000005f0 <free_c_can_dev>:
}
EXPORT_SYMBOL_GPL(c_can_power_up);
#endif
void free_c_can_dev(struct net_device *dev)
{
5f0: e1a0c00d mov ip, sp
5f4: e92dd818 push {r3, r4, fp, ip, lr, pc}
5f8: e24cb004 sub fp, ip, #4
5fc: e52de004 push {lr} ; (str lr, [sp, #-4]!)
600: ebfffffe bl 0 <__gnu_mcount_nc>
604: e1a04000 mov r4, r0
struct c_can_priv *priv = netdev_priv(dev);
netif_napi_del(&priv->napi);
608: e2800e57 add r0, r0, #1392 ; 0x570
60c: ebfffffe bl 0 <netif_napi_del>
free_candev(dev);
610: e1a00004 mov r0, r4
614: ebfffffe bl 0 <free_candev>
618: e89da818 ldm sp, {r3, r4, fp, sp, pc}
0000061c <c_can_close>:
c_can_pm_runtime_put_sync(priv);
return err;
}
static int c_can_close(struct net_device *dev)
{
61c: e1a0c00d mov ip, sp
620: e92dd830 push {r4, r5, fp, ip, lr, pc}
624: e24cb004 sub fp, ip, #4
628: e52de004 push {lr} ; (str lr, [sp, #-4]!)
62c: ebfffffe bl 0 <__gnu_mcount_nc>
630: e1a04000 mov r4, r0
}
}
static inline void netif_tx_stop_queue(struct netdev_queue *dev_queue)
{
set_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state);
634: e3a00000 mov r0, #0
638: e5941240 ldr r1, [r4, #576] ; 0x240
struct c_can_priv *priv = netdev_priv(dev);
netif_stop_queue(dev);
napi_disable(&priv->napi);
63c: e2845d13 add r5, r4, #1216 ; 0x4c0
640: e2811050 add r1, r1, #80 ; 0x50
644: ebfffffe bl 0 <_set_bit>
648: e2840e57 add r0, r4, #1392 ; 0x570
64c: ebfffffe bl 0 <napi_disable>
c_can_stop(dev);
650: e1a00004 mov r0, r4
654: ebfffe7c bl 4c <c_can_stop>
free_irq(dev->irq, dev);
658: e5940028 ldr r0, [r4, #40] ; 0x28
65c: e1a01004 mov r1, r4
660: ebfffffe bl 0 <free_irq>
close_candev(dev);
664: e1a00004 mov r0, r4
668: ebfffffe bl 0 <close_candev>
pm_runtime_put_sync(priv->device);
}
static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable)
{
if (priv->raminit)
66c: e5943620 ldr r3, [r4, #1568] ; 0x620
670: e3530000 cmp r3, #0
674: 0a000002 beq 684 <c_can_close+0x68>
priv->raminit(priv, enable);
678: e1a00005 mov r0, r5
67c: e3a01000 mov r1, #0
680: e12fff33 blx r3
pm_runtime_get_sync(priv->device);
}
static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv)
{
if (priv->device)
684: e59405e4 ldr r0, [r4, #1508] ; 0x5e4
688: e3500000 cmp r0, #0
68c: 0a000001 beq 698 <c_can_close+0x7c>
690: e3a01004 mov r1, #4
694: ebfffffe bl 0 <__pm_runtime_idle>
c_can_pm_runtime_put_sync(priv);
can_led_event(dev, CAN_LED_EVENT_STOP);
return 0;
}
698: e3a00000 mov r0, #0
69c: e89da830 ldm sp, {r4, r5, fp, sp, pc}
000006a0 <c_can_isr>:
return work_done;
}
static irqreturn_t c_can_isr(int irq, void *dev_id)
{
6a0: e1a0c00d mov ip, sp
6a4: e92dd830 push {r4, r5, fp, ip, lr, pc}
6a8: e24cb004 sub fp, ip, #4
6ac: e52de004 push {lr} ; (str lr, [sp, #-4]!)
6b0: ebfffffe bl 0 <__gnu_mcount_nc>
6b4: e1a04001 mov r4, r1
struct net_device *dev = (struct net_device *)dev_id;
struct c_can_priv *priv = netdev_priv(dev);
if (!priv->read_reg(priv, C_CAN_INT_REG))
6b8: e3a01005 mov r1, #5
}
static irqreturn_t c_can_isr(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *)dev_id;
struct c_can_priv *priv = netdev_priv(dev);
6bc: e2845d13 add r5, r4, #1216 ; 0x4c0
if (!priv->read_reg(priv, C_CAN_INT_REG))
6c0: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
6c4: e1a00005 mov r0, r5
6c8: e12fff33 blx r3
6cc: e3500000 cmp r0, #0
6d0: 089da830 ldmeq sp, {r4, r5, fp, sp, pc}
return IRQ_NONE;
/* disable all interrupts and schedule the NAPI */
c_can_irq_control(priv, false);
6d4: e1a00005 mov r0, r5
6d8: e3a01000 mov r1, #0
6dc: ebfffe47 bl 0 <c_can_irq_control>
* @nr: bit number to test
* @addr: Address to start counting from
*/
static inline int test_bit(int nr, const volatile unsigned long *addr)
{
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
6e0: e5940578 ldr r0, [r4, #1400] ; 0x578
6e4: e7e000d0 ubfx r0, r0, #1, #1
* insure only one NAPI poll instance runs. We also make
* sure there is no pending NAPI disable.
*/
static inline bool napi_schedule_prep(struct napi_struct *n)
{
return !napi_disable_pending(n) &&
6e8: e3500000 cmp r0, #0
6ec: 0a000001 beq 6f8 <c_can_isr+0x58>
napi_schedule(&priv->napi);
return IRQ_HANDLED;
6f0: e3a00001 mov r0, #1
}
6f4: e89da830 ldm sp, {r4, r5, fp, sp, pc}
!test_and_set_bit(NAPI_STATE_SCHED, &n->state);
6f8: e2844e57 add r4, r4, #1392 ; 0x570
6fc: e2841008 add r1, r4, #8
700: ebfffffe bl 0 <_test_and_set_bit>
* insure only one NAPI poll instance runs. We also make
* sure there is no pending NAPI disable.
*/
static inline bool napi_schedule_prep(struct napi_struct *n)
{
return !napi_disable_pending(n) &&
704: e3500000 cmp r0, #0
708: 1afffff8 bne 6f0 <c_can_isr+0x50>
* running.
*/
static inline void napi_schedule(struct napi_struct *n)
{
if (napi_schedule_prep(n))
__napi_schedule(n);
70c: e1a00004 mov r0, r4
710: ebfffffe bl 0 <__napi_schedule>
/* disable all interrupts and schedule the NAPI */
c_can_irq_control(priv, false);
napi_schedule(&priv->napi);
return IRQ_HANDLED;
714: e3a00001 mov r0, #1
718: e89da830 ldm sp, {r4, r5, fp, sp, pc}
0000071c <unregister_c_can_dev>:
return err;
}
EXPORT_SYMBOL_GPL(register_c_can_dev);
void unregister_c_can_dev(struct net_device *dev)
{
71c: e1a0c00d mov ip, sp
720: e92dd818 push {r3, r4, fp, ip, lr, pc}
724: e24cb004 sub fp, ip, #4
728: e52de004 push {lr} ; (str lr, [sp, #-4]!)
72c: ebfffffe bl 0 <__gnu_mcount_nc>
730: e1a04000 mov r4, r0
struct c_can_priv *priv = netdev_priv(dev);
unregister_candev(dev);
734: ebfffffe bl 0 <unregister_candev>
pm_runtime_enable(priv->device);
}
static inline void c_can_pm_runtime_disable(const struct c_can_priv *priv)
{
if (priv->device)
738: e59405e4 ldr r0, [r4, #1508] ; 0x5e4
73c: e3500000 cmp r0, #0
740: 089da818 ldmeq sp, {r3, r4, fp, sp, pc}
__pm_runtime_set_status(dev, RPM_SUSPENDED);
}
static inline void pm_runtime_disable(struct device *dev)
{
__pm_runtime_disable(dev, true);
744: e3a01001 mov r1, #1
748: ebfffffe bl 0 <__pm_runtime_disable>
74c: e89da818 ldm sp, {r3, r4, fp, sp, pc}
00000750 <register_c_can_dev>:
.ndo_start_xmit = c_can_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
int register_c_can_dev(struct net_device *dev)
{
750: e1a0c00d mov ip, sp
754: e92dd830 push {r4, r5, fp, ip, lr, pc}
758: e24cb004 sub fp, ip, #4
75c: e52de004 push {lr} ; (str lr, [sp, #-4]!)
760: ebfffffe bl 0 <__gnu_mcount_nc>
764: e1a04000 mov r4, r0
.brp_inc = 1,
};
static inline void c_can_pm_runtime_enable(const struct c_can_priv *priv)
{
if (priv->device)
768: e59005e4 ldr r0, [r0, #1508] ; 0x5e4
76c: e3500000 cmp r0, #0
770: 0a000000 beq 778 <register_c_can_dev+0x28>
pm_runtime_enable(priv->device);
774: ebfffffe bl 0 <pm_runtime_enable>
*/
pinctrl_pm_select_sleep_state(dev->dev.parent);
c_can_pm_runtime_enable(priv);
dev->flags |= IFF_ECHO; /* we support local echo */
778: e5942130 ldr r2, [r4, #304] ; 0x130
dev->netdev_ops = &c_can_netdev_ops;
err = register_candev(dev);
77c: e1a00004 mov r0, r4
pinctrl_pm_select_sleep_state(dev->dev.parent);
c_can_pm_runtime_enable(priv);
dev->flags |= IFF_ECHO; /* we support local echo */
dev->netdev_ops = &c_can_netdev_ops;
780: e59f3030 ldr r3, [pc, #48] ; 7b8 <register_c_can_dev+0x68>
*/
pinctrl_pm_select_sleep_state(dev->dev.parent);
c_can_pm_runtime_enable(priv);
dev->flags |= IFF_ECHO; /* we support local echo */
784: e3822701 orr r2, r2, #262144 ; 0x40000
788: e5842130 str r2, [r4, #304] ; 0x130
dev->netdev_ops = &c_can_netdev_ops;
78c: e5843124 str r3, [r4, #292] ; 0x124
err = register_candev(dev);
790: ebfffffe bl 0 <register_candev>
if (err)
794: e2505000 subs r5, r0, #0
798: 0a000004 beq 7b0 <register_c_can_dev+0x60>
pm_runtime_enable(priv->device);
}
static inline void c_can_pm_runtime_disable(const struct c_can_priv *priv)
{
if (priv->device)
79c: e59405e4 ldr r0, [r4, #1508] ; 0x5e4
7a0: e3500000 cmp r0, #0
7a4: 0a000001 beq 7b0 <register_c_can_dev+0x60>
7a8: e3a01001 mov r1, #1
7ac: ebfffffe bl 0 <__pm_runtime_disable>
c_can_pm_runtime_disable(priv);
else
devm_can_led_init(dev);
return err;
}
7b0: e1a00005 mov r0, r5
7b4: e89da830 ldm sp, {r4, r5, fp, sp, pc}
7b8: 00000030 .word 0x00000030
000007bc <c_can_setup_receive_object.constprop.2>:
netif_receive_skb(skb);
return 0;
}
static void c_can_setup_receive_object(struct net_device *dev, int iface,
7bc: e1a0c00d mov ip, sp
7c0: e92dd8f0 push {r4, r5, r6, r7, fp, ip, lr, pc}
7c4: e24cb004 sub fp, ip, #4
7c8: e52de004 push {lr} ; (str lr, [sp, #-4]!)
7cc: ebfffffe bl 0 <__gnu_mcount_nc>
7d0: e1a04000 mov r4, r0
u32 obj, u32 mask, u32 id, u32 mcont)
{
struct c_can_priv *priv = netdev_priv(dev);
7d4: e2805d13 add r5, r0, #1216 ; 0x4c0
netif_receive_skb(skb);
return 0;
}
static void c_can_setup_receive_object(struct net_device *dev, int iface,
7d8: e1a06001 mov r6, r1
7dc: e1a07002 mov r7, r2
u32 obj, u32 mask, u32 id, u32 mcont)
{
struct c_can_priv *priv = netdev_priv(dev);
mask |= BIT(29);
priv->write_reg32(priv, C_CAN_IFACE(MASK1_REG, iface), mask);
7e0: e1a00005 mov r0, r5
7e4: e5943600 ldr r3, [r4, #1536] ; 0x600
7e8: e3a0100a mov r1, #10
7ec: e3a02202 mov r2, #536870912 ; 0x20000000
7f0: e12fff33 blx r3
id |= IF_ARB_MSGVAL;
priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), id);
7f4: e1a00005 mov r0, r5
7f8: e5943600 ldr r3, [r4, #1536] ; 0x600
7fc: e3a0100c mov r1, #12
800: e3a02102 mov r2, #-2147483648 ; 0x80000000
804: e12fff33 blx r3
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont);
808: e1a00005 mov r0, r5
80c: e6ff2077 uxth r2, r7
810: e59435f8 ldr r3, [r4, #1528] ; 0x5f8
814: e3a0100e mov r1, #14
818: e12fff33 blx r3
}
static inline void c_can_object_put(struct net_device *dev, int iface,
u32 obj, u32 cmd)
{
c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj);
81c: e1a00004 mov r0, r4
820: e1a03006 mov r3, r6
824: e3a01000 mov r1, #0
828: e3a020f0 mov r2, #240 ; 0xf0
82c: ebfffe50 bl 174 <c_can_obj_update>
830: e89da8f0 ldm sp, {r4, r5, r6, r7, fp, sp, pc}
00000834 <c_can_start>:
/* set bittiming params */
return c_can_set_bittiming(dev);
}
static int c_can_start(struct net_device *dev)
{
834: e1a0c00d mov ip, sp
838: e92ddbf0 push {r4, r5, r6, r7, r8, r9, fp, ip, lr, pc}
83c: e24cb004 sub fp, ip, #4
840: e52de004 push {lr} ; (str lr, [sp, #-4]!)
844: ebfffffe bl 0 <__gnu_mcount_nc>
static int c_can_chip_config(struct net_device *dev)
{
struct c_can_priv *priv = netdev_priv(dev);
/* enable automatic retransmission */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR);
848: e3a01000 mov r1, #0
* - set operating mode
* - configure message objects
*/
static int c_can_chip_config(struct net_device *dev)
{
struct c_can_priv *priv = netdev_priv(dev);
84c: e2806d13 add r6, r0, #1216 ; 0x4c0
/* enable automatic retransmission */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR);
850: e59035f8 ldr r3, [r0, #1528] ; 0x5f8
/* set bittiming params */
return c_can_set_bittiming(dev);
}
static int c_can_start(struct net_device *dev)
{
854: e1a05000 mov r5, r0
static int c_can_chip_config(struct net_device *dev)
{
struct c_can_priv *priv = netdev_priv(dev);
/* enable automatic retransmission */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR);
858: e1a02001 mov r2, r1
85c: e1a00006 mov r0, r6
860: e12fff33 blx r3
if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) &&
864: e5953528 ldr r3, [r5, #1320] ; 0x528
868: e2032003 and r2, r3, #3
86c: e3520003 cmp r2, #3
870: 0a00007c beq a68 <c_can_start+0x234>
(priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) {
/* loopback + silent mode : useful for hot self-test */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK | TEST_SILENT);
} else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
874: e2131001 ands r1, r3, #1
878: 1a00006f bne a3c <c_can_start+0x208>
/* loopback mode : useful for self-test function */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK);
} else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
87c: e3130002 tst r3, #2
880: 1a000046 bne 9a0 <c_can_start+0x16c>
/* set bittiming params */
return c_can_set_bittiming(dev);
}
static int c_can_start(struct net_device *dev)
{
884: e3a04001 mov r4, #1
{
int i;
/* first invalidate all message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++)
c_can_inval_msg_object(dev, IF_RX, i);
888: e1a02004 mov r2, r4
88c: e1a00005 mov r0, r5
890: e3a01000 mov r1, #0
static void c_can_configure_msg_objects(struct net_device *dev)
{
int i;
/* first invalidate all message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++)
894: e2844001 add r4, r4, #1
c_can_inval_msg_object(dev, IF_RX, i);
898: ebfffe6d bl 254 <c_can_inval_msg_object>
static void c_can_configure_msg_objects(struct net_device *dev)
{
int i;
/* first invalidate all message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++)
89c: e3540021 cmp r4, #33 ; 0x21
8a0: 1afffff8 bne 888 <c_can_start+0x54>
8a4: e3a04001 mov r4, #1
c_can_inval_msg_object(dev, IF_RX, i);
/* setup receive message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++)
c_can_setup_receive_object(dev, IF_RX, i, 0, 0, IF_MCONT_RCV);
8a8: e1a01004 mov r1, r4
8ac: e1a00005 mov r0, r5
8b0: e3a02b05 mov r2, #5120 ; 0x1400
/* first invalidate all message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++)
c_can_inval_msg_object(dev, IF_RX, i);
/* setup receive message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++)
8b4: e2844001 add r4, r4, #1
c_can_setup_receive_object(dev, IF_RX, i, 0, 0, IF_MCONT_RCV);
8b8: ebffffbf bl 7bc <c_can_setup_receive_object.constprop.2>
/* first invalidate all message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++)
c_can_inval_msg_object(dev, IF_RX, i);
/* setup receive message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++)
8bc: e3540010 cmp r4, #16
8c0: 1afffff8 bne 8a8 <c_can_start+0x74>
c_can_setup_receive_object(dev, IF_RX, i, 0, 0, IF_MCONT_RCV);
c_can_setup_receive_object(dev, IF_RX, C_CAN_MSG_OBJ_RX_LAST, 0, 0,
8c4: e1a01004 mov r1, r4
8c8: e1a00005 mov r0, r5
8cc: e3a02d52 mov r2, #5248 ; 0x1480
/* set a `lec` value so that we can check for updates later */
priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
/* Clear all internal status */
atomic_set(&priv->tx_active, 0);
8d0: e3a04000 mov r4, #0
/* setup receive message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++)
c_can_setup_receive_object(dev, IF_RX, i, 0, 0, IF_MCONT_RCV);
c_can_setup_receive_object(dev, IF_RX, C_CAN_MSG_OBJ_RX_LAST, 0, 0,
8d4: ebffffb8 bl 7bc <c_can_setup_receive_object.constprop.2>
/* configure message objects */
c_can_configure_msg_objects(dev);
/* set a `lec` value so that we can check for updates later */
priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
8d8: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
8dc: e1a00006 mov r0, r6
8e0: e3a01002 mov r1, #2
8e4: e3a02007 mov r2, #7
8e8: e12fff33 blx r3
/* c_can provides a 6-bit brp and 4-bit brpe fields */
ten_bit_brp = bt->brp - 1;
brp = ten_bit_brp & BTR_BRP_MASK;
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
8ec: e59574f0 ldr r7, [r5, #1264] ; 0x4f0
tseg2 = bt->phase_seg2 - 1;
reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
(tseg2 << BTR_TSEG2_SHIFT);
reg_brpe = brpe & BRP_EXT_BRPE_MASK;
netdev_info(dev,
8f0: e3001000 movw r1, #0
struct c_can_priv *priv = netdev_priv(dev);
const struct can_bittiming *bt = &priv->can.bittiming;
int res;
/* c_can provides a 6-bit brp and 4-bit brpe fields */
ten_bit_brp = bt->brp - 1;
8f4: e59534f4 ldr r3, [r5, #1268] ; 0x4f4
tseg2 = bt->phase_seg2 - 1;
reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
(tseg2 << BTR_TSEG2_SHIFT);
reg_brpe = brpe & BRP_EXT_BRPE_MASK;
netdev_info(dev,
8f8: e3401000 movt r1, #0
brp = ten_bit_brp & BTR_BRP_MASK;
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
tseg2 = bt->phase_seg2 - 1;
8fc: e59524ec ldr r2, [r5, #1260] ; 0x4ec
reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
(tseg2 << BTR_TSEG2_SHIFT);
reg_brpe = brpe & BRP_EXT_BRPE_MASK;
netdev_info(dev,
900: e1a00005 mov r0, r5
ten_bit_brp = bt->brp - 1;
brp = ten_bit_brp & BTR_BRP_MASK;
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
904: e595e4e8 ldr lr, [r5, #1256] ; 0x4e8
/* c_can provides a 6-bit brp and 4-bit brpe fields */
ten_bit_brp = bt->brp - 1;
brp = ten_bit_brp & BTR_BRP_MASK;
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
908: e2477001 sub r7, r7, #1
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
90c: e59584e4 ldr r8, [r5, #1252] ; 0x4e4
struct c_can_priv *priv = netdev_priv(dev);
const struct can_bittiming *bt = &priv->can.bittiming;
int res;
/* c_can provides a 6-bit brp and 4-bit brpe fields */
ten_bit_brp = bt->brp - 1;
910: e2433001 sub r3, r3, #1
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
tseg2 = bt->phase_seg2 - 1;
reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
914: e6ef7077 uxtb r7, r7
918: e203c03f and ip, r3, #63 ; 0x3f
brp = ten_bit_brp & BTR_BRP_MASK;
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
tseg2 = bt->phase_seg2 - 1;
91c: e2422001 sub r2, r2, #1
/* set a `lec` value so that we can check for updates later */
priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
/* Clear all internal status */
atomic_set(&priv->tx_active, 0);
920: e58545e8 str r4, [r5, #1512] ; 0x5e8
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
tseg2 = bt->phase_seg2 - 1;
reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
924: e18cc307 orr ip, ip, r7, lsl #6
ten_bit_brp = bt->brp - 1;
brp = ten_bit_brp & BTR_BRP_MASK;
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
928: e088800e add r8, r8, lr
tseg2 = bt->phase_seg2 - 1;
reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
(tseg2 << BTR_TSEG2_SHIFT);
92c: e6ef2072 uxtb r2, r2
ten_bit_brp = bt->brp - 1;
brp = ten_bit_brp & BTR_BRP_MASK;
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
930: e2488001 sub r8, r8, #1
tseg2 = bt->phase_seg2 - 1;
reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
934: e6ef8078 uxtb r8, r8
(tseg2 << BTR_TSEG2_SHIFT);
reg_brpe = brpe & BRP_EXT_BRPE_MASK;
938: e7e37353 ubfx r7, r3, #6, #4
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
tseg2 = bt->phase_seg2 - 1;
reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
93c: e18c2602 orr r2, ip, r2, lsl #12
/* set a `lec` value so that we can check for updates later */
priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
/* Clear all internal status */
atomic_set(&priv->tx_active, 0);
priv->rxmasked = 0;
940: e5854628 str r4, [r5, #1576] ; 0x628
priv->tx_dir = 0;
944: e58545ec str r4, [r5, #1516] ; 0x5ec
tseg2 = bt->phase_seg2 - 1;
reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
(tseg2 << BTR_TSEG2_SHIFT);
reg_brpe = brpe & BRP_EXT_BRPE_MASK;
netdev_info(dev,
948: e1a03007 mov r3, r7
brpe = ten_bit_brp >> 6;
sjw = bt->sjw - 1;
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
tseg2 = bt->phase_seg2 - 1;
reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
94c: e1828408 orr r8, r2, r8, lsl #8
(tseg2 << BTR_TSEG2_SHIFT);
reg_brpe = brpe & BRP_EXT_BRPE_MASK;
netdev_info(dev,
950: e1a02008 mov r2, r8
954: ebfffffe bl 0 <netdev_info>
"setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe);
ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG);
958: e1a01004 mov r1, r4
95c: e59535f4 ldr r3, [r5, #1524] ; 0x5f4
960: e1a00006 mov r0, r6
964: e12fff33 blx r3
ctrl_save &= ~CONTROL_INIT;
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_CCE | CONTROL_INIT);
968: e1a01004 mov r1, r4
96c: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
970: e3a02041 mov r2, #65 ; 0x41
reg_brpe = brpe & BRP_EXT_BRPE_MASK;
netdev_info(dev,
"setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe);
ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG);
974: e1a09000 mov r9, r0
ctrl_save &= ~CONTROL_INIT;
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_CCE | CONTROL_INIT);
978: e1a00006 mov r0, r6
97c: e12fff33 blx r3
res = c_can_wait_for_ctrl_init(dev, priv, CONTROL_INIT);
980: e1a00005 mov r0, r5
984: e1a01006 mov r1, r6
988: e3a02001 mov r2, #1
98c: ebfffe4a bl 2bc <c_can_wait_for_ctrl_init>
if (res)
990: e2504000 subs r4, r0, #0
994: 0a00000b beq 9c8 <c_can_start+0x194>
998: e1a00004 mov r0, r4
pinctrl_put(p);
else
pinctrl_pm_select_default_state(priv->device);
return 0;
}
99c: e89dabf0 ldm sp, {r4, r5, r6, r7, r8, r9, fp, sp, pc}
/* loopback mode : useful for self-test function */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK);
} else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
/* silent mode : bus-monitoring mode */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
9a0: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
9a4: e1a00006 mov r0, r6
9a8: e3a02080 mov r2, #128 ; 0x80
9ac: e12fff33 blx r3
priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT);
9b0: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
9b4: e1a00006 mov r0, r6
9b8: e3a01006 mov r1, #6
9bc: e3a02008 mov r2, #8
9c0: e12fff33 blx r3
9c4: eaffffae b 884 <c_can_start+0x50>
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_CCE | CONTROL_INIT);
res = c_can_wait_for_ctrl_init(dev, priv, CONTROL_INIT);
if (res)
return res;
priv->write_reg(priv, C_CAN_BTR_REG, reg_btr);
9c8: e6ff2078 uxth r2, r8
9cc: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
9d0: e1a00006 mov r0, r6
9d4: e3a01004 mov r1, #4
9d8: e12fff33 blx r3
priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe);
9dc: e1a02007 mov r2, r7
9e0: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
9e4: e1a00006 mov r0, r6
9e8: e3a01007 mov r1, #7
9ec: e12fff33 blx r3
priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save);
9f0: e30f2ffe movw r2, #65534 ; 0xfffe
9f4: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
9f8: e0022009 and r2, r2, r9
9fc: e1a00006 mov r0, r6
a00: e1a01004 mov r1, r4
a04: e12fff33 blx r3
return c_can_wait_for_ctrl_init(dev, priv, 0);
a08: e1a00005 mov r0, r5
a0c: e1a01006 mov r1, r6
a10: e1a02004 mov r2, r4
a14: ebfffe28 bl 2bc <c_can_wait_for_ctrl_init>
int err;
struct pinctrl *p;
/* basic c_can configuration */
err = c_can_chip_config(dev);
if (err)
a18: e3500000 cmp r0, #0
a1c: 189dabf0 ldmne sp, {r4, r5, r6, r7, r8, r9, fp, sp, pc}
return err;
/* Setup the command for new messages */
priv->comm_rcv_high = priv->type != BOSCH_D_CAN ?
a20: e5953610 ldr r3, [r5, #1552] ; 0x610
IF_COMM_RCV_LOW : IF_COMM_RCV_HIGH;
priv->can.state = CAN_STATE_ERROR_ACTIVE;
a24: e5850524 str r0, [r5, #1316] ; 0x524
err = c_can_chip_config(dev);
if (err)
return err;
/* Setup the command for new messages */
priv->comm_rcv_high = priv->type != BOSCH_D_CAN ?
a28: e3530002 cmp r3, #2
a2c: 03a0307f moveq r3, #127 ; 0x7f
a30: 13a0307b movne r3, #123 ; 0x7b
a34: e5853624 str r3, [r5, #1572] ; 0x624
a38: e89dabf0 ldm sp, {r4, r5, r6, r7, r8, r9, fp, sp, pc}
/* loopback + silent mode : useful for hot self-test */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK | TEST_SILENT);
} else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
/* loopback mode : useful for self-test function */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
a3c: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
a40: e1a00006 mov r0, r6
a44: e3a01000 mov r1, #0
a48: e3a02080 mov r2, #128 ; 0x80
a4c: e12fff33 blx r3
priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK);
a50: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
a54: e1a00006 mov r0, r6
a58: e3a01006 mov r1, #6
a5c: e3a02010 mov r2, #16
a60: e12fff33 blx r3
a64: eaffff86 b 884 <c_can_start+0x50>
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR);
if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) &&
(priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) {
/* loopback + silent mode : useful for hot self-test */
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
a68: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
a6c: e1a00006 mov r0, r6
a70: e3a01000 mov r1, #0
a74: e3a02080 mov r2, #128 ; 0x80
a78: e12fff33 blx r3
priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK | TEST_SILENT);
a7c: e59535f8 ldr r3, [r5, #1528] ; 0x5f8
a80: e1a00006 mov r0, r6
a84: e3a01006 mov r1, #6
a88: e3a02018 mov r2, #24
a8c: e12fff33 blx r3
a90: eaffff7b b 884 <c_can_start+0x50>
00000a94 <c_can_set_mode>:
pinctrl_pm_select_sleep_state(dev->dev.parent);
priv->can.state = CAN_STATE_STOPPED;
}
static int c_can_set_mode(struct net_device *dev, enum can_mode mode)
{
a94: e1a0c00d mov ip, sp
a98: e92dd878 push {r3, r4, r5, r6, fp, ip, lr, pc}
a9c: e24cb004 sub fp, ip, #4
aa0: e52de004 push {lr} ; (str lr, [sp, #-4]!)
aa4: ebfffffe bl 0 <__gnu_mcount_nc>
struct c_can_priv *priv = netdev_priv(dev);
int err;
switch (mode) {
aa8: e3510001 cmp r1, #1
pinctrl_pm_select_sleep_state(dev->dev.parent);
priv->can.state = CAN_STATE_STOPPED;
}
static int c_can_set_mode(struct net_device *dev, enum can_mode mode)
{
aac: e1a04001 mov r4, r1
ab0: e1a06000 mov r6, r0
struct c_can_priv *priv = netdev_priv(dev);
int err;
switch (mode) {
ab4: 1a00000b bne ae8 <c_can_set_mode+0x54>
case CAN_MODE_START:
err = c_can_start(dev);
ab8: ebffff5d bl 834 <c_can_start>
if (err)
abc: e2505000 subs r5, r0, #0
ac0: 0a000001 beq acc <c_can_set_mode+0x38>
ac4: e1a00005 mov r0, r5
default:
return -EOPNOTSUPP;
}
return 0;
}
ac8: e89da878 ldm sp, {r3, r4, r5, r6, fp, sp, pc}
* Allow upper layers to call the device hard_start_xmit routine.
* Used for flow control when transmit resources are available.
*/
static inline void netif_wake_queue(struct net_device *dev)
{
netif_tx_wake_queue(netdev_get_tx_queue(dev, 0));
acc: e5960240 ldr r0, [r6, #576] ; 0x240
ad0: ebfffffe bl 0 <netif_tx_wake_queue>
case CAN_MODE_START:
err = c_can_start(dev);
if (err)
return err;
netif_wake_queue(dev);
c_can_irq_control(priv, true);
ad4: e2860d13 add r0, r6, #1216 ; 0x4c0
ad8: e1a01004 mov r1, r4
adc: ebfffd47 bl 0 <c_can_irq_control>
break;
default:
return -EOPNOTSUPP;
}
return 0;
ae0: e1a00005 mov r0, r5
ae4: e89da878 ldm sp, {r3, r4, r5, r6, fp, sp, pc}
return err;
netif_wake_queue(dev);
c_can_irq_control(priv, true);
break;
default:
return -EOPNOTSUPP;
ae8: e3e0005e mvn r0, #94 ; 0x5e
aec: e89da878 ldm sp, {r3, r4, r5, r6, fp, sp, pc}
00000af0 <c_can_power_up>:
return 0;
}
EXPORT_SYMBOL_GPL(c_can_power_down);
int c_can_power_up(struct net_device *dev)
{
af0: e1a0c00d mov ip, sp
af4: e92dd8f0 push {r4, r5, r6, r7, fp, ip, lr, pc}
af8: e24cb004 sub fp, ip, #4
afc: e52de004 push {lr} ; (str lr, [sp, #-4]!)
b00: ebfffffe bl 0 <__gnu_mcount_nc>
b04: e1a04000 mov r4, r0
u32 val;
unsigned long time_out;
struct c_can_priv *priv = netdev_priv(dev);
int ret;
if (!(dev->flags & IFF_UP))
b08: e5900130 ldr r0, [r0, #304] ; 0x130
b0c: e2100001 ands r0, r0, #1
b10: 089da8f0 ldmeq sp, {r4, r5, r6, r7, fp, sp, pc}
return 0;
WARN_ON(priv->type != BOSCH_D_CAN);
b14: e5943610 ldr r3, [r4, #1552] ; 0x610
b18: e3530002 cmp r3, #2
b1c: 1a00003f bne c20 <c_can_power_up+0x130>
pm_runtime_disable(priv->device);
}
static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv)
{
if (priv->device)
b20: e59405e4 ldr r0, [r4, #1508] ; 0x5e4
b24: e3500000 cmp r0, #0
b28: 0a000001 beq b34 <c_can_power_up+0x44>
return __pm_runtime_resume(dev, RPM_GET_PUT | RPM_ASYNC);
}
static inline int pm_runtime_get_sync(struct device *dev)
{
return __pm_runtime_resume(dev, RPM_GET_PUT);
b2c: e3a01004 mov r1, #4
b30: ebfffffe bl 0 <__pm_runtime_resume>
pm_runtime_put_sync(priv->device);
}
static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable)
{
if (priv->raminit)
b34: e5943620 ldr r3, [r4, #1568] ; 0x620
int c_can_power_up(struct net_device *dev)
{
u32 val;
unsigned long time_out;
struct c_can_priv *priv = netdev_priv(dev);
b38: e2845d13 add r5, r4, #1216 ; 0x4c0
pm_runtime_put_sync(priv->device);
}
static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable)
{
if (priv->raminit)
b3c: e3530000 cmp r3, #0
b40: 0a000002 beq b50 <c_can_power_up+0x60>
priv->raminit(priv, enable);
b44: e1a00005 mov r0, r5
b48: e3a01001 mov r1, #1
b4c: e12fff33 blx r3
c_can_pm_runtime_get_sync(priv);
c_can_reset_ram(priv, true);
/* Clear PDR and INIT bits */
val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
b50: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
b54: e3a01001 mov r1, #1
b58: e1a00005 mov r0, r5
val = priv->read_reg(priv, C_CAN_CTRL_REG);
val &= ~CONTROL_INIT;
priv->write_reg(priv, C_CAN_CTRL_REG, val);
/* Wait for the PDA bit to get clear */
time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
b5c: e3006000 movw r6, #0
c_can_pm_runtime_get_sync(priv);
c_can_reset_ram(priv, true);
/* Clear PDR and INIT bits */
val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
b60: e12fff33 blx r3
val &= ~CONTROL_EX_PDR;
priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
b64: e30f2eff movw r2, #65279 ; 0xfeff
b68: e59435f8 ldr r3, [r4, #1528] ; 0x5f8
b6c: e0022000 and r2, r2, r0
b70: e3a01001 mov r1, #1
b74: e1a00005 mov r0, r5
val = priv->read_reg(priv, C_CAN_CTRL_REG);
val &= ~CONTROL_INIT;
priv->write_reg(priv, C_CAN_CTRL_REG, val);
/* Wait for the PDA bit to get clear */
time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
b78: e3406000 movt r6, #0
c_can_reset_ram(priv, true);
/* Clear PDR and INIT bits */
val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
val &= ~CONTROL_EX_PDR;
priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
b7c: e12fff33 blx r3
val = priv->read_reg(priv, C_CAN_CTRL_REG);
b80: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
b84: e3a01000 mov r1, #0
b88: e1a00005 mov r0, r5
b8c: e12fff33 blx r3
val &= ~CONTROL_INIT;
priv->write_reg(priv, C_CAN_CTRL_REG, val);
b90: e30f2ffe movw r2, #65534 ; 0xfffe
b94: e59435f8 ldr r3, [r4, #1528] ; 0x5f8
b98: e0022000 and r2, r2, r0
b9c: e3a01000 mov r1, #0
ba0: e1a00005 mov r0, r5
ba4: e12fff33 blx r3
/* Wait for the PDA bit to get clear */
time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
ba8: e5967000 ldr r7, [r6]
bac: e2877064 add r7, r7, #100 ; 0x64
while ((priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
bb0: ea000003 b bc4 <c_can_power_up+0xd4>
time_after(time_out, jiffies))
bb4: e5963000 ldr r3, [r6]
bb8: e0673003 rsb r3, r7, r3
bbc: e3530000 cmp r3, #0
bc0: aa000005 bge bdc <c_can_power_up+0xec>
val &= ~CONTROL_INIT;
priv->write_reg(priv, C_CAN_CTRL_REG, val);
/* Wait for the PDA bit to get clear */
time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
while ((priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
bc4: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
bc8: e1a00005 mov r0, r5
bcc: e3a01002 mov r1, #2
bd0: e12fff33 blx r3
bd4: e3100b01 tst r0, #1024 ; 0x400
bd8: 1afffff5 bne bb4 <c_can_power_up+0xc4>
time_after(time_out, jiffies))
cpu_relax();
if (time_after(jiffies, time_out))
bdc: e5963000 ldr r3, [r6]
be0: e0637007 rsb r7, r3, r7
be4: e3570000 cmp r7, #0
be8: ba00000a blt c18 <c_can_power_up+0x128>
return -ETIMEDOUT;
ret = c_can_start(dev);
bec: e1a00004 mov r0, r4
bf0: ebffff0f bl 834 <c_can_start>
if (!ret)
bf4: e2504000 subs r4, r0, #0
bf8: 0a000001 beq c04 <c_can_power_up+0x114>
bfc: e1a00004 mov r0, r4
c_can_irq_control(priv, true);
return ret;
}
c00: e89da8f0 ldm sp, {r4, r5, r6, r7, fp, sp, pc}
if (time_after(jiffies, time_out))
return -ETIMEDOUT;
ret = c_can_start(dev);
if (!ret)
c_can_irq_control(priv, true);
c04: e1a00005 mov r0, r5
c08: e3a01001 mov r1, #1
c0c: ebfffcfb bl 0 <c_can_irq_control>
c10: e1a00004 mov r0, r4
c14: e89da8f0 ldm sp, {r4, r5, r6, r7, fp, sp, pc}
while ((priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
time_after(time_out, jiffies))
cpu_relax();
if (time_after(jiffies, time_out))
return -ETIMEDOUT;
c18: e3e0006d mvn r0, #109 ; 0x6d
c1c: e89da8f0 ldm sp, {r4, r5, r6, r7, fp, sp, pc}
int ret;
if (!(dev->flags & IFF_UP))
return 0;
WARN_ON(priv->type != BOSCH_D_CAN);
c20: e3000000 movw r0, #0
c24: e30014ba movw r1, #1210 ; 0x4ba
c28: e3400000 movt r0, #0
c2c: ebfffffe bl 0 <warn_slowpath_null>
c30: eaffffba b b20 <c_can_power_up+0x30>
00000c34 <c_can_open>:
return IRQ_HANDLED;
}
static int c_can_open(struct net_device *dev)
{
c34: e1a0c00d mov ip, sp
c38: e92dd870 push {r4, r5, r6, fp, ip, lr, pc}
c3c: e24cb004 sub fp, ip, #4
c40: e24dd00c sub sp, sp, #12
c44: e52de004 push {lr} ; (str lr, [sp, #-4]!)
c48: ebfffffe bl 0 <__gnu_mcount_nc>
c4c: e1a04000 mov r4, r0
pm_runtime_disable(priv->device);
}
static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv)
{
if (priv->device)
c50: e59005e4 ldr r0, [r0, #1508] ; 0x5e4
}
static int c_can_open(struct net_device *dev)
{
int err;
struct c_can_priv *priv = netdev_priv(dev);
c54: e2846d13 add r6, r4, #1216 ; 0x4c0
pm_runtime_disable(priv->device);
}
static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv)
{
if (priv->device)
c58: e3500000 cmp r0, #0
c5c: 0a000001 beq c68 <c_can_open+0x34>
c60: e3a01004 mov r1, #4
c64: ebfffffe bl 0 <__pm_runtime_resume>
pm_runtime_put_sync(priv->device);
}
static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable)
{
if (priv->raminit)
c68: e5943620 ldr r3, [r4, #1568] ; 0x620
c6c: e3530000 cmp r3, #0
c70: 0a000002 beq c80 <c_can_open+0x4c>
priv->raminit(priv, enable);
c74: e1a00006 mov r0, r6
c78: e3a01001 mov r1, #1
c7c: e12fff33 blx r3
c_can_pm_runtime_get_sync(priv);
c_can_reset_ram(priv, true);
/* open the can device */
err = open_candev(dev);
c80: e1a00004 mov r0, r4
c84: ebfffffe bl 0 <open_candev>
if (err) {
c88: e2505000 subs r5, r0, #0
c8c: 0a000012 beq cdc <c_can_open+0xa8>
netdev_err(dev, "failed to open can device\n");
c90: e3001000 movw r1, #0
c94: e1a00004 mov r0, r4
c98: e3401000 movt r1, #0
c9c: ebfffffe bl 0 <netdev_err>
pm_runtime_put_sync(priv->device);
}
static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable)
{
if (priv->raminit)
ca0: e5943620 ldr r3, [r4, #1568] ; 0x620
ca4: e3530000 cmp r3, #0
ca8: 0a000002 beq cb8 <c_can_open+0x84>
priv->raminit(priv, enable);
cac: e1a00006 mov r0, r6
cb0: e3a01000 mov r1, #0
cb4: e12fff33 blx r3
pm_runtime_get_sync(priv->device);
}
static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv)
{
if (priv->device)
cb8: e59405e4 ldr r0, [r4, #1508] ; 0x5e4
cbc: e3500000 cmp r0, #0
exit_irq_fail:
close_candev(dev);
exit_open_fail:
c_can_reset_ram(priv, false);
c_can_pm_runtime_put_sync(priv);
return err;
cc0: 01a00005 moveq r0, r5
pm_runtime_get_sync(priv->device);
}
static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv)
{
if (priv->device)
cc4: 0a000002 beq cd4 <c_can_open+0xa0>
RPM_GET_PUT | RPM_ASYNC | RPM_AUTO);
}
static inline int pm_runtime_put_sync(struct device *dev)
{
return __pm_runtime_idle(dev, RPM_GET_PUT);
cc8: e3a01004 mov r1, #4
ccc: ebfffffe bl 0 <__pm_runtime_idle>
exit_irq_fail:
close_candev(dev);
exit_open_fail:
c_can_reset_ram(priv, false);
c_can_pm_runtime_put_sync(priv);
return err;
cd0: e1a00005 mov r0, r5
}
cd4: e24bd018 sub sp, fp, #24
cd8: e89da870 ldm sp, {r4, r5, r6, fp, sp, pc}
static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
{
return request_threaded_irq(irq, handler, NULL, flags, name, dev);
cdc: e3001000 movw r1, #0
ce0: e5940028 ldr r0, [r4, #40] ; 0x28
ce4: e1a02005 mov r2, r5
ce8: e58d4000 str r4, [sp]
cec: e58d4004 str r4, [sp, #4]
cf0: e3401000 movt r1, #0
cf4: e3a03080 mov r3, #128 ; 0x80
cf8: ebfffffe bl 0 <request_threaded_irq>
}
/* register interrupt handler */
err = request_irq(dev->irq, &c_can_isr, IRQF_SHARED, dev->name,
dev);
if (err < 0) {
cfc: e2505000 subs r5, r0, #0
d00: ba000019 blt d6c <c_can_open+0x138>
netdev_err(dev, "failed to request interrupt\n");
goto exit_irq_fail;
}
/* start the c_can controller */
err = c_can_start(dev);
d04: e1a00004 mov r0, r4
d08: ebfffec9 bl 834 <c_can_start>
if (err)
d0c: e2505000 subs r5, r0, #0
d10: 1a00001c bne d88 <c_can_open+0x154>
d14: e5943578 ldr r3, [r4, #1400] ; 0x578
* Resume NAPI from being scheduled on this context.
* Must be paired with napi_disable.
*/
static inline void napi_enable(struct napi_struct *n)
{
BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
d18: e3130001 tst r3, #1
d1c: 0a00001d beq d98 <c_can_open+0x164>
smp_mb__before_atomic();
d20: f57ff05b dmb ish
clear_bit(NAPI_STATE_SCHED, &n->state);
d24: e2845e57 add r5, r4, #1392 ; 0x570
d28: e3a00000 mov r0, #0
d2c: e2855008 add r5, r5, #8
d30: e1a01005 mov r1, r5
d34: ebfffffe bl 0 <_clear_bit>
clear_bit(NAPI_STATE_NPSVC, &n->state);
d38: e1a01005 mov r1, r5
d3c: e3a00002 mov r0, #2
d40: ebfffffe bl 0 <_clear_bit>
can_led_event(dev, CAN_LED_EVENT_OPEN);
napi_enable(&priv->napi);
/* enable status change, error and module interrupts */
c_can_irq_control(priv, true);
d44: e1a00006 mov r0, r6
d48: e3a01001 mov r1, #1
d4c: ebfffcab bl 0 <c_can_irq_control>
netif_schedule_queue(netdev_get_tx_queue(dev, i));
}
static inline void netif_tx_start_queue(struct netdev_queue *dev_queue)
{
clear_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state);
d50: e5941240 ldr r1, [r4, #576] ; 0x240
d54: e3a00000 mov r0, #0
d58: e2811050 add r1, r1, #80 ; 0x50
d5c: ebfffffe bl 0 <_clear_bit>
netif_start_queue(dev);
return 0;
d60: e3a00000 mov r0, #0
close_candev(dev);
exit_open_fail:
c_can_reset_ram(priv, false);
c_can_pm_runtime_put_sync(priv);
return err;
}
d64: e24bd018 sub sp, fp, #24
d68: e89da870 ldm sp, {r4, r5, r6, fp, sp, pc}
/* register interrupt handler */
err = request_irq(dev->irq, &c_can_isr, IRQF_SHARED, dev->name,
dev);
if (err < 0) {
netdev_err(dev, "failed to request interrupt\n");
d6c: e3001000 movw r1, #0
d70: e1a00004 mov r0, r4
d74: e3401000 movt r1, #0
d78: ebfffffe bl 0 <netdev_err>
return 0;
exit_start_fail:
free_irq(dev->irq, dev);
exit_irq_fail:
close_candev(dev);
d7c: e1a00004 mov r0, r4
d80: ebfffffe bl 0 <close_candev>
d84: eaffffc5 b ca0 <c_can_open+0x6c>
netif_start_queue(dev);
return 0;
exit_start_fail:
free_irq(dev->irq, dev);
d88: e5940028 ldr r0, [r4, #40] ; 0x28
d8c: e1a01004 mov r1, r4
d90: ebfffffe bl 0 <free_irq>
d94: eafffff8 b d7c <c_can_open+0x148>
d98: e7f001f2 .word 0xe7f001f2
00000d9c <c_can_poll>:
netif_receive_skb(skb);
return 1;
}
static int c_can_poll(struct napi_struct *napi, int quota)
{
d9c: e1a0c00d mov ip, sp
da0: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
da4: e24cb004 sub fp, ip, #4
da8: e24dd034 sub sp, sp, #52 ; 0x34
dac: e52de004 push {lr} ; (str lr, [sp, #-4]!)
db0: ebfffffe bl 0 <__gnu_mcount_nc>
struct net_device *dev = napi->dev;
db4: e5904018 ldr r4, [r0, #24]
netif_receive_skb(skb);
return 1;
}
static int c_can_poll(struct napi_struct *napi, int quota)
{
db8: e50b0058 str r0, [fp, #-88] ; 0x58
dbc: e50b1050 str r1, [fp, #-80] ; 0x50
struct net_device *dev = napi->dev;
struct c_can_priv *priv = netdev_priv(dev);
u16 curr, last = priv->last_status;
int work_done = 0;
priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG);
dc0: e3a01002 mov r1, #2
}
static int c_can_poll(struct napi_struct *napi, int quota)
{
struct net_device *dev = napi->dev;
struct c_can_priv *priv = netdev_priv(dev);
dc4: e2848d13 add r8, r4, #1216 ; 0x4c0
u16 curr, last = priv->last_status;
int work_done = 0;
priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG);
dc8: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
dcc: e1a00008 mov r0, r8
static int c_can_poll(struct napi_struct *napi, int quota)
{
struct net_device *dev = napi->dev;
struct c_can_priv *priv = netdev_priv(dev);
u16 curr, last = priv->last_status;
dd0: e59475f0 ldr r7, [r4, #1520] ; 0x5f0
int work_done = 0;
priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG);
dd4: e12fff33 blx r3
/* Ack status on C_CAN. D_CAN is self clearing */
if (priv->type != BOSCH_D_CAN)
dd8: e5943610 ldr r3, [r4, #1552] ; 0x610
struct net_device *dev = napi->dev;
struct c_can_priv *priv = netdev_priv(dev);
u16 curr, last = priv->last_status;
int work_done = 0;
priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG);
ddc: e1a05000 mov r5, r0
de0: e58405f0 str r0, [r4, #1520] ; 0x5f0
/* Ack status on C_CAN. D_CAN is self clearing */
if (priv->type != BOSCH_D_CAN)
de4: e3530002 cmp r3, #2
de8: 0a000004 beq e00 <c_can_poll+0x64>
priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
dec: e59435f8 ldr r3, [r4, #1528] ; 0x5f8
df0: e1a00008 mov r0, r8
df4: e3a01002 mov r1, #2
df8: e3a02007 mov r2, #7
dfc: e12fff33 blx r3
/* handle state changes */
if ((curr & STATUS_EWARN) && (!(last & STATUS_EWARN))) {
e00: e205a040 and sl, r5, #64 ; 0x40
e04: e6ff7077 uxth r7, r7
e08: e6ffa07a uxth sl, sl
e0c: e35a0000 cmp sl, #0
e10: 0a000002 beq e20 <c_can_poll+0x84>
e14: e3170040 tst r7, #64 ; 0x40
static int c_can_poll(struct napi_struct *napi, int quota)
{
struct net_device *dev = napi->dev;
struct c_can_priv *priv = netdev_priv(dev);
u16 curr, last = priv->last_status;
int work_done = 0;
e18: 13a0a000 movne sl, #0
/* Ack status on C_CAN. D_CAN is self clearing */
if (priv->type != BOSCH_D_CAN)
priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
/* handle state changes */
if ((curr & STATUS_EWARN) && (!(last & STATUS_EWARN))) {
e1c: 0a000170 beq 13e4 <c_can_poll+0x648>
netdev_dbg(dev, "entered error warning state\n");
work_done += c_can_handle_state_change(dev, C_CAN_ERROR_WARNING);
}
if ((curr & STATUS_EPASS) && (!(last & STATUS_EPASS))) {
e20: e2056020 and r6, r5, #32
e24: e6ff6076 uxth r6, r6
e28: e3560000 cmp r6, #0
e2c: 0a000001 beq e38 <c_can_poll+0x9c>
e30: e3170020 tst r7, #32
e34: 0a00015f beq 13b8 <c_can_poll+0x61c>
netdev_dbg(dev, "entered error passive state\n");
work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE);
}
if ((curr & STATUS_BOFF) && (!(last & STATUS_BOFF))) {
e38: e2059080 and r9, r5, #128 ; 0x80
e3c: e6ff9079 uxth r9, r9
e40: e3590000 cmp r9, #0
e44: 1a000114 bne 129c <c_can_poll+0x500>
work_done += c_can_handle_state_change(dev, C_CAN_BUS_OFF);
goto end;
}
/* handle bus recovery events */
if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) {
e48: e3170080 tst r7, #128 ; 0x80
e4c: 1a00016f bne 1410 <c_can_poll+0x674>
netdev_dbg(dev, "left bus off state\n");
priv->can.state = CAN_STATE_ERROR_ACTIVE;
}
if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) {
e50: e3560000 cmp r6, #0
e54: 0a00012d beq 1310 <c_can_poll+0x574>
/*
* early exit if no lec update or no error.
* no lec update means that no CAN bus event has been detected
* since CPU wrote 0x7 value to status reg.
*/
if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR)
e58: e2155007 ands r5, r5, #7
e5c: 03a03001 moveq r3, #1
e60: 13a03000 movne r3, #0
e64: e3550007 cmp r5, #7
e68: 03833001 orreq r3, r3, #1
e6c: e3530000 cmp r3, #0
e70: 1a000002 bne e80 <c_can_poll+0xe4>
return 0;
if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
e74: e5943528 ldr r3, [r4, #1320] ; 0x528
e78: e3130010 tst r3, #16
e7c: 1a00012d bne 1338 <c_can_poll+0x59c>
* early exit if no lec update or no error.
* no lec update means that no CAN bus event has been detected
* since CPU wrote 0x7 value to status reg.
*/
if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR)
return 0;
e80: e3a03000 mov r3, #0
/* handle lec errors on the bus */
work_done += c_can_handle_bus_err(dev, curr & LEC_MASK);
/* Handle Tx/Rx events. We do this unconditionally */
work_done += c_can_do_rx_poll(dev, (quota - work_done));
e84: e51b0050 ldr r0, [fp, #-80] ; 0x50
netdev_dbg(dev, "left error passive state\n");
priv->can.state = CAN_STATE_ERROR_ACTIVE;
}
/* handle lec errors on the bus */
work_done += c_can_handle_bus_err(dev, curr & LEC_MASK);
e88: e08a3003 add r3, sl, r3
e8c: e50b3054 str r3, [fp, #-84] ; 0x54
/* Handle Tx/Rx events. We do this unconditionally */
work_done += c_can_do_rx_poll(dev, (quota - work_done));
e90: e0630000 rsb r0, r3, r0
* for a maximum number of 16 objects.
*/
BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16,
"Implementation does not support more message objects than 16");
while (quota > 0) {
e94: e3500000 cmp r0, #0
/* handle lec errors on the bus */
work_done += c_can_handle_bus_err(dev, curr & LEC_MASK);
/* Handle Tx/Rx events. We do this unconditionally */
work_done += c_can_do_rx_poll(dev, (quota - work_done));
e98: e50b0040 str r0, [fp, #-64] ; 0x40
* for a maximum number of 16 objects.
*/
BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16,
"Implementation does not support more message objects than 16");
while (quota > 0) {
e9c: da000165 ble 1438 <c_can_poll+0x69c>
/*
* Find the first set bit after the gap. We walk backwards
* from the last set bit.
*/
for (lasts--; pend & (1 << (lasts - 1)); lasts--);
ea0: e3a0a001 mov sl, #1
* This can result in packet reordering when the readout is slow.
*/
static int c_can_do_rx_poll(struct net_device *dev, int quota)
{
struct c_can_priv *priv = netdev_priv(dev);
u32 pkts = 0, pend = 0, toread, n;
ea4: e3a02000 mov r2, #0
ea8: e50b204c str r2, [fp, #-76] ; 0x4c
eac: e50b2038 str r2, [fp, #-56] ; 0x38
*/
BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16,
"Implementation does not support more message objects than 16");
while (quota > 0) {
if (!pend) {
eb0: e51b3038 ldr r3, [fp, #-56] ; 0x38
eb4: e3530000 cmp r3, #0
eb8: 0a000090 beq 1100 <c_can_poll+0x364>
ebc: e51b5038 ldr r5, [fp, #-56] ; 0x38
ec0: e1e03003 mvn r3, r3
toread = c_can_adjust_pending(pend);
} else {
toread = pend;
}
/* Remove the bits from pend */
pend &= ~toread;
ec4: e51b2038 ldr r2, [fp, #-56] ; 0x38
}
static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv,
u32 pend, int quota)
{
u32 pkts = 0, ctrl, obj;
ec8: e3a09000 mov r9, #0
toread = c_can_adjust_pending(pend);
} else {
toread = pend;
}
/* Remove the bits from pend */
pend &= ~toread;
ecc: e51b7040 ldr r7, [fp, #-64] ; 0x40
ed0: e0022003 and r2, r2, r3
ed4: e50b2038 str r2, [fp, #-56] ; 0x38
* ffs() returns zero if the input was zero, otherwise returns the bit
* position of the first set bit, where the LSB is 1 and MSB is 32.
*/
static inline int ffs(int x)
{
return fls(x & -x);
ed8: e2653000 rsb r3, r5, #0
edc: e0033005 and r3, r3, r5
*/
static inline unsigned int __clz(unsigned int x)
{
unsigned int ret;
asm("clz\t%0, %1" : "=r" (ret) : "r" (x));
ee0: e16f3f13 clz r3, r3
static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv,
u32 pend, int quota)
{
u32 pkts = 0, ctrl, obj;
while ((obj = ffs(pend)) && quota > 0) {
ee4: e2736020 rsbs r6, r3, #32
ee8: 0a0000a2 beq 1178 <c_can_poll+0x3dc>
eec: e3570000 cmp r7, #0
ef0: 0a0000a0 beq 1178 <c_can_poll+0x3dc>
pend &= ~BIT(obj - 1);
ef4: e263c01f rsb ip, r3, #31
}
static inline void c_can_object_get(struct net_device *dev, int iface,
u32 obj, u32 cmd)
{
c_can_obj_update(dev, iface, cmd, obj);
ef8: e5942624 ldr r2, [r4, #1572] ; 0x624
efc: e1a00004 mov r0, r4
f00: e3a01000 mov r1, #0
f04: e1a03006 mov r3, r6
u32 pend, int quota)
{
u32 pkts = 0, ctrl, obj;
while ((obj = ffs(pend)) && quota > 0) {
pend &= ~BIT(obj - 1);
f08: e1c55c1a bic r5, r5, sl, lsl ip
}
static inline void c_can_object_get(struct net_device *dev, int iface,
u32 obj, u32 cmd)
{
c_can_obj_update(dev, iface, cmd, obj);
f0c: ebfffc98 bl 174 <c_can_obj_update>
while ((obj = ffs(pend)) && quota > 0) {
pend &= ~BIT(obj - 1);
c_can_rx_object_get(dev, priv, obj);
ctrl = priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, IF_RX));
f10: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
f14: e1a00008 mov r0, r8
f18: e3a0100e mov r1, #14
f1c: e12fff33 blx r3
if (ctrl & IF_MCONT_MSGLST) {
f20: e3100901 tst r0, #16384 ; 0x4000
while ((obj = ffs(pend)) && quota > 0) {
pend &= ~BIT(obj - 1);
c_can_rx_object_get(dev, priv, obj);
ctrl = priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, IF_RX));
f24: e1a02000 mov r2, r0
if (ctrl & IF_MCONT_MSGLST) {
f28: 1a00004b bne 105c <c_can_poll+0x2c0>
/*
* This really should not happen, but this covers some
* odd HW behaviour. Do not remove that unless you
* want to brick your machine.
*/
if (!(ctrl & IF_MCONT_NEWDAT))
f2c: e3100902 tst r0, #32768 ; 0x8000
f30: 0affffe8 beq ed8 <c_can_poll+0x13c>
struct c_can_priv *priv = netdev_priv(dev);
struct can_frame *frame;
struct sk_buff *skb;
u32 arb, data;
skb = alloc_can_skb(dev, &frame);
f34: e1a00004 mov r0, r4
f38: e24b1030 sub r1, fp, #48 ; 0x30
f3c: e50b205c str r2, [fp, #-92] ; 0x5c
f40: ebfffffe bl 0 <alloc_can_skb>
if (!skb) {
f44: e3500000 cmp r0, #0
f48: e51b205c ldr r2, [fp, #-92] ; 0x5c
f4c: e50b003c str r0, [fp, #-60] ; 0x3c
f50: 0a000111 beq 139c <c_can_poll+0x600>
stats->rx_dropped++;
return -ENOMEM;
}
frame->can_dlc = get_can_dlc(ctrl & 0x0F);
f54: e202200f and r2, r2, #15
f58: e51b3030 ldr r3, [fp, #-48] ; 0x30
f5c: e3520008 cmp r2, #8
arb = priv->read_reg32(priv, C_CAN_IFACE(ARB1_REG, iface));
f60: e1a00008 mov r0, r8
if (!skb) {
stats->rx_dropped++;
return -ENOMEM;
}
frame->can_dlc = get_can_dlc(ctrl & 0x0F);
f64: 23a02008 movcs r2, #8
arb = priv->read_reg32(priv, C_CAN_IFACE(ARB1_REG, iface));
f68: e3a0100c mov r1, #12
if (!skb) {
stats->rx_dropped++;
return -ENOMEM;
}
frame->can_dlc = get_can_dlc(ctrl & 0x0F);
f6c: e5c32004 strb r2, [r3, #4]
arb = priv->read_reg32(priv, C_CAN_IFACE(ARB1_REG, iface));
f70: e59435fc ldr r3, [r4, #1532] ; 0x5fc
f74: e12fff33 blx r3
if (arb & IF_ARB_MSGXTD)
frame->can_id = (arb & CAN_EFF_MASK) | CAN_EFF_FLAG;
f78: e51b3030 ldr r3, [fp, #-48] ; 0x30
frame->can_dlc = get_can_dlc(ctrl & 0x0F);
arb = priv->read_reg32(priv, C_CAN_IFACE(ARB1_REG, iface));
if (arb & IF_ARB_MSGXTD)
f7c: e3100101 tst r0, #1073741824 ; 0x40000000
frame->can_id = (arb & CAN_EFF_MASK) | CAN_EFF_FLAG;
f80: 13c0220e bicne r2, r0, #-536870912 ; 0xe0000000
else
frame->can_id = (arb >> 18) & CAN_SFF_MASK;
f84: 07ea2950 ubfxeq r2, r0, #18, #11
frame->can_dlc = get_can_dlc(ctrl & 0x0F);
arb = priv->read_reg32(priv, C_CAN_IFACE(ARB1_REG, iface));
if (arb & IF_ARB_MSGXTD)
frame->can_id = (arb & CAN_EFF_MASK) | CAN_EFF_FLAG;
f88: 13822102 orrne r2, r2, #-2147483648 ; 0x80000000
else
frame->can_id = (arb >> 18) & CAN_SFF_MASK;
f8c: e5832000 str r2, [r3]
if (arb & IF_ARB_TRANSMIT) {
f90: e2103202 ands r3, r0, #536870912 ; 0x20000000
f94: 1a000053 bne 10e8 <c_can_poll+0x34c>
frame->can_id |= CAN_RTR_FLAG;
} else {
int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
f98: e51b0030 ldr r0, [fp, #-48] ; 0x30
f9c: e5d02004 ldrb r2, [r0, #4]
fa0: e3520000 cmp r2, #0
fa4: 0a000017 beq 1008 <c_can_poll+0x26c>
fa8: e3a0200f mov r2, #15
fac: e50b5044 str r5, [fp, #-68] ; 0x44
fb0: e50b6048 str r6, [fp, #-72] ; 0x48
fb4: e1a05004 mov r5, r4
fb8: e1a06002 mov r6, r2
fbc: e1a04003 mov r4, r3
data = priv->read_reg(priv, dreg);
fc0: e1a01006 mov r1, r6
fc4: e595c5f4 ldr ip, [r5, #1524] ; 0x5f4
fc8: e1a00008 mov r0, r8
if (arb & IF_ARB_TRANSMIT) {
frame->can_id |= CAN_RTR_FLAG;
} else {
int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
fcc: e2866001 add r6, r6, #1
data = priv->read_reg(priv, dreg);
fd0: e12fff3c blx ip
frame->data[i] = data;
fd4: e51b1030 ldr r1, [fp, #-48] ; 0x30
frame->data[i + 1] = data >> 8;
fd8: e1a0e420 lsr lr, r0, #8
} else {
int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
data = priv->read_reg(priv, dreg);
frame->data[i] = data;
fdc: e081c004 add ip, r1, r4
if (arb & IF_ARB_TRANSMIT) {
frame->can_id |= CAN_RTR_FLAG;
} else {
int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
fe0: e2844002 add r4, r4, #2
data = priv->read_reg(priv, dreg);
frame->data[i] = data;
frame->data[i + 1] = data >> 8;
fe4: e5cce009 strb lr, [ip, #9]
} else {
int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
data = priv->read_reg(priv, dreg);
frame->data[i] = data;
fe8: e5cc0008 strb r0, [ip, #8]
if (arb & IF_ARB_TRANSMIT) {
frame->can_id |= CAN_RTR_FLAG;
} else {
int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
fec: e5d10004 ldrb r0, [r1, #4]
ff0: e1540000 cmp r4, r0
ff4: bafffff1 blt fc0 <c_can_poll+0x224>
ff8: e1a04005 mov r4, r5
ffc: e51b6048 ldr r6, [fp, #-72] ; 0x48
1000: e51b5044 ldr r5, [fp, #-68] ; 0x44
data = priv->read_reg(priv, dreg);
frame->data[i] = data;
1004: e1a00001 mov r0, r1
frame->data[i + 1] = data >> 8;
}
}
stats->rx_packets++;
1008: e59430c0 ldr r3, [r4, #192] ; 0xc0
stats->rx_bytes += frame->can_dlc;
100c: e59420c8 ldr r2, [r4, #200] ; 0xc8
int netif_rx(struct sk_buff *skb);
int netif_rx_ni(struct sk_buff *skb);
int netif_receive_skb_sk(struct sock *sk, struct sk_buff *skb);
static inline int netif_receive_skb(struct sk_buff *skb)
{
return netif_receive_skb_sk(skb->sk, skb);
1010: e51b103c ldr r1, [fp, #-60] ; 0x3c
frame->data[i] = data;
frame->data[i + 1] = data >> 8;
}
}
stats->rx_packets++;
1014: e2833001 add r3, r3, #1
1018: e58430c0 str r3, [r4, #192] ; 0xc0
stats->rx_bytes += frame->can_dlc;
101c: e5d03004 ldrb r3, [r0, #4]
1020: e0823003 add r3, r2, r3
1024: e58430c8 str r3, [r4, #200] ; 0xc8
1028: e5910010 ldr r0, [r1, #16]
102c: ebfffffe bl 0 <netif_receive_skb_sk>
}
static inline void c_can_rx_finalize(struct net_device *dev,
struct c_can_priv *priv, u32 obj)
{
if (priv->type != BOSCH_D_CAN)
1030: e5943610 ldr r3, [r4, #1552] ; 0x610
1034: e3530002 cmp r3, #2
1038: 0a000004 beq 1050 <c_can_poll+0x2b4>
}
static inline void c_can_object_get(struct net_device *dev, int iface,
u32 obj, u32 cmd)
{
c_can_obj_update(dev, iface, cmd, obj);
103c: e1a03006 mov r3, r6
1040: e1a00004 mov r0, r4
1044: e3a01000 mov r1, #0
1048: e3a02004 mov r2, #4
104c: ebfffc48 bl 174 <c_can_obj_update>
/* read the data from the message object */
c_can_read_msg_object(dev, IF_RX, ctrl);
c_can_rx_finalize(dev, priv, obj);
pkts++;
1050: e2899001 add r9, r9, #1
quota--;
1054: e2477001 sub r7, r7, #1
1058: eaffff9e b ed8 <c_can_poll+0x13c>
struct c_can_priv *priv = netdev_priv(dev);
struct can_frame *frame;
struct sk_buff *skb;
ctrl &= ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
105c: e7ec2050 ubfx r2, r0, #0, #13
1060: e59435f8 ldr r3, [r4, #1528] ; 0x5f8
1064: e1a00008 mov r0, r8
1068: e3a0100e mov r1, #14
106c: e12fff33 blx r3
}
static inline void c_can_object_put(struct net_device *dev, int iface,
u32 obj, u32 cmd)
{
c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj);
1070: e1a00004 mov r0, r4
1074: e1a03006 mov r3, r6
1078: e3a01000 mov r1, #0
107c: e3a02090 mov r2, #144 ; 0x90
1080: ebfffc3b bl 174 <c_can_obj_update>
ctrl &= ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
c_can_object_put(dev, iface, objno, IF_COMM_CONTROL);
stats->rx_errors++;
1084: e59420d0 ldr r2, [r4, #208] ; 0xd0
stats->rx_over_errors++;
/* create an error msg */
skb = alloc_can_err_skb(dev, &frame);
1088: e1a00004 mov r0, r4
ctrl &= ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
c_can_object_put(dev, iface, objno, IF_COMM_CONTROL);
stats->rx_errors++;
stats->rx_over_errors++;
108c: e59430ec ldr r3, [r4, #236] ; 0xec
/* create an error msg */
skb = alloc_can_err_skb(dev, &frame);
1090: e24b1030 sub r1, fp, #48 ; 0x30
ctrl &= ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
c_can_object_put(dev, iface, objno, IF_COMM_CONTROL);
stats->rx_errors++;
1094: e2822001 add r2, r2, #1
stats->rx_over_errors++;
1098: e2833001 add r3, r3, #1
ctrl &= ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
c_can_object_put(dev, iface, objno, IF_COMM_CONTROL);
stats->rx_errors++;
109c: e58420d0 str r2, [r4, #208] ; 0xd0
stats->rx_over_errors++;
10a0: e58430ec str r3, [r4, #236] ; 0xec
/* create an error msg */
skb = alloc_can_err_skb(dev, &frame);
10a4: ebfffffe bl 0 <alloc_can_err_skb>
if (unlikely(!skb))
10a8: e3500000 cmp r0, #0
10ac: 0a000138 beq 1594 <c_can_poll+0x7f8>
return 0;
frame->can_id |= CAN_ERR_CRTL;
10b0: e51b3030 ldr r3, [fp, #-48] ; 0x30
10b4: e1a01000 mov r1, r0
10b8: e5932000 ldr r2, [r3]
10bc: e3822004 orr r2, r2, #4
10c0: e5832000 str r2, [r3]
frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
10c4: e51b3030 ldr r3, [fp, #-48] ; 0x30
10c8: e5c3a009 strb sl, [r3, #9]
10cc: e5900010 ldr r0, [r0, #16]
10d0: ebfffffe bl 0 <netif_receive_skb_sk>
10d4: e3a03001 mov r3, #1
netif_receive_skb(skb);
return 1;
10d8: e1a02003 mov r2, r3
ctrl = priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, IF_RX));
if (ctrl & IF_MCONT_MSGLST) {
int n = c_can_handle_lost_msg_obj(dev, IF_RX, obj, ctrl);
pkts += n;
10dc: e0899003 add r9, r9, r3
quota -= n;
10e0: e0627007 rsb r7, r2, r7
10e4: eaffff7b b ed8 <c_can_poll+0x13c>
frame->can_id = (arb & CAN_EFF_MASK) | CAN_EFF_FLAG;
else
frame->can_id = (arb >> 18) & CAN_SFF_MASK;
if (arb & IF_ARB_TRANSMIT) {
frame->can_id |= CAN_RTR_FLAG;
10e8: e51b3030 ldr r3, [fp, #-48] ; 0x30
10ec: e5932000 ldr r2, [r3]
10f0: e3822101 orr r2, r2, #1073741824 ; 0x40000000
10f4: e5832000 str r2, [r3]
10f8: e51b0030 ldr r0, [fp, #-48] ; 0x30
10fc: eaffffc1 b 1008 <c_can_poll+0x26c>
return pkts;
}
static inline u32 c_can_get_pending(struct c_can_priv *priv)
{
u32 pend = priv->read_reg(priv, C_CAN_NEWDAT1_REG);
1100: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
1104: e1a00008 mov r0, r8
1108: e3a01020 mov r1, #32
110c: e12fff33 blx r3
"Implementation does not support more message objects than 16");
while (quota > 0) {
if (!pend) {
pend = c_can_get_pending(priv);
if (!pend)
1110: e3500000 cmp r0, #0
return pkts;
}
static inline u32 c_can_get_pending(struct c_can_priv *priv)
{
u32 pend = priv->read_reg(priv, C_CAN_NEWDAT1_REG);
1114: e50b0038 str r0, [fp, #-56] ; 0x38
1118: e1a06000 mov r6, r0
"Implementation does not support more message objects than 16");
while (quota > 0) {
if (!pend) {
pend = c_can_get_pending(priv);
if (!pend)
111c: 0a00001d beq 1198 <c_can_poll+0x3fc>
*/
static u32 c_can_adjust_pending(u32 pend)
{
u32 weight, lasts;
if (pend == RECEIVE_OBJECT_BITS)
1120: e51b2038 ldr r2, [fp, #-56] ; 0x38
1124: e30f3fff movw r3, #65535 ; 0xffff
1128: e1520003 cmp r2, r3
112c: 0a000052 beq 127c <c_can_poll+0x4e0>
#include <asm/types.h>
static inline unsigned int __arch_hweight32(unsigned int w)
{
return __sw_hweight32(w);
1130: ebfffffe bl 0 <__sw_hweight32>
1134: e51b3038 ldr r3, [fp, #-56] ; 0x38
1138: e16f2f13 clz r2, r3
static inline int fls(int x)
{
if (__builtin_constant_p(x))
return constant_fls(x);
return 32 - __clz(x);
113c: e2623020 rsb r3, r2, #32
*/
weight = hweight32(pend);
lasts = fls(pend);
/* If the bits are linear, nothing to do */
if (lasts == weight)
1140: e1500003 cmp r0, r3
/*
* Find the first set bit after the gap. We walk backwards
* from the last set bit.
*/
for (lasts--; pend & (1 << (lasts - 1)); lasts--);
1144: 1262201f rsbne r2, r2, #31
*/
weight = hweight32(pend);
lasts = fls(pend);
/* If the bits are linear, nothing to do */
if (lasts == weight)
1148: 1a000001 bne 1154 <c_can_poll+0x3b8>
114c: ea00004e b 128c <c_can_poll+0x4f0>
/*
* Find the first set bit after the gap. We walk backwards
* from the last set bit.
*/
for (lasts--; pend & (1 << (lasts - 1)); lasts--);
1150: e1a02003 mov r2, r3
1154: e2423001 sub r3, r2, #1
1158: e3a01001 mov r1, #1
115c: e016031a ands r0, r6, sl, lsl r3
1160: 1afffffa bne 1150 <c_can_poll+0x3b4>
return pend & ~((1 << lasts) - 1);
1164: e1a05211 lsl r5, r1, r2
1168: e2655000 rsb r5, r5, #0
116c: e0055006 and r5, r5, r6
1170: e1e03005 mvn r3, r5
1174: eaffff52 b ec4 <c_can_poll+0x128>
/* Remove the bits from pend */
pend &= ~toread;
/* Read the objects */
n = c_can_read_objects(dev, priv, toread, quota);
pkts += n;
quota -= n;
1178: e51b0040 ldr r0, [fp, #-64] ; 0x40
}
/* Remove the bits from pend */
pend &= ~toread;
/* Read the objects */
n = c_can_read_objects(dev, priv, toread, quota);
pkts += n;
117c: e51b204c ldr r2, [fp, #-76] ; 0x4c
quota -= n;
1180: e0690000 rsb r0, r9, r0
* for a maximum number of 16 objects.
*/
BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16,
"Implementation does not support more message objects than 16");
while (quota > 0) {
1184: e3500000 cmp r0, #0
}
/* Remove the bits from pend */
pend &= ~toread;
/* Read the objects */
n = c_can_read_objects(dev, priv, toread, quota);
pkts += n;
1188: e0822009 add r2, r2, r9
quota -= n;
118c: e50b0040 str r0, [fp, #-64] ; 0x40
}
/* Remove the bits from pend */
pend &= ~toread;
/* Read the objects */
n = c_can_read_objects(dev, priv, toread, quota);
pkts += n;
1190: e50b204c str r2, [fp, #-76] ; 0x4c
* for a maximum number of 16 objects.
*/
BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16,
"Implementation does not support more message objects than 16");
while (quota > 0) {
1194: caffff45 bgt eb0 <c_can_poll+0x114>
1198: e51ba04c ldr sl, [fp, #-76] ; 0x4c
/* handle lec errors on the bus */
work_done += c_can_handle_bus_err(dev, curr & LEC_MASK);
/* Handle Tx/Rx events. We do this unconditionally */
work_done += c_can_do_rx_poll(dev, (quota - work_done));
119c: e51b2054 ldr r2, [fp, #-84] ; 0x54
{
struct c_can_priv *priv = netdev_priv(dev);
struct net_device_stats *stats = &dev->stats;
u32 idx, obj, pkts = 0, bytes = 0, pend, clr;
clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
11a0: e1a00008 mov r0, r8
11a4: e59435f4 ldr r3, [r4, #1524] ; 0x5f4
11a8: e3a01023 mov r1, #35 ; 0x23
static void c_can_do_tx(struct net_device *dev)
{
struct c_can_priv *priv = netdev_priv(dev);
struct net_device_stats *stats = &dev->stats;
u32 idx, obj, pkts = 0, bytes = 0, pend, clr;
11ac: e3a09000 mov r9, #0
clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
while ((idx = ffs(pend))) {
idx--;
pend &= ~(1 << idx);
11b0: e3a07001 mov r7, #1
/* handle lec errors on the bus */
work_done += c_can_handle_bus_err(dev, curr & LEC_MASK);
/* Handle Tx/Rx events. We do this unconditionally */
work_done += c_can_do_rx_poll(dev, (quota - work_done));
11b4: e082a00a add sl, r2, sl
11b8: e50ba03c str sl, [fp, #-60] ; 0x3c
static void c_can_do_tx(struct net_device *dev)
{
struct c_can_priv *priv = netdev_priv(dev);
struct net_device_stats *stats = &dev->stats;
u32 idx, obj, pkts = 0, bytes = 0, pend, clr;
11bc: e1a0a009 mov sl, r9
clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
11c0: e12fff33 blx r3
11c4: e50b0038 str r0, [fp, #-56] ; 0x38
11c8: e1a05000 mov r5, r0
11cc: ea000007 b 11f0 <c_can_poll+0x454>
while ((idx = ffs(pend))) {
idx--;
pend &= ~(1 << idx);
obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
c_can_inval_tx_object(dev, IF_RX, obj);
11d0: ebfffc0a bl 200 <c_can_inval_tx_object>
can_get_echo_skb(dev, idx);
11d4: e1a01006 mov r1, r6
bytes += priv->dlc[idx];
11d8: e0846106 add r6, r4, r6, lsl #2
while ((idx = ffs(pend))) {
idx--;
pend &= ~(1 << idx);
obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
c_can_inval_tx_object(dev, IF_RX, obj);
can_get_echo_skb(dev, idx);
11dc: e1a00004 mov r0, r4
11e0: ebfffffe bl 0 <can_get_echo_skb>
bytes += priv->dlc[idx];
11e4: e596362c ldr r3, [r6, #1580] ; 0x62c
pkts++;
11e8: e28aa001 add sl, sl, #1
idx--;
pend &= ~(1 << idx);
obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
c_can_inval_tx_object(dev, IF_RX, obj);
can_get_echo_skb(dev, idx);
bytes += priv->dlc[idx];
11ec: e0899003 add r9, r9, r3
* ffs() returns zero if the input was zero, otherwise returns the bit
* position of the first set bit, where the LSB is 1 and MSB is 32.
*/
static inline int ffs(int x)
{
return fls(x & -x);
11f0: e2653000 rsb r3, r5, #0
while ((idx = ffs(pend))) {
idx--;
pend &= ~(1 << idx);
obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
c_can_inval_tx_object(dev, IF_RX, obj);
11f4: e1a00004 mov r0, r4
11f8: e0033005 and r3, r3, r5
11fc: e3a01000 mov r1, #0
*/
static inline unsigned int __clz(unsigned int x)
{
unsigned int ret;
asm("clz\t%0, %1" : "=r" (ret) : "r" (x));
1200: e16f3f13 clz r3, r3
struct net_device_stats *stats = &dev->stats;
u32 idx, obj, pkts = 0, bytes = 0, pend, clr;
clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
while ((idx = ffs(pend))) {
1204: e3530020 cmp r3, #32
idx--;
1208: e263601f rsb r6, r3, #31
pend &= ~(1 << idx);
obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
c_can_inval_tx_object(dev, IF_RX, obj);
120c: e2632030 rsb r2, r3, #48 ; 0x30
clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
while ((idx = ffs(pend))) {
idx--;
pend &= ~(1 << idx);
1210: e1c55617 bic r5, r5, r7, lsl r6
struct net_device_stats *stats = &dev->stats;
u32 idx, obj, pkts = 0, bytes = 0, pend, clr;
clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
while ((idx = ffs(pend))) {
1214: 1affffed bne 11d0 <c_can_poll+0x434>
bytes += priv->dlc[idx];
pkts++;
}
/* Clear the bits in the tx_active mask */
atomic_sub(clr, &priv->tx_active);
1218: e2882f4a add r2, r8, #296 ; 0x128
#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
#define ARCH_HAS_PREFETCHW
static inline void prefetchw(const void *ptr)
{
__asm__ __volatile__(
121c: f592f000 pldw [r2]
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_OP_RETURN(op, c_op, asm_op)
ATOMIC_OPS(add, +=, add)
ATOMIC_OPS(sub, -=, sub)
1220: e51b3038 ldr r3, [fp, #-56] ; 0x38
1224: e1921f9f ldrex r1, [r2]
1228: e0411003 sub r1, r1, r3
122c: e1820f91 strex r0, r1, [r2]
1230: e3300000 teq r0, #0
1234: 1afffffa bne 1224 <c_can_poll+0x488>
if (clr & (1 << (C_CAN_MSG_OBJ_TX_NUM - 1)))
1238: e3130902 tst r3, #32768 ; 0x8000
123c: 1a00005a bne 13ac <c_can_poll+0x610>
netif_wake_queue(dev);
if (pkts) {
1240: e35a0000 cmp sl, #0
1244: 0a000005 beq 1260 <c_can_poll+0x4c4>
stats->tx_bytes += bytes;
1248: e59410cc ldr r1, [r4, #204] ; 0xcc
stats->tx_packets += pkts;
124c: e59420c4 ldr r2, [r4, #196] ; 0xc4
if (clr & (1 << (C_CAN_MSG_OBJ_TX_NUM - 1)))
netif_wake_queue(dev);
if (pkts) {
stats->tx_bytes += bytes;
1250: e081c009 add ip, r1, r9
stats->tx_packets += pkts;
1254: e082300a add r3, r2, sl
if (clr & (1 << (C_CAN_MSG_OBJ_TX_NUM - 1)))
netif_wake_queue(dev);
if (pkts) {
stats->tx_bytes += bytes;
1258: e584c0cc str ip, [r4, #204] ; 0xcc
stats->tx_packets += pkts;
125c: e58430c4 str r3, [r4, #196] ; 0xc4
/* Handle Tx/Rx events. We do this unconditionally */
work_done += c_can_do_rx_poll(dev, (quota - work_done));
c_can_do_tx(dev);
end:
if (work_done < quota) {
1260: e51b303c ldr r3, [fp, #-60] ; 0x3c
1264: e51b0050 ldr r0, [fp, #-80] ; 0x50
1268: e1530000 cmp r3, r0
126c: ba00001b blt 12e0 <c_can_poll+0x544>
if (priv->can.state != CAN_STATE_BUS_OFF)
c_can_irq_control(priv, true);
}
return work_done;
}
1270: e51b003c ldr r0, [fp, #-60] ; 0x3c
1274: e24bd028 sub sp, fp, #40 ; 0x28
1278: e89daff0 ldm sp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
*/
static u32 c_can_adjust_pending(u32 pend)
{
u32 weight, lasts;
if (pend == RECEIVE_OBJECT_BITS)
127c: e51b5038 ldr r5, [fp, #-56] ; 0x38
1280: e3a03000 mov r3, #0
1284: e7df3815 bfi r3, r5, #16, #16
1288: eaffff0d b ec4 <c_can_poll+0x128>
128c: e51b0038 ldr r0, [fp, #-56] ; 0x38
1290: e1e03000 mvn r3, r0
*/
weight = hweight32(pend);
lasts = fls(pend);
/* If the bits are linear, nothing to do */
if (lasts == weight)
1294: e1a05000 mov r5, r0
1298: eaffff09 b ec4 <c_can_poll+0x128>
if ((curr & STATUS_EPASS) && (!(last & STATUS_EPASS))) {
netdev_dbg(dev, "entered error passive state\n");
work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE);
}
if ((curr & STATUS_BOFF) && (!(last & STATUS_BOFF))) {
129c: e3170080 tst r7, #128 ; 0x80
12a0: 1afffeea bne e50 <c_can_poll+0xb4>
netdev_dbg(dev, "entered bus off state\n");
12a4: e3000000 movw r0, #0
12a8: e3002000 movw r2, #0
12ac: e3400000 movt r0, #0
12b0: e3402000 movt r2, #0
12b4: e1a01004 mov r1, r4
12b8: ebfffffe bl 0 <netdev_printk>
work_done += c_can_handle_state_change(dev, C_CAN_BUS_OFF);
12bc: e1a00004 mov r0, r4
12c0: e3a01001 mov r1, #1
12c4: ebfffc1d bl 340 <c_can_handle_state_change>
12c8: e080a00a add sl, r0, sl
/* Handle Tx/Rx events. We do this unconditionally */
work_done += c_can_do_rx_poll(dev, (quota - work_done));
c_can_do_tx(dev);
end:
if (work_done < quota) {
12cc: e51b0050 ldr r0, [fp, #-80] ; 0x50
work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE);
}
if ((curr & STATUS_BOFF) && (!(last & STATUS_BOFF))) {
netdev_dbg(dev, "entered bus off state\n");
work_done += c_can_handle_state_change(dev, C_CAN_BUS_OFF);
12d0: e50ba03c str sl, [fp, #-60] ; 0x3c
/* Handle Tx/Rx events. We do this unconditionally */
work_done += c_can_do_rx_poll(dev, (quota - work_done));
c_can_do_tx(dev);
end:
if (work_done < quota) {
12d4: e51b303c ldr r3, [fp, #-60] ; 0x3c
12d8: e1530000 cmp r3, r0
12dc: aaffffe3 bge 1270 <c_can_poll+0x4d4>
* Mark NAPI processing as complete.
* Consider using napi_complete_done() instead.
*/
static inline void napi_complete(struct napi_struct *n)
{
return napi_complete_done(n, 0);
12e0: e51b0058 ldr r0, [fp, #-88] ; 0x58
12e4: e3a01000 mov r1, #0
12e8: ebfffffe bl 0 <napi_complete_done>
napi_complete(napi);
/* enable all IRQs if we are not in bus off state */
if (priv->can.state != CAN_STATE_BUS_OFF)
12ec: e5943524 ldr r3, [r4, #1316] ; 0x524
12f0: e3530003 cmp r3, #3
12f4: 0affffdd beq 1270 <c_can_poll+0x4d4>
c_can_irq_control(priv, true);
12f8: e1a00008 mov r0, r8
12fc: e3a01001 mov r1, #1
1300: ebfffb3e bl 0 <c_can_irq_control>
}
return work_done;
}
1304: e51b003c ldr r0, [fp, #-60] ; 0x3c
1308: e24bd028 sub sp, fp, #40 ; 0x28
130c: e89daff0 ldm sp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
/* handle bus recovery events */
if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) {
netdev_dbg(dev, "left bus off state\n");
priv->can.state = CAN_STATE_ERROR_ACTIVE;
}
if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) {
1310: e3170020 tst r7, #32
1314: 0afffecf beq e58 <c_can_poll+0xbc>
netdev_dbg(dev, "left error passive state\n");
1318: e3000000 movw r0, #0
131c: e3002000 movw r2, #0
1320: e3400000 movt r0, #0
1324: e3402000 movt r2, #0
1328: e1a01004 mov r1, r4
132c: ebfffffe bl 0 <netdev_printk>
priv->can.state = CAN_STATE_ERROR_ACTIVE;
1330: e5846524 str r6, [r4, #1316] ; 0x524
1334: eafffec7 b e58 <c_can_poll+0xbc>
if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
return 0;
/* common for all type of bus errors */
priv->can.can_stats.bus_error++;
1338: e59424c0 ldr r2, [r4, #1216] ; 0x4c0
stats->rx_errors++;
/* propagate the error condition to the CAN stack */
skb = alloc_can_err_skb(dev, &cf);
133c: e1a00004 mov r0, r4
if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
return 0;
/* common for all type of bus errors */
priv->can.can_stats.bus_error++;
stats->rx_errors++;
1340: e59430d0 ldr r3, [r4, #208] ; 0xd0
/* propagate the error condition to the CAN stack */
skb = alloc_can_err_skb(dev, &cf);
1344: e24b1030 sub r1, fp, #48 ; 0x30
if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
return 0;
/* common for all type of bus errors */
priv->can.can_stats.bus_error++;
1348: e2822001 add r2, r2, #1
stats->rx_errors++;
134c: e2833001 add r3, r3, #1
if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
return 0;
/* common for all type of bus errors */
priv->can.can_stats.bus_error++;
1350: e58424c0 str r2, [r4, #1216] ; 0x4c0
stats->rx_errors++;
1354: e58430d0 str r3, [r4, #208] ; 0xd0
/* propagate the error condition to the CAN stack */
skb = alloc_can_err_skb(dev, &cf);
1358: ebfffffe bl 0 <alloc_can_err_skb>
if (unlikely(!skb))
135c: e2506000 subs r6, r0, #0
1360: 0afffec6 beq e80 <c_can_poll+0xe4>
/*
* check for 'last error code' which tells us the
* type of the last error to occur on the CAN bus
*/
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
1364: e51b3030 ldr r3, [fp, #-48] ; 0x30
cf->data[2] |= CAN_ERR_PROT_UNSPEC;
switch (lec_type) {
1368: e2455001 sub r5, r5, #1
/*
* check for 'last error code' which tells us the
* type of the last error to occur on the CAN bus
*/
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
136c: e5932000 ldr r2, [r3]
1370: e3822088 orr r2, r2, #136 ; 0x88
1374: e5832000 str r2, [r3]
cf->data[2] |= CAN_ERR_PROT_UNSPEC;
switch (lec_type) {
1378: e3550005 cmp r5, #5
137c: 979ff105 ldrls pc, [pc, r5, lsl #2]
1380: ea000081 b 158c <c_can_poll+0x7f0>
1384: 0000155c .word 0x0000155c
1388: 0000149c .word 0x0000149c
138c: 000014cc .word 0x000014cc
1390: 000014fc .word 0x000014fc
1394: 0000152c .word 0x0000152c
1398: 00001440 .word 0x00001440
struct sk_buff *skb;
u32 arb, data;
skb = alloc_can_skb(dev, &frame);
if (!skb) {
stats->rx_dropped++;
139c: e59430d8 ldr r3, [r4, #216] ; 0xd8
13a0: e2833001 add r3, r3, #1
13a4: e58430d8 str r3, [r4, #216] ; 0xd8
13a8: eaffff20 b 1030 <c_can_poll+0x294>
* Allow upper layers to call the device hard_start_xmit routine.
* Used for flow control when transmit resources are available.
*/
static inline void netif_wake_queue(struct net_device *dev)
{
netif_tx_wake_queue(netdev_get_tx_queue(dev, 0));
13ac: e5940240 ldr r0, [r4, #576] ; 0x240
13b0: ebfffffe bl 0 <netif_tx_wake_queue>
13b4: eaffffa1 b 1240 <c_can_poll+0x4a4>
netdev_dbg(dev, "entered error warning state\n");
work_done += c_can_handle_state_change(dev, C_CAN_ERROR_WARNING);
}
if ((curr & STATUS_EPASS) && (!(last & STATUS_EPASS))) {
netdev_dbg(dev, "entered error passive state\n");
13b8: e3000000 movw r0, #0
13bc: e3002000 movw r2, #0
13c0: e3400000 movt r0, #0
13c4: e3402000 movt r2, #0
13c8: e1a01004 mov r1, r4
13cc: ebfffffe bl 0 <netdev_printk>
work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE);
13d0: e1a00004 mov r0, r4
13d4: e3a01003 mov r1, #3
13d8: ebfffbd8 bl 340 <c_can_handle_state_change>
13dc: e08aa000 add sl, sl, r0
13e0: eafffe94 b e38 <c_can_poll+0x9c>
if (priv->type != BOSCH_D_CAN)
priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
/* handle state changes */
if ((curr & STATUS_EWARN) && (!(last & STATUS_EWARN))) {
netdev_dbg(dev, "entered error warning state\n");
13e4: e3000000 movw r0, #0
13e8: e3002000 movw r2, #0
13ec: e3400000 movt r0, #0
13f0: e3402000 movt r2, #0
13f4: e1a01004 mov r1, r4
13f8: ebfffffe bl 0 <netdev_printk>
work_done += c_can_handle_state_change(dev, C_CAN_ERROR_WARNING);
13fc: e1a00004 mov r0, r4
1400: e3a01002 mov r1, #2
1404: ebfffbcd bl 340 <c_can_handle_state_change>
1408: e1a0a000 mov sl, r0
140c: eafffe83 b e20 <c_can_poll+0x84>
goto end;
}
/* handle bus recovery events */
if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) {
netdev_dbg(dev, "left bus off state\n");
1410: e3000000 movw r0, #0
1414: e3002000 movw r2, #0
1418: e3400000 movt r0, #0
141c: e3402000 movt r2, #0
1420: e1a01004 mov r1, r4
1424: ebfffffe bl 0 <netdev_printk>
priv->can.state = CAN_STATE_ERROR_ACTIVE;
}
if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) {
1428: e3560000 cmp r6, #0
}
/* handle bus recovery events */
if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) {
netdev_dbg(dev, "left bus off state\n");
priv->can.state = CAN_STATE_ERROR_ACTIVE;
142c: e5849524 str r9, [r4, #1316] ; 0x524
}
if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) {
1430: 1afffe88 bne e58 <c_can_poll+0xbc>
1434: eaffffb5 b 1310 <c_can_poll+0x574>
* for a maximum number of 16 objects.
*/
BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16,
"Implementation does not support more message objects than 16");
while (quota > 0) {
1438: e3a0a000 mov sl, #0
143c: eaffff56 b 119c <c_can_poll+0x400>
case LEC_BIT0_ERROR:
netdev_dbg(dev, "bit0 error\n");
cf->data[2] |= CAN_ERR_PROT_BIT0;
break;
case LEC_CRC_ERROR:
netdev_dbg(dev, "CRC error\n");
1440: e3000000 movw r0, #0
1444: e3002000 movw r2, #0
1448: e3402000 movt r2, #0
144c: e1a01004 mov r1, r4
1450: e3400000 movt r0, #0
1454: ebfffffe bl 0 <netdev_printk>
cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
1458: e51b2030 ldr r2, [fp, #-48] ; 0x30
145c: e5d2100b ldrb r1, [r2, #11]
1460: e1a03002 mov r3, r2
1464: e3811018 orr r1, r1, #24
1468: e5c2100b strb r1, [r2, #11]
break;
default:
break;
}
stats->rx_packets++;
146c: e59400c0 ldr r0, [r4, #192] ; 0xc0
int netif_rx(struct sk_buff *skb);
int netif_rx_ni(struct sk_buff *skb);
int netif_receive_skb_sk(struct sock *sk, struct sk_buff *skb);
static inline int netif_receive_skb(struct sk_buff *skb)
{
return netif_receive_skb_sk(skb->sk, skb);
1470: e1a01006 mov r1, r6
stats->rx_bytes += cf->can_dlc;
1474: e59420c8 ldr r2, [r4, #200] ; 0xc8
break;
default:
break;
}
stats->rx_packets++;
1478: e2800001 add r0, r0, #1
147c: e58400c0 str r0, [r4, #192] ; 0xc0
stats->rx_bytes += cf->can_dlc;
1480: e5d33004 ldrb r3, [r3, #4]
1484: e0823003 add r3, r2, r3
1488: e58430c8 str r3, [r4, #200] ; 0xc8
148c: e5960010 ldr r0, [r6, #16]
1490: ebfffffe bl 0 <netif_receive_skb_sk>
netif_receive_skb(skb);
return 1;
1494: e3a03001 mov r3, #1
1498: eafffe79 b e84 <c_can_poll+0xe8>
case LEC_STUFF_ERROR:
netdev_dbg(dev, "stuff error\n");
cf->data[2] |= CAN_ERR_PROT_STUFF;
break;
case LEC_FORM_ERROR:
netdev_dbg(dev, "form error\n");
149c: e3000000 movw r0, #0
14a0: e3002000 movw r2, #0
14a4: e3402000 movt r2, #0
14a8: e1a01004 mov r1, r4
14ac: e3400000 movt r0, #0
14b0: ebfffffe bl 0 <netdev_printk>
cf->data[2] |= CAN_ERR_PROT_FORM;
14b4: e51b2030 ldr r2, [fp, #-48] ; 0x30
14b8: e5d2100a ldrb r1, [r2, #10]
14bc: e1a03002 mov r3, r2
14c0: e3811002 orr r1, r1, #2
14c4: e5c2100a strb r1, [r2, #10]
14c8: eaffffe7 b 146c <c_can_poll+0x6d0>
break;
case LEC_ACK_ERROR:
netdev_dbg(dev, "ack error\n");
14cc: e3000000 movw r0, #0
14d0: e3002000 movw r2, #0
14d4: e3402000 movt r2, #0
14d8: e1a01004 mov r1, r4
14dc: e3400000 movt r0, #0
14e0: ebfffffe bl 0 <netdev_printk>
cf->data[3] |= (CAN_ERR_PROT_LOC_ACK |
14e4: e51b2030 ldr r2, [fp, #-48] ; 0x30
14e8: e5d2100b ldrb r1, [r2, #11]
14ec: e1a03002 mov r3, r2
14f0: e381101b orr r1, r1, #27
14f4: e5c2100b strb r1, [r2, #11]
14f8: eaffffdb b 146c <c_can_poll+0x6d0>
CAN_ERR_PROT_LOC_ACK_DEL);
break;
case LEC_BIT1_ERROR:
netdev_dbg(dev, "bit1 error\n");
14fc: e3000000 movw r0, #0
1500: e3002000 movw r2, #0
1504: e3402000 movt r2, #0
1508: e1a01004 mov r1, r4
150c: e3400000 movt r0, #0
1510: ebfffffe bl 0 <netdev_printk>
cf->data[2] |= CAN_ERR_PROT_BIT1;
1514: e51b2030 ldr r2, [fp, #-48] ; 0x30
1518: e5d2100a ldrb r1, [r2, #10]
151c: e1a03002 mov r3, r2
1520: e3811010 orr r1, r1, #16
1524: e5c2100a strb r1, [r2, #10]
1528: eaffffcf b 146c <c_can_poll+0x6d0>
break;
case LEC_BIT0_ERROR:
netdev_dbg(dev, "bit0 error\n");
152c: e3000000 movw r0, #0
1530: e3002000 movw r2, #0
1534: e3402000 movt r2, #0
1538: e1a01004 mov r1, r4
153c: e3400000 movt r0, #0
1540: ebfffffe bl 0 <netdev_printk>
cf->data[2] |= CAN_ERR_PROT_BIT0;
1544: e51b2030 ldr r2, [fp, #-48] ; 0x30
1548: e5d2100a ldrb r1, [r2, #10]
154c: e1a03002 mov r3, r2
1550: e3811008 orr r1, r1, #8
1554: e5c2100a strb r1, [r2, #10]
1558: eaffffc3 b 146c <c_can_poll+0x6d0>
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
cf->data[2] |= CAN_ERR_PROT_UNSPEC;
switch (lec_type) {
case LEC_STUFF_ERROR:
netdev_dbg(dev, "stuff error\n");
155c: e3000000 movw r0, #0
1560: e3002000 movw r2, #0
1564: e3402000 movt r2, #0
1568: e1a01004 mov r1, r4
156c: e3400000 movt r0, #0
1570: ebfffffe bl 0 <netdev_printk>
cf->data[2] |= CAN_ERR_PROT_STUFF;
1574: e51b2030 ldr r2, [fp, #-48] ; 0x30
1578: e5d2100a ldrb r1, [r2, #10]
157c: e1a03002 mov r3, r2
1580: e3811004 orr r1, r1, #4
1584: e5c2100a strb r1, [r2, #10]
1588: eaffffb7 b 146c <c_can_poll+0x6d0>
158c: e51b3030 ldr r3, [fp, #-48] ; 0x30
1590: eaffffb5 b 146c <c_can_poll+0x6d0>
stats->rx_errors++;
stats->rx_over_errors++;
/* create an error msg */
skb = alloc_can_err_skb(dev, &frame);
if (unlikely(!skb))
1594: e1a03000 mov r3, r0
return 0;
1598: e1a02000 mov r2, r0
159c: eafffece b 10dc <c_can_poll+0x340>
000015a0 <c_can_start_xmit>:
c_can_object_put(dev, iface, obj, IF_COMM_RCV_SETUP);
}
static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
15a0: e1a0c00d mov ip, sp
15a4: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
15a8: e24cb004 sub fp, ip, #4
15ac: e24dd00c sub sp, sp, #12
15b0: e52de004 push {lr} ; (str lr, [sp, #-4]!)
15b4: ebfffffe bl 0 <__gnu_mcount_nc>
static inline int can_dropped_invalid_skb(struct net_device *dev,
struct sk_buff *skb)
{
const struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
if (skb->protocol == htons(ETH_P_CAN)) {
15b8: e1d038bc ldrh r3, [r0, #140] ; 0x8c
15bc: e1a09000 mov r9, r0
15c0: e1a04001 mov r4, r1
struct can_frame *frame = (struct can_frame *)skb->data;
15c4: e59060a0 ldr r6, [r0, #160] ; 0xa0
15c8: e3530b03 cmp r3, #3072 ; 0xc00
15cc: 0a000009 beq 15f8 <c_can_start_xmit+0x58>
if (unlikely(skb->len != CAN_MTU ||
cfd->len > CAN_MAX_DLEN))
goto inval_skb;
} else if (skb->protocol == htons(ETH_P_CANFD)) {
15d0: e3530c0d cmp r3, #3328 ; 0xd00
15d4: 0a000068 beq 177c <c_can_start_xmit+0x1dc>
goto inval_skb;
return 0;
inval_skb:
kfree_skb(skb);
15d8: e1a00009 mov r0, r9
15dc: ebfffffe bl 0 <kfree_skb>
dev->stats.tx_dropped++;
15e0: e59430dc ldr r3, [r4, #220] ; 0xdc
atomic_add((1 << idx), &priv->tx_active);
/* Start transmission */
c_can_object_put(dev, IF_TX, obj, IF_COMM_TX);
return NETDEV_TX_OK;
}
15e4: e3a00000 mov r0, #0
15e8: e2833001 add r3, r3, #1
15ec: e58430dc str r3, [r4, #220] ; 0xdc
15f0: e24bd028 sub sp, fp, #40 ; 0x28
15f4: e89daff0 ldm sp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
struct sk_buff *skb)
{
const struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
if (skb->protocol == htons(ETH_P_CAN)) {
if (unlikely(skb->len != CAN_MTU ||
15f8: e5903054 ldr r3, [r0, #84] ; 0x54
15fc: e3530010 cmp r3, #16
1600: 1afffff4 bne 15d8 <c_can_start_xmit+0x38>
1604: e5d63004 ldrb r3, [r6, #4]
1608: e3530008 cmp r3, #8
160c: 8afffff1 bhi 15d8 <c_can_start_xmit+0x38>
return NETDEV_TX_OK;
/*
* This is not a FIFO. C/D_CAN sends out the buffers
* prioritized. The lowest buffer number wins.
*/
idx = fls(atomic_read(&priv->tx_active));
1610: e594a5e8 ldr sl, [r4, #1512] ; 0x5e8
1614: e16faf1a clz sl, sl
static inline int fls(int x)
{
if (__builtin_constant_p(x))
return constant_fls(x);
return 32 - __clz(x);
1618: e26a7020 rsb r7, sl, #32
obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
161c: e26aa031 rsb sl, sl, #49 ; 0x31
/* If this is the last buffer, stop the xmit queue */
if (idx == C_CAN_MSG_OBJ_TX_NUM - 1)
1620: e357000f cmp r7, #15
/*
* This is not a FIFO. C/D_CAN sends out the buffers
* prioritized. The lowest buffer number wins.
*/
idx = fls(atomic_read(&priv->tx_active));
obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
1624: e50ba030 str sl, [fp, #-48] ; 0x30
/* If this is the last buffer, stop the xmit queue */
if (idx == C_CAN_MSG_OBJ_TX_NUM - 1)
1628: 0a00005a beq 1798 <c_can_start_xmit+0x1f8>
static void c_can_setup_tx_object(struct net_device *dev, int iface,
struct can_frame *frame, int idx)
{
struct c_can_priv *priv = netdev_priv(dev);
u16 ctrl = IF_MCONT_TX | frame->can_dlc;
bool rtr = frame->can_id & CAN_RTR_FLAG;
162c: e5963000 ldr r3, [r6]
1630: e287001f add r0, r7, #31
}
static void c_can_setup_tx_object(struct net_device *dev, int iface,
struct can_frame *frame, int idx)
{
struct c_can_priv *priv = netdev_priv(dev);
1634: e2848d13 add r8, r4, #1216 ; 0x4c0
1638: e207101f and r1, r7, #31
/*
* If we change the DIR bit, we need to invalidate the buffer
* first, i.e. clear the MSGVAL flag in the arbiter.
*/
if (rtr != (bool)test_bit(idx, &priv->tx_dir)) {
163c: e288cf4b add ip, r8, #300 ; 0x12c
static void c_can_setup_tx_object(struct net_device *dev, int iface,
struct can_frame *frame, int idx)
{
struct c_can_priv *priv = netdev_priv(dev);
u16 ctrl = IF_MCONT_TX | frame->can_dlc;
1640: e5d65004 ldrb r5, [r6, #4]
bool rtr = frame->can_id & CAN_RTR_FLAG;
u32 arb = IF_ARB_MSGVAL;
int i;
if (frame->can_id & CAN_EFF_FLAG) {
1644: e3530000 cmp r3, #0
static void c_can_setup_tx_object(struct net_device *dev, int iface,
struct can_frame *frame, int idx)
{
struct c_can_priv *priv = netdev_priv(dev);
u16 ctrl = IF_MCONT_TX | frame->can_dlc;
bool rtr = frame->can_id & CAN_RTR_FLAG;
1648: e7e02f53 ubfx r2, r3, #30, #1
if (frame->can_id & CAN_EFF_FLAG) {
arb |= frame->can_id & CAN_EFF_MASK;
arb |= IF_ARB_MSGXTD;
} else {
arb |= (frame->can_id & CAN_SFF_MASK) << 18;
164c: a7ea3053 ubfxge r3, r3, #0, #11
bool rtr = frame->can_id & CAN_RTR_FLAG;
u32 arb = IF_ARB_MSGVAL;
int i;
if (frame->can_id & CAN_EFF_FLAG) {
arb |= frame->can_id & CAN_EFF_MASK;
1650: b3c3320e biclt r3, r3, #-536870912 ; 0xe0000000
arb |= IF_ARB_MSGXTD;
} else {
arb |= (frame->can_id & CAN_SFF_MASK) << 18;
1654: a1a03903 lslge r3, r3, #18
u32 arb = IF_ARB_MSGVAL;
int i;
if (frame->can_id & CAN_EFF_FLAG) {
arb |= frame->can_id & CAN_EFF_MASK;
arb |= IF_ARB_MSGXTD;
1658: b383a103 orrlt sl, r3, #-1073741824 ; 0xc0000000
static void c_can_setup_tx_object(struct net_device *dev, int iface,
struct can_frame *frame, int idx)
{
struct c_can_priv *priv = netdev_priv(dev);
u16 ctrl = IF_MCONT_TX | frame->can_dlc;
165c: e3855d22 orr r5, r5, #2176 ; 0x880
if (frame->can_id & CAN_EFF_FLAG) {
arb |= frame->can_id & CAN_EFF_MASK;
arb |= IF_ARB_MSGXTD;
} else {
arb |= (frame->can_id & CAN_SFF_MASK) << 18;
1660: a383a102 orrge sl, r3, #-2147483648 ; 0x80000000
}
if (!rtr)
1664: e3520000 cmp r2, #0
arb |= IF_ARB_TRANSMIT;
1668: 038aa202 orreq sl, sl, #536870912 ; 0x20000000
166c: e3570000 cmp r7, #0
1670: a1a00007 movge r0, r7
1674: e1a002c0 asr r0, r0, #5
1678: e79c0100 ldr r0, [ip, r0, lsl #2]
167c: e1a01130 lsr r1, r0, r1
1680: e2011001 and r1, r1, #1
/*
* If we change the DIR bit, we need to invalidate the buffer
* first, i.e. clear the MSGVAL flag in the arbiter.
*/
if (rtr != (bool)test_bit(idx, &priv->tx_dir)) {
1684: e1520001 cmp r2, r1
1688: 0a000008 beq 16b0 <c_can_start_xmit+0x110>
u32 obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
c_can_inval_msg_object(dev, iface, obj);
168c: e1a00004 mov r0, r4
1690: e3a01001 mov r1, #1
1694: e2872011 add r2, r7, #17
1698: e50bc034 str ip, [fp, #-52] ; 0x34
169c: ebfffaec bl 254 <c_can_inval_msg_object>
change_bit(idx, &priv->tx_dir);
16a0: e51bc034 ldr ip, [fp, #-52] ; 0x34
16a4: e1a00007 mov r0, r7
16a8: e1a0100c mov r1, ip
16ac: ebfffffe bl 0 <_change_bit>
}
priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), arb);
16b0: e1a0200a mov r2, sl
16b4: e5943600 ldr r3, [r4, #1536] ; 0x600
16b8: e1a00008 mov r0, r8
16bc: e3a01017 mov r1, #23
16c0: e12fff33 blx r3
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
16c4: e1a02005 mov r2, r5
16c8: e59435f8 ldr r3, [r4, #1528] ; 0x5f8
16cc: e1a00008 mov r0, r8
16d0: e3a01019 mov r1, #25
16d4: e12fff33 blx r3
for (i = 0; i < frame->can_dlc; i += 2) {
16d8: e5d62004 ldrb r2, [r6, #4]
16dc: e3520000 cmp r2, #0
16e0: 0a00000e beq 1720 <c_can_start_xmit+0x180>
16e4: e1a0a006 mov sl, r6
16e8: e3a05000 mov r5, #0
priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
frame->data[i] | (frame->data[i + 1] << 8));
16ec: e5dae009 ldrb lr, [sl, #9]
priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), arb);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
for (i = 0; i < frame->can_dlc; i += 2) {
priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
16f0: e1a010c5 asr r1, r5, #1
16f4: e5da2008 ldrb r2, [sl, #8]
16f8: e1a00008 mov r0, r8
16fc: e281101a add r1, r1, #26
1700: e594c5f8 ldr ip, [r4, #1528] ; 0x5f8
priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), arb);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
for (i = 0; i < frame->can_dlc; i += 2) {
1704: e2855002 add r5, r5, #2
1708: e28aa002 add sl, sl, #2
priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
170c: e182240e orr r2, r2, lr, lsl #8
1710: e12fff3c blx ip
priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), arb);
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
for (i = 0; i < frame->can_dlc; i += 2) {
1714: e5d62004 ldrb r2, [r6, #4]
1718: e1550002 cmp r5, r2
171c: bafffff2 blt 16ec <c_can_start_xmit+0x14c>
* Store the message in the interface so we can call
* can_put_echo_skb(). We must do this before we enable
* transmit as we might race against do_tx().
*/
c_can_setup_tx_object(dev, IF_TX, frame, idx);
priv->dlc[idx] = frame->can_dlc;
1720: e0843107 add r3, r4, r7, lsl #2
can_put_echo_skb(skb, dev, idx);
1724: e1a00009 mov r0, r9
1728: e1a01004 mov r1, r4
* Store the message in the interface so we can call
* can_put_echo_skb(). We must do this before we enable
* transmit as we might race against do_tx().
*/
c_can_setup_tx_object(dev, IF_TX, frame, idx);
priv->dlc[idx] = frame->can_dlc;
172c: e583262c str r2, [r3, #1580] ; 0x62c
can_put_echo_skb(skb, dev, idx);
1730: e1a02007 mov r2, r7
1734: ebfffffe bl 0 <can_put_echo_skb>
/* Update the active bits */
atomic_add((1 << idx), &priv->tx_active);
1738: e2888f4a add r8, r8, #296 ; 0x128
173c: f598f000 pldw [r8]
1740: e3a03001 mov r3, #1
1744: e1a07713 lsl r7, r3, r7
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_OP_RETURN(op, c_op, asm_op)
ATOMIC_OPS(add, +=, add)
1748: e1983f9f ldrex r3, [r8]
174c: e0833007 add r3, r3, r7
1750: e1882f93 strex r2, r3, [r8]
1754: e3320000 teq r2, #0
1758: 1afffffa bne 1748 <c_can_start_xmit+0x1a8>
}
static inline void c_can_object_put(struct net_device *dev, int iface,
u32 obj, u32 cmd)
{
c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj);
175c: e3a01001 mov r1, #1
1760: e1a00004 mov r0, r4
1764: e51b3030 ldr r3, [fp, #-48] ; 0x30
1768: e3a020b7 mov r2, #183 ; 0xb7
176c: ebfffa80 bl 174 <c_can_obj_update>
atomic_add((1 << idx), &priv->tx_active);
/* Start transmission */
c_can_object_put(dev, IF_TX, obj, IF_COMM_TX);
return NETDEV_TX_OK;
}
1770: e3a00000 mov r0, #0
1774: e24bd028 sub sp, fp, #40 ; 0x28
1778: e89daff0 ldm sp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
cfd->len > CAN_MAX_DLEN))
goto inval_skb;
} else if (skb->protocol == htons(ETH_P_CANFD)) {
if (unlikely(skb->len != CANFD_MTU ||
177c: e5903054 ldr r3, [r0, #84] ; 0x54
1780: e3530048 cmp r3, #72 ; 0x48
1784: 1affff93 bne 15d8 <c_can_start_xmit+0x38>
1788: e5d63004 ldrb r3, [r6, #4]
178c: e3530040 cmp r3, #64 ; 0x40
1790: 9affff9e bls 1610 <c_can_start_xmit+0x70>
1794: eaffff8f b 15d8 <c_can_start_xmit+0x38>
}
}
static inline void netif_tx_stop_queue(struct netdev_queue *dev_queue)
{
set_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state);
1798: e5941240 ldr r1, [r4, #576] ; 0x240
179c: e3a00000 mov r0, #0
17a0: e2811050 add r1, r1, #80 ; 0x50
17a4: ebfffffe bl 0 <_set_bit>
17a8: eaffff9f b 162c <c_can_start_xmit+0x8c>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment