Skip to content

Commit

Permalink
Merge branch 'for-linville' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/luca/wl12xx
  • Loading branch information
John W. Linville committed Jun 22, 2012
2 parents 9ffddb1 + da0b1ba commit d217249
Show file tree
Hide file tree
Showing 17 changed files with 332 additions and 109 deletions.
16 changes: 10 additions & 6 deletions drivers/net/wireless/ti/wl12xx/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
struct wl1271_radio_parms_cmd *radio_parms;
struct wl1271_ini_general_params *gp = &nvs->general_params;
int ret;
int ret, fem_idx;

if (!wl->nvs)
return -ENODEV;
Expand All @@ -185,19 +185,21 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)

radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;

fem_idx = WL12XX_FEM_TO_NVS_ENTRY(gp->tx_bip_fem_manufacturer);

/* 2.4GHz parameters */
memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
sizeof(struct wl1271_ini_band_params_2));
memcpy(&radio_parms->dyn_params_2,
&nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
&nvs->dyn_radio_params_2[fem_idx].params,
sizeof(struct wl1271_ini_fem_params_2));

/* 5GHz parameters */
memcpy(&radio_parms->static_params_5,
&nvs->stat_radio_params_5,
sizeof(struct wl1271_ini_band_params_5));
memcpy(&radio_parms->dyn_params_5,
&nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
&nvs->dyn_radio_params_5[fem_idx].params,
sizeof(struct wl1271_ini_fem_params_5));

wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
Expand All @@ -216,7 +218,7 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl)
struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
struct wl128x_radio_parms_cmd *radio_parms;
struct wl128x_ini_general_params *gp = &nvs->general_params;
int ret;
int ret, fem_idx;

if (!wl->nvs)
return -ENODEV;
Expand All @@ -227,19 +229,21 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl)

radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;

fem_idx = WL12XX_FEM_TO_NVS_ENTRY(gp->tx_bip_fem_manufacturer);

/* 2.4GHz parameters */
memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
sizeof(struct wl128x_ini_band_params_2));
memcpy(&radio_parms->dyn_params_2,
&nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
&nvs->dyn_radio_params_2[fem_idx].params,
sizeof(struct wl128x_ini_fem_params_2));

/* 5GHz parameters */
memcpy(&radio_parms->static_params_5,
&nvs->stat_radio_params_5,
sizeof(struct wl128x_ini_band_params_5));
memcpy(&radio_parms->dyn_params_5,
&nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
&nvs->dyn_radio_params_5[fem_idx].params,
sizeof(struct wl128x_ini_fem_params_5));

radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
Expand Down
7 changes: 3 additions & 4 deletions drivers/net/wireless/ti/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ static struct wlcore_conf wl12xx_conf = {
.forced_ps = false,
.keep_alive_interval = 55000,
.max_listen_interval = 20,
.sta_sleep_auth = WL1271_PSM_ILLEGAL,
},
.itrim = {
.enable = false,
Expand Down Expand Up @@ -1448,10 +1449,8 @@ static int __devinit wl12xx_probe(struct platform_device *pdev)
wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
wl->fw_status_priv_len = 0;
wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], &wl12xx_ht_cap,
sizeof(wl12xx_ht_cap));
memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], &wl12xx_ht_cap,
sizeof(wl12xx_ht_cap));
wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap);
wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
wl12xx_conf_init(wl);

if (!fref_param) {
Expand Down
105 changes: 60 additions & 45 deletions drivers/net/wireless/ti/wl18xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@

#define WL18XX_RX_CHECKSUM_MASK 0x40

static char *ht_mode_param = "wide";
static char *ht_mode_param = "default";
static char *board_type_param = "hdk";
static bool checksum_param = false;
static bool enable_11a_param = true;
static int num_rx_desc_param = -1;

/* phy paramters */
static int dc2dc_param = -1;
Expand Down Expand Up @@ -372,6 +373,7 @@ static struct wlcore_conf wl18xx_conf = {
.forced_ps = false,
.keep_alive_interval = 55000,
.max_listen_interval = 20,
.sta_sleep_auth = WL1271_PSM_ILLEGAL,
},
.itrim = {
.enable = false,
Expand Down Expand Up @@ -606,8 +608,8 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
wl->plt_fw_name = WL18XX_FW_NAME;
wl->quirks |= WLCORE_QUIRK_NO_ELP |
WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
WLCORE_QUIRK_TX_PAD_LAST_FRAME;

break;
case CHIP_ID_185x_PG10:
wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG10)",
Expand Down Expand Up @@ -1021,8 +1023,7 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev)
}

