{
        /* Deliver to the uncontrolled port by default */
        enum rx_handler_result ret = RX_HANDLER_PASS;
+       struct ethhdr *hdr = eth_hdr(skb);
        struct macsec_rxh_data *rxd;
        struct macsec_dev *macsec;
 
        rcu_read_lock();
        rxd = macsec_data_rcu(skb->dev);
 
-       /* 10.6 If the management control validateFrames is not
-        * Strict, frames without a SecTAG are received, counted, and
-        * delivered to the Controlled Port
-        */
        list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
                struct sk_buff *nskb;
                struct pcpu_secy_stats *secy_stats = this_cpu_ptr(macsec->stats);
+               struct net_device *ndev = macsec->secy.netdev;
 
-               if (!macsec_is_offloaded(macsec) &&
-                   macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) {
+               /* If h/w offloading is enabled, HW decodes frames and strips
+                * the SecTAG, so we have to deduce which port to deliver to.
+                */
+               if (macsec_is_offloaded(macsec) && netif_running(ndev)) {
+                       if (ether_addr_equal_64bits(hdr->h_dest,
+                                                   ndev->dev_addr)) {
+                               /* exact match, divert skb to this port */
+                               skb->dev = ndev;
+                               skb->pkt_type = PACKET_HOST;
+                               ret = RX_HANDLER_ANOTHER;
+                               goto out;
+                       } else if (is_multicast_ether_addr_64bits(
+                                          hdr->h_dest)) {
+                               /* multicast frame, deliver on this port too */
+                               nskb = skb_clone(skb, GFP_ATOMIC);
+                               if (!nskb)
+                                       break;
+
+                               nskb->dev = ndev;
+                               if (ether_addr_equal_64bits(hdr->h_dest,
+                                                           ndev->broadcast))
+                                       nskb->pkt_type = PACKET_BROADCAST;
+                               else
+                                       nskb->pkt_type = PACKET_MULTICAST;
+
+                               netif_rx(nskb);
+                       }
+                       continue;
+               }
+
+               /* 10.6 If the management control validateFrames is not
+                * Strict, frames without a SecTAG are received, counted, and
+                * delivered to the Controlled Port
+                */
+               if (macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) {
                        u64_stats_update_begin(&secy_stats->syncp);
                        secy_stats->stats.InPktsNoTag++;
                        u64_stats_update_end(&secy_stats->syncp);
                if (!nskb)
                        break;
 
-               nskb->dev = macsec->secy.netdev;
+               nskb->dev = ndev;
 
                if (netif_rx(nskb) == NET_RX_SUCCESS) {
                        u64_stats_update_begin(&secy_stats->syncp);
                        secy_stats->stats.InPktsUntagged++;
                        u64_stats_update_end(&secy_stats->syncp);
                }
-
-               if (netif_running(macsec->secy.netdev) &&
-                   macsec_is_offloaded(macsec)) {
-                       ret = RX_HANDLER_EXACT;
-                       goto out;
-               }
        }
 
 out: