Lines Matching +full:dma +full:- +full:byte +full:- +full:en
1 // SPDX-License-Identifier: GPL-2.0
25 priv->irq_mask &= ~mask; in _intr2_mask_clear()
31 priv->irq_mask |= mask; in _intr2_mask_set()
34 void bcmasp_enable_phy_irq(struct bcmasp_intf *intf, int en) in bcmasp_enable_phy_irq() argument
36 struct bcmasp_priv *priv = intf->parent; in bcmasp_enable_phy_irq()
39 if (!intf->internal_phy) in bcmasp_enable_phy_irq()
42 if (en) in bcmasp_enable_phy_irq()
43 _intr2_mask_clear(priv, ASP_INTR2_PHY_EVENT(intf->channel)); in bcmasp_enable_phy_irq()
45 _intr2_mask_set(priv, ASP_INTR2_PHY_EVENT(intf->channel)); in bcmasp_enable_phy_irq()
48 void bcmasp_enable_tx_irq(struct bcmasp_intf *intf, int en) in bcmasp_enable_tx_irq() argument
50 struct bcmasp_priv *priv = intf->parent; in bcmasp_enable_tx_irq()
52 if (en) in bcmasp_enable_tx_irq()
53 _intr2_mask_clear(priv, ASP_INTR2_TX_DESC(intf->channel)); in bcmasp_enable_tx_irq()
55 _intr2_mask_set(priv, ASP_INTR2_TX_DESC(intf->channel)); in bcmasp_enable_tx_irq()
59 void bcmasp_enable_rx_irq(struct bcmasp_intf *intf, int en) in bcmasp_enable_rx_irq() argument
61 struct bcmasp_priv *priv = intf->parent; in bcmasp_enable_rx_irq()
63 if (en) in bcmasp_enable_rx_irq()
64 _intr2_mask_clear(priv, ASP_INTR2_RX_ECH(intf->channel)); in bcmasp_enable_rx_irq()
66 _intr2_mask_set(priv, ASP_INTR2_RX_ECH(intf->channel)); in bcmasp_enable_rx_irq()
73 priv->irq_mask = 0xffffffff; in bcmasp_intr2_mask_set_all()
83 if (status & ASP_INTR2_RX_ECH(intf->channel)) { in bcmasp_intr2_handling()
84 if (likely(napi_schedule_prep(&intf->rx_napi))) { in bcmasp_intr2_handling()
86 __napi_schedule_irqoff(&intf->rx_napi); in bcmasp_intr2_handling()
90 if (status & ASP_INTR2_TX_DESC(intf->channel)) { in bcmasp_intr2_handling()
91 if (likely(napi_schedule_prep(&intf->tx_napi))) { in bcmasp_intr2_handling()
93 __napi_schedule_irqoff(&intf->tx_napi); in bcmasp_intr2_handling()
97 if (status & ASP_INTR2_PHY_EVENT(intf->channel)) in bcmasp_intr2_handling()
98 phy_mac_interrupt(intf->ndev->phydev); in bcmasp_intr2_handling()
113 dev_warn(&priv->pdev->dev, "l2 spurious interrupt\n"); in bcmasp_isr()
118 list_for_each_entry(intf, &priv->intfs, list) in bcmasp_isr()
126 struct bcmasp_priv *priv = intf->parent; in bcmasp_flush_rx_port()
129 switch (intf->port) { in bcmasp_flush_rx_port()
144 rx_ctrl_core_wl(priv, mask, priv->hw_info->rx_ctrl_flush); in bcmasp_flush_rx_port()
151 ASP_RX_FILTER_NET_OFFSET(nfilt->hw_index)); in bcmasp_netfilt_hw_en_wake()
157 ASP_RX_FILTER_NET_OFFSET(nfilt->hw_index + 1)); in bcmasp_netfilt_hw_en_wake()
159 rx_filter_core_wl(priv, ASP_RX_FILTER_NET_CFG_CH(nfilt->port + 8) | in bcmasp_netfilt_hw_en_wake()
166 ASP_RX_FILTER_NET_CFG_UMC(nfilt->port), in bcmasp_netfilt_hw_en_wake()
167 ASP_RX_FILTER_NET_CFG(nfilt->hw_index)); in bcmasp_netfilt_hw_en_wake()
169 rx_filter_core_wl(priv, ASP_RX_FILTER_NET_CFG_CH(nfilt->port + 8) | in bcmasp_netfilt_hw_en_wake()
176 ASP_RX_FILTER_NET_CFG_UMC(nfilt->port), in bcmasp_netfilt_hw_en_wake()
177 ASP_RX_FILTER_NET_CFG(nfilt->hw_index + 1)); in bcmasp_netfilt_hw_en_wake()
196 filter_sel = nfilt->hw_index; in bcmasp_netfilt_get_reg_offset()
199 filter_sel = nfilt->hw_index + 1; in bcmasp_netfilt_get_reg_offset()
202 filter_sel = nfilt->hw_index; in bcmasp_netfilt_get_reg_offset()
205 filter_sel = nfilt->hw_index + 1; in bcmasp_netfilt_get_reg_offset()
208 filter_sel = nfilt->hw_index; in bcmasp_netfilt_get_reg_offset()
211 filter_sel = nfilt->hw_index + 1; in bcmasp_netfilt_get_reg_offset()
214 filter_sel = nfilt->hw_index; in bcmasp_netfilt_get_reg_offset()
217 filter_sel = nfilt->hw_index + 1; in bcmasp_netfilt_get_reg_offset()
219 return -EINVAL; in bcmasp_netfilt_get_reg_offset()
230 return -EINVAL; in bcmasp_netfilt_get_reg_offset()
241 /* HW only accepts 4 byte aligned writes */ in bcmasp_netfilt_wr()
258 /* HW only accepts 4 byte aligned writes */ in bcmasp_netfilt_rd()
277 return -EINVAL; in bcmasp_netfilt_wr_m_wake()
279 while (size--) { in bcmasp_netfilt_wr_m_wake()
280 /* The HW only accepts 4 byte aligned writes, so if we in bcmasp_netfilt_wr_m_wake()
294 shift = (3 - (offset % 4)) * 8; in bcmasp_netfilt_wr_m_wake()
300 /* If last byte or last byte of word, write to reg */ in bcmasp_netfilt_wr_m_wake()
343 &match->tos, &mask->tos, in bcmasp_netfilt_tcpip4_wr()
344 sizeof(match->tos)); in bcmasp_netfilt_tcpip4_wr()
346 &match->ip4src, &mask->ip4src, in bcmasp_netfilt_tcpip4_wr()
347 sizeof(match->ip4src)); in bcmasp_netfilt_tcpip4_wr()
349 &match->ip4dst, &mask->ip4dst, in bcmasp_netfilt_tcpip4_wr()
350 sizeof(match->ip4dst)); in bcmasp_netfilt_tcpip4_wr()
352 &match->psrc, &mask->psrc, in bcmasp_netfilt_tcpip4_wr()
353 sizeof(match->psrc)); in bcmasp_netfilt_tcpip4_wr()
355 &match->pdst, &mask->pdst, in bcmasp_netfilt_tcpip4_wr()
356 sizeof(match->pdst)); in bcmasp_netfilt_tcpip4_wr()
371 val_16 = htons(match->tclass << 4); in bcmasp_netfilt_tcpip6_wr()
372 mask_16 = htons(mask->tclass << 4); in bcmasp_netfilt_tcpip6_wr()
376 &match->ip6src, &mask->ip6src, in bcmasp_netfilt_tcpip6_wr()
377 sizeof(match->ip6src)); in bcmasp_netfilt_tcpip6_wr()
379 &match->ip6dst, &mask->ip6dst, in bcmasp_netfilt_tcpip6_wr()
380 sizeof(match->ip6dst)); in bcmasp_netfilt_tcpip6_wr()
382 &match->psrc, &mask->psrc, in bcmasp_netfilt_tcpip6_wr()
383 sizeof(match->psrc)); in bcmasp_netfilt_tcpip6_wr()
385 &match->pdst, &mask->pdst, in bcmasp_netfilt_tcpip6_wr()
386 sizeof(match->pdst)); in bcmasp_netfilt_tcpip6_wr()
392 struct ethtool_rx_flow_spec *fs = &nfilt->fs; in bcmasp_netfilt_wr_to_hw()
398 if (!nfilt->wake_filter) in bcmasp_netfilt_wr_to_hw()
399 return -EINVAL; in bcmasp_netfilt_wr_to_hw()
403 if (fs->flow_type & FLOW_MAC_EXT) { in bcmasp_netfilt_wr_to_hw()
404 bcmasp_netfilt_wr_m_wake(priv, nfilt, 0, &fs->h_ext.h_dest, in bcmasp_netfilt_wr_to_hw()
405 &fs->m_ext.h_dest, in bcmasp_netfilt_wr_to_hw()
406 sizeof(fs->h_ext.h_dest)); in bcmasp_netfilt_wr_to_hw()
409 if ((fs->flow_type & FLOW_EXT) && in bcmasp_netfilt_wr_to_hw()
410 (fs->m_ext.vlan_etype || fs->m_ext.vlan_tci)) { in bcmasp_netfilt_wr_to_hw()
412 &fs->h_ext.vlan_etype, in bcmasp_netfilt_wr_to_hw()
413 &fs->m_ext.vlan_etype, in bcmasp_netfilt_wr_to_hw()
414 sizeof(fs->h_ext.vlan_etype)); in bcmasp_netfilt_wr_to_hw()
416 &fs->h_ext.vlan_tci, in bcmasp_netfilt_wr_to_hw()
417 &fs->m_ext.vlan_tci, in bcmasp_netfilt_wr_to_hw()
418 sizeof(fs->h_ext.vlan_tci)); in bcmasp_netfilt_wr_to_hw()
422 switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { in bcmasp_netfilt_wr_to_hw()
425 &fs->h_u.ether_spec.h_dest, in bcmasp_netfilt_wr_to_hw()
426 &fs->m_u.ether_spec.h_dest, in bcmasp_netfilt_wr_to_hw()
427 sizeof(fs->h_u.ether_spec.h_dest)); in bcmasp_netfilt_wr_to_hw()
429 &fs->h_u.ether_spec.h_source, in bcmasp_netfilt_wr_to_hw()
430 &fs->m_u.ether_spec.h_source, in bcmasp_netfilt_wr_to_hw()
431 sizeof(fs->h_u.ether_spec.h_source)); in bcmasp_netfilt_wr_to_hw()
433 &fs->h_u.ether_spec.h_proto, in bcmasp_netfilt_wr_to_hw()
434 &fs->m_u.ether_spec.h_proto, in bcmasp_netfilt_wr_to_hw()
435 sizeof(fs->h_u.ether_spec.h_proto)); in bcmasp_netfilt_wr_to_hw()
444 &fs->h_u.usr_ip4_spec.tos, in bcmasp_netfilt_wr_to_hw()
445 &fs->m_u.usr_ip4_spec.tos, in bcmasp_netfilt_wr_to_hw()
446 sizeof(fs->h_u.usr_ip4_spec.tos)); in bcmasp_netfilt_wr_to_hw()
448 &fs->h_u.usr_ip4_spec.proto, in bcmasp_netfilt_wr_to_hw()
449 &fs->m_u.usr_ip4_spec.proto, in bcmasp_netfilt_wr_to_hw()
450 sizeof(fs->h_u.usr_ip4_spec.proto)); in bcmasp_netfilt_wr_to_hw()
452 &fs->h_u.usr_ip4_spec.ip4src, in bcmasp_netfilt_wr_to_hw()
453 &fs->m_u.usr_ip4_spec.ip4src, in bcmasp_netfilt_wr_to_hw()
454 sizeof(fs->h_u.usr_ip4_spec.ip4src)); in bcmasp_netfilt_wr_to_hw()
456 &fs->h_u.usr_ip4_spec.ip4dst, in bcmasp_netfilt_wr_to_hw()
457 &fs->m_u.usr_ip4_spec.ip4dst, in bcmasp_netfilt_wr_to_hw()
458 sizeof(fs->h_u.usr_ip4_spec.ip4dst)); in bcmasp_netfilt_wr_to_hw()
459 if (!fs->m_u.usr_ip4_spec.l4_4_bytes) in bcmasp_netfilt_wr_to_hw()
462 /* Only supports 20 byte IPv4 header */ in bcmasp_netfilt_wr_to_hw()
469 &fs->h_u.usr_ip4_spec.l4_4_bytes, in bcmasp_netfilt_wr_to_hw()
470 &fs->m_u.usr_ip4_spec.l4_4_bytes, in bcmasp_netfilt_wr_to_hw()
471 sizeof(fs->h_u.usr_ip4_spec.l4_4_bytes) in bcmasp_netfilt_wr_to_hw()
477 bcmasp_netfilt_tcpip4_wr(priv, nfilt, &fs->h_u.tcp_ip4_spec, in bcmasp_netfilt_wr_to_hw()
478 &fs->m_u.tcp_ip4_spec, offset); in bcmasp_netfilt_wr_to_hw()
485 bcmasp_netfilt_tcpip4_wr(priv, nfilt, &fs->h_u.udp_ip4_spec, in bcmasp_netfilt_wr_to_hw()
486 &fs->m_u.udp_ip4_spec, offset); in bcmasp_netfilt_wr_to_hw()
494 bcmasp_netfilt_tcpip6_wr(priv, nfilt, &fs->h_u.tcp_ip6_spec, in bcmasp_netfilt_wr_to_hw()
495 &fs->m_u.tcp_ip6_spec, offset); in bcmasp_netfilt_wr_to_hw()
502 bcmasp_netfilt_tcpip6_wr(priv, nfilt, &fs->h_u.udp_ip6_spec, in bcmasp_netfilt_wr_to_hw()
503 &fs->m_u.udp_ip6_spec, offset); in bcmasp_netfilt_wr_to_hw()
516 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_suspend()
523 if (!priv->net_filters[i].claimed || in bcmasp_netfilt_suspend()
524 priv->net_filters[i].port != intf->port) in bcmasp_netfilt_suspend()
528 priv->net_filters[i].wake_filter && in bcmasp_netfilt_suspend()
529 priv->net_filters[i - 1].wake_filter) in bcmasp_netfilt_suspend()
532 ret = bcmasp_netfilt_wr_to_hw(priv, &priv->net_filters[i]); in bcmasp_netfilt_suspend()
551 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_get_all_active()
555 if (!priv->net_filters[i].claimed || in bcmasp_netfilt_get_all_active()
556 priv->net_filters[i].port != intf->port) in bcmasp_netfilt_get_all_active()
560 priv->net_filters[i].wake_filter && in bcmasp_netfilt_get_all_active()
561 priv->net_filters[i - 1].wake_filter) in bcmasp_netfilt_get_all_active()
565 return -EMSGSIZE; in bcmasp_netfilt_get_all_active()
567 rule_locs[j++] = priv->net_filters[i].fs.location; in bcmasp_netfilt_get_all_active()
577 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_get_active()
581 if (!priv->net_filters[i].claimed || in bcmasp_netfilt_get_active()
582 priv->net_filters[i].port != intf->port) in bcmasp_netfilt_get_active()
587 priv->net_filters[i].wake_filter && in bcmasp_netfilt_get_active()
588 priv->net_filters[i - 1].wake_filter) in bcmasp_netfilt_get_active()
600 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_check_dup()
606 if (!priv->net_filters[i].claimed || in bcmasp_netfilt_check_dup()
607 priv->net_filters[i].port != intf->port) in bcmasp_netfilt_check_dup()
610 cur = &priv->net_filters[i].fs; in bcmasp_netfilt_check_dup()
612 if (cur->flow_type != fs->flow_type || in bcmasp_netfilt_check_dup()
613 cur->ring_cookie != fs->ring_cookie) in bcmasp_netfilt_check_dup()
616 switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { in bcmasp_netfilt_check_dup()
635 if (memcmp(&cur->h_u, &fs->h_u, fs_size) || in bcmasp_netfilt_check_dup()
636 memcmp(&cur->m_u, &fs->m_u, fs_size)) in bcmasp_netfilt_check_dup()
639 if (cur->flow_type & FLOW_EXT) { in bcmasp_netfilt_check_dup()
640 if (cur->h_ext.vlan_etype != fs->h_ext.vlan_etype || in bcmasp_netfilt_check_dup()
641 cur->m_ext.vlan_etype != fs->m_ext.vlan_etype || in bcmasp_netfilt_check_dup()
642 cur->h_ext.vlan_tci != fs->h_ext.vlan_tci || in bcmasp_netfilt_check_dup()
643 cur->m_ext.vlan_tci != fs->m_ext.vlan_tci || in bcmasp_netfilt_check_dup()
644 cur->h_ext.data[0] != fs->h_ext.data[0]) in bcmasp_netfilt_check_dup()
647 if (cur->flow_type & FLOW_MAC_EXT) { in bcmasp_netfilt_check_dup()
648 if (memcmp(&cur->h_ext.h_dest, in bcmasp_netfilt_check_dup()
649 &fs->h_ext.h_dest, ETH_ALEN) || in bcmasp_netfilt_check_dup()
650 memcmp(&cur->m_ext.h_dest, in bcmasp_netfilt_check_dup()
651 &fs->m_ext.h_dest, ETH_ALEN)) in bcmasp_netfilt_check_dup()
669 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_get_init()
670 int i, open_index = -1; in bcmasp_netfilt_get_init()
674 return ERR_PTR(-EINVAL); in bcmasp_netfilt_get_init()
679 if (loc != RX_CLS_LOC_ANY && init && priv->net_filters[loc].claimed) in bcmasp_netfilt_get_init()
680 return ERR_PTR(-EBUSY); in bcmasp_netfilt_get_init()
682 /* We need two filters for wake-up, so we cannot use an odd filter */ in bcmasp_netfilt_get_init()
684 return ERR_PTR(-EINVAL); in bcmasp_netfilt_get_init()
692 priv->net_filters[i].claimed && in bcmasp_netfilt_get_init()
693 priv->net_filters[i].hw_index == i && in bcmasp_netfilt_get_init()
694 priv->net_filters[i].port == intf->port) in bcmasp_netfilt_get_init()
695 return &priv->net_filters[i]; in bcmasp_netfilt_get_init()
706 if (wake_filter && !(i % 2) && !priv->net_filters[i].claimed && in bcmasp_netfilt_get_init()
707 !priv->net_filters[i + 1].claimed) in bcmasp_netfilt_get_init()
709 else if (!priv->net_filters[i].claimed) in bcmasp_netfilt_get_init()
714 nfilter = &priv->net_filters[open_index]; in bcmasp_netfilt_get_init()
715 nfilter->claimed = true; in bcmasp_netfilt_get_init()
716 nfilter->port = intf->port; in bcmasp_netfilt_get_init()
717 nfilter->hw_index = open_index; in bcmasp_netfilt_get_init()
722 priv->net_filters[open_index + 1].claimed = true; in bcmasp_netfilt_get_init()
723 priv->net_filters[open_index + 1].wake_filter = true; in bcmasp_netfilt_get_init()
724 nfilter->wake_filter = true; in bcmasp_netfilt_get_init()
727 return nfilter ? nfilter : ERR_PTR(-EINVAL); in bcmasp_netfilt_get_init()
733 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_release()
735 if (nfilt->wake_filter) { in bcmasp_netfilt_release()
736 memset(&priv->net_filters[nfilt->hw_index + 1], 0, in bcmasp_netfilt_release()
755 struct bcmasp_priv *priv = intf->parent; in bcmasp_set_mda_filter()
759 ether_addr_copy(priv->mda_filters[i].mask, mask); in bcmasp_set_mda_filter()
760 ether_addr_copy(priv->mda_filters[i].addr, addr); in bcmasp_set_mda_filter()
763 bcmasp_addr_to_uint(priv->mda_filters[i].mask, &mask_h, &mask_l); in bcmasp_set_mda_filter()
764 bcmasp_addr_to_uint(priv->mda_filters[i].addr, &addr_h, &addr_l); in bcmasp_set_mda_filter()
771 static void bcmasp_en_mda_filter(struct bcmasp_intf *intf, bool en, in bcmasp_en_mda_filter() argument
774 struct bcmasp_priv *priv = intf->parent; in bcmasp_en_mda_filter()
776 if (priv->mda_filters[i].en == en) in bcmasp_en_mda_filter()
779 priv->mda_filters[i].en = en; in bcmasp_en_mda_filter()
780 priv->mda_filters[i].port = intf->port; in bcmasp_en_mda_filter()
782 rx_filter_core_wl(priv, ((intf->channel + 8) | in bcmasp_en_mda_filter()
783 (en << ASP_RX_FILTER_MDA_CFG_EN_SHIFT) | in bcmasp_en_mda_filter()
784 ASP_RX_FILTER_MDA_CFG_UMC_SEL(intf->port)), in bcmasp_en_mda_filter()
790 * - Promisc: Filter to allow all packets when promisc is enabled
791 * - All Multicast
792 * - Broadcast
793 * - Own address
796 * - Promisc: (index * 4) + 0
797 * - All Multicast: (index * 4) + 1
798 * - Broadcast: (index * 4) + 2
799 * - Own address: (index * 4) + 3
809 #define ASP_RX_FILT_MDA(intf, name) (((intf)->index * \
815 return list_count_nodes(&priv->intfs) * ASP_RX_FILTER_MDA_RES_MAX; in bcmasp_total_res_mda_cnt()
818 void bcmasp_set_promisc(struct bcmasp_intf *intf, bool en) in bcmasp_set_promisc() argument
826 bcmasp_en_mda_filter(intf, en, i); in bcmasp_set_promisc()
829 void bcmasp_set_allmulti(struct bcmasp_intf *intf, bool en) in bcmasp_set_allmulti() argument
836 bcmasp_en_mda_filter(intf, en, i); in bcmasp_set_allmulti()
839 void bcmasp_set_broad(struct bcmasp_intf *intf, bool en) in bcmasp_set_broad() argument
846 bcmasp_en_mda_filter(intf, en, i); in bcmasp_set_broad()
850 bool en) in bcmasp_set_oaddr() argument
856 bcmasp_en_mda_filter(intf, en, i); in bcmasp_set_oaddr()
861 struct bcmasp_priv *priv = intf->parent; in bcmasp_disable_all_filters()
865 res_count = bcmasp_total_res_mda_cnt(intf->parent); in bcmasp_disable_all_filters()
869 if (priv->mda_filters[i].en && in bcmasp_disable_all_filters()
870 priv->mda_filters[i].port == intf->port) in bcmasp_disable_all_filters()
879 struct bcmasp_priv *priv = intf->parent; in bcmasp_combine_set_filter()
883 addr1 = ether_addr_to_u64(priv->mda_filters[i].addr); in bcmasp_combine_set_filter()
884 mask1 = ether_addr_to_u64(priv->mda_filters[i].mask); in bcmasp_combine_set_filter()
900 return -EINVAL; in bcmasp_combine_set_filter()
906 struct bcmasp_priv *priv = intf->parent; in bcmasp_set_en_mda_filter()
910 res_count = bcmasp_total_res_mda_cnt(intf->parent); in bcmasp_set_en_mda_filter()
914 if (!priv->mda_filters[i].en || in bcmasp_set_en_mda_filter()
915 priv->mda_filters[i].port != intf->port) in bcmasp_set_en_mda_filter()
921 intf->mib.filters_combine_cnt++; in bcmasp_set_en_mda_filter()
928 if (priv->mda_filters[i].en) in bcmasp_set_en_mda_filter()
937 return -EINVAL; in bcmasp_set_en_mda_filter()
949 priv->mda_filters[i].en = 0; in bcmasp_core_init_filters()
956 * GEN_WAKE_CLEAR to clear the network filter wake-up which would in bcmasp_core_init_filters()
984 /* Disable and clear both UniMAC's wake-up interrupts to avoid in bcmasp_core_init()
1042 spin_lock_irqsave(&priv->clk_lock, flags); in bcmasp_core_clock_set()
1044 spin_unlock_irqrestore(&priv->clk_lock, flags); in bcmasp_core_clock_set()
1047 void bcmasp_core_clock_set_intf(struct bcmasp_intf *intf, bool en) in bcmasp_core_clock_set_intf() argument
1049 u32 intf_mask = ASP_CTRL_CLOCK_CTRL_ASP_RGMII_DIS(intf->port); in bcmasp_core_clock_set_intf()
1050 struct bcmasp_priv *priv = intf->parent; in bcmasp_core_clock_set_intf()
1060 spin_lock_irqsave(&priv->clk_lock, flags); in bcmasp_core_clock_set_intf()
1061 if (en) { in bcmasp_core_clock_set_intf()
1073 spin_unlock_irqrestore(&priv->clk_lock, flags); in bcmasp_core_clock_set_intf()
1082 if (priv->wol_irq <= 0) in bcmasp_isr_wol()
1090 pm_wakeup_event(&priv->pdev->dev, 0); in bcmasp_isr_wol()
1096 struct platform_device *pdev = priv->pdev; in bcmasp_get_and_request_irq()
1103 ret = devm_request_irq(&pdev->dev, irq, bcmasp_isr_wol, 0, in bcmasp_get_and_request_irq()
1104 pdev->name, priv); in bcmasp_get_and_request_irq()
1113 struct platform_device *pdev = priv->pdev; in bcmasp_init_wol_shared()
1114 struct device *dev = &pdev->dev; in bcmasp_init_wol_shared()
1123 priv->wol_irq = irq; in bcmasp_init_wol_shared()
1124 priv->wol_irq_enabled_mask = 0; in bcmasp_init_wol_shared()
1125 device_set_wakeup_capable(&pdev->dev, 1); in bcmasp_init_wol_shared()
1128 static void bcmasp_enable_wol_shared(struct bcmasp_intf *intf, bool en) in bcmasp_enable_wol_shared() argument
1130 struct bcmasp_priv *priv = intf->parent; in bcmasp_enable_wol_shared()
1131 struct device *dev = &priv->pdev->dev; in bcmasp_enable_wol_shared()
1133 if (en) { in bcmasp_enable_wol_shared()
1134 if (priv->wol_irq_enabled_mask) { in bcmasp_enable_wol_shared()
1135 set_bit(intf->port, &priv->wol_irq_enabled_mask); in bcmasp_enable_wol_shared()
1140 set_bit(intf->port, &priv->wol_irq_enabled_mask); in bcmasp_enable_wol_shared()
1141 enable_irq_wake(priv->wol_irq); in bcmasp_enable_wol_shared()
1144 if (!priv->wol_irq_enabled_mask) in bcmasp_enable_wol_shared()
1147 clear_bit(intf->port, &priv->wol_irq_enabled_mask); in bcmasp_enable_wol_shared()
1148 if (priv->wol_irq_enabled_mask) in bcmasp_enable_wol_shared()
1152 disable_irq_wake(priv->wol_irq); in bcmasp_enable_wol_shared()
1159 if (priv->wol_irq > 0) in bcmasp_wol_irq_destroy_shared()
1160 free_irq(priv->wol_irq, priv); in bcmasp_wol_irq_destroy_shared()
1165 struct platform_device *pdev = priv->pdev; in bcmasp_init_wol_per_intf()
1166 struct device *dev = &pdev->dev; in bcmasp_init_wol_per_intf()
1170 list_for_each_entry(intf, &priv->intfs, list) { in bcmasp_init_wol_per_intf()
1171 irq = bcmasp_get_and_request_irq(priv, intf->port + 1); in bcmasp_init_wol_per_intf()
1174 intf->port, irq); in bcmasp_init_wol_per_intf()
1178 intf->wol_irq = irq; in bcmasp_init_wol_per_intf()
1179 intf->wol_irq_enabled = false; in bcmasp_init_wol_per_intf()
1180 device_set_wakeup_capable(&pdev->dev, 1); in bcmasp_init_wol_per_intf()
1184 static void bcmasp_enable_wol_per_intf(struct bcmasp_intf *intf, bool en) in bcmasp_enable_wol_per_intf() argument
1186 struct device *dev = &intf->parent->pdev->dev; in bcmasp_enable_wol_per_intf()
1188 if (en ^ intf->wol_irq_enabled) in bcmasp_enable_wol_per_intf()
1189 irq_set_irq_wake(intf->wol_irq, en); in bcmasp_enable_wol_per_intf()
1191 intf->wol_irq_enabled = en; in bcmasp_enable_wol_per_intf()
1192 device_set_wakeup_enable(dev, en); in bcmasp_enable_wol_per_intf()
1199 list_for_each_entry(intf, &priv->intfs, list) { in bcmasp_wol_irq_destroy_per_intf()
1200 if (intf->wol_irq > 0) in bcmasp_wol_irq_destroy_per_intf()
1201 free_irq(intf->wol_irq, priv); in bcmasp_wol_irq_destroy_per_intf()
1205 static void bcmasp_eee_fixup(struct bcmasp_intf *intf, bool en) in bcmasp_eee_fixup() argument
1209 reg = rx_edpkt_core_rl(intf->parent, ASP_EDPKT_SPARE_REG); in bcmasp_eee_fixup()
1210 phy_lpi_overwrite = intf->internal_phy ? ASP_EDPKT_SPARE_REG_EPHY_LPI : in bcmasp_eee_fixup()
1213 if (en) in bcmasp_eee_fixup()
1218 rx_edpkt_core_wl(intf->parent, reg, ASP_EDPKT_SPARE_REG); in bcmasp_eee_fixup()
1267 priv->init_wol = pdata->init_wol; in bcmasp_set_pdata()
1268 priv->enable_wol = pdata->enable_wol; in bcmasp_set_pdata()
1269 priv->destroy_wol = pdata->destroy_wol; in bcmasp_set_pdata()
1270 priv->core_clock_select = pdata->core_clock_select; in bcmasp_set_pdata()
1271 priv->eee_fixup = pdata->eee_fixup; in bcmasp_set_pdata()
1272 priv->hw_info = pdata->hw_info; in bcmasp_set_pdata()
1276 { .compatible = "brcm,asp-v2.0", .data = &v20_plat_data },
1277 { .compatible = "brcm,asp-v2.1", .data = &v21_plat_data },
1278 { .compatible = "brcm,asp-v2.2", .data = &v22_plat_data },
1284 { .compatible = "brcm,asp-v2.2-mdio", },
1285 { .compatible = "brcm,asp-v2.1-mdio", },
1286 { .compatible = "brcm,asp-v2.0-mdio", },
1295 list_for_each_entry_safe(intf, n, &priv->intfs, list) { in bcmasp_remove_intfs()
1296 list_del(&intf->list); in bcmasp_remove_intfs()
1304 struct device *dev = &pdev->dev; in bcmasp_probe()
1313 return -ENOMEM; in bcmasp_probe()
1315 priv->irq = platform_get_irq(pdev, 0); in bcmasp_probe()
1316 if (priv->irq <= 0) in bcmasp_probe()
1317 return -EINVAL; in bcmasp_probe()
1319 priv->clk = devm_clk_get_optional_enabled(dev, "sw_asp"); in bcmasp_probe()
1320 if (IS_ERR(priv->clk)) in bcmasp_probe()
1321 return dev_err_probe(dev, PTR_ERR(priv->clk), in bcmasp_probe()
1325 priv->base = devm_platform_ioremap_resource(pdev, 0); in bcmasp_probe()
1326 if (IS_ERR(priv->base)) in bcmasp_probe()
1327 return dev_err_probe(dev, PTR_ERR(priv->base), "failed to iomap\n"); in bcmasp_probe()
1329 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40)); in bcmasp_probe()
1331 return dev_err_probe(dev, ret, "unable to set DMA mask: %d\n", ret); in bcmasp_probe()
1333 dev_set_drvdata(&pdev->dev, priv); in bcmasp_probe()
1334 priv->pdev = pdev; in bcmasp_probe()
1335 spin_lock_init(&priv->mda_lock); in bcmasp_probe()
1336 spin_lock_init(&priv->clk_lock); in bcmasp_probe()
1337 mutex_init(&priv->wol_lock); in bcmasp_probe()
1338 mutex_init(&priv->net_lock); in bcmasp_probe()
1339 INIT_LIST_HEAD(&priv->intfs); in bcmasp_probe()
1341 pdata = device_get_match_data(&pdev->dev); in bcmasp_probe()
1343 return dev_err_probe(dev, -EINVAL, "unable to find platform data\n"); in bcmasp_probe()
1351 priv->core_clock_select(priv, false); in bcmasp_probe()
1356 ret = devm_request_irq(&pdev->dev, priv->irq, bcmasp_isr, 0, in bcmasp_probe()
1357 pdev->name, priv); in bcmasp_probe()
1362 of_platform_populate(dev->of_node, bcmasp_mdio_of_match, NULL, dev); in bcmasp_probe()
1370 ports_node = of_find_node_by_name(dev->of_node, "ethernet-ports"); in bcmasp_probe()
1373 return -EINVAL; in bcmasp_probe()
1382 ret = -ENOMEM; in bcmasp_probe()
1385 list_add_tail(&intf->list, &priv->intfs); in bcmasp_probe()
1390 priv->init_wol(priv); in bcmasp_probe()
1397 clk_disable_unprepare(priv->clk); in bcmasp_probe()
1402 list_for_each_entry(intf, &priv->intfs, list) { in bcmasp_probe()
1403 ret = register_netdev(intf->ndev); in bcmasp_probe()
1405 netdev_err(intf->ndev, in bcmasp_probe()
1407 priv->destroy_wol(priv); in bcmasp_probe()
1423 struct bcmasp_priv *priv = dev_get_drvdata(&pdev->dev); in bcmasp_remove()
1428 priv->destroy_wol(priv); in bcmasp_remove()
1443 list_for_each_entry(intf, &priv->intfs, list) { in bcmasp_suspend()
1449 ret = clk_prepare_enable(priv->clk); in bcmasp_suspend()
1453 /* Whether Wake-on-LAN is enabled or not, we can always disable in bcmasp_suspend()
1458 priv->core_clock_select(priv, true); in bcmasp_suspend()
1460 clk_disable_unprepare(priv->clk); in bcmasp_suspend()
1471 ret = clk_prepare_enable(priv->clk); in bcmasp_resume()
1476 priv->core_clock_select(priv, false); in bcmasp_resume()
1478 /* Re-enable all clocks for re-initialization */ in bcmasp_resume()
1487 clk_disable_unprepare(priv->clk); in bcmasp_resume()
1489 list_for_each_entry(intf, &priv->intfs, list) { in bcmasp_resume()
1506 .name = "brcm,asp-v2",
1514 MODULE_ALIAS("platform:brcm,asp-v2");