コード例 #1
0
static int msg_from_mpoad(struct atm_vcc *vcc, struct sk_buff *skb)
{

	struct mpoa_client *mpc = find_mpc_by_vcc(vcc);
	struct k_message *mesg = (struct k_message *)skb->data;
	atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);

	if (mpc == NULL) {
		pr_info("no mpc found\n");
		return 0;
	}
	dprintk("(%s)", mpc->dev ? mpc->dev->name : "<unknown>");
	switch (mesg->type) {
	case MPOA_RES_REPLY_RCVD:
		dprintk_cont("mpoa_res_reply_rcvd\n");
		MPOA_res_reply_rcvd(mesg, mpc);
		break;
	case MPOA_TRIGGER_RCVD:
		dprintk_cont("mpoa_trigger_rcvd\n");
		MPOA_trigger_rcvd(mesg, mpc);
		break;
	case INGRESS_PURGE_RCVD:
		dprintk_cont("nhrp_purge_rcvd\n");
		ingress_purge_rcvd(mesg, mpc);
		break;
	case EGRESS_PURGE_RCVD:
		dprintk_cont("egress_purge_reply_rcvd\n");
		egress_purge_rcvd(mesg, mpc);
		break;
	case MPS_DEATH:
		dprintk_cont("mps_death\n");
		mps_death(mesg, mpc);
		break;
	case CACHE_IMPOS_RCVD:
		dprintk_cont("cache_impos_rcvd\n");
		MPOA_cache_impos_rcvd(mesg, mpc);
		break;
	case SET_MPC_CTRL_ADDR:
		dprintk_cont("set_mpc_ctrl_addr\n");
		set_mpc_ctrl_addr_rcvd(mesg, mpc);
		break;
	case SET_MPS_MAC_ADDR:
		dprintk_cont("set_mps_mac_addr\n");
		set_mps_mac_addr_rcvd(mesg, mpc);
		break;
	case CLEAN_UP_AND_EXIT:
		dprintk_cont("clean_up_and_exit\n");
		clean_up(mesg, mpc, DIE);
		break;
	case RELOAD:
		dprintk_cont("reload\n");
		clean_up(mesg, mpc, RELOAD);
		break;
	case SET_MPC_PA
コード例 #2
0
ファイル: mpc.c プロジェクト: A2109devs/lenovo_a2109a_kernel
static void stop_mpc(struct mpoa_client *mpc)
{
	struct net_device *dev = mpc->dev;
	dprintk("(%s)", mpc->dev->name);

	/* Lets not nullify lec device's dev->hard_start_xmit */
	if (dev->netdev_ops != &mpc->new_ops) {
		dprintk_cont(" mpc already stopped, not fatal\n");
		return;
	}
	dprintk_cont("\n");

	dev->netdev_ops = mpc->old_ops;
	mpc->old_ops = NULL;

	/* close_shortcuts(mpc);    ??? FIXME */
}
コード例 #3
0
ファイル: mpc.c プロジェクト: A2109devs/lenovo_a2109a_kernel
static void set_mpc_ctrl_addr_rcvd(struct k_message *mesg,
				   struct mpoa_client *mpc)
{
	struct lec_priv *priv;
	int i, retval ;

	uint8_t tlv[4 + 1 + 1 + 1 + ATM_ESA_LEN];

	tlv[0] = 00; tlv[1] = 0xa0; tlv[2] = 0x3e; tlv[3] = 0x2a; /* type  */
	tlv[4] = 1 + 1 + ATM_ESA_LEN;  /* length                           */
	tlv[5] = 0x02;                 /* MPOA client                      */
	tlv[6] = 0x00;                 /* number of MPS MAC addresses      */

	memcpy(&tlv[7], mesg->MPS_ctrl, ATM_ESA_LEN); /* MPC ctrl ATM addr */
	memcpy(mpc->our_ctrl_addr, mesg->MPS_ctrl, ATM_ESA_LEN);

	dprintk("(%s) setting MPC ctrl ATM address to",
		mpc->dev ? mpc->dev->name : "<unknown>");
	for (i = 7; i < sizeof(tlv); i++)
		dprintk_cont(" %02x", tlv[i]);
	dprintk_cont("\n");

	if (mpc->dev) {
		priv = netdev_priv(mpc->dev);
		retval = priv->lane2_ops->associate_req(mpc->dev,
							mpc->dev->dev_addr,
							tlv, sizeof(tlv));
		if (retval == 0)
			pr_info("(%s) MPOA device type TLV association failed\n",
				mpc->dev->name);
		retval = priv->lane2_ops->resolve(mpc->dev, NULL, 1, NULL, NULL);
		if (retval < 0)
			pr_info("(%s) targetless LE_ARP request failed\n",
				mpc->dev->name);
	}

	return;
}
コード例 #4
0
ファイル: mpc.c プロジェクト: A2109devs/lenovo_a2109a_kernel
/*
 * lec device calls this via its netdev_priv(dev)->lane2_ops
 * ->associate_indicator() when it sees a TLV in LE_ARP packet.
 * We fill in the pointer above when we see a LANE2 lec initializing
 * See LANE2 spec 3.1.5
 *
 * Quite a big and ugly function but when you look at it
 * all it does is to try to locate and parse MPOA Device
 * Type TLV.
 * We give our lec a pointer to this function and when the
 * lec sees a TLV it uses the pointer to call this function.
 *
 */
static void lane2_assoc_ind(struct net_device *dev, const u8 *mac_addr,
			    const u8 *tlvs, u32 sizeoftlvs)
{
	uint32_t type;
	uint8_t length, mpoa_device_type, number_of_mps_macs;
	const uint8_t *end_of_tlvs;
	struct mpoa_client *mpc;

	mpoa_device_type = number_of_mps_macs = 0; /* silence gcc */
	dprintk("(%s) received TLV(s), ", dev->name);
	dprintk("total length of all TLVs %d\n", sizeoftlvs);
	mpc = find_mpc_by_lec(dev); /* Sampo-Fix: moved here from below */
	if (mpc == NULL) {
		pr_info("(%s) no mpc\n", dev->name);
		return;
	}
	end_of_tlvs = tlvs + sizeoftlvs;
	while (end_of_tlvs - tlvs >= 5) {
		type = ((tlvs[0] << 24) | (tlvs[1] << 16) |
			(tlvs[2] << 8) | tlvs[3]);
		length = tlvs[4];
		tlvs += 5;
		dprintk("    type 0x%x length %02x\n", type, length);
		if (tlvs + length > end_of_tlvs) {
			pr_info("TLV value extends past its buffer, aborting parse\n");
			return;
		}

		if (type == 0) {
			pr_info("mpoa: (%s) TLV type was 0, returning\n",
				dev->name);
			return;
		}

		if (type != TLV_MPOA_DEVICE_TYPE) {
			tlvs += length;
			continue;  /* skip other TLVs */
		}
		mpoa_device_type = *tlvs++;
		number_of_mps_macs = *tlvs++;
		dprintk("(%s) MPOA device type '%s', ",
			dev->name, mpoa_device_type_string(mpoa_device_type));
		if (mpoa_device_type == MPS_AND_MPC &&
		    length < (42 + number_of_mps_macs*ETH_ALEN)) { /* :) */
			pr_info("(%s) short MPOA Device Type TLV\n",
				dev->name);
			continue;
		}
		if ((mpoa_device_type == MPS || mpoa_device_type == MPC) &&
		    length < 22 + number_of_mps_macs*ETH_ALEN) {
			pr_info("(%s) short MPOA Device Type TLV\n", dev->name);
			continue;
		}
		if (mpoa_device_type != MPS &&
		    mpoa_device_type != MPS_AND_MPC) {
			dprintk("ignoring non-MPS device ");
			if (mpoa_device_type == MPC)
				tlvs += 20;
			continue;  /* we are only interested in MPSs */
		}
		if (number_of_mps_macs == 0 &&
		    mpoa_device_type == MPS_AND_MPC) {
			pr_info("(%s) MPS_AND_MPC has zero MACs\n", dev->name);
			continue;  /* someone should read the spec */
		}
		dprintk_cont("this MPS has %d MAC addresses\n",
			     number_of_mps_macs);

		/*
		 * ok, now we can go and tell our daemon
		 * the control address of MPS
		 */
		send_set_mps_ctrl_addr(tlvs, mpc);

		tlvs = copy_macs(mpc, mac_addr, tlvs,
				 number_of_mps_macs, mpoa_device_type);
		if (tlvs == NULL)
			return;
	}
	if (end_of_tlvs - tlvs != 0)
		pr_info("(%s) ignoring %Zd bytes of trailing TLV garbage\n",
			dev->name, end_of_tlvs - tlvs);
	return;
}