if (fw->size != WL18XX_CONF_SIZE) {
wl1271_error("configuration binary file size is wrong, "
"expected %ld got %zd",
wl1271_error("configuration binary file size is wrong, expected %zu got %zu",
WL18XX_CONF_SIZE, fw->size);
ret = -EINVAL;
goto out;
Expand Down Expand Up @@ -1214,8 +1215,8 @@ static struct wlcore_ops wl18xx_ops = {
.pre_pkt_send = wl18xx_pre_pkt_send,
};

/* HT cap appropriate for wide channels */
static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap = {
/* HT cap appropriate for wide channels in 2Ghz */
static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40,
.ht_supported = true,
Expand All @@ -1228,40 +1229,42 @@ static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap = {
},
};

/* HT cap appropriate for SISO 20 */
static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
.cap = IEEE80211_HT_CAP_SGI_20,
/* HT cap appropriate for wide channels in 5Ghz */
static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
IEEE80211_HT_CAP_SUP_WIDTH_20_40,
.ht_supported = true,
.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
.mcs = {
.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
.rx_highest = cpu_to_le16(72),
.rx_highest = cpu_to_le16(150),
.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
},
};

/* HT cap appropriate for MIMO rates in 20mhz channel */
static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
/* HT cap appropriate for SISO 20 */
static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
.cap = IEEE80211_HT_CAP_SGI_20,
.ht_supported = true,
.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
.mcs = {
.rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, },
.rx_highest = cpu_to_le16(144),
.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
.rx_highest = cpu_to_le16(72),
.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
},
};

static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_5ghz = {
/* HT cap appropriate for MIMO rates in 20mhz channel */
static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
.cap = IEEE80211_HT_CAP_SGI_20,
.ht_supported = true,
.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
.mcs = {
.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
.rx_highest = cpu_to_le16(72),
.rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, },
.rx_highest = cpu_to_le16(144),
.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
},
};
Expand All @@ -1286,40 +1289,16 @@ static int __devinit wl18xx_probe(struct platform_device *pdev)
wl->ptable = wl18xx_ptable;
wl->rtable = wl18xx_rtable;
wl->num_tx_desc = 32;
wl->num_rx_desc = 16;
wl->num_rx_desc = 32;
wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv);
wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics);
wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv);

if (!strcmp(ht_mode_param, "wide")) {
memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ],
&wl18xx_siso40_ht_cap,
sizeof(wl18xx_siso40_ht_cap));
memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ],
&wl18xx_siso40_ht_cap,
sizeof(wl18xx_siso40_ht_cap));
} else if (!strcmp(ht_mode_param, "mimo")) {
memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ],
&wl18xx_mimo_ht_cap_2ghz,
sizeof(wl18xx_mimo_ht_cap_2ghz));
memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ],
&wl18xx_mimo_ht_cap_5ghz,
sizeof(wl18xx_mimo_ht_cap_5ghz));
} else if (!strcmp(ht_mode_param, "siso20")) {
memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ],
&wl18xx_siso20_ht_cap,
sizeof(wl18xx_siso20_ht_cap));
memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ],
&wl18xx_siso20_ht_cap,
sizeof(wl18xx_siso20_ht_cap));
} else {
wl1271_error("invalid ht_mode '%s'", ht_mode_param);
ret = -EINVAL;
goto out_free;
}
if (num_rx_desc_param != -1)
wl->num_rx_desc = num_rx_desc_param;

ret = wl18xx_conf_init(wl, &pdev->dev);
if (ret < 0)
Expand Down Expand Up @@ -1366,6 +1345,37 @@ static int __devinit wl18xx_probe(struct platform_device *pdev)
if (dc2dc_param != -1)
priv->conf.phy.external_pa_dc2dc = dc2dc_param;

if (!strcmp(ht_mode_param, "default")) {
/*
* Only support mimo with multiple antennas. Fall back to
* siso20.
*/
if (priv->conf.phy.number_of_assembled_ant2_4 >= 2)
wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
&wl18xx_mimo_ht_cap_2ghz);
else
wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
&wl18xx_siso20_ht_cap);

