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_tx_irq(struct bcmasp_intf *intf, int en) in bcmasp_enable_tx_irq() argument
36 struct bcmasp_priv *priv = intf->parent; in bcmasp_enable_tx_irq()
38 if (en) in bcmasp_enable_tx_irq()
39 _intr2_mask_clear(priv, ASP_INTR2_TX_DESC(intf->channel)); in bcmasp_enable_tx_irq()
41 _intr2_mask_set(priv, ASP_INTR2_TX_DESC(intf->channel)); in bcmasp_enable_tx_irq()
45 void bcmasp_enable_rx_irq(struct bcmasp_intf *intf, int en) in bcmasp_enable_rx_irq() argument
47 struct bcmasp_priv *priv = intf->parent; in bcmasp_enable_rx_irq()
49 if (en) in bcmasp_enable_rx_irq()
50 _intr2_mask_clear(priv, ASP_INTR2_RX_ECH(intf->channel)); in bcmasp_enable_rx_irq()
52 _intr2_mask_set(priv, ASP_INTR2_RX_ECH(intf->channel)); in bcmasp_enable_rx_irq()
59 priv->irq_mask = 0xffffffff; in bcmasp_intr2_mask_set_all()
69 if (status & ASP_INTR2_RX_ECH(intf->channel)) { in bcmasp_intr2_handling()
70 if (likely(napi_schedule_prep(&intf->rx_napi))) { in bcmasp_intr2_handling()
72 __napi_schedule_irqoff(&intf->rx_napi); in bcmasp_intr2_handling()
76 if (status & ASP_INTR2_TX_DESC(intf->channel)) { in bcmasp_intr2_handling()
77 if (likely(napi_schedule_prep(&intf->tx_napi))) { in bcmasp_intr2_handling()
79 __napi_schedule_irqoff(&intf->tx_napi); in bcmasp_intr2_handling()
96 dev_warn(&priv->pdev->dev, "l2 spurious interrupt\n"); in bcmasp_isr()
101 list_for_each_entry(intf, &priv->intfs, list) in bcmasp_isr()
109 struct bcmasp_priv *priv = intf->parent; in bcmasp_flush_rx_port()
112 switch (intf->port) { in bcmasp_flush_rx_port()
127 rx_ctrl_core_wl(priv, mask, priv->hw_info->rx_ctrl_flush); in bcmasp_flush_rx_port()
134 ASP_RX_FILTER_NET_OFFSET(nfilt->hw_index)); in bcmasp_netfilt_hw_en_wake()
140 ASP_RX_FILTER_NET_OFFSET(nfilt->hw_index + 1)); in bcmasp_netfilt_hw_en_wake()
142 rx_filter_core_wl(priv, ASP_RX_FILTER_NET_CFG_CH(nfilt->port + 8) | in bcmasp_netfilt_hw_en_wake()
149 ASP_RX_FILTER_NET_CFG_UMC(nfilt->port), in bcmasp_netfilt_hw_en_wake()
150 ASP_RX_FILTER_NET_CFG(nfilt->hw_index)); in bcmasp_netfilt_hw_en_wake()
152 rx_filter_core_wl(priv, ASP_RX_FILTER_NET_CFG_CH(nfilt->port + 8) | in bcmasp_netfilt_hw_en_wake()
159 ASP_RX_FILTER_NET_CFG_UMC(nfilt->port), in bcmasp_netfilt_hw_en_wake()
160 ASP_RX_FILTER_NET_CFG(nfilt->hw_index + 1)); in bcmasp_netfilt_hw_en_wake()
179 filter_sel = nfilt->hw_index; in bcmasp_netfilt_get_reg_offset()
182 filter_sel = nfilt->hw_index + 1; in bcmasp_netfilt_get_reg_offset()
185 filter_sel = nfilt->hw_index; in bcmasp_netfilt_get_reg_offset()
188 filter_sel = nfilt->hw_index + 1; in bcmasp_netfilt_get_reg_offset()
191 filter_sel = nfilt->hw_index; in bcmasp_netfilt_get_reg_offset()
194 filter_sel = nfilt->hw_index + 1; in bcmasp_netfilt_get_reg_offset()
197 filter_sel = nfilt->hw_index; in bcmasp_netfilt_get_reg_offset()
200 filter_sel = nfilt->hw_index + 1; in bcmasp_netfilt_get_reg_offset()
202 return -EINVAL; in bcmasp_netfilt_get_reg_offset()
213 return -EINVAL; in bcmasp_netfilt_get_reg_offset()
224 /* HW only accepts 4 byte aligned writes */ in bcmasp_netfilt_wr()
241 /* HW only accepts 4 byte aligned writes */ in bcmasp_netfilt_rd()
260 return -EINVAL; in bcmasp_netfilt_wr_m_wake()
262 while (size--) { in bcmasp_netfilt_wr_m_wake()
263 /* The HW only accepts 4 byte aligned writes, so if we in bcmasp_netfilt_wr_m_wake()
277 shift = (3 - (offset % 4)) * 8; in bcmasp_netfilt_wr_m_wake()
283 /* If last byte or last byte of word, write to reg */ in bcmasp_netfilt_wr_m_wake()
326 &match->tos, &mask->tos, in bcmasp_netfilt_tcpip4_wr()
327 sizeof(match->tos)); in bcmasp_netfilt_tcpip4_wr()
329 &match->ip4src, &mask->ip4src, in bcmasp_netfilt_tcpip4_wr()
330 sizeof(match->ip4src)); in bcmasp_netfilt_tcpip4_wr()
332 &match->ip4dst, &mask->ip4dst, in bcmasp_netfilt_tcpip4_wr()
333 sizeof(match->ip4dst)); in bcmasp_netfilt_tcpip4_wr()
335 &match->psrc, &mask->psrc, in bcmasp_netfilt_tcpip4_wr()
336 sizeof(match->psrc)); in bcmasp_netfilt_tcpip4_wr()
338 &match->pdst, &mask->pdst, in bcmasp_netfilt_tcpip4_wr()
339 sizeof(match->pdst)); in bcmasp_netfilt_tcpip4_wr()
354 val_16 = htons(match->tclass << 4); in bcmasp_netfilt_tcpip6_wr()
355 mask_16 = htons(mask->tclass << 4); in bcmasp_netfilt_tcpip6_wr()
359 &match->ip6src, &mask->ip6src, in bcmasp_netfilt_tcpip6_wr()
360 sizeof(match->ip6src)); in bcmasp_netfilt_tcpip6_wr()
362 &match->ip6dst, &mask->ip6dst, in bcmasp_netfilt_tcpip6_wr()
363 sizeof(match->ip6dst)); in bcmasp_netfilt_tcpip6_wr()
365 &match->psrc, &mask->psrc, in bcmasp_netfilt_tcpip6_wr()
366 sizeof(match->psrc)); in bcmasp_netfilt_tcpip6_wr()
368 &match->pdst, &mask->pdst, in bcmasp_netfilt_tcpip6_wr()
369 sizeof(match->pdst)); in bcmasp_netfilt_tcpip6_wr()
375 struct ethtool_rx_flow_spec *fs = &nfilt->fs; in bcmasp_netfilt_wr_to_hw()
381 if (!nfilt->wake_filter) in bcmasp_netfilt_wr_to_hw()
382 return -EINVAL; in bcmasp_netfilt_wr_to_hw()
386 if (fs->flow_type & FLOW_MAC_EXT) { in bcmasp_netfilt_wr_to_hw()
387 bcmasp_netfilt_wr_m_wake(priv, nfilt, 0, &fs->h_ext.h_dest, in bcmasp_netfilt_wr_to_hw()
388 &fs->m_ext.h_dest, in bcmasp_netfilt_wr_to_hw()
389 sizeof(fs->h_ext.h_dest)); in bcmasp_netfilt_wr_to_hw()
392 if ((fs->flow_type & FLOW_EXT) && in bcmasp_netfilt_wr_to_hw()
393 (fs->m_ext.vlan_etype || fs->m_ext.vlan_tci)) { in bcmasp_netfilt_wr_to_hw()
395 &fs->h_ext.vlan_etype, in bcmasp_netfilt_wr_to_hw()
396 &fs->m_ext.vlan_etype, in bcmasp_netfilt_wr_to_hw()
397 sizeof(fs->h_ext.vlan_etype)); in bcmasp_netfilt_wr_to_hw()
399 &fs->h_ext.vlan_tci, in bcmasp_netfilt_wr_to_hw()
400 &fs->m_ext.vlan_tci, in bcmasp_netfilt_wr_to_hw()
401 sizeof(fs->h_ext.vlan_tci)); in bcmasp_netfilt_wr_to_hw()
405 switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { in bcmasp_netfilt_wr_to_hw()
408 &fs->h_u.ether_spec.h_dest, in bcmasp_netfilt_wr_to_hw()
409 &fs->m_u.ether_spec.h_dest, in bcmasp_netfilt_wr_to_hw()
410 sizeof(fs->h_u.ether_spec.h_dest)); in bcmasp_netfilt_wr_to_hw()
412 &fs->h_u.ether_spec.h_source, in bcmasp_netfilt_wr_to_hw()
413 &fs->m_u.ether_spec.h_source, in bcmasp_netfilt_wr_to_hw()
414 sizeof(fs->h_u.ether_spec.h_source)); in bcmasp_netfilt_wr_to_hw()
416 &fs->h_u.ether_spec.h_proto, in bcmasp_netfilt_wr_to_hw()
417 &fs->m_u.ether_spec.h_proto, in bcmasp_netfilt_wr_to_hw()
418 sizeof(fs->h_u.ether_spec.h_proto)); in bcmasp_netfilt_wr_to_hw()
427 &fs->h_u.usr_ip4_spec.tos, in bcmasp_netfilt_wr_to_hw()
428 &fs->m_u.usr_ip4_spec.tos, in bcmasp_netfilt_wr_to_hw()
429 sizeof(fs->h_u.usr_ip4_spec.tos)); in bcmasp_netfilt_wr_to_hw()
431 &fs->h_u.usr_ip4_spec.proto, in bcmasp_netfilt_wr_to_hw()
432 &fs->m_u.usr_ip4_spec.proto, in bcmasp_netfilt_wr_to_hw()
433 sizeof(fs->h_u.usr_ip4_spec.proto)); in bcmasp_netfilt_wr_to_hw()
435 &fs->h_u.usr_ip4_spec.ip4src, in bcmasp_netfilt_wr_to_hw()
436 &fs->m_u.usr_ip4_spec.ip4src, in bcmasp_netfilt_wr_to_hw()
437 sizeof(fs->h_u.usr_ip4_spec.ip4src)); in bcmasp_netfilt_wr_to_hw()
439 &fs->h_u.usr_ip4_spec.ip4dst, in bcmasp_netfilt_wr_to_hw()
440 &fs->m_u.usr_ip4_spec.ip4dst, in bcmasp_netfilt_wr_to_hw()
441 sizeof(fs->h_u.usr_ip4_spec.ip4dst)); in bcmasp_netfilt_wr_to_hw()
442 if (!fs->m_u.usr_ip4_spec.l4_4_bytes) in bcmasp_netfilt_wr_to_hw()
445 /* Only supports 20 byte IPv4 header */ in bcmasp_netfilt_wr_to_hw()
452 &fs->h_u.usr_ip4_spec.l4_4_bytes, in bcmasp_netfilt_wr_to_hw()
453 &fs->m_u.usr_ip4_spec.l4_4_bytes, in bcmasp_netfilt_wr_to_hw()
454 sizeof(fs->h_u.usr_ip4_spec.l4_4_bytes) in bcmasp_netfilt_wr_to_hw()
460 bcmasp_netfilt_tcpip4_wr(priv, nfilt, &fs->h_u.tcp_ip4_spec, in bcmasp_netfilt_wr_to_hw()
461 &fs->m_u.tcp_ip4_spec, offset); in bcmasp_netfilt_wr_to_hw()
468 bcmasp_netfilt_tcpip4_wr(priv, nfilt, &fs->h_u.udp_ip4_spec, in bcmasp_netfilt_wr_to_hw()
469 &fs->m_u.udp_ip4_spec, offset); in bcmasp_netfilt_wr_to_hw()
477 bcmasp_netfilt_tcpip6_wr(priv, nfilt, &fs->h_u.tcp_ip6_spec, in bcmasp_netfilt_wr_to_hw()
478 &fs->m_u.tcp_ip6_spec, offset); in bcmasp_netfilt_wr_to_hw()
485 bcmasp_netfilt_tcpip6_wr(priv, nfilt, &fs->h_u.udp_ip6_spec, in bcmasp_netfilt_wr_to_hw()
486 &fs->m_u.udp_ip6_spec, offset); in bcmasp_netfilt_wr_to_hw()
499 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_suspend()
506 if (!priv->net_filters[i].claimed || in bcmasp_netfilt_suspend()
507 priv->net_filters[i].port != intf->port) in bcmasp_netfilt_suspend()
511 priv->net_filters[i].wake_filter && in bcmasp_netfilt_suspend()
512 priv->net_filters[i - 1].wake_filter) in bcmasp_netfilt_suspend()
515 ret = bcmasp_netfilt_wr_to_hw(priv, &priv->net_filters[i]); in bcmasp_netfilt_suspend()
534 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_get_all_active()
538 if (!priv->net_filters[i].claimed || in bcmasp_netfilt_get_all_active()
539 priv->net_filters[i].port != intf->port) in bcmasp_netfilt_get_all_active()
543 priv->net_filters[i].wake_filter && in bcmasp_netfilt_get_all_active()
544 priv->net_filters[i - 1].wake_filter) in bcmasp_netfilt_get_all_active()
548 return -EMSGSIZE; in bcmasp_netfilt_get_all_active()
550 rule_locs[j++] = priv->net_filters[i].fs.location; in bcmasp_netfilt_get_all_active()
560 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_get_active()
564 if (!priv->net_filters[i].claimed || in bcmasp_netfilt_get_active()
565 priv->net_filters[i].port != intf->port) in bcmasp_netfilt_get_active()
570 priv->net_filters[i].wake_filter && in bcmasp_netfilt_get_active()
571 priv->net_filters[i - 1].wake_filter) in bcmasp_netfilt_get_active()
583 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_check_dup()
589 if (!priv->net_filters[i].claimed || in bcmasp_netfilt_check_dup()
590 priv->net_filters[i].port != intf->port) in bcmasp_netfilt_check_dup()
593 cur = &priv->net_filters[i].fs; in bcmasp_netfilt_check_dup()
595 if (cur->flow_type != fs->flow_type || in bcmasp_netfilt_check_dup()
596 cur->ring_cookie != fs->ring_cookie) in bcmasp_netfilt_check_dup()
599 switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { in bcmasp_netfilt_check_dup()
618 if (memcmp(&cur->h_u, &fs->h_u, fs_size) || in bcmasp_netfilt_check_dup()
619 memcmp(&cur->m_u, &fs->m_u, fs_size)) in bcmasp_netfilt_check_dup()
622 if (cur->flow_type & FLOW_EXT) { in bcmasp_netfilt_check_dup()
623 if (cur->h_ext.vlan_etype != fs->h_ext.vlan_etype || in bcmasp_netfilt_check_dup()
624 cur->m_ext.vlan_etype != fs->m_ext.vlan_etype || in bcmasp_netfilt_check_dup()
625 cur->h_ext.vlan_tci != fs->h_ext.vlan_tci || in bcmasp_netfilt_check_dup()
626 cur->m_ext.vlan_tci != fs->m_ext.vlan_tci || in bcmasp_netfilt_check_dup()
627 cur->h_ext.data[0] != fs->h_ext.data[0]) in bcmasp_netfilt_check_dup()
630 if (cur->flow_type & FLOW_MAC_EXT) { in bcmasp_netfilt_check_dup()
631 if (memcmp(&cur->h_ext.h_dest, in bcmasp_netfilt_check_dup()
632 &fs->h_ext.h_dest, ETH_ALEN) || in bcmasp_netfilt_check_dup()
633 memcmp(&cur->m_ext.h_dest, in bcmasp_netfilt_check_dup()
634 &fs->m_ext.h_dest, ETH_ALEN)) in bcmasp_netfilt_check_dup()
652 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_get_init()
653 int i, open_index = -1; in bcmasp_netfilt_get_init()
657 return ERR_PTR(-EINVAL); in bcmasp_netfilt_get_init()
662 if (loc != RX_CLS_LOC_ANY && init && priv->net_filters[loc].claimed) in bcmasp_netfilt_get_init()
663 return ERR_PTR(-EBUSY); in bcmasp_netfilt_get_init()
665 /* We need two filters for wake-up, so we cannot use an odd filter */ in bcmasp_netfilt_get_init()
667 return ERR_PTR(-EINVAL); in bcmasp_netfilt_get_init()
675 priv->net_filters[i].claimed && in bcmasp_netfilt_get_init()
676 priv->net_filters[i].hw_index == i && in bcmasp_netfilt_get_init()
677 priv->net_filters[i].port == intf->port) in bcmasp_netfilt_get_init()
678 return &priv->net_filters[i]; in bcmasp_netfilt_get_init()
689 if (wake_filter && !(i % 2) && !priv->net_filters[i].claimed && in bcmasp_netfilt_get_init()
690 !priv->net_filters[i + 1].claimed) in bcmasp_netfilt_get_init()
692 else if (!priv->net_filters[i].claimed) in bcmasp_netfilt_get_init()
697 nfilter = &priv->net_filters[open_index]; in bcmasp_netfilt_get_init()
698 nfilter->claimed = true; in bcmasp_netfilt_get_init()
699 nfilter->port = intf->port; in bcmasp_netfilt_get_init()
700 nfilter->hw_index = open_index; in bcmasp_netfilt_get_init()
705 priv->net_filters[open_index + 1].claimed = true; in bcmasp_netfilt_get_init()
706 priv->net_filters[open_index + 1].wake_filter = true; in bcmasp_netfilt_get_init()
707 nfilter->wake_filter = true; in bcmasp_netfilt_get_init()
710 return nfilter ? nfilter : ERR_PTR(-EINVAL); in bcmasp_netfilt_get_init()
716 struct bcmasp_priv *priv = intf->parent; in bcmasp_netfilt_release()
718 if (nfilt->wake_filter) { in bcmasp_netfilt_release()
719 memset(&priv->net_filters[nfilt->hw_index + 1], 0, in bcmasp_netfilt_release()
738 struct bcmasp_priv *priv = intf->parent; in bcmasp_set_mda_filter()
742 ether_addr_copy(priv->mda_filters[i].mask, mask); in bcmasp_set_mda_filter()
743 ether_addr_copy(priv->mda_filters[i].addr, addr); in bcmasp_set_mda_filter()
746 bcmasp_addr_to_uint(priv->mda_filters[i].mask, &mask_h, &mask_l); in bcmasp_set_mda_filter()
747 bcmasp_addr_to_uint(priv->mda_filters[i].addr, &addr_h, &addr_l); in bcmasp_set_mda_filter()
754 static void bcmasp_en_mda_filter(struct bcmasp_intf *intf, bool en, in bcmasp_en_mda_filter() argument
757 struct bcmasp_priv *priv = intf->parent; in bcmasp_en_mda_filter()
759 if (priv->mda_filters[i].en == en) in bcmasp_en_mda_filter()
762 priv->mda_filters[i].en = en; in bcmasp_en_mda_filter()
763 priv->mda_filters[i].port = intf->port; in bcmasp_en_mda_filter()
765 rx_filter_core_wl(priv, ((intf->channel + 8) | in bcmasp_en_mda_filter()
766 (en << ASP_RX_FILTER_MDA_CFG_EN_SHIFT) | in bcmasp_en_mda_filter()
767 ASP_RX_FILTER_MDA_CFG_UMC_SEL(intf->port)), in bcmasp_en_mda_filter()
773 * - Promisc: Filter to allow all packets when promisc is enabled
774 * - All Multicast
775 * - Broadcast
776 * - Own address
779 * - Promisc: (index * 4) + 0
780 * - All Multicast: (index * 4) + 1
781 * - Broadcast: (index * 4) + 2
782 * - Own address: (index * 4) + 3
792 #define ASP_RX_FILT_MDA(intf, name) (((intf)->index * \
798 return list_count_nodes(&priv->intfs) * ASP_RX_FILTER_MDA_RES_MAX; in bcmasp_total_res_mda_cnt()
801 void bcmasp_set_promisc(struct bcmasp_intf *intf, bool en) in bcmasp_set_promisc() argument
809 bcmasp_en_mda_filter(intf, en, i); in bcmasp_set_promisc()
812 void bcmasp_set_allmulti(struct bcmasp_intf *intf, bool en) in bcmasp_set_allmulti() argument
819 bcmasp_en_mda_filter(intf, en, i); in bcmasp_set_allmulti()
822 void bcmasp_set_broad(struct bcmasp_intf *intf, bool en) in bcmasp_set_broad() argument
829 bcmasp_en_mda_filter(intf, en, i); in bcmasp_set_broad()
833 bool en) in bcmasp_set_oaddr() argument
839 bcmasp_en_mda_filter(intf, en, i); in bcmasp_set_oaddr()
844 struct bcmasp_priv *priv = intf->parent; in bcmasp_disable_all_filters()
848 res_count = bcmasp_total_res_mda_cnt(intf->parent); in bcmasp_disable_all_filters()
852 if (priv->mda_filters[i].en && in bcmasp_disable_all_filters()
853 priv->mda_filters[i].port == intf->port) in bcmasp_disable_all_filters()
862 struct bcmasp_priv *priv = intf->parent; in bcmasp_combine_set_filter()
866 addr1 = ether_addr_to_u64(priv->mda_filters[i].addr); in bcmasp_combine_set_filter()
867 mask1 = ether_addr_to_u64(priv->mda_filters[i].mask); in bcmasp_combine_set_filter()
883 return -EINVAL; in bcmasp_combine_set_filter()
889 struct bcmasp_priv *priv = intf->parent; in bcmasp_set_en_mda_filter()
893 res_count = bcmasp_total_res_mda_cnt(intf->parent); in bcmasp_set_en_mda_filter()
897 if (!priv->mda_filters[i].en || in bcmasp_set_en_mda_filter()
898 priv->mda_filters[i].port != intf->port) in bcmasp_set_en_mda_filter()
904 intf->mib.filters_combine_cnt++; in bcmasp_set_en_mda_filter()
911 if (priv->mda_filters[i].en) in bcmasp_set_en_mda_filter()
920 return -EINVAL; in bcmasp_set_en_mda_filter()
932 priv->mda_filters[i].en = 0; in bcmasp_core_init_filters()
939 * GEN_WAKE_CLEAR to clear the network filter wake-up which would in bcmasp_core_init_filters()
967 /* Disable and clear both UniMAC's wake-up interrupts to avoid in bcmasp_core_init()
1006 spin_lock_irqsave(&priv->clk_lock, flags); in bcmasp_core_clock_set()
1008 spin_unlock_irqrestore(&priv->clk_lock, flags); in bcmasp_core_clock_set()
1011 void bcmasp_core_clock_set_intf(struct bcmasp_intf *intf, bool en) in bcmasp_core_clock_set_intf() argument
1013 u32 intf_mask = ASP_CTRL_CLOCK_CTRL_ASP_RGMII_DIS(intf->port); in bcmasp_core_clock_set_intf()
1014 struct bcmasp_priv *priv = intf->parent; in bcmasp_core_clock_set_intf()
1024 spin_lock_irqsave(&priv->clk_lock, flags); in bcmasp_core_clock_set_intf()
1025 if (en) { in bcmasp_core_clock_set_intf()
1037 spin_unlock_irqrestore(&priv->clk_lock, flags); in bcmasp_core_clock_set_intf()
1046 if (priv->wol_irq <= 0) in bcmasp_isr_wol()
1054 pm_wakeup_event(&priv->pdev->dev, 0); in bcmasp_isr_wol()
1060 struct platform_device *pdev = priv->pdev; in bcmasp_get_and_request_irq()
1067 ret = devm_request_irq(&pdev->dev, irq, bcmasp_isr_wol, 0, in bcmasp_get_and_request_irq()
1068 pdev->name, priv); in bcmasp_get_and_request_irq()
1077 struct platform_device *pdev = priv->pdev; in bcmasp_init_wol_shared()
1078 struct device *dev = &pdev->dev; in bcmasp_init_wol_shared()
1087 priv->wol_irq = irq; in bcmasp_init_wol_shared()
1088 priv->wol_irq_enabled_mask = 0; in bcmasp_init_wol_shared()
1089 device_set_wakeup_capable(&pdev->dev, 1); in bcmasp_init_wol_shared()
1092 static void bcmasp_enable_wol_shared(struct bcmasp_intf *intf, bool en) in bcmasp_enable_wol_shared() argument
1094 struct bcmasp_priv *priv = intf->parent; in bcmasp_enable_wol_shared()
1095 struct device *dev = &priv->pdev->dev; in bcmasp_enable_wol_shared()
1097 if (en) { in bcmasp_enable_wol_shared()
1098 if (priv->wol_irq_enabled_mask) { in bcmasp_enable_wol_shared()
1099 set_bit(intf->port, &priv->wol_irq_enabled_mask); in bcmasp_enable_wol_shared()
1104 set_bit(intf->port, &priv->wol_irq_enabled_mask); in bcmasp_enable_wol_shared()
1105 enable_irq_wake(priv->wol_irq); in bcmasp_enable_wol_shared()
1108 if (!priv->wol_irq_enabled_mask) in bcmasp_enable_wol_shared()
1111 clear_bit(intf->port, &priv->wol_irq_enabled_mask); in bcmasp_enable_wol_shared()
1112 if (priv->wol_irq_enabled_mask) in bcmasp_enable_wol_shared()
1116 disable_irq_wake(priv->wol_irq); in bcmasp_enable_wol_shared()
1123 if (priv->wol_irq > 0) in bcmasp_wol_irq_destroy_shared()
1124 free_irq(priv->wol_irq, priv); in bcmasp_wol_irq_destroy_shared()
1129 struct platform_device *pdev = priv->pdev; in bcmasp_init_wol_per_intf()
1130 struct device *dev = &pdev->dev; in bcmasp_init_wol_per_intf()
1134 list_for_each_entry(intf, &priv->intfs, list) { in bcmasp_init_wol_per_intf()
1135 irq = bcmasp_get_and_request_irq(priv, intf->port + 1); in bcmasp_init_wol_per_intf()
1138 intf->port, irq); in bcmasp_init_wol_per_intf()
1142 intf->wol_irq = irq; in bcmasp_init_wol_per_intf()
1143 intf->wol_irq_enabled = false; in bcmasp_init_wol_per_intf()
1144 device_set_wakeup_capable(&pdev->dev, 1); in bcmasp_init_wol_per_intf()
1148 static void bcmasp_enable_wol_per_intf(struct bcmasp_intf *intf, bool en) in bcmasp_enable_wol_per_intf() argument
1150 struct device *dev = &intf->parent->pdev->dev; in bcmasp_enable_wol_per_intf()
1152 if (en ^ intf->wol_irq_enabled) in bcmasp_enable_wol_per_intf()
1153 irq_set_irq_wake(intf->wol_irq, en); in bcmasp_enable_wol_per_intf()
1155 intf->wol_irq_enabled = en; in bcmasp_enable_wol_per_intf()
1156 device_set_wakeup_enable(dev, en); in bcmasp_enable_wol_per_intf()
1163 list_for_each_entry(intf, &priv->intfs, list) { in bcmasp_wol_irq_destroy_per_intf()
1164 if (intf->wol_irq > 0) in bcmasp_wol_irq_destroy_per_intf()
1165 free_irq(intf->wol_irq, priv); in bcmasp_wol_irq_destroy_per_intf()
1201 { .compatible = "brcm,asp-v2.0", .data = &v20_plat_data },
1202 { .compatible = "brcm,asp-v2.1", .data = &v21_plat_data },
1208 { .compatible = "brcm,asp-v2.1-mdio", },
1209 { .compatible = "brcm,asp-v2.0-mdio", },
1218 list_for_each_entry_safe(intf, n, &priv->intfs, list) { in bcmasp_remove_intfs()
1219 list_del(&intf->list); in bcmasp_remove_intfs()
1228 struct device *dev = &pdev->dev; in bcmasp_probe()
1236 return -ENOMEM; in bcmasp_probe()
1238 priv->irq = platform_get_irq(pdev, 0); in bcmasp_probe()
1239 if (priv->irq <= 0) in bcmasp_probe()
1240 return -EINVAL; in bcmasp_probe()
1242 priv->clk = devm_clk_get_optional_enabled(dev, "sw_asp"); in bcmasp_probe()
1243 if (IS_ERR(priv->clk)) in bcmasp_probe()
1244 return dev_err_probe(dev, PTR_ERR(priv->clk), in bcmasp_probe()
1248 priv->base = devm_platform_ioremap_resource(pdev, 0); in bcmasp_probe()
1249 if (IS_ERR(priv->base)) in bcmasp_probe()
1250 return dev_err_probe(dev, PTR_ERR(priv->base), "failed to iomap\n"); in bcmasp_probe()
1252 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40)); in bcmasp_probe()
1254 return dev_err_probe(dev, ret, "unable to set DMA mask: %d\n", ret); in bcmasp_probe()
1256 dev_set_drvdata(&pdev->dev, priv); in bcmasp_probe()
1257 priv->pdev = pdev; in bcmasp_probe()
1258 spin_lock_init(&priv->mda_lock); in bcmasp_probe()
1259 spin_lock_init(&priv->clk_lock); in bcmasp_probe()
1260 mutex_init(&priv->wol_lock); in bcmasp_probe()
1261 mutex_init(&priv->net_lock); in bcmasp_probe()
1262 INIT_LIST_HEAD(&priv->intfs); in bcmasp_probe()
1264 pdata = device_get_match_data(&pdev->dev); in bcmasp_probe()
1266 return dev_err_probe(dev, -EINVAL, "unable to find platform data\n"); in bcmasp_probe()
1268 priv->init_wol = pdata->init_wol; in bcmasp_probe()
1269 priv->enable_wol = pdata->enable_wol; in bcmasp_probe()
1270 priv->destroy_wol = pdata->destroy_wol; in bcmasp_probe()
1271 priv->hw_info = pdata->hw_info; in bcmasp_probe()
1282 ret = devm_request_irq(&pdev->dev, priv->irq, bcmasp_isr, 0, in bcmasp_probe()
1283 pdev->name, priv); in bcmasp_probe()
1288 of_platform_populate(dev->of_node, bcmasp_mdio_of_match, NULL, dev); in bcmasp_probe()
1296 ports_node = of_find_node_by_name(dev->of_node, "ethernet-ports"); in bcmasp_probe()
1299 return -EINVAL; in bcmasp_probe()
1309 ret = -ENOMEM; in bcmasp_probe()
1312 list_add_tail(&intf->list, &priv->intfs); in bcmasp_probe()
1317 priv->init_wol(priv); in bcmasp_probe()
1324 clk_disable_unprepare(priv->clk); in bcmasp_probe()
1329 list_for_each_entry(intf, &priv->intfs, list) { in bcmasp_probe()
1330 ret = register_netdev(intf->ndev); in bcmasp_probe()
1332 netdev_err(intf->ndev, in bcmasp_probe()
1334 priv->destroy_wol(priv); in bcmasp_probe()
1350 struct bcmasp_priv *priv = dev_get_drvdata(&pdev->dev); in bcmasp_remove()
1355 priv->destroy_wol(priv); in bcmasp_remove()
1372 list_for_each_entry(intf, &priv->intfs, list) { in bcmasp_suspend()
1378 ret = clk_prepare_enable(priv->clk); in bcmasp_suspend()
1382 /* Whether Wake-on-LAN is enabled or not, we can always disable in bcmasp_suspend()
1389 clk_disable_unprepare(priv->clk); in bcmasp_suspend()
1400 ret = clk_prepare_enable(priv->clk); in bcmasp_resume()
1407 /* Re-enable all clocks for re-initialization */ in bcmasp_resume()
1416 clk_disable_unprepare(priv->clk); in bcmasp_resume()
1418 list_for_each_entry(intf, &priv->intfs, list) { in bcmasp_resume()
1435 .name = "brcm,asp-v2",
1443 MODULE_ALIAS("platform:brcm,asp-v2");