From: Felix Varghese <felixvarg...@gmail.com>

Adds the implementation for MLME-SET primitive in mac802154.
This is according to IEEE 802.15.4-2006 specification.

Signed-off-by: Felix Varghese <felixvarg...@gmail.com>
Signed-off-by: Prajosh Premdas <premdas.praj...@gmail.com>
---
 net/mac802154/mlme_pib.c |  186 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 186 insertions(+), 0 deletions(-)

diff --git a/net/mac802154/mlme_pib.c b/net/mac802154/mlme_pib.c
index 74573b4..a1ed573 100644
--- a/net/mac802154/mlme_pib.c
+++ b/net/mac802154/mlme_pib.c
@@ -42,6 +42,8 @@ struct mlme_set_req_notify_work {
 /* MLME_GET request worker functions */
 static void internal_mlme_get_req_worker(struct work_struct *work);
 
+/* MLME_SET request worker functions */
+static void internal_mlme_set_req_worker(struct work_struct *work);
 
 void mac_pib_reset_def(struct net_device *dev)
 {
@@ -353,7 +355,191 @@ int internal_get_mac_pib(struct net_device *dev, u8 
PIBattr, void *PIBval)
 
 int mlme_set_req(struct net_device *dev, u8 PIBattr, void *PIBval)
 {
+       struct mac802154_sub_if_data *priv = netdev_priv(dev);
+       struct mlme_set_req_notify_work *work;
        int ret = 0;
+
+       work = kmalloc(sizeof(*work), GFP_ATOMIC);
+       if (!work) {
+               /* Out of memory */
+               ret = -ENOMEM;
+               goto error_no_mem;
+       }
+
+       INIT_WORK(&work->work, internal_mlme_set_req_worker);
+       work->dev               = dev;
+       work->PIBattr   = PIBattr;
+       memcpy(&(work->PIBval), PIBval, sizeof(union pib_value_t));
+
+       queue_work(priv->hw->dev_workqueue, &work->work);
+
+error_no_mem:
        return ret;
 }
 
+static void internal_mlme_set_req_worker(struct work_struct *work)
+{
+       struct mlme_set_req_notify_work *nw = container_of(work,
+                       struct mlme_set_req_notify_work, work);
+
+       int ret;
+
+       /*
+        * Call the mlme_get_req with parameters
+        * 1. struct dev : nw->dev
+        * 2. attribute to be read: nw->PIBattr
+        * 3. memory location where the value is: nw->PIBval
+        */
+       ret = internal_set_mac_pib(nw->dev, nw->PIBattr,
+                                  (void *)(&(nw->PIBval)));
+
+       ieee802154_nl_set_confirm(nw->dev, nw->PIBattr, ret);
+
+       /* Work is done */
+       kfree(nw);
+}
+
+int internal_set_mac_pib(struct net_device *dev, u8 PIBattr, void *PIBval)
+{
+       struct mac802154_sub_if_data *priv = netdev_priv(dev);
+       struct mac802154_priv *trx = priv->hw;
+       int ret_from_radio;
+       int ret = 0;
+
+       /*
+        * Try the radio's set primitive first in case it supports some of
+        * the MAC attributes (eg., for address filtering).
+        */
+       ret_from_radio = trx->ops->set(&trx->hw, PIBattr, PIBval);
+
+       /*
+        * If the return value indicates that the attribute is not supported
+        * in the radio, see if MAC supports it.
+        * If it is supported by both MAC & the radio, update MAC's copy so
+        * that it can be used in case the radio does not implement a GET
+        * for this attribute.
+        * In case of any other return value, propagate the error back all
+        * the way to user space.
+        */
+       if ((ret_from_radio < 0) && (ret_from_radio != -EOPNOTSUPP))
+               return ret_from_radio;
+
+       mutex_lock(&priv->macPIB_lock);
+
+       switch (PIBattr) {
+       case macAssociatedPANCoord:
+               priv->macPIB.AssociatedPANCoord = *((u8 *)PIBval);
+               break;
+
+       case macAssociationPermit:
+               priv->macPIB.AssociationPermit = *((u8 *)PIBval);
+               break;
+
+       case macAutoRequest:
+               priv->macPIB.AutoRequest = *((u8 *)PIBval);
+               break;
+
+       case macBattLifeExt:
+               priv->macPIB.BattLifeExt = *((u8 *)PIBval);
+               break;
+
+       case macBattLifeExtPeriods:
+               priv->macPIB.BattLifeExtPeriods = *((u8 *)PIBval);
+               break;
+
+       case macBeaconPayload:
+               memcpy(priv->macPIB.BeaconPayload, PIBval,
+                      priv->macPIB.BeaconPayloadLength);
+               break;
+
+       case macBeaconPayloadLength:
+               priv->macPIB.BeaconPayloadLength = *((u8 *)PIBval);
+               break;
+
+       case macBeaconOrder:
+               priv->macPIB.BeaconOrder = *((u8 *)PIBval);
+               break;
+
+       case macBSN:
+               priv->macPIB.BSN = *((u8 *)PIBval);
+               break;
+
+       case macCoordExtendedAddress:
+               priv->macPIB.CoordExtendedAddress = *((u64 *)PIBval);
+               break;
+
+       case macCoordShortAddress:
+               priv->macPIB.CoordShortAddress = *((u16 *)PIBval);
+               break;
+
+       case macDSN:
+               priv->macPIB.DSN = *((u8 *)PIBval);
+               break;
+
+       case macMaxBE:
+               priv->macPIB.MaxBE = *((u8 *)PIBval);
+               break;
+
+       case macMaxCSMABackoffs:
+               priv->macPIB.MaxCSMABackoffs = *((u8 *)PIBval);
+               break;
+
+       case macMaxFrameTotalWaitTime:
+               priv->macPIB.MaxFrameTotalWaitTime = *((u16 *)PIBval);
+               break;
+
+       case macMaxFrameRetries:
+               priv->macPIB.MaxFrameRetries = *((u8 *)PIBval);
+               break;
+
+       case macMinBE:
+               priv->macPIB.MinBE = *((u8 *)PIBval);
+               break;
+
+       case macPANId:
+               priv->macPIB.PANId = *((u16 *)PIBval);
+               break;
+
+       case macPromiscuousMode:
+               priv->macPIB.PromiscuousMode = *((u8 *)PIBval);
+               break;
+
+       case macResponseWaitTime:
+               priv->macPIB.ResponseWaitTime = *((u16 *)PIBval);
+               break;
+
+       case macRxOnWhenIdle:
+               priv->macPIB.RxOnWhenIdle = *((u8 *)PIBval);
+               break;
+
+       case macSecurityEnabled:
+               priv->macPIB.SecurityEnabled = *((u8 *)PIBval);
+               break;
+
+       case macShortAddress:
+               priv->macPIB.ShortAddress = *((u16 *)PIBval);
+               break;
+
+       case macTransactionPersistenceTime:
+               priv->macPIB.TransactionPersistenceTime = *((u16 *)PIBval);
+               break;
+
+       case macBeaconTxTime:
+       case macSuperframeOrder:
+               /*
+                * These are read-only attributes. If the radio does not
+                * support these, return READ_ONLY status. If it allows
+                * setting these, return whatever status the radio returned.
+                */
+               if (ret_from_radio == -EOPNOTSUPP)
+                       ret = -EPERM;
+
+       default:
+               /* PIB is not found so return the error from radio */
+               ret = ret_from_radio;
+               break;
+       }
+
+       mutex_unlock(&priv->macPIB_lock);
+       return ret;
+}
-- 
1.7.4.1


------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel

Reply via email to