/* 5Ghz is always wide */
wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
&wl18xx_siso40_ht_cap_5ghz);
} else if (!strcmp(ht_mode_param, "wide")) {
wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
&wl18xx_siso40_ht_cap_2ghz);
wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
&wl18xx_siso40_ht_cap_5ghz);
} else if (!strcmp(ht_mode_param, "siso20")) {
wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
&wl18xx_siso20_ht_cap);
wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
&wl18xx_siso20_ht_cap);
} else {
wl1271_error("invalid ht_mode '%s'", ht_mode_param);
ret = -EINVAL;
goto out_free;
}

if (!checksum_param) {
wl18xx_ops.set_rx_csum = NULL;
wl18xx_ops.init_vif = NULL;
Expand Down Expand Up @@ -1410,7 +1420,7 @@ static void __exit wl18xx_exit(void)
module_exit(wl18xx_exit);

module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR);
MODULE_PARM_DESC(ht_mode, "Force HT mode: wide (default), mimo or siso20");
MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20");

module_param_named(board_type, board_type_param, charp, S_IRUSR);
MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or "
Expand Down Expand Up @@ -1458,6 +1468,11 @@ module_param_named(pwr_limit_reference_11_abg,
MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 "
"(default is 0xc8)");

module_param_named(num_rx_desc,
num_rx_desc_param, int, S_IRUSR);
MODULE_PARM_DESC(num_rx_desc_param,
"Number of Rx descriptors: u8 (default is 32)");

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
MODULE_FIRMWARE(WL18XX_FW_NAME);
8 changes: 7 additions & 1 deletion drivers/net/wireless/ti/wlcore/acx.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
struct acx_sleep_auth *auth;
int ret;

wl1271_debug(DEBUG_ACX, "acx sleep auth");
wl1271_debug(DEBUG_ACX, "acx sleep auth %d", sleep_auth);

auth = kzalloc(sizeof(*auth), GFP_KERNEL);
if (!auth) {
Expand All @@ -81,7 +81,13 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
auth->sleep_auth = sleep_auth;

ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
if (ret < 0) {
wl1271_error("could not configure sleep_auth to %d: %d",
sleep_auth, ret);
goto out;
}

wl->sleep_auth = sleep_auth;
out:
kfree(auth);
return ret;
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/wireless/ti/wlcore/acx.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ enum wl1271_psm_mode {

/* Extreme low power */
WL1271_PSM_ELP = 2,

WL1271_PSM_MAX = WL1271_PSM_ELP,

/* illegal out of band value of PSM mode */
WL1271_PSM_ILLEGAL = 0xff
};

struct acx_sleep_auth {
Expand Down
21 changes: 21 additions & 0 deletions drivers/net/wireless/ti/wlcore/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -652,4 +652,25 @@ struct wl12xx_cmd_stop_channel_switch {
struct wl1271_cmd_header header;
} __packed;

/* Used to check radio status after calibration */
#define MAX_TLV_LENGTH 500
#define TEST_CMD_P2G_CAL 2 /* TX BiP */

struct wl1271_cmd_cal_p2g {
struct wl1271_cmd_header header;

struct wl1271_cmd_test_header test;

__le32 ver;
__le16 len;
u8 buf[MAX_TLV_LENGTH];
u8 type;
u8 padding;

__le16 radio_status;

u8 sub_band_mask;
u8 padding2;
} __packed;

#endif /* __WL1271_CMD_H__ */
8 changes: 7 additions & 1 deletion drivers/net/wireless/ti/wlcore/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,12 @@ struct conf_conn_settings {
* Range: u16
*/
u8 max_listen_interval;

/*
* Default sleep authorization for a new STA interface. This determines
* whether we can go to ELP.
*/
u8 sta_sleep_auth;
} __packed;

enum {
Expand Down Expand Up @@ -1276,7 +1282,7 @@ struct conf_hangover_settings {
* version, the two LSB are the lower driver's private conf
* version.
*/
#define WLCORE_CONF_VERSION (0x0001 << 16)
#define WLCORE_CONF_VERSION (0x0002 << 16)
#define WLCORE_CONF_MASK 0xffff0000
#define WLCORE_CONF_SIZE (sizeof(struct wlcore_conf_header) + \
sizeof(struct wlcore_conf))
Expand Down
Loading

0 comments on commit d217249

Please sign in to comment.