};
static inline struct net_device *vlan_group_get_device(struct vlan_group *vg,
- unsigned int vlan_id)
+ u16 vlan_id)
{
struct net_device **array;
array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN];
}
static inline void vlan_group_set_device(struct vlan_group *vg,
- unsigned int vlan_id,
+ u16 vlan_id,
struct net_device *dev)
{
struct net_device **array;
array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev;
}
-/* VLAN tx hw acceleration helpers. */
-struct vlan_skb_tx_cookie {
- u32 magic;
- u32 vlan_tag;
-};
-
-#define VLAN_TX_COOKIE_MAGIC 0x564c414e /* "VLAN" in ascii. */
-#define VLAN_TX_SKB_CB(__skb) ((struct vlan_skb_tx_cookie *)&((__skb)->cb[0]))
-#define vlan_tx_tag_present(__skb) \
- (VLAN_TX_SKB_CB(__skb)->magic == VLAN_TX_COOKIE_MAGIC)
-#define vlan_tx_tag_get(__skb) (VLAN_TX_SKB_CB(__skb)->vlan_tag)
+#define vlan_tx_tag_present(__skb) ((__skb)->vlan_tci)
+#define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci)
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
extern u16 vlan_dev_vlan_id(const struct net_device *dev);
extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
- unsigned short vlan_tag, int polling);
+ u16 vlan_tci, int polling);
+extern int vlan_hwaccel_do_receive(struct sk_buff *skb);
+
#else
static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
{
}
static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
- unsigned short vlan_tag, int polling)
+ u16 vlan_tci, int polling)
{
BUG();
return NET_XMIT_SUCCESS;
}
+
+static inline int vlan_hwaccel_do_receive(struct sk_buff *skb)
+{
+ return 0;
+}
#endif
+/**
+ * vlan_hwaccel_rx - netif_rx wrapper for VLAN RX acceleration
+ * @skb: buffer
+ * @grp: vlan group
+ * @vlan_tci: VLAN TCI as received from the card
+ */
static inline int vlan_hwaccel_rx(struct sk_buff *skb,
struct vlan_group *grp,
- unsigned short vlan_tag)
+ u16 vlan_tci)
{
- return __vlan_hwaccel_rx(skb, grp, vlan_tag, 0);
+ return __vlan_hwaccel_rx(skb, grp, vlan_tci, 0);
}
+/**
+ * vlan_hwaccel_receive_skb - netif_receive_skb wrapper for VLAN RX acceleration
+ * @skb: buffer
+ * @grp: vlan group
+ * @vlan_tci: VLAN TCI as received from the card
+ */
static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb,
struct vlan_group *grp,
- unsigned short vlan_tag)
+ u16 vlan_tci)
{
- return __vlan_hwaccel_rx(skb, grp, vlan_tag, 1);
+ return __vlan_hwaccel_rx(skb, grp, vlan_tci, 1);
}
/**
* __vlan_put_tag - regular VLAN tag inserting
* @skb: skbuff to tag
- * @tag: VLAN tag to insert
+ * @vlan_tci: VLAN TCI to insert
*
* Inserts the VLAN tag into @skb as part of the payload
* Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
- *
+ *
* Following the skb_unshare() example, in case of error, the calling function
* doesn't have to worry about freeing the original skb.
*/
-static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, unsigned short tag)
+static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
{
struct vlan_ethhdr *veth;
- if (skb_headroom(skb) < VLAN_HLEN) {
- struct sk_buff *sk_tmp = skb;
- skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
- kfree_skb(sk_tmp);
- if (!skb) {
- printk(KERN_ERR "vlan: failed to realloc headroom\n");
- return NULL;
- }
- } else {
- skb = skb_unshare(skb, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_ERR "vlan: failed to unshare skbuff\n");
- return NULL;
- }
+ if (skb_cow_head(skb, VLAN_HLEN) < 0) {
+ kfree_skb(skb);
+ return NULL;
}
-
veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
/* Move the mac addresses to the beginning of the new header. */
/* first, the ethernet type */
veth->h_vlan_proto = htons(ETH_P_8021Q);
- /* now, the tag */
- veth->h_vlan_TCI = htons(tag);
+ /* now, the TCI */
+ veth->h_vlan_TCI = htons(vlan_tci);
skb->protocol = htons(ETH_P_8021Q);
/**
* __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting
* @skb: skbuff to tag
- * @tag: VLAN tag to insert
+ * @vlan_tci: VLAN TCI to insert
*
- * Puts the VLAN tag in @skb->cb[] and lets the device do the rest
+ * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest
*/
-static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, unsigned short tag)
+static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb,
+ u16 vlan_tci)
{
- struct vlan_skb_tx_cookie *cookie;
-
- cookie = VLAN_TX_SKB_CB(skb);
- cookie->magic = VLAN_TX_COOKIE_MAGIC;
- cookie->vlan_tag = tag;
-
+ skb->vlan_tci = vlan_tci;
return skb;
}
/**
* vlan_put_tag - inserts VLAN tag according to device features
* @skb: skbuff to tag
- * @tag: VLAN tag to insert
+ * @vlan_tci: VLAN TCI to insert
*
* Assumes skb->dev is the target that will xmit this frame.
* Returns a VLAN tagged skb.
*/
-static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, unsigned short tag)
+static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
{
if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
- return __vlan_hwaccel_put_tag(skb, tag);
+ return __vlan_hwaccel_put_tag(skb, vlan_tci);
} else {
- return __vlan_put_tag(skb, tag);
+ return __vlan_put_tag(skb, vlan_tci);
}
}
/**
* __vlan_get_tag - get the VLAN ID that is part of the payload
* @skb: skbuff to query
- * @tag: buffer to store vlaue
- *
+ * @vlan_tci: buffer to store vlaue
+ *
* Returns error if the skb is not of VLAN type
*/
-static inline int __vlan_get_tag(const struct sk_buff *skb, unsigned short *tag)
+static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
{
struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
return -EINVAL;
}
- *tag = ntohs(veth->h_vlan_TCI);
-
+ *vlan_tci = ntohs(veth->h_vlan_TCI);
return 0;
}
/**
* __vlan_hwaccel_get_tag - get the VLAN ID that is in @skb->cb[]
* @skb: skbuff to query
- * @tag: buffer to store vlaue
- *
- * Returns error if @skb->cb[] is not set correctly
+ * @vlan_tci: buffer to store vlaue
+ *
+ * Returns error if @skb->vlan_tci is not set correctly
*/
static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb,
- unsigned short *tag)
+ u16 *vlan_tci)
{
- struct vlan_skb_tx_cookie *cookie;
-
- cookie = VLAN_TX_SKB_CB(skb);
- if (cookie->magic == VLAN_TX_COOKIE_MAGIC) {
- *tag = cookie->vlan_tag;
+ if (vlan_tx_tag_present(skb)) {
+ *vlan_tci = skb->vlan_tci;
return 0;
} else {
- *tag = 0;
+ *vlan_tci = 0;
return -EINVAL;
}
}
/**
* vlan_get_tag - get the VLAN ID from the skb
* @skb: skbuff to query
- * @tag: buffer to store vlaue
- *
+ * @vlan_tci: buffer to store vlaue
+ *
* Returns error if the skb is not VLAN tagged
*/
-static inline int vlan_get_tag(const struct sk_buff *skb, unsigned short *tag)
+static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
{
if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
- return __vlan_hwaccel_get_tag(skb, tag);
+ return __vlan_hwaccel_get_tag(skb, vlan_tci);
} else {
- return __vlan_get_tag(skb, tag);
+ return __vlan_get_tag(skb, vlan_tci);
}
}