|
7 | 7 | #include <linux/ip.h>
|
8 | 8 | #include <linux/of_platform.h>
|
9 | 9 | #include <linux/of_net.h>
|
10 |
| -#include <linux/packing.h> |
11 | 10 | #include <linux/phy/phy.h>
|
12 | 11 | #include <linux/reset.h>
|
13 | 12 | #include <net/addrconf.h>
|
@@ -305,46 +304,57 @@ static int lan966x_port_ifh_xmit(struct sk_buff *skb,
|
305 | 304 | return NETDEV_TX_BUSY;
|
306 | 305 | }
|
307 | 306 |
|
| 307 | +static void lan966x_ifh_set(u8 *ifh, size_t val, size_t pos, size_t length) |
| 308 | +{ |
| 309 | + int i = 0; |
| 310 | + |
| 311 | + do { |
| 312 | + u8 p = IFH_LEN_BYTES - (pos + i) / 8 - 1; |
| 313 | + u8 v = val >> i & 0xff; |
| 314 | + |
| 315 | + /* There is no need to check for limits of the array, as these |
| 316 | + * will never be written |
| 317 | + */ |
| 318 | + ifh[p] |= v << ((pos + i) % 8); |
| 319 | + ifh[p - 1] |= v >> (8 - (pos + i) % 8); |
| 320 | + |
| 321 | + i += 8; |
| 322 | + } while (i < length); |
| 323 | +} |
| 324 | + |
308 | 325 | void lan966x_ifh_set_bypass(void *ifh, u64 bypass)
|
309 | 326 | {
|
310 |
| - packing(ifh, &bypass, IFH_POS_BYPASS + IFH_WID_BYPASS - 1, |
311 |
| - IFH_POS_BYPASS, IFH_LEN * 4, PACK, 0); |
| 327 | + lan966x_ifh_set(ifh, bypass, IFH_POS_BYPASS, IFH_WID_BYPASS); |
312 | 328 | }
|
313 | 329 |
|
314 |
| -void lan966x_ifh_set_port(void *ifh, u64 bypass) |
| 330 | +void lan966x_ifh_set_port(void *ifh, u64 port) |
315 | 331 | {
|
316 |
| - packing(ifh, &bypass, IFH_POS_DSTS + IFH_WID_DSTS - 1, |
317 |
| - IFH_POS_DSTS, IFH_LEN * 4, PACK, 0); |
| 332 | + lan966x_ifh_set(ifh, port, IFH_POS_DSTS, IFH_WID_DSTS); |
318 | 333 | }
|
319 | 334 |
|
320 |
| -static void lan966x_ifh_set_qos_class(void *ifh, u64 bypass) |
| 335 | +static void lan966x_ifh_set_qos_class(void *ifh, u64 qos) |
321 | 336 | {
|
322 |
| - packing(ifh, &bypass, IFH_POS_QOS_CLASS + IFH_WID_QOS_CLASS - 1, |
323 |
| - IFH_POS_QOS_CLASS, IFH_LEN * 4, PACK, 0); |
| 337 | + lan966x_ifh_set(ifh, qos, IFH_POS_QOS_CLASS, IFH_WID_QOS_CLASS); |
324 | 338 | }
|
325 | 339 |
|
326 |
| -static void lan966x_ifh_set_ipv(void *ifh, u64 bypass) |
| 340 | +static void lan966x_ifh_set_ipv(void *ifh, u64 ipv) |
327 | 341 | {
|
328 |
| - packing(ifh, &bypass, IFH_POS_IPV + IFH_WID_IPV - 1, |
329 |
| - IFH_POS_IPV, IFH_LEN * 4, PACK, 0); |
| 342 | + lan966x_ifh_set(ifh, ipv, IFH_POS_IPV, IFH_WID_IPV); |
330 | 343 | }
|
331 | 344 |
|
332 | 345 | static void lan966x_ifh_set_vid(void *ifh, u64 vid)
|
333 | 346 | {
|
334 |
| - packing(ifh, &vid, IFH_POS_TCI + IFH_WID_TCI - 1, |
335 |
| - IFH_POS_TCI, IFH_LEN * 4, PACK, 0); |
| 347 | + lan966x_ifh_set(ifh, vid, IFH_POS_TCI, IFH_WID_TCI); |
336 | 348 | }
|
337 | 349 |
|
338 | 350 | static void lan966x_ifh_set_rew_op(void *ifh, u64 rew_op)
|
339 | 351 | {
|
340 |
| - packing(ifh, &rew_op, IFH_POS_REW_CMD + IFH_WID_REW_CMD - 1, |
341 |
| - IFH_POS_REW_CMD, IFH_LEN * 4, PACK, 0); |
| 352 | + lan966x_ifh_set(ifh, rew_op, IFH_POS_REW_CMD, IFH_WID_REW_CMD); |
342 | 353 | }
|
343 | 354 |
|
344 | 355 | static void lan966x_ifh_set_timestamp(void *ifh, u64 timestamp)
|
345 | 356 | {
|
346 |
| - packing(ifh, ×tamp, IFH_POS_TIMESTAMP + IFH_WID_TIMESTAMP - 1, |
347 |
| - IFH_POS_TIMESTAMP, IFH_LEN * 4, PACK, 0); |
| 357 | + lan966x_ifh_set(ifh, timestamp, IFH_POS_TIMESTAMP, IFH_WID_TIMESTAMP); |
348 | 358 | }
|
349 | 359 |
|
350 | 360 | static netdev_tx_t lan966x_port_xmit(struct sk_buff *skb,
|
@@ -582,22 +592,38 @@ static int lan966x_rx_frame_word(struct lan966x *lan966x, u8 grp, u32 *rval)
|
582 | 592 | }
|
583 | 593 | }
|
584 | 594 |
|
| 595 | +static u64 lan966x_ifh_get(u8 *ifh, size_t pos, size_t length) |
| 596 | +{ |
| 597 | + u64 val = 0; |
| 598 | + u8 v; |
| 599 | + |
| 600 | + for (int i = 0; i < length ; i++) { |
| 601 | + int j = pos + i; |
| 602 | + int k = j % 8; |
| 603 | + |
| 604 | + if (i == 0 || k == 0) |
| 605 | + v = ifh[IFH_LEN_BYTES - (j / 8) - 1]; |
| 606 | + |
| 607 | + if (v & (1 << k)) |
| 608 | + val |= (1 << i); |
| 609 | + } |
| 610 | + |
| 611 | + return val; |
| 612 | +} |
| 613 | + |
585 | 614 | void lan966x_ifh_get_src_port(void *ifh, u64 *src_port)
|
586 | 615 | {
|
587 |
| - packing(ifh, src_port, IFH_POS_SRCPORT + IFH_WID_SRCPORT - 1, |
588 |
| - IFH_POS_SRCPORT, IFH_LEN * 4, UNPACK, 0); |
| 616 | + *src_port = lan966x_ifh_get(ifh, IFH_POS_SRCPORT, IFH_WID_SRCPORT); |
589 | 617 | }
|
590 | 618 |
|
591 | 619 | static void lan966x_ifh_get_len(void *ifh, u64 *len)
|
592 | 620 | {
|
593 |
| - packing(ifh, len, IFH_POS_LEN + IFH_WID_LEN - 1, |
594 |
| - IFH_POS_LEN, IFH_LEN * 4, UNPACK, 0); |
| 621 | + *len = lan966x_ifh_get(ifh, IFH_POS_LEN, IFH_WID_LEN); |
595 | 622 | }
|
596 | 623 |
|
597 | 624 | void lan966x_ifh_get_timestamp(void *ifh, u64 *timestamp)
|
598 | 625 | {
|
599 |
| - packing(ifh, timestamp, IFH_POS_TIMESTAMP + IFH_WID_TIMESTAMP - 1, |
600 |
| - IFH_POS_TIMESTAMP, IFH_LEN * 4, UNPACK, 0); |
| 626 | + *timestamp = lan966x_ifh_get(ifh, IFH_POS_TIMESTAMP, IFH_WID_TIMESTAMP); |
601 | 627 | }
|
602 | 628 |
|
603 | 629 | static irqreturn_t lan966x_xtr_irq_handler(int irq, void *args)
|
|
0 commit comments