191094Sdes// SPDX-License-Identifier: GPL-2.0-only 291094Sdes/* 391094Sdes * llc_output.c - LLC minimal output path 491094Sdes * 591094Sdes * Copyright (c) 1997 by Procom Technology, Inc. 691094Sdes * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> 791094Sdes */ 891094Sdes 991094Sdes#include <linux/if_arp.h> 1091094Sdes#include <linux/netdevice.h> 1191094Sdes#include <linux/skbuff.h> 1291094Sdes#include <linux/export.h> 1391094Sdes#include <net/llc.h> 1491094Sdes#include <net/llc_pdu.h> 1591094Sdes 1691094Sdes/** 1791094Sdes * llc_mac_hdr_init - fills MAC header fields 1891094Sdes * @skb: Address of the frame to initialize its MAC header 1991094Sdes * @sa: The MAC source address 2091094Sdes * @da: The MAC destination address 2191094Sdes * 2291094Sdes * Fills MAC header fields, depending on MAC type. Returns 0, If MAC type 2391094Sdes * is a valid type and initialization completes correctly 1, otherwise. 2491094Sdes */ 2591094Sdesint llc_mac_hdr_init(struct sk_buff *skb, 2691094Sdes const unsigned char *sa, const unsigned char *da) 2791094Sdes{ 2891094Sdes int rc = -EINVAL; 2991094Sdes 3091094Sdes switch (skb->dev->type) { 3191094Sdes case ARPHRD_ETHER: 3291094Sdes case ARPHRD_LOOPBACK: 3391094Sdes rc = dev_hard_header(skb, skb->dev, ETH_P_802_2, da, sa, 3491094Sdes skb->len); 3591094Sdes if (rc > 0) 3691094Sdes rc = 0; 3791094Sdes break; 3891094Sdes default: 3991094Sdes break; 4091094Sdes } 4191094Sdes return rc; 4291094Sdes} 4391094Sdes 4491094Sdes/** 4591094Sdes * llc_build_and_send_ui_pkt - unitdata request interface for upper layers 4691094Sdes * @sap: sap to use 4791094Sdes * @skb: packet to send 4891094Sdes * @dmac: destination mac address 4991094Sdes * @dsap: destination sap 5091094Sdes * 5191094Sdes * Upper layers calls this function when upper layer wants to send data 5291094Sdes * using connection-less mode communication (UI pdu). 5391094Sdes * 5491094Sdes * Accept data frame from network layer to be sent using connection- 5591094Sdes * less mode communication; timeout/retries handled by network layer; 5691094Sdes * package primitive as an event and send to SAP event handler 5791094Sdes */ 5891094Sdesint llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb, 5991094Sdes const unsigned char *dmac, unsigned char dsap) 6091094Sdes{ 6191094Sdes int rc; 6291094Sdes llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, 6391094Sdes dsap, LLC_PDU_CMD); 6491094Sdes llc_pdu_init_as_ui_cmd(skb); 6591094Sdes rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac); 6691094Sdes if (likely(!rc)) 6791094Sdes rc = dev_queue_xmit(skb); 6891094Sdes else 6991094Sdes kfree_skb(skb); 7091094Sdes return rc; 7191094Sdes} 7291094Sdes 7391094SdesEXPORT_SYMBOL(llc_mac_hdr_init); 7491094SdesEXPORT_SYMBOL(llc_build_and_send_ui_pkt); 7591094Sdes