avb_status_t avb_1722_1_adp_advertising_periodic(chanend c_tx, chanend ptp) { guid_t ptp_current; switch (adp_advertise_state) { case ADP_ADVERTISE_IDLE: break; case ADP_ADVERTISE_WAITING: if (avb_timer_expired(&adp_readvertise_timer)) { adp_advertise_state = ADP_ADVERTISE_ADVERTISE_1; } break; case ADP_ADVERTISE_ADVERTISE_0: avb_1722_1_adp_change_ptp_grandmaster(ptp_current.c); start_avb_timer(&ptp_monitor_timer, 1); //Every second adp_advertise_state = ADP_ADVERTISE_ADVERTISE_1; // Fall through and send immediately case ADP_ADVERTISE_ADVERTISE_1: avb_1722_1_create_adp_packet(ENTITY_AVAILABLE, my_guid); mac_tx(c_tx, avb_1722_1_buf, AVB_1722_1_ADP_PACKET_SIZE, ETH_BROADCAST); start_avb_timer(&adp_readvertise_timer, AVB_1722_1_ADP_REPEAT_TIME); adp_advertise_state = ADP_ADVERTISE_WAITING; avb_1722_1_available_index++; break; case ADP_ADVERTISE_DEPARTING: avb_1722_1_create_adp_packet(ENTITY_DEPARTING, my_guid); mac_tx(c_tx, avb_1722_1_buf, AVB_1722_1_ADP_PACKET_SIZE, ETH_BROADCAST); adp_advertise_state = ADP_ADVERTISE_IDLE; avb_1722_1_available_index = 0; break; default: break; } if (ADP_ADVERTISE_IDLE != adp_advertise_state) { if(avb_timer_expired(&ptp_monitor_timer)) { ptp_get_current_grandmaster(ptp, ptp_current.c); if(as_grandmaster_id.l != ptp_current.l) { avb_1722_1_adp_change_ptp_grandmaster(ptp_current.c); adp_advertise_state = ADP_ADVERTISE_ADVERTISE_1; } start_avb_timer(&ptp_monitor_timer, 1); //Every second } } return AVB_NO_STATUS; }
static int mac_bpf_tx(uintptr_t chandle, mblk_t *pkt) { /* * If the mac layer cannot deliver a packet as requested by BPF then * simply have the mac layer drop it. BPF isn't interested in doing * any amount of retry - that's left to the application. */ return (mac_tx((mac_client_handle_t)chandle, pkt, 0, MAC_DROP_ON_NO_DESC, NULL)); }
avb_status_t process_avb_1722_1_aecp_packet(unsigned char dest_addr[6], avb_1722_1_aecp_packet_t *pkt, chanend c_tx) { int message_type = GET_1722_1_MSG_TYPE(((avb_1722_1_packet_header_t*)pkt)); if (compare_guid(pkt->target_guid, &my_guid)==0) return AVB_1722_1_OK; switch (message_type) { case AECP_CMD_AVDECC_MSG_COMMAND: { avb_1722_1_aecp_avdecc_msg_t *msg = &(pkt->data.avdecc); process_avb_1722_1_aecp_avdecc_msg(msg); break; } case AECP_CMD_ADDRESS_ACCESS_COMMAND: { break; } case AECP_CMD_AVC_COMMAND: { # if AVB_1722_1_USE_AVC uint32_t length = 0 ; struct ethernet_hdr_t *eth_hdr = (ethernet_hdr_t*) &avb_1722_1_buf[0]; avb_1722_1_packet_header_t *pkt_hdr = (avb_1722_1_packet_header_t*) (eth_hdr + 1); avb_1722_1_aecp_avc_t* payload = (avb_1722_1_aecp_avc_t*)avb_1722_1_create_aecp_packet(dest_addr, AECP_CMD_AVC_RESPONSE, pkt); bcopy(pkt->data.payload, payload, 514); length = ((uint32_t)payload->avc_length[0] << 8) | payload->avc_length[1]; processAVCCommand(payload->avc_command_response, &length); payload->avc_length[0] = (length >> 8) & 0xff; payload->avc_length[1] = length & 0xff; SET_1722_1_DATALENGTH(pkt_hdr, length+12); mac_tx(c_tx, avb_1722_1_buf, sizeof(ethernet_hdr_t)+sizeof(avb_1722_1_packet_header_t)+36+length, ETH_BROADCAST); #endif break; } case AECP_CMD_VENDOR_UNIQUE_COMMAND: { break; } case AECP_CMD_EXTENDED_COMMAND: { break; } default: // This node is not expecting a response break; } return AVB_1722_1_OK; }
/* * Send a message out over the physical device * via the MAC layer. * * Returns any mblks that it was unable to transmit. */ mblk_t * vsw_tx_msg(vsw_t *vswp, mblk_t *mp, int caller, vsw_port_t *port) { mac_client_handle_t mch; mac_unicast_handle_t muh; READ_MACCL_ENTER(vswp, port, caller); mch = (caller == VSW_LOCALDEV) ? vswp->mch : port->p_mch; muh = (caller == VSW_LOCALDEV) ? vswp->muh : port->p_muh; if (mch == NULL || muh == NULL) { RW_MACCL_EXIT(vswp, port, caller); return (mp); } /* packets are sent or dropped */ (void) mac_tx(mch, mp, 0, MAC_DROP_ON_NO_DESC, NULL); RW_MACCL_EXIT(vswp, port, caller); return (NULL); }
/* * Packets from the peer come here. We pass them to the mac device. */ static void xnbo_to_mac(xnb_t *xnbp, mblk_t *mp) { xnbo_t *xnbop = xnbp->xnb_flavour_data; ASSERT(mp != NULL); if (!xnbop->o_running) { xnbp->xnb_stat_tx_too_early++; goto fail; } if (mac_tx(xnbop->o_mch, mp, 0, MAC_DROP_ON_NO_DESC, NULL) != NULL) { xnbp->xnb_stat_mac_full++; } return; fail: freemsgchain(mp); }
avb_status_t avb_1722_1_adp_discovery_periodic(chanend c_tx) { switch (adp_discovery_state) { case ADP_DISCOVERY_IDLE: break; case ADP_DISCOVERY_WAITING: { unsigned lost=0; if (avb_timer_expired(&adp_discovery_timer)) { adp_two_second_counter++; lost = avb_1722_1_entity_database_check_timeout(); start_avb_timer(&adp_discovery_timer, 1); } return (lost > 0) ? AVB_1722_1_ENTITY_REMOVED : AVB_NO_STATUS; } case ADP_DISCOVERY_DISCOVER: { avb_1722_1_create_adp_packet(ENTITY_DISCOVER, discover_guid); mac_tx(c_tx, avb_1722_1_buf, AVB_1722_1_ADP_PACKET_SIZE, ETH_BROADCAST); adp_discovery_state = ADP_DISCOVERY_WAITING; break; } case ADP_DISCOVERY_ADDED: { adp_discovery_state = ADP_DISCOVERY_WAITING; return AVB_1722_1_ENTITY_ADDED; } case ADP_DISCOVERY_REMOVED: { adp_discovery_state = ADP_DISCOVERY_WAITING; return AVB_1722_1_ENTITY_REMOVED; } } return AVB_NO_STATUS; }
// this forces the sending of the current PDU. this happens when // that PDU has had all of the attributes that it is going to get, // or when adding an attribute has filled the PDU up. static void force_send(chanend c_tx) { char *buf = &send_buf[0]; char *ptr = send_ptr; // Strip out attribute length fields for MMRP and MVRP strip_attribute_list_length_fields(); if (ptr != buf+sizeof(mrp_ethernet_hdr)+sizeof(mrp_header)) { // Check that the buffer is long enough for a valid ethernet packet char *end = ptr + 4; if (end < buf + 64) end = buf + 64; // Pad with zero if necessary for (char *p = ptr;p<end;p++) *p = 0; // Transmit mac_tx(c_tx, (unsigned int *) buf, end - buf, ETH_BROADCAST); } send_ptr = buf+sizeof(mrp_ethernet_hdr)+sizeof(mrp_header); return; }
/* ARGSUSED */ static int sdpfp_senduio(sock_lower_handle_t handle, struct uio *uiop, struct nmsghdr *msg, struct cred *cred) { struct sockaddr_ll *sol; mac_client_handle_t mch; struct pfpsock *ps; boolean_t new_open; mac_handle_t mh; size_t mpsize; uint_t maxsdu; mblk_t *mp0; mblk_t *mp; int error; mp = NULL; mp0 = NULL; new_open = B_FALSE; ps = (struct pfpsock *)handle; mh = ps->ps_mh; mch = ps->ps_mch; maxsdu = ps->ps_max_sdu; sol = (struct sockaddr_ll *)msg->msg_name; if (sol == NULL) { /* * If no sockaddr_ll has been provided with the send call, * use the one constructed when the socket was bound to an * interface and fail if it hasn't been bound. */ if (!ps->ps_bound) { ks_stats.kp_send_unbound.value.ui64++; return (EPROTO); } sol = (struct sockaddr_ll *)&ps->ps_sock; } else { /* * Verify the sockaddr_ll message passed down before using * it to send a packet out with. If it refers to an interface * that has not been bound, it is necessary to open it. */ struct sockaddr_ll *sll; if (msg->msg_namelen < sizeof (struct sockaddr_ll)) { ks_stats.kp_send_short_msg.value.ui64++; return (EINVAL); } if (sol->sll_family != AF_PACKET) { ks_stats.kp_send_wrong_family.value.ui64++; return (EAFNOSUPPORT); } sll = (struct sockaddr_ll *)&ps->ps_sock; if (sol->sll_ifindex != sll->sll_ifindex) { error = pfp_open_index(sol->sll_ifindex, &mh, &mch, cred); if (error != 0) { ks_stats.kp_send_open_fail.value.ui64++; return (error); } mac_sdu_get(mh, NULL, &maxsdu); new_open = B_TRUE; } } mpsize = uiop->uio_resid; if (mpsize > maxsdu) { ks_stats.kp_send_too_big.value.ui64++; error = EMSGSIZE; goto done; } if ((mp = allocb(mpsize, BPRI_HI)) == NULL) { ks_stats.kp_send_alloc_fail.value.ui64++; error = ENOBUFS; goto done; } mp->b_wptr = mp->b_rptr + mpsize; error = uiomove(mp->b_rptr, mpsize, UIO_WRITE, uiop); if (error != 0) { ks_stats.kp_send_uiomove_fail.value.ui64++; goto done; } if (ps->ps_type == SOCK_DGRAM) { mp0 = mac_header(mh, sol->sll_addr, sol->sll_protocol, mp, 0); if (mp0 == NULL) { ks_stats.kp_send_no_memory.value.ui64++; error = ENOBUFS; goto done; } linkb(mp0, mp); mp = mp0; } /* * As this is sending datagrams and no promise is made about * how or if a packet will be sent/delivered, no effort is to * be expended in recovering from a situation where the packet * cannot be sent - it is just dropped. */ error = mac_tx(mch, mp, 0, MAC_DROP_ON_NO_DESC, NULL); if (error == 0) { mp = NULL; ks_stats.kp_send_ok.value.ui64++; } else { ks_stats.kp_send_failed.value.ui64++; } done: if (new_open) { ASSERT(mch != ps->ps_mch); ASSERT(mh != ps->ps_mh); pfp_close(mh, mch); } if (mp != NULL) freemsg(mp); return (error); }