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