iwlagn: allow application own the uCode operation
authorWey-Yi Guy <wey-yi.w.guy@intel.com>
Fri, 8 Jul 2011 15:46:26 +0000 (08:46 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 11 Jul 2011 19:02:08 +0000 (15:02 -0400)
Since we open the door to allow application control the device behavior through
testmode, add command to allow application request the ownership of the uCode

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-sv-open.c
drivers/net/wireless/iwlwifi/iwl-testmode.h

index b7e9fd1..fa0827f 100644 (file)
@@ -1263,6 +1263,10 @@ struct iwl_trans {
        const struct iwl_trans_ops *ops;
 };
 
+/* uCode ownership */
+#define IWL_OWNERSHIP_DRIVER   0
+#define IWL_OWNERSHIP_TM       1
+
 struct iwl_priv {
 
        /* ieee device used by generic ieee processing code */
@@ -1351,6 +1355,10 @@ struct iwl_priv {
        int fw_index;                   /* firmware we're trying to load */
        u32 ucode_ver;                  /* version of ucode, copy of
                                           iwl_ucode.ver */
+
+       /* uCode owner: default: IWL_OWNERSHIP_DRIVER */
+       u8 ucode_owner;
+
        struct fw_img ucode_rt;
        struct fw_img ucode_init;
 
index 653b787..ed9bd91 100644 (file)
@@ -105,6 +105,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
 
        [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
 
+       [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
 };
 
 /*
@@ -587,6 +588,42 @@ static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
        return -ENOBUFS;
 }
 
+/*
+ * This function handles the user application switch ucode ownership.
+ *
+ * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and
+ * decide who the current owner of the uCode
+ *
+ * If the current owner is OWNERSHIP_TM, then the only host command
+ * can deliver to uCode is from testmode, all the other host commands
+ * will dropped.
+ *
+ * default driver is the owner of uCode in normal operational mode
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+       struct iwl_priv *priv = hw->priv;
+       u8 owner;
+
+       if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
+               IWL_DEBUG_INFO(priv, "Error finding ucode owner\n");
+               return -ENOMSG;
+       }
+
+       owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
+       if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM))
+               priv->ucode_owner = owner;
+       else {
+               IWL_DEBUG_INFO(priv, "Invalid owner\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+
 /* The testmode gnl message handler that takes the gnl message from the
  * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
  * invoke the corresponding handlers.
@@ -656,6 +693,11 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
                result = iwl_testmode_trace(hw, tb);
                break;
 
+       case IWL_TM_CMD_APP2DEV_OWNERSHIP:
+               IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n");
+               result = iwl_testmode_ownership(hw, tb);
+               break;
+
        default:
                IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
                result = -ENOSYS;
index d825188..b980bda 100644 (file)
  * @IWL_TM_CMD_DEV2APP_EEPROM_RSP:
  *     commands from kernel space to carry the eeprom response
  *     to user application
+ * @IWL_TM_CMD_APP2DEV_OWNERSHIP:
+ *     commands from user application to own change the ownership of the uCode
+ *     if application has the ownership, the only host command from
+ *     testmode will deliver to uCode. Default owner is driver
  */
 enum iwl_tm_cmd_t {
        IWL_TM_CMD_APP2DEV_UCODE                = 1,
@@ -121,7 +125,8 @@ enum iwl_tm_cmd_t {
        IWL_TM_CMD_DEV2APP_SYNC_RSP             = 14,
        IWL_TM_CMD_DEV2APP_UCODE_RX_PKT         = 15,
        IWL_TM_CMD_DEV2APP_EEPROM_RSP           = 16,
-       IWL_TM_CMD_MAX                          = 17,
+       IWL_TM_CMD_APP2DEV_OWNERSHIP            = 17,
+       IWL_TM_CMD_MAX                          = 18,
 };
 
 /*
@@ -187,6 +192,10 @@ enum iwl_tm_cmd_t {
  *     The mandatory fields are:
  *     IWL_TM_ATTR_FIXRATE for the fixed rate
  *
+ * @IWL_TM_ATTR_UCODE_OWNER:
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_OWNERSHIP,
+ *     The mandatory fields are:
+ *     IWL_TM_ATTR_UCODE_OWNER for the new owner
  */
 enum iwl_tm_attr_t {
        IWL_TM_ATTR_NOT_APPLICABLE              = 0,
@@ -203,7 +212,8 @@ enum iwl_tm_attr_t {
        IWL_TM_ATTR_TRACE_SIZE                  = 11,
        IWL_TM_ATTR_TRACE_DUMP                  = 12,
        IWL_TM_ATTR_FIXRATE                     = 13,
-       IWL_TM_ATTR_MAX                         = 14,
+       IWL_TM_ATTR_UCODE_OWNER                 = 14,
+       IWL_TM_ATTR_MAX                         = 15,
 };
 
 /* uCode trace buffer */