summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c48
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c51
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c1
12 files changed, 91 insertions, 70 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 5f7c52053c18..cf3fbc6b98ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -73,6 +73,18 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
}
+/* NIC configuration for 1000 series */
+static void iwl1000_nic_config(struct iwl_priv *priv)
+{
+ iwl5000_nic_config(priv);
+
+ /* Setting digital SVR for 1000 card to 1.32V */
+ /* locking is acquired in iwl_set_bits_mask_prph() function */
+ iwl_set_bits_mask_prph(priv, APMG_DIGITAL_SVR_REG,
+ APMG_SVR_DIGITAL_VOLTAGE_1_32,
+ ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
+}
+
static struct iwl_lib_ops iwl1000_lib = {
.set_hw_params = iwl5000_hw_set_hw_params,
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
@@ -95,7 +107,7 @@ static struct iwl_lib_ops iwl1000_lib = {
.init = iwl5000_apm_init,
.reset = iwl5000_apm_reset,
.stop = iwl5000_apm_stop,
- .config = iwl5000_nic_config,
+ .config = iwl1000_nic_config,
.set_pwr_src = iwl_set_pwr_src,
},
.eeprom_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index ddd64fef3039..87957c052839 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -198,6 +198,7 @@ out:
}
+/* NIC configuration for 5000 series and up */
void iwl5000_nic_config(struct iwl_priv *priv)
{
unsigned long flags;
@@ -239,18 +240,11 @@ void iwl5000_nic_config(struct iwl_priv *priv)
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
- if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_1000) {
- /* Setting digital SVR for 1000 card to 1.32V */
- iwl_set_bits_mask_prph(priv, APMG_DIGITAL_SVR_REG,
- APMG_SVR_DIGITAL_VOLTAGE_1_32,
- ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
- }
spin_unlock_irqrestore(&priv->lock, flags);
}
-
/*
* EEPROM
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 59ff73536f3a..4450943d3dac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -68,6 +68,24 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
}
+/* NIC configuration for 6000 series */
+static void iwl6000_nic_config(struct iwl_priv *priv)
+{
+ iwl5000_nic_config(priv);
+
+ /* no locking required for register write */
+ if (priv->cfg->pa_type == IWL_PA_HYBRID) {
+ /* 2x2 hybrid phy type */
+ iwl_write32(priv, CSR_GP_DRIVER_REG,
+ CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB);
+ } else if (priv->cfg->pa_type == IWL_PA_INTERNAL) {
+ /* 2x2 IPA phy type */
+ iwl_write32(priv, CSR_GP_DRIVER_REG,
+ CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
+ }
+ /* else do nothing, uCode configured */
+}
+
static struct iwl_lib_ops iwl6000_lib = {
.set_hw_params = iwl5000_hw_set_hw_params,
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
@@ -90,7 +108,7 @@ static struct iwl_lib_ops iwl6000_lib = {
.init = iwl5000_apm_init,
.reset = iwl5000_apm_reset,
.stop = iwl5000_apm_stop,
- .config = iwl5000_nic_config,
+ .config = iwl6000_nic_config,
.set_pwr_src = iwl_set_pwr_src,
},
.eeprom_ops = {
@@ -132,23 +150,31 @@ static struct iwl_ops iwl6000_ops = {
.utils = &iwl6000_hcmd_utils,
};
-struct iwl_cfg iwl6000_2ag_cfg = {
- .name = "6000 Series 2x2 AG",
+
+/*
+ * "h": Hybrid configuration, use both internal and external Power Amplifier
+ */
+struct iwl_cfg iwl6000h_2agn_cfg = {
+ .name = "6000 Series 2x2 AGN",
.fw_name_pre = IWL6000_FW_PRE,
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.ops = &iwl6000_ops,
.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
- .valid_tx_ant = ANT_BC,
- .valid_rx_ant = ANT_BC,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
.need_pll_cfg = false,
+ .pa_type = IWL_PA_HYBRID,
};
-struct iwl_cfg iwl6000_2agn_cfg = {
+/*
+ * "i": Internal configuration, use internal Power Amplifier
+ */
+struct iwl_cfg iwl6000i_2agn_cfg = {
.name = "6000 Series 2x2 AGN",
.fw_name_pre = IWL6000_FW_PRE,
.ucode_api_max = IWL6000_UCODE_API_MAX,
@@ -159,9 +185,10 @@ struct iwl_cfg iwl6000_2agn_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
.need_pll_cfg = false,
+ .pa_type = IWL_PA_INTERNAL,
};
struct iwl_cfg iwl6050_2agn_cfg = {
@@ -178,6 +205,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.valid_tx_ant = ANT_AB,
.valid_rx_ant = ANT_AB,
.need_pll_cfg = false,
+ .pa_type = IWL_PA_SYSTEM,
};
struct iwl_cfg iwl6000_3agn_cfg = {
@@ -194,6 +222,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.valid_tx_ant = ANT_ABC,
.valid_rx_ant = ANT_ABC,
.need_pll_cfg = false,
+ .pa_type = IWL_PA_SYSTEM,
};
struct iwl_cfg iwl6050_3agn_cfg = {
@@ -210,6 +239,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
.valid_tx_ant = ANT_ABC,
.valid_rx_ant = ANT_ABC,
.need_pll_cfg = false,
+ .pa_type = IWL_PA_SYSTEM,
};
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 4cb1a1b73483..db580cbf5982 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1291,6 +1291,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
size_t len;
u32 api_ver, build;
u32 inst_size, data_size, init_size, init_data_size, boot_size;
+ u16 eeprom_ver;
/* Ask kernel firmware_class module to get the boot firmware off disk.
* request_firmware() is synchronous, file is in memory on return. */
@@ -1368,6 +1369,11 @@ static int iwl_read_ucode(struct iwl_priv *priv)
if (build)
IWL_DEBUG_INFO(priv, "Build %u\n", build);
+ eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
+ IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
+ (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+ ? "OTP" : "EEPROM", eeprom_ver);
+
IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
priv->ucode_ver);
IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
@@ -2483,39 +2489,6 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
#endif /* CONFIG_IWLWIFI_DEBUG */
-static ssize_t show_version(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl_priv *priv = dev_get_drvdata(d);
- struct iwl_alive_resp *palive = &priv->card_alive;
- ssize_t pos = 0;
- u16 eeprom_ver;
-
- if (palive->is_valid)
- pos += sprintf(buf + pos,
- "fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n"
- "fw type: 0x%01X 0x%01X\n",
- palive->ucode_major, palive->ucode_minor,
- palive->sw_rev[0], palive->sw_rev[1],
- palive->ver_type, palive->ver_subtype);
- else
- pos += sprintf(buf + pos, "fw not loaded\n");
-
- if (priv->eeprom) {
- eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
- pos += sprintf(buf + pos, "NVM Type: %s, version: 0x%x\n",
- (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
- ? "OTP" : "EEPROM", eeprom_ver);
-
- } else {
- pos += sprintf(buf + pos, "EEPROM not initialzed\n");
- }
-
- return pos;
-}
-
-static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL);
-
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
@@ -2779,7 +2752,6 @@ static struct attribute *iwl_sysfs_entries[] = {
#ifdef CONFIG_IWLWIFI_DEBUG
&dev_attr_debug_level.attr,
#endif
- &dev_attr_version.attr,
NULL
};
@@ -3139,15 +3111,12 @@ static struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)},
{IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},
/* 6000/6050 Series */
- {IWL_PCI_DEVICE(0x0082, 0x1102, iwl6000_2ag_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x008D, PCI_ANY_ID, iwl6000h_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x008E, PCI_ANY_ID, iwl6000h_2agn_cfg)},
{IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
- {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000i_2agn_cfg)},
{IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
- {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000i_2agn_cfg)},
{IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
{IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
{IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 8570d56b3124..6797076bd45f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -548,9 +548,6 @@ int iwlcore_init_geos(struct iwl_priv *priv)
geo_ch->flags |= IEEE80211_CHAN_DISABLED;
}
- /* Save flags for reg domain usage */
- geo_ch->orig_flags = geo_ch->flags;
-
IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
ch->channel, geo_ch->center_freq,
is_channel_a_band(ch) ? "5.2" : "2.4",
@@ -1140,7 +1137,6 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
}
}
-EXPORT_SYMBOL(iwl_set_flags_for_band);
/*
* initialize rxon structure with default values from eeprom
@@ -2291,7 +2287,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
return iwl_send_cmd(priv, &cmd);
}
-EXPORT_SYMBOL(iwl_send_card_state);
void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
@@ -2335,7 +2330,6 @@ void iwl_clear_isr_stats(struct iwl_priv *priv)
{
memset(&priv->isr_stats, 0, sizeof(priv->isr_stats));
}
-EXPORT_SYMBOL(iwl_clear_isr_stats);
int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index febcf76e1d41..10ddcdda1041 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -206,6 +206,7 @@ struct iwl_mod_params {
* filename is constructed as fw_name_pre<api>.ucode.
* @ucode_api_max: Highest version of uCode API supported by driver.
* @ucode_api_min: Lowest version of uCode API supported by driver.
+ * @pa_type: used by 6000 series only to identify the type of Power Amplifier
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
@@ -226,6 +227,7 @@ struct iwl_mod_params {
* iwl_hcmd_utils_ops etc. we accommodate different command structures
* and flows between hardware versions (4965/5000) as well as their API
* versions.
+ *
*/
struct iwl_cfg {
const char *name;
@@ -242,6 +244,7 @@ struct iwl_cfg {
u8 valid_rx_ant;
bool need_pll_cfg;
bool use_isr_legacy;
+ enum iwl_pa_type pa_type;
};
/***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index f03dae1b2f36..06437d13e73e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -91,7 +91,8 @@
#define CSR_EEPROM_GP (CSR_BASE+0x030)
#define CSR_OTP_GP_REG (CSR_BASE+0x034)
#define CSR_GIO_REG (CSR_BASE+0x03C)
-#define CSR_GP_UCODE (CSR_BASE+0x044)
+#define CSR_GP_UCODE_REG (CSR_BASE+0x048)
+#define CSR_GP_DRIVER_REG (CSR_BASE+0x050)
#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054)
#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058)
#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c)
@@ -245,6 +246,13 @@
#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004)
#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008)
+/* GP Driver */
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_MSK (0x00000003)
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000)
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001)
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002)
+
+
/* GI Chicken Bits */
#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 0ee3ad245697..cab6255210d5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -56,8 +56,8 @@ extern struct iwl_cfg iwl5350_agn_cfg;
extern struct iwl_cfg iwl5100_bg_cfg;
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
-extern struct iwl_cfg iwl6000_2ag_cfg;
-extern struct iwl_cfg iwl6000_2agn_cfg;
+extern struct iwl_cfg iwl6000h_2agn_cfg;
+extern struct iwl_cfg iwl6000i_2agn_cfg;
extern struct iwl_cfg iwl6000_3agn_cfg;
extern struct iwl_cfg iwl6050_2agn_cfg;
extern struct iwl_cfg iwl6050_3agn_cfg;
@@ -888,6 +888,19 @@ enum iwl_nvm_type {
NVM_DEVICE_TYPE_OTP,
};
+
+/**
+ * enum iwl_pa_type - Power Amplifier type
+ * @IWL_PA_SYSTEM: based on uCode configuration
+ * @IWL_PA_HYBRID: use both Internal and external PA
+ * @IWL_PA_INTERNAL: use Internal only
+ */
+enum iwl_pa_type {
+ IWL_PA_SYSTEM = 0,
+ IWL_PA_HYBRID = 1,
+ IWL_PA_INTERNAL = 2,
+};
+
/* interrupt statistics */
struct isr_statistics {
u32 hw;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 7cce8f85bcc6..3d61cb43151c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -335,7 +335,6 @@ void iwl_leds_background(struct iwl_priv *priv)
priv->last_blink_time = jiffies;
priv->last_blink_rate = blink_idx;
}
-EXPORT_SYMBOL(iwl_leds_background);
/* Register all led handler */
int iwl_leds_register(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 5d5f2153f445..e002c8b56c49 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -406,7 +406,6 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
rxq->free_count = 0;
spin_unlock_irqrestore(&rxq->lock, flags);
}
-EXPORT_SYMBOL(iwl_rx_queue_reset);
int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 79ea5cc2c89a..efcae0d5e193 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -464,7 +464,6 @@ out:
spin_unlock_irqrestore(&priv->sta_lock, flags);
return ret;
}
-EXPORT_SYMBOL(iwl_remove_station);
/**
* iwl_clear_stations_table - Clear the driver's station table
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 6bb9602f3477..288b871e974b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -970,6 +970,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
out_cmd = txq->cmd[idx];
out_meta = &txq->meta[idx];
+ memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
out_meta->flags = cmd->flags;
if (cmd->flags & CMD_WANT_SKB)
out_meta->source = cmd;