From patchwork Sat May 12 13:59:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: alex.bluesman.smirnov@gmail.com X-Patchwork-Id: 158751 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id B356DB7010 for ; Sun, 13 May 2012 00:01:07 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756449Ab2ELOBF (ORCPT ); Sat, 12 May 2012 10:01:05 -0400 Received: from mail-we0-f174.google.com ([74.125.82.174]:50719 "EHLO mail-we0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752730Ab2ELOAO (ORCPT ); Sat, 12 May 2012 10:00:14 -0400 Received: by mail-we0-f174.google.com with SMTP id u7so920892wey.19 for ; Sat, 12 May 2012 07:00:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=MiLlm373X+PPC6vBgvEQi08TAXCJ85lRRzjrLpoXTww=; b=OVmMswZU8pRIwr3794QqicQmV1v2w+58Gnn14g15tJqvDf3y07t6gVmYgVT353+oaJ XsD/GMiJNfT7feuhiVpTye6/837eqRrE51vxMw1XZuOqjcL5BqKmn7mfoKyh3pTCMQpT lXod06P2Xjs5JJ39FOBVWA72V8wu0dEptajAfdSkf1e1HT5Wn37bv0+CXlrZEMs4Cj5Z lDrAriFDFDemIrmlwkhMJab71vRUfGC5FGMEj/tzkCWZfFtY19GfAfCkk+dBnLnXp5MB 6BUR31lhXxzM46cTuaUKOLD1JiCJSyjleAo09blvJ68Nn3AoIOukN3pxLDvt5EJbniOK O9+A== Received: by 10.180.24.35 with SMTP id r3mr4528736wif.7.1336831213657; Sat, 12 May 2012 07:00:13 -0700 (PDT) Received: from localhost.localdomain ([91.213.169.4]) by mx.google.com with ESMTPS id bn9sm19099868wib.5.2012.05.12.07.00.12 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 12 May 2012 07:00:13 -0700 (PDT) From: Alexander Smirnov To: davem@davemloft.net Cc: netdev@vger.kernel.org, dbaryshkov@gmail.com, Alexander Smirnov Subject: [PATCH net-next v4 03/13] mac802154: RX data path Date: Sat, 12 May 2012 17:59:15 +0400 Message-Id: <1336831165-23944-4-git-send-email-alex.bluesman.smirnov@gmail.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1336831165-23944-1-git-send-email-alex.bluesman.smirnov@gmail.com> References: <1336831165-23944-1-git-send-email-alex.bluesman.smirnov@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Main RX data path implementation between physical and mac layers. The ieee802.15.4 standard defines 4 MAC packet types: - beacon frame - MAC command frame - acknowledgement frame - data frame and only the data frame should be pushed to the upper layers, other types are just internal MAC layer management information. So only data packets are going to be sent to the networking queue, all other will be processed right here. Signed-off-by: Alexander Smirnov --- include/net/ieee802154_netdev.h | 2 + include/net/mac802154.h | 4 ++ net/mac802154/Makefile | 2 +- net/mac802154/rx.c | 109 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 1 deletions(-) create mode 100644 net/mac802154/rx.c diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 5743055..12a7ee4 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -26,6 +26,8 @@ #ifndef IEEE802154_NETDEVICE_H #define IEEE802154_NETDEVICE_H +#include + /* * A control block of skb passed between the ARPHRD_IEEE802154 device * and other stack parts. diff --git a/include/net/mac802154.h b/include/net/mac802154.h index ef27d07..cdc0100 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -134,4 +134,8 @@ void ieee802154_free_device(struct ieee802154_dev *dev); int ieee802154_register_device(struct ieee802154_dev *dev); void ieee802154_unregister_device(struct ieee802154_dev *dev); +void ieee802154_rx(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi); +void ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, + u8 lqi); + #endif /* NET_MAC802154_H */ diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index cda9393..e00fe47 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_MAC802154) += mac802154.o -mac802154-objs := ieee802154_dev.o +mac802154-objs := ieee802154_dev.o rx.o diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c new file mode 100644 index 0000000..3446379 --- /dev/null +++ b/net/mac802154/rx.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2007-2011 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Written by: + * Pavel Smolenskiy + * Maxim Gorbachyov + * Dmitry Eremin-Solenikov + * Alexander Smirnov + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "mac802154.h" + +static void +mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) +{ + struct mac802154_priv *priv = mac802154_to_priv(hw); + + mac_cb(skb)->lqi = lqi; + skb->protocol = htons(ETH_P_IEEE802154); + skb_reset_mac_header(skb); + + BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb)); + + if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + u16 crc; + + if (skb->len < 2) { + pr_debug("(%s): got invalid frame\n", __func__); + goto out; + } + crc = crc_ccitt(0, skb->data, skb->len); + if (crc) { + pr_debug("(%s): CRC mismatch\n", __func__); + goto out; + } + skb_trim(skb, skb->len - 2); /* CRC */ + } + +out: + dev_kfree_skb(skb); + return; +} + +struct rx_work { + struct sk_buff *skb; + struct work_struct work; + struct ieee802154_dev *dev; + u8 lqi; +}; + +static void mac802154_rx_worker(struct work_struct *work) +{ + struct rx_work *rw = container_of(work, struct rx_work, work); + struct sk_buff *skb = rw->skb; + + mac802154_subif_rx(rw->dev, skb, rw->lqi); + kfree(rw); +} + +void +ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) +{ + struct mac802154_priv *priv = mac802154_to_priv(dev); + struct rx_work *work; + + if (!skb) + return; + + work = kzalloc(sizeof(struct rx_work), GFP_ATOMIC); + if (!work) + return; + + INIT_WORK(&work->work, mac802154_rx_worker); + work->skb = skb; + work->dev = dev; + work->lqi = lqi; + + queue_work(priv->dev_workqueue, &work->work); +} +EXPORT_SYMBOL(ieee802154_rx_irqsafe); + +void mac802154_rx(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) +{ + if (skb) + mac802154_subif_rx(dev, skb, lqi); +} +EXPORT_SYMBOL(mac802154_rx);