--- zzzz-none-000/linux-2.6.39.4/net/8021q/vlan.c 2011-08-03 19:43:28.000000000 +0000 +++ puma6-arm-6490-729/linux-2.6.39.4/net/8021q/vlan.c 2021-11-10 13:23:11.000000000 +0000 @@ -35,6 +35,7 @@ #include #include +#include #include "vlan.h" #include "vlanproc.h" @@ -114,7 +115,13 @@ grp = rtnl_dereference(real_dev->vlgrp); BUG_ON(!grp); - +#ifdef CONFIG_TI_PACKET_PROCESSOR + /* Send an event to HIL PP indicating that the VLAN + * device is being brought down. The HIL PP could + * clean up any if existing references to this VLAN + * device in its domain. */ + ti_hil_pp_event(TI_VLAN_DEV_DELETED, (void *)dev); +#endif //CONFIG_TI_PACKET_PROCESSOR /* Take it out of our own structures, but be sure to interlock with * HW accelerating devices or SW vlan input packet processing if * VLAN is not 0 (leave it there for 802.1p). @@ -295,7 +302,16 @@ err = register_vlan_dev(new_dev); if (err < 0) goto out_free_newdev; - +#ifdef CONFIG_TI_PACKET_PROCESSOR + /* Inheritance at work here. We copy the VPID Information block from the parent device + * to the new VLAN virtual device. */ + ti_hil_clone_netdev_pp_info(new_dev, real_dev); + + /* Send an event to HIL PP indicating that a new VLAN device + * is being created. The HIL may store the VLAN info and use it + * later for PP session creation and acceleration decision making */ + ti_hil_pp_event(TI_VLAN_DEV_CREATED, (void *)new_dev); +#endif return 0; out_free_newdev: @@ -303,6 +319,66 @@ return err; } +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +int avm_register_vlan_device(struct net_device *real_dev, u16 vlan_id, const char *name, struct net_device **vlan_dev) +{ + struct net_device *new_dev = NULL; + struct net *net; + int result; + + if(vlan_dev != NULL){ + *vlan_dev = NULL; + } + + net = dev_net(real_dev); + + if (vlan_id >= VLAN_VID_MASK){ + result = -ERANGE; + goto err_out; + } + + result = vlan_check_real_dev(real_dev, vlan_id); + if(result < 0){ + goto err_out; + } + + new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name, vlan_setup); + if(new_dev == NULL){ + result = -ENOBUFS; + goto err_out; + } + + dev_net_set(new_dev, net); + /* need 4 bytes for extra VLAN header info, + * hope the underlying device can handle it. + */ + new_dev->mtu = real_dev->mtu; + + vlan_dev_info(new_dev)->vlan_id = vlan_id; + vlan_dev_info(new_dev)->real_dev = real_dev; + vlan_dev_info(new_dev)->dent = NULL; + vlan_dev_info(new_dev)->flags = VLAN_FLAG_REORDER_HDR; + + new_dev->rtnl_link_ops = &vlan_link_ops; + + result = register_vlan_dev(new_dev); + if(result < 0){ + goto err_out; + } + + if(vlan_dev != NULL){ + *vlan_dev = new_dev; + } + +err_out: + if(result != 0 && new_dev != NULL){ + free_netdev(new_dev); + } + + return result; +} + static void vlan_sync_address(struct net_device *dev, struct net_device *vlandev) {