Staging/IIO fixes for 5.6-rc7
Here are a number of small staging and IIO driver fixes for 5.6-rc7 Nothing major here, just resolutions for some reported problems: - iio bugfixes for a number of different drivers - greybus loopback_test fixes - wfx driver fixes All of these have been in linux-next with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCXnTRmQ8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ykkCwCfS8zLibsZtuv655yAK17C/6YghPQAoJ3iSew+ EkzEDWQ9j2NLE+lpWtKQ =fZ2X -----END PGP SIGNATURE----- Merge tag 'staging-5.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging Pull staging/IIO fixes from Greg KH: "Here are a number of small staging and IIO driver fixes for 5.6-rc7 Nothing major here, just resolutions for some reported problems: - iio bugfixes for a number of different drivers - greybus loopback_test fixes - wfx driver fixes All of these have been in linux-next with no reported issues" * tag 'staging-5.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: staging: rtl8188eu: Add device id for MERCUSYS MW150US v2 staging: greybus: loopback_test: fix potential path truncations staging: greybus: loopback_test: fix potential path truncation staging: greybus: loopback_test: fix poll-mask build breakage staging: wfx: fix RCU usage between hif_join() and ieee80211_bss_get_ie() staging: wfx: fix RCU usage in wfx_join_finalize() staging: wfx: make warning about pending frame less scary staging: wfx: fix lines ending with a comma instead of a semicolon staging: wfx: fix warning about freeing in-use mutex during device unregister staging/speakup: fix get_word non-space look-ahead iio: ping: set pa_laser_ping_cfg in of_ping_match iio: chemical: sps30: fix missing triggered buffer dependency iio: st_sensors: remap SMO8840 to LIS2DH12 iio: light: vcnl4000: update sampling periods for vcnl4040 iio: light: vcnl4000: update sampling periods for vcnl4200 iio: accel: adxl372: Set iio_chan BE iio: magnetometer: ak8974: Fix negative raw values in sysfs iio: trigger: stm32-timer: disable master mode when stopping iio: adc: stm32-dfsdm: fix sleep in atomic context iio: adc: at91-sama5d2_adc: fix differential channels in triggered mode
This commit is contained in:
commit
3bd14829d3
@ -237,6 +237,7 @@ static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = {
|
|||||||
.realbits = 12, \
|
.realbits = 12, \
|
||||||
.storagebits = 16, \
|
.storagebits = 16, \
|
||||||
.shift = 4, \
|
.shift = 4, \
|
||||||
|
.endianness = IIO_BE, \
|
||||||
}, \
|
}, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ MODULE_DEVICE_TABLE(of, st_accel_of_match);
|
|||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
static const struct acpi_device_id st_accel_acpi_match[] = {
|
static const struct acpi_device_id st_accel_acpi_match[] = {
|
||||||
{"SMO8840", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME},
|
{"SMO8840", (kernel_ulong_t)LIS2DH12_ACCEL_DEV_NAME},
|
||||||
{"SMO8A90", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME},
|
{"SMO8A90", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME},
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
@ -723,6 +723,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
|||||||
|
|
||||||
for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) {
|
for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) {
|
||||||
struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit);
|
struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit);
|
||||||
|
u32 cor;
|
||||||
|
|
||||||
if (!chan)
|
if (!chan)
|
||||||
continue;
|
continue;
|
||||||
@ -731,6 +732,20 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
|||||||
chan->type == IIO_PRESSURE)
|
chan->type == IIO_PRESSURE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (state) {
|
||||||
|
cor = at91_adc_readl(st, AT91_SAMA5D2_COR);
|
||||||
|
|
||||||
|
if (chan->differential)
|
||||||
|
cor |= (BIT(chan->channel) |
|
||||||
|
BIT(chan->channel2)) <<
|
||||||
|
AT91_SAMA5D2_COR_DIFF_OFFSET;
|
||||||
|
else
|
||||||
|
cor &= ~(BIT(chan->channel) <<
|
||||||
|
AT91_SAMA5D2_COR_DIFF_OFFSET);
|
||||||
|
|
||||||
|
at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
|
||||||
|
}
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
at91_adc_writel(st, AT91_SAMA5D2_CHER,
|
at91_adc_writel(st, AT91_SAMA5D2_CHER,
|
||||||
BIT(chan->channel));
|
BIT(chan->channel));
|
||||||
|
@ -842,31 +842,6 @@ static inline void stm32_dfsdm_process_data(struct stm32_dfsdm_adc *adc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t stm32_dfsdm_adc_trigger_handler(int irq, void *p)
|
|
||||||
{
|
|
||||||
struct iio_poll_func *pf = p;
|
|
||||||
struct iio_dev *indio_dev = pf->indio_dev;
|
|
||||||
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
|
|
||||||
int available = stm32_dfsdm_adc_dma_residue(adc);
|
|
||||||
|
|
||||||
while (available >= indio_dev->scan_bytes) {
|
|
||||||
s32 *buffer = (s32 *)&adc->rx_buf[adc->bufi];
|
|
||||||
|
|
||||||
stm32_dfsdm_process_data(adc, buffer);
|
|
||||||
|
|
||||||
iio_push_to_buffers_with_timestamp(indio_dev, buffer,
|
|
||||||
pf->timestamp);
|
|
||||||
available -= indio_dev->scan_bytes;
|
|
||||||
adc->bufi += indio_dev->scan_bytes;
|
|
||||||
if (adc->bufi >= adc->buf_sz)
|
|
||||||
adc->bufi = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stm32_dfsdm_dma_buffer_done(void *data)
|
static void stm32_dfsdm_dma_buffer_done(void *data)
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = data;
|
struct iio_dev *indio_dev = data;
|
||||||
@ -874,11 +849,6 @@ static void stm32_dfsdm_dma_buffer_done(void *data)
|
|||||||
int available = stm32_dfsdm_adc_dma_residue(adc);
|
int available = stm32_dfsdm_adc_dma_residue(adc);
|
||||||
size_t old_pos;
|
size_t old_pos;
|
||||||
|
|
||||||
if (indio_dev->currentmode & INDIO_BUFFER_TRIGGERED) {
|
|
||||||
iio_trigger_poll_chained(indio_dev->trig);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: In Kernel interface does not support cyclic DMA buffer,and
|
* FIXME: In Kernel interface does not support cyclic DMA buffer,and
|
||||||
* offers only an interface to push data samples per samples.
|
* offers only an interface to push data samples per samples.
|
||||||
@ -906,7 +876,15 @@ static void stm32_dfsdm_dma_buffer_done(void *data)
|
|||||||
adc->bufi = 0;
|
adc->bufi = 0;
|
||||||
old_pos = 0;
|
old_pos = 0;
|
||||||
}
|
}
|
||||||
/* regular iio buffer without trigger */
|
/*
|
||||||
|
* In DMA mode the trigger services of IIO are not used
|
||||||
|
* (e.g. no call to iio_trigger_poll).
|
||||||
|
* Calling irq handler associated to the hardware trigger is not
|
||||||
|
* relevant as the conversions have already been done. Data
|
||||||
|
* transfers are performed directly in DMA callback instead.
|
||||||
|
* This implementation avoids to call trigger irq handler that
|
||||||
|
* may sleep, in an atomic context (DMA irq handler context).
|
||||||
|
*/
|
||||||
if (adc->dev_data->type == DFSDM_IIO)
|
if (adc->dev_data->type == DFSDM_IIO)
|
||||||
iio_push_to_buffers(indio_dev, buffer);
|
iio_push_to_buffers(indio_dev, buffer);
|
||||||
}
|
}
|
||||||
@ -1536,8 +1514,7 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = iio_triggered_buffer_setup(indio_dev,
|
ret = iio_triggered_buffer_setup(indio_dev,
|
||||||
&iio_pollfunc_store_time,
|
&iio_pollfunc_store_time, NULL,
|
||||||
&stm32_dfsdm_adc_trigger_handler,
|
|
||||||
&stm32_dfsdm_buffer_setup_ops);
|
&stm32_dfsdm_buffer_setup_ops);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
stm32_dfsdm_dma_release(indio_dev);
|
stm32_dfsdm_dma_release(indio_dev);
|
||||||
|
@ -91,6 +91,8 @@ config SPS30
|
|||||||
tristate "SPS30 particulate matter sensor"
|
tristate "SPS30 particulate matter sensor"
|
||||||
depends on I2C
|
depends on I2C
|
||||||
select CRC8
|
select CRC8
|
||||||
|
select IIO_BUFFER
|
||||||
|
select IIO_TRIGGERED_BUFFER
|
||||||
help
|
help
|
||||||
Say Y here to build support for the Sensirion SPS30 particulate
|
Say Y here to build support for the Sensirion SPS30 particulate
|
||||||
matter sensor.
|
matter sensor.
|
||||||
|
@ -167,16 +167,17 @@ static int vcnl4200_init(struct vcnl4000_data *data)
|
|||||||
data->vcnl4200_ps.reg = VCNL4200_PS_DATA;
|
data->vcnl4200_ps.reg = VCNL4200_PS_DATA;
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case VCNL4200_PROD_ID:
|
case VCNL4200_PROD_ID:
|
||||||
/* Integration time is 50ms, but the experiments */
|
/* Default wait time is 50ms, add 20% tolerance. */
|
||||||
/* show 54ms in total. */
|
data->vcnl4200_al.sampling_rate = ktime_set(0, 60000 * 1000);
|
||||||
data->vcnl4200_al.sampling_rate = ktime_set(0, 54000 * 1000);
|
/* Default wait time is 4.8ms, add 20% tolerance. */
|
||||||
data->vcnl4200_ps.sampling_rate = ktime_set(0, 4200 * 1000);
|
data->vcnl4200_ps.sampling_rate = ktime_set(0, 5760 * 1000);
|
||||||
data->al_scale = 24000;
|
data->al_scale = 24000;
|
||||||
break;
|
break;
|
||||||
case VCNL4040_PROD_ID:
|
case VCNL4040_PROD_ID:
|
||||||
/* Integration time is 80ms, add 10ms. */
|
/* Default wait time is 80ms, add 20% tolerance. */
|
||||||
data->vcnl4200_al.sampling_rate = ktime_set(0, 100000 * 1000);
|
data->vcnl4200_al.sampling_rate = ktime_set(0, 96000 * 1000);
|
||||||
data->vcnl4200_ps.sampling_rate = ktime_set(0, 100000 * 1000);
|
/* Default wait time is 5ms, add 20% tolerance. */
|
||||||
|
data->vcnl4200_ps.sampling_rate = ktime_set(0, 6000 * 1000);
|
||||||
data->al_scale = 120000;
|
data->al_scale = 120000;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -564,7 +564,7 @@ static int ak8974_read_raw(struct iio_dev *indio_dev,
|
|||||||
* We read all axes and discard all but one, for optimized
|
* We read all axes and discard all but one, for optimized
|
||||||
* reading, use the triggered buffer.
|
* reading, use the triggered buffer.
|
||||||
*/
|
*/
|
||||||
*val = le16_to_cpu(hw_values[chan->address]);
|
*val = (s16)le16_to_cpu(hw_values[chan->address]);
|
||||||
|
|
||||||
ret = IIO_VAL_INT;
|
ret = IIO_VAL_INT;
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ static const struct iio_chan_spec ping_chan_spec[] = {
|
|||||||
|
|
||||||
static const struct of_device_id of_ping_match[] = {
|
static const struct of_device_id of_ping_match[] = {
|
||||||
{ .compatible = "parallax,ping", .data = &pa_ping_cfg},
|
{ .compatible = "parallax,ping", .data = &pa_ping_cfg},
|
||||||
{ .compatible = "parallax,laserping", .data = &pa_ping_cfg},
|
{ .compatible = "parallax,laserping", .data = &pa_laser_ping_cfg},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,7 +161,8 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stm32_timer_stop(struct stm32_timer_trigger *priv)
|
static void stm32_timer_stop(struct stm32_timer_trigger *priv,
|
||||||
|
struct iio_trigger *trig)
|
||||||
{
|
{
|
||||||
u32 ccer, cr1;
|
u32 ccer, cr1;
|
||||||
|
|
||||||
@ -179,6 +180,12 @@ static void stm32_timer_stop(struct stm32_timer_trigger *priv)
|
|||||||
regmap_write(priv->regmap, TIM_PSC, 0);
|
regmap_write(priv->regmap, TIM_PSC, 0);
|
||||||
regmap_write(priv->regmap, TIM_ARR, 0);
|
regmap_write(priv->regmap, TIM_ARR, 0);
|
||||||
|
|
||||||
|
/* Force disable master mode */
|
||||||
|
if (stm32_timer_is_trgo2_name(trig->name))
|
||||||
|
regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, 0);
|
||||||
|
else
|
||||||
|
regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0);
|
||||||
|
|
||||||
/* Make sure that registers are updated */
|
/* Make sure that registers are updated */
|
||||||
regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
|
regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
|
||||||
}
|
}
|
||||||
@ -197,7 +204,7 @@ static ssize_t stm32_tt_store_frequency(struct device *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (freq == 0) {
|
if (freq == 0) {
|
||||||
stm32_timer_stop(priv);
|
stm32_timer_stop(priv, trig);
|
||||||
} else {
|
} else {
|
||||||
ret = stm32_timer_start(priv, trig, freq);
|
ret = stm32_timer_start(priv, trig, freq);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#define MAX_NUM_DEVICES 10
|
#define MAX_NUM_DEVICES 10
|
||||||
|
#define MAX_SYSFS_PREFIX 0x80
|
||||||
#define MAX_SYSFS_PATH 0x200
|
#define MAX_SYSFS_PATH 0x200
|
||||||
#define CSV_MAX_LINE 0x1000
|
#define CSV_MAX_LINE 0x1000
|
||||||
#define SYSFS_MAX_INT 0x20
|
#define SYSFS_MAX_INT 0x20
|
||||||
@ -67,7 +68,7 @@ struct loopback_results {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct loopback_device {
|
struct loopback_device {
|
||||||
char name[MAX_SYSFS_PATH];
|
char name[MAX_STR_LEN];
|
||||||
char sysfs_entry[MAX_SYSFS_PATH];
|
char sysfs_entry[MAX_SYSFS_PATH];
|
||||||
char debugfs_entry[MAX_SYSFS_PATH];
|
char debugfs_entry[MAX_SYSFS_PATH];
|
||||||
struct loopback_results results;
|
struct loopback_results results;
|
||||||
@ -93,8 +94,8 @@ struct loopback_test {
|
|||||||
int stop_all;
|
int stop_all;
|
||||||
int poll_count;
|
int poll_count;
|
||||||
char test_name[MAX_STR_LEN];
|
char test_name[MAX_STR_LEN];
|
||||||
char sysfs_prefix[MAX_SYSFS_PATH];
|
char sysfs_prefix[MAX_SYSFS_PREFIX];
|
||||||
char debugfs_prefix[MAX_SYSFS_PATH];
|
char debugfs_prefix[MAX_SYSFS_PREFIX];
|
||||||
struct timespec poll_timeout;
|
struct timespec poll_timeout;
|
||||||
struct loopback_device devices[MAX_NUM_DEVICES];
|
struct loopback_device devices[MAX_NUM_DEVICES];
|
||||||
struct loopback_results aggregate_results;
|
struct loopback_results aggregate_results;
|
||||||
@ -637,7 +638,7 @@ baddir:
|
|||||||
static int open_poll_files(struct loopback_test *t)
|
static int open_poll_files(struct loopback_test *t)
|
||||||
{
|
{
|
||||||
struct loopback_device *dev;
|
struct loopback_device *dev;
|
||||||
char buf[MAX_STR_LEN];
|
char buf[MAX_SYSFS_PATH + MAX_STR_LEN];
|
||||||
char dummy;
|
char dummy;
|
||||||
int fds_idx = 0;
|
int fds_idx = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -655,7 +656,7 @@ static int open_poll_files(struct loopback_test *t)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
read(t->fds[fds_idx].fd, &dummy, 1);
|
read(t->fds[fds_idx].fd, &dummy, 1);
|
||||||
t->fds[fds_idx].events = EPOLLERR|EPOLLPRI;
|
t->fds[fds_idx].events = POLLERR | POLLPRI;
|
||||||
t->fds[fds_idx].revents = 0;
|
t->fds[fds_idx].revents = 0;
|
||||||
fds_idx++;
|
fds_idx++;
|
||||||
}
|
}
|
||||||
@ -748,7 +749,7 @@ static int wait_for_complete(struct loopback_test *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < t->poll_count; i++) {
|
for (i = 0; i < t->poll_count; i++) {
|
||||||
if (t->fds[i].revents & EPOLLPRI) {
|
if (t->fds[i].revents & POLLPRI) {
|
||||||
/* Dummy read to clear the event */
|
/* Dummy read to clear the event */
|
||||||
read(t->fds[i].fd, &dummy, 1);
|
read(t->fds[i].fd, &dummy, 1);
|
||||||
number_of_events++;
|
number_of_events++;
|
||||||
@ -907,10 +908,10 @@ int main(int argc, char *argv[])
|
|||||||
t.iteration_max = atoi(optarg);
|
t.iteration_max = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", optarg);
|
snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg);
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", optarg);
|
snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
t.mask = atol(optarg);
|
t.mask = atol(optarg);
|
||||||
@ -961,10 +962,10 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(t.sysfs_prefix, ""))
|
if (!strcmp(t.sysfs_prefix, ""))
|
||||||
snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", sysfs_prefix);
|
snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", sysfs_prefix);
|
||||||
|
|
||||||
if (!strcmp(t.debugfs_prefix, ""))
|
if (!strcmp(t.debugfs_prefix, ""))
|
||||||
snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", debugfs_prefix);
|
snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", debugfs_prefix);
|
||||||
|
|
||||||
ret = find_loopback_devices(&t);
|
ret = find_loopback_devices(&t);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -38,6 +38,7 @@ static const struct usb_device_id rtw_usb_id_tbl[] = {
|
|||||||
{USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */
|
{USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */
|
||||||
{USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
|
{USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
|
||||||
{USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */
|
{USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */
|
||||||
|
{USB_DEVICE(0x2C4E, 0x0102)}, /* MERCUSYS MW150US v2 */
|
||||||
{USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */
|
{USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */
|
||||||
{USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */
|
{USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */
|
||||||
{} /* Terminating entry */
|
{} /* Terminating entry */
|
||||||
|
@ -561,7 +561,7 @@ static u_long get_word(struct vc_data *vc)
|
|||||||
return 0;
|
return 0;
|
||||||
} else if (tmpx < vc->vc_cols - 2 &&
|
} else if (tmpx < vc->vc_cols - 2 &&
|
||||||
(ch == SPACE || ch == 0 || (ch < 0x100 && IS_WDLM(ch))) &&
|
(ch == SPACE || ch == 0 || (ch < 0x100 && IS_WDLM(ch))) &&
|
||||||
get_char(vc, (u_short *)&tmp_pos + 1, &temp) > SPACE) {
|
get_char(vc, (u_short *)tmp_pos + 1, &temp) > SPACE) {
|
||||||
tmp_pos += 2;
|
tmp_pos += 2;
|
||||||
tmpx++;
|
tmpx++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -140,6 +140,7 @@ int hif_shutdown(struct wfx_dev *wdev)
|
|||||||
else
|
else
|
||||||
control_reg_write(wdev, 0);
|
control_reg_write(wdev, 0);
|
||||||
mutex_unlock(&wdev->hif_cmd.lock);
|
mutex_unlock(&wdev->hif_cmd.lock);
|
||||||
|
mutex_unlock(&wdev->hif_cmd.key_renew_lock);
|
||||||
kfree(hif);
|
kfree(hif);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -289,7 +290,7 @@ int hif_stop_scan(struct wfx_vif *wvif)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
|
int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
|
||||||
const struct ieee80211_channel *channel, const u8 *ssidie)
|
struct ieee80211_channel *channel, const u8 *ssid, int ssidlen)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct hif_msg *hif;
|
struct hif_msg *hif;
|
||||||
@ -307,9 +308,9 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
|
|||||||
body->basic_rate_set =
|
body->basic_rate_set =
|
||||||
cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates));
|
cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates));
|
||||||
memcpy(body->bssid, conf->bssid, sizeof(body->bssid));
|
memcpy(body->bssid, conf->bssid, sizeof(body->bssid));
|
||||||
if (!conf->ibss_joined && ssidie) {
|
if (!conf->ibss_joined && ssid) {
|
||||||
body->ssid_length = cpu_to_le32(ssidie[1]);
|
body->ssid_length = cpu_to_le32(ssidlen);
|
||||||
memcpy(body->ssid, &ssidie[2], ssidie[1]);
|
memcpy(body->ssid, ssid, ssidlen);
|
||||||
}
|
}
|
||||||
wfx_fill_header(hif, wvif->id, HIF_REQ_ID_JOIN, sizeof(*body));
|
wfx_fill_header(hif, wvif->id, HIF_REQ_ID_JOIN, sizeof(*body));
|
||||||
ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
|
ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
|
||||||
@ -427,9 +428,9 @@ int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
|
|||||||
struct hif_msg *hif;
|
struct hif_msg *hif;
|
||||||
struct hif_req_start *body = wfx_alloc_hif(sizeof(*body), &hif);
|
struct hif_req_start *body = wfx_alloc_hif(sizeof(*body), &hif);
|
||||||
|
|
||||||
body->dtim_period = conf->dtim_period,
|
body->dtim_period = conf->dtim_period;
|
||||||
body->short_preamble = conf->use_short_preamble,
|
body->short_preamble = conf->use_short_preamble;
|
||||||
body->channel_number = cpu_to_le16(channel->hw_value),
|
body->channel_number = cpu_to_le16(channel->hw_value);
|
||||||
body->beacon_interval = cpu_to_le32(conf->beacon_int);
|
body->beacon_interval = cpu_to_le32(conf->beacon_int);
|
||||||
body->basic_rate_set =
|
body->basic_rate_set =
|
||||||
cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates));
|
cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates));
|
||||||
|
@ -46,7 +46,7 @@ int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req80211,
|
|||||||
int chan_start, int chan_num);
|
int chan_start, int chan_num);
|
||||||
int hif_stop_scan(struct wfx_vif *wvif);
|
int hif_stop_scan(struct wfx_vif *wvif);
|
||||||
int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
|
int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
|
||||||
const struct ieee80211_channel *channel, const u8 *ssidie);
|
struct ieee80211_channel *channel, const u8 *ssid, int ssidlen);
|
||||||
int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout);
|
int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout);
|
||||||
int hif_set_bss_params(struct wfx_vif *wvif,
|
int hif_set_bss_params(struct wfx_vif *wvif,
|
||||||
const struct hif_req_set_bss_params *arg);
|
const struct hif_req_set_bss_params *arg);
|
||||||
|
@ -191,10 +191,10 @@ static inline int hif_set_block_ack_policy(struct wfx_vif *wvif,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int hif_set_association_mode(struct wfx_vif *wvif,
|
static inline int hif_set_association_mode(struct wfx_vif *wvif,
|
||||||
struct ieee80211_bss_conf *info,
|
struct ieee80211_bss_conf *info)
|
||||||
struct ieee80211_sta_ht_cap *ht_cap)
|
|
||||||
{
|
{
|
||||||
int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates);
|
int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates);
|
||||||
|
struct ieee80211_sta *sta = NULL;
|
||||||
struct hif_mib_set_association_mode val = {
|
struct hif_mib_set_association_mode val = {
|
||||||
.preambtype_use = 1,
|
.preambtype_use = 1,
|
||||||
.mode = 1,
|
.mode = 1,
|
||||||
@ -204,12 +204,17 @@ static inline int hif_set_association_mode(struct wfx_vif *wvif,
|
|||||||
.basic_rate_set = cpu_to_le32(basic_rates)
|
.basic_rate_set = cpu_to_le32(basic_rates)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rcu_read_lock(); // protect sta
|
||||||
|
if (info->bssid && !info->ibss_joined)
|
||||||
|
sta = ieee80211_find_sta(wvif->vif, info->bssid);
|
||||||
|
|
||||||
// FIXME: it is strange to not retrieve all information from bss_info
|
// FIXME: it is strange to not retrieve all information from bss_info
|
||||||
if (ht_cap && ht_cap->ht_supported) {
|
if (sta && sta->ht_cap.ht_supported) {
|
||||||
val.mpdu_start_spacing = ht_cap->ampdu_density;
|
val.mpdu_start_spacing = sta->ht_cap.ampdu_density;
|
||||||
if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
|
if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
|
||||||
val.greenfield = !!(ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD);
|
val.greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
return hif_write_mib(wvif->wdev, wvif->id,
|
return hif_write_mib(wvif->wdev, wvif->id,
|
||||||
HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val));
|
HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val));
|
||||||
|
@ -491,9 +491,11 @@ static void wfx_set_mfp(struct wfx_vif *wvif,
|
|||||||
static void wfx_do_join(struct wfx_vif *wvif)
|
static void wfx_do_join(struct wfx_vif *wvif)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
const u8 *ssidie;
|
|
||||||
struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
|
struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
|
||||||
struct cfg80211_bss *bss = NULL;
|
struct cfg80211_bss *bss = NULL;
|
||||||
|
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||||
|
const u8 *ssidie = NULL;
|
||||||
|
int ssidlen = 0;
|
||||||
|
|
||||||
wfx_tx_lock_flush(wvif->wdev);
|
wfx_tx_lock_flush(wvif->wdev);
|
||||||
|
|
||||||
@ -514,11 +516,14 @@ static void wfx_do_join(struct wfx_vif *wvif)
|
|||||||
if (!wvif->beacon_int)
|
if (!wvif->beacon_int)
|
||||||
wvif->beacon_int = 1;
|
wvif->beacon_int = 1;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock(); // protect ssidie
|
||||||
if (!conf->ibss_joined)
|
if (!conf->ibss_joined)
|
||||||
ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
|
ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
|
||||||
else
|
if (ssidie) {
|
||||||
ssidie = NULL;
|
ssidlen = ssidie[1];
|
||||||
|
memcpy(ssid, &ssidie[2], ssidie[1]);
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
wfx_tx_flush(wvif->wdev);
|
wfx_tx_flush(wvif->wdev);
|
||||||
|
|
||||||
@ -527,10 +532,8 @@ static void wfx_do_join(struct wfx_vif *wvif)
|
|||||||
|
|
||||||
wfx_set_mfp(wvif, bss);
|
wfx_set_mfp(wvif, bss);
|
||||||
|
|
||||||
/* Perform actual join */
|
|
||||||
wvif->wdev->tx_burst_idx = -1;
|
wvif->wdev->tx_burst_idx = -1;
|
||||||
ret = hif_join(wvif, conf, wvif->channel, ssidie);
|
ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen);
|
||||||
rcu_read_unlock();
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ieee80211_connection_loss(wvif->vif);
|
ieee80211_connection_loss(wvif->vif);
|
||||||
wvif->join_complete_status = -1;
|
wvif->join_complete_status = -1;
|
||||||
@ -605,7 +608,9 @@ int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(sta_priv->buffered); i++)
|
for (i = 0; i < ARRAY_SIZE(sta_priv->buffered); i++)
|
||||||
WARN(sta_priv->buffered[i], "release station while Tx is in progress");
|
if (sta_priv->buffered[i])
|
||||||
|
dev_warn(wvif->wdev->dev, "release station while %d pending frame on queue %d",
|
||||||
|
sta_priv->buffered[i], i);
|
||||||
// FIXME: see note in wfx_sta_add()
|
// FIXME: see note in wfx_sta_add()
|
||||||
if (vif->type == NL80211_IFTYPE_STATION)
|
if (vif->type == NL80211_IFTYPE_STATION)
|
||||||
return 0;
|
return 0;
|
||||||
@ -689,6 +694,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
|
|||||||
wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]);
|
wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]);
|
||||||
else
|
else
|
||||||
wvif->bss_params.operational_rate_set = -1;
|
wvif->bss_params.operational_rate_set = -1;
|
||||||
|
rcu_read_unlock();
|
||||||
if (sta &&
|
if (sta &&
|
||||||
info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
|
info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
|
||||||
hif_dual_cts_protection(wvif, true);
|
hif_dual_cts_protection(wvif, true);
|
||||||
@ -701,8 +707,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
|
|||||||
wvif->bss_params.beacon_lost_count = 20;
|
wvif->bss_params.beacon_lost_count = 20;
|
||||||
wvif->bss_params.aid = info->aid;
|
wvif->bss_params.aid = info->aid;
|
||||||
|
|
||||||
hif_set_association_mode(wvif, info, sta ? &sta->ht_cap : NULL);
|
hif_set_association_mode(wvif, info);
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
if (!info->ibss_joined) {
|
if (!info->ibss_joined) {
|
||||||
hif_keep_alive_period(wvif, 30 /* sec */);
|
hif_keep_alive_period(wvif, 30 /* sec */);
|
||||||
|
Loading…
Reference in New Issue
Block a user