Online Linux Driver Verification Service (alpha)

Rule violation
Driver: test-0032-wl12xx-unsafe.tar.bz2
Kernel: linux-2.6.32.12
Verification architecture: x86_64
Rule: Mutex lock/unlock
Error trace
Function bodies
Blocks
  • Others...
    Entry point
    Entry point body
    Function calls
    Initialization function calls
    Function without body calls
    Function stack overflows
    Initialization function bodies
    Returns
    Return values
    Asserts
    Assert conditions
    Identation
    Driver environment initialization
    Driver environment function calls
    Driver environment function bodies
    Model asserts
    Model state changes
    Model returns
    Model function calls
    Model function bodies
    Model function function calls
    Model function function bodies
    Model others
    Function bodies without model function calls
Hide Entry point Hide Entry point body Hide Function calls Hide Initialization function calls Hide Function without body calls Hide Function stack overflows Hide Function bodies Hide Initialization function bodies Hide Blocks Hide Returns Hide Return values Hide Asserts Hide Assert conditions Hide Identation Hide Driver environment initialization Hide Driver environment function calls Hide Driver environment function bodies Hide Model asserts Hide Model state changes Hide Model returns Hide Model function calls Hide Model function bodies Hide Model function function calls Hide Model function function bodies Hide Model others Hide Function bodies without model function calls
-entry_point();
{
-__BLAST_initialize_/home/ldv/ldv-new/ldv-tools-inst/tmp/run/work/current--X--test-0032-wl12xx-unsafe.tar.bz2_24--X--defaultlinux-2.6.32.12--X--32_7/linux-2.6.32.12/csd_deg_dscv/2/dscv_tempdir/dscv/rcv/32_7/main-ldv_main0_sequence_infinite_withcheck_stateful/preprocess/1-cpp/drivers-test-0032-wl12xx-unsafe-main.c.common.i();
{
669 -bcast_addr[ 0 ] = 255;
bcast_addr[ 1 ] = 255;
bcast_addr[ 2 ] = 255;
bcast_addr[ 3 ] = 255;
bcast_addr[ 4 ] = 255;
bcast_addr[ 5 ] = 255;
wl12xx_rates[ 0 ].flags = 0;
wl12xx_rates[ 0 ].bitrate = 10;
wl12xx_rates[ 0 ].hw_value = 1;
wl12xx_rates[ 0 ].hw_value_short = 1;
wl12xx_rates[ 1 ].flags = 1;
wl12xx_rates[ 1 ].bitrate = 20;
wl12xx_rates[ 1 ].hw_value = 2;
wl12xx_rates[ 1 ].hw_value_short = 2;
wl12xx_rates[ 2 ].flags = 1;
wl12xx_rates[ 2 ].bitrate = 55;
wl12xx_rates[ 2 ].hw_value = 4;
wl12xx_rates[ 2 ].hw_value_short = 4;
wl12xx_rates[ 3 ].flags = 1;
wl12xx_rates[ 3 ].bitrate = 110;
wl12xx_rates[ 3 ].hw_value = 32;
wl12xx_rates[ 3 ].hw_value_short = 32;
wl12xx_rates[ 4 ].flags = 0;
wl12xx_rates[ 4 ].bitrate = 60;
wl12xx_rates[ 4 ].hw_value = 8;
wl12xx_rates[ 4 ].hw_value_short = 8;
wl12xx_rates[ 5 ].flags = 0;
wl12xx_rates[ 5 ].bitrate = 90;
wl12xx_rates[ 5 ].hw_value = 16;
wl12xx_rates[ 5 ].hw_value_short = 16;
wl12xx_rates[ 6 ].flags = 0;
wl12xx_rates[ 6 ].bitrate = 120;
wl12xx_rates[ 6 ].hw_value = 64;
wl12xx_rates[ 6 ].hw_value_short = 64;
wl12xx_rates[ 7 ].flags = 0;
wl12xx_rates[ 7 ].bitrate = 180;
wl12xx_rates[ 7 ].hw_value = 128;
wl12xx_rates[ 7 ].hw_value_short = 128;
wl12xx_rates[ 8 ].flags = 0;
wl12xx_rates[ 8 ].bitrate = 240;
wl12xx_rates[ 8 ].hw_value = 512;
wl12xx_rates[ 8 ].hw_value_short = 512;
wl12xx_rates[ 9 ].flags = 0;
wl12xx_rates[ 9 ].bitrate = 360;
wl12xx_rates[ 9 ].hw_value = 1024;
wl12xx_rates[ 9 ].hw_value_short = 1024;
wl12xx_rates[ 10 ].flags = 0;
wl12xx_rates[ 10 ].bitrate = 480;
wl12xx_rates[ 10 ].hw_value = 2048;
wl12xx_rates[ 10 ].hw_value_short = 2048;
wl12xx_rates[ 11 ].flags = 0;
wl12xx_rates[ 11 ].bitrate = 540;
wl12xx_rates[ 11 ].hw_value = 4096;
wl12xx_rates[ 11 ].hw_value_short = 4096;
wl12xx_channels[ 0 ].band = 0;
wl12xx_channels[ 0 ].center_freq = 2412;
wl12xx_channels[ 0 ].hw_value = 1;
wl12xx_channels[ 0 ].flags = 0;
wl12xx_channels[ 0 ].max_antenna_gain = 0;
wl12xx_channels[ 0 ].max_power = 0;
wl12xx_channels[ 0 ].beacon_found = 0;
wl12xx_channels[ 0 ].orig_flags = 0;
wl12xx_channels[ 0 ].orig_mag = 0;
wl12xx_channels[ 0 ].orig_mpwr = 0;
wl12xx_channels[ 1 ].band = 0;
wl12xx_channels[ 1 ].center_freq = 2417;
wl12xx_channels[ 1 ].hw_value = 2;
wl12xx_channels[ 1 ].flags = 0;
wl12xx_channels[ 1 ].max_antenna_gain = 0;
wl12xx_channels[ 1 ].max_power = 0;
wl12xx_channels[ 1 ].beacon_found = 0;
wl12xx_channels[ 1 ].orig_flags = 0;
wl12xx_channels[ 1 ].orig_mag = 0;
wl12xx_channels[ 1 ].orig_mpwr = 0;
wl12xx_channels[ 2 ].band = 0;
wl12xx_channels[ 2 ].center_freq = 2422;
wl12xx_channels[ 2 ].hw_value = 3;
wl12xx_channels[ 2 ].flags = 0;
wl12xx_channels[ 2 ].max_antenna_gain = 0;
wl12xx_channels[ 2 ].max_power = 0;
wl12xx_channels[ 2 ].beacon_found = 0;
wl12xx_channels[ 2 ].orig_flags = 0;
wl12xx_channels[ 2 ].orig_mag = 0;
wl12xx_channels[ 2 ].orig_mpwr = 0;
wl12xx_channels[ 3 ].band = 0;
wl12xx_channels[ 3 ].center_freq = 2427;
wl12xx_channels[ 3 ].hw_value = 4;
wl12xx_channels[ 3 ].flags = 0;
wl12xx_channels[ 3 ].max_antenna_gain = 0;
wl12xx_channels[ 3 ].max_power = 0;
wl12xx_channels[ 3 ].beacon_found = 0;
wl12xx_channels[ 3 ].orig_flags = 0;
wl12xx_channels[ 3 ].orig_mag = 0;
wl12xx_channels[ 3 ].orig_mpwr = 0;
wl12xx_channels[ 4 ].band = 0;
wl12xx_channels[ 4 ].center_freq = 2432;
wl12xx_channels[ 4 ].hw_value = 5;
wl12xx_channels[ 4 ].flags = 0;
wl12xx_channels[ 4 ].max_antenna_gain = 0;
wl12xx_channels[ 4 ].max_power = 0;
wl12xx_channels[ 4 ].beacon_found = 0;
wl12xx_channels[ 4 ].orig_flags = 0;
wl12xx_channels[ 4 ].orig_mag = 0;
wl12xx_channels[ 4 ].orig_mpwr = 0;
wl12xx_channels[ 5 ].band = 0;
wl12xx_channels[ 5 ].center_freq = 2437;
wl12xx_channels[ 5 ].hw_value = 6;
wl12xx_channels[ 5 ].flags = 0;
wl12xx_channels[ 5 ].max_antenna_gain = 0;
wl12xx_channels[ 5 ].max_power = 0;
wl12xx_channels[ 5 ].beacon_found = 0;
wl12xx_channels[ 5 ].orig_flags = 0;
wl12xx_channels[ 5 ].orig_mag = 0;
wl12xx_channels[ 5 ].orig_mpwr = 0;
wl12xx_channels[ 6 ].band = 0;
wl12xx_channels[ 6 ].center_freq = 2442;
wl12xx_channels[ 6 ].hw_value = 7;
wl12xx_channels[ 6 ].flags = 0;
wl12xx_channels[ 6 ].max_antenna_gain = 0;
wl12xx_channels[ 6 ].max_power = 0;
wl12xx_channels[ 6 ].beacon_found = 0;
wl12xx_channels[ 6 ].orig_flags = 0;
wl12xx_channels[ 6 ].orig_mag = 0;
wl12xx_channels[ 6 ].orig_mpwr = 0;
wl12xx_channels[ 7 ].band = 0;
wl12xx_channels[ 7 ].center_freq = 2447;
wl12xx_channels[ 7 ].hw_value = 8;
wl12xx_channels[ 7 ].flags = 0;
wl12xx_channels[ 7 ].max_antenna_gain = 0;
wl12xx_channels[ 7 ].max_power = 0;
wl12xx_channels[ 7 ].beacon_found = 0;
wl12xx_channels[ 7 ].orig_flags = 0;
wl12xx_channels[ 7 ].orig_mag = 0;
wl12xx_channels[ 7 ].orig_mpwr = 0;
wl12xx_channels[ 8 ].band = 0;
wl12xx_channels[ 8 ].center_freq = 2452;
wl12xx_channels[ 8 ].hw_value = 9;
wl12xx_channels[ 8 ].flags = 0;
wl12xx_channels[ 8 ].max_antenna_gain = 0;
wl12xx_channels[ 8 ].max_power = 0;
wl12xx_channels[ 8 ].beacon_found = 0;
wl12xx_channels[ 8 ].orig_flags = 0;
wl12xx_channels[ 8 ].orig_mag = 0;
wl12xx_channels[ 8 ].orig_mpwr = 0;
wl12xx_channels[ 9 ].band = 0;
wl12xx_channels[ 9 ].center_freq = 2457;
wl12xx_channels[ 9 ].hw_value = 10;
wl12xx_channels[ 9 ].flags = 0;
wl12xx_channels[ 9 ].max_antenna_gain = 0;
wl12xx_channels[ 9 ].max_power = 0;
wl12xx_channels[ 9 ].beacon_found = 0;
wl12xx_channels[ 9 ].orig_flags = 0;
wl12xx_channels[ 9 ].orig_mag = 0;
wl12xx_channels[ 9 ].orig_mpwr = 0;
wl12xx_channels[ 10 ].band = 0;
wl12xx_channels[ 10 ].center_freq = 2462;
wl12xx_channels[ 10 ].hw_value = 11;
wl12xx_channels[ 10 ].flags = 0;
wl12xx_channels[ 10 ].max_antenna_gain = 0;
wl12xx_channels[ 10 ].max_power = 0;
wl12xx_channels[ 10 ].beacon_found = 0;
wl12xx_channels[ 10 ].orig_flags = 0;
wl12xx_channels[ 10 ].orig_mag = 0;
wl12xx_channels[ 10 ].orig_mpwr = 0;
wl12xx_channels[ 11 ].band = 0;
wl12xx_channels[ 11 ].center_freq = 2467;
wl12xx_channels[ 11 ].hw_value = 12;
wl12xx_channels[ 11 ].flags = 0;
wl12xx_channels[ 11 ].max_antenna_gain = 0;
wl12xx_channels[ 11 ].max_power = 0;
wl12xx_channels[ 11 ].beacon_found = 0;
wl12xx_channels[ 11 ].orig_flags = 0;
wl12xx_channels[ 11 ].orig_mag = 0;
wl12xx_channels[ 11 ].orig_mpwr = 0;
wl12xx_channels[ 12 ].band = 0;
wl12xx_channels[ 12 ].center_freq = 2472;
wl12xx_channels[ 12 ].hw_value = 13;
wl12xx_channels[ 12 ].flags = 0;
wl12xx_channels[ 12 ].max_antenna_gain = 0;
wl12xx_channels[ 12 ].max_power = 0;
wl12xx_channels[ 12 ].beacon_found = 0;
wl12xx_channels[ 12 ].orig_flags = 0;
wl12xx_channels[ 12 ].orig_mag = 0;
wl12xx_channels[ 12 ].orig_mpwr = 0;
wl12xx_band_2ghz.channels = wl12xx_channels;
wl12xx_band_2ghz.bitrates = wl12xx_rates;
wl12xx_band_2ghz.band = 0;
wl12xx_band_2ghz.n_channels = 29952 / 2304 + 0;
wl12xx_band_2ghz.n_bitrates = 9216 / 768 + 0;
wl12xx_band_2ghz.ht_cap.cap = 0;
wl12xx_band_2ghz.ht_cap.ht_supported = 0;
wl12xx_band_2ghz.ht_cap.ampdu_factor = 0;
wl12xx_band_2ghz.ht_cap.ampdu_density = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_mask[ 0 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_mask[ 1 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_mask[ 2 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_mask[ 3 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_mask[ 4 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_mask[ 5 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_mask[ 6 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_mask[ 7 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_mask[ 8 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_mask[ 9 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.rx_highest = 0;
wl12xx_band_2ghz.ht_cap.mcs.tx_params = 0;
wl12xx_band_2ghz.ht_cap.mcs.reserved[ 0 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.reserved[ 1 ] = 0;
wl12xx_band_2ghz.ht_cap.mcs.reserved[ 2 ] = 0;
wl12xx_ops.tx = &(wl12xx_op_tx);
wl12xx_ops.start = &(wl12xx_op_start);
wl12xx_ops.stop = &(wl12xx_op_stop);
wl12xx_ops.add_interface = &(wl12xx_op_add_interface);
wl12xx_ops.remove_interface = &(wl12xx_op_remove_interface);
wl12xx_ops.config = &(wl12xx_op_config);
wl12xx_ops.bss_info_changed = &(wl12xx_op_bss_info_changed);
wl12xx_ops.prepare_multicast = 0;
wl12xx_ops.configure_filter = &(wl12xx_op_configure_filter);
wl12xx_ops.set_tim = 0;
wl12xx_ops.set_key = &(wl12xx_op_set_key);
wl12xx_ops.update_tkip_key = 0;
wl12xx_ops.hw_scan = &(wl12xx_op_hw_scan);
wl12xx_ops.sw_scan_start = 0;
wl12xx_ops.sw_scan_complete = 0;
wl12xx_ops.get_stats = 0;
wl12xx_ops.get_tkip_seq = 0;
wl12xx_ops.set_rts_threshold = &(wl12xx_op_set_rts_threshold);
wl12xx_ops.sta_notify = 0;
wl12xx_ops.conf_tx = 0;
wl12xx_ops.get_tx_stats = 0;
wl12xx_ops.get_tsf = 0;
wl12xx_ops.set_tsf = 0;
wl12xx_ops.reset_tsf = 0;
wl12xx_ops.tx_last_beacon = 0;
wl12xx_ops.ampdu_action = 0;
wl12xx_ops.rfkill_poll = 0;
wl12xx_ops.testmode_cmd = 0;
nokia_oui[ 0 ] = 0;
nokia_oui[ 1 ] = 31;
nokia_oui[ 2 ] = 223;
wl12xx_spi_driver.id_table = 0;
wl12xx_spi_driver.probe = &(wl12xx_probe);
wl12xx_spi_driver.remove = &(wl12xx_remove);
wl12xx_spi_driver.shutdown = 0;
wl12xx_spi_driver.suspend = 0;
wl12xx_spi_driver.resume = 0;
wl12xx_spi_driver.driver.name = "wl12xx";
wl12xx_spi_driver.driver.bus = &(spi_bus_type);
wl12xx_spi_driver.driver.owner = &(__this_module);
wl12xx_spi_driver.driver.mod_name = 0;
wl12xx_spi_driver.driver.suppress_bind_attrs = 0;
wl12xx_spi_driver.driver.probe = 0;
wl12xx_spi_driver.driver.remove = 0;
wl12xx_spi_driver.driver.shutdown = 0;
wl12xx_spi_driver.driver.suspend = 0;
wl12xx_spi_driver.driver.resume = 0;
wl12xx_spi_driver.driver.groups = 0;
wl12xx_spi_driver.driver.pm = 0;
wl12xx_spi_driver.driver.p = 0;
__mod_license1357[ 0 ] = 108;
__mod_license1357[ 1 ] = 105;
__mod_license1357[ 2 ] = 99;
__mod_license1357[ 3 ] = 101;
__mod_license1357[ 4 ] = 110;
__mod_license1357[ 5 ] = 115;
__mod_license1357[ 6 ] = 101;
__mod_license1357[ 7 ] = 61;
__mod_license1357[ 8 ] = 71;
__mod_license1357[ 9 ] = 80;
__mod_license1357[ 10 ] = 76;
__mod_license1357[ 11 ] = 0;
__mod_author1359[ 0 ] = 97;
__mod_author1359[ 1 ] = 117;
__mod_author1359[ 2 ] = 116;
__mod_author1359[ 3 ] = 104;
__mod_author1359[ 4 ] = 111;
__mod_author1359[ 5 ] = 114;
__mod_author1359[ 6 ] = 61;
__mod_author1359[ 7 ] = 75;
__mod_author1359[ 8 ] = 97;
__mod_author1359[ 9 ] = 108;
__mod_author1359[ 10 ] = 108;
__mod_author1359[ 11 ] = 101;
__mod_author1359[ 12 ] = 32;
__mod_author1359[ 13 ] = 86;
__mod_author1359[ 14 ] = 97;
__mod_author1359[ 15 ] = 108;
__mod_author1359[ 16 ] = 111;
__mod_author1359[ 17 ] = 32;
__mod_author1359[ 18 ] = 60;
__mod_author1359[ 19 ] = 75;
__mod_author1359[ 20 ] = 97;
__mod_author1359[ 21 ] = 108;
__mod_author1359[ 22 ] = 108;
__mod_author1359[ 23 ] = 101;
__mod_author1359[ 24 ] = 46;
__mod_author1359[ 25 ] = 86;
__mod_author1359[ 26 ] = 97;
__mod_author1359[ 27 ] = 108;
__mod_author1359[ 28 ] = 111;
__mod_author1359[ 29 ] = 64;
__mod_author1359[ 30 ] = 110;
__mod_author1359[ 31 ] = 111;
__mod_author1359[ 32 ] = 107;
__mod_author1359[ 33 ] = 105;
__mod_author1359[ 34 ] = 97;
__mod_author1359[ 35 ] = 46;
__mod_author1359[ 36 ] = 99;
__mod_author1359[ 37 ] = 111;
__mod_author1359[ 38 ] = 109;
__mod_author1359[ 39 ] = 62;
__mod_author1359[ 40 ] = 44;
__mod_author1359[ 41 ] = 32;
__mod_author1359[ 42 ] = 76;
__mod_author1359[ 43 ] = 117;
__mod_author1359[ 44 ] = 99;
__mod_author1359[ 45 ] = 105;
__mod_author1359[ 46 ] = 97;
__mod_author1359[ 47 ] = 110;
__mod_author1359[ 48 ] = 111;
__mod_author1359[ 49 ] = 32;
__mod_author1359[ 50 ] = 67;
__mod_author1359[ 51 ] = 111;
__mod_author1359[ 52 ] = 101;
__mod_author1359[ 53 ] = 108;
__mod_author1359[ 54 ] = 104;
__mod_author1359[ 55 ] = 111;
__mod_author1359[ 56 ] = 32;
__mod_author1359[ 57 ] = 60;
__mod_author1359[ 58 ] = 108;
__mod_author1359[ 59 ] = 117;
__mod_author1359[ 60 ] = 99;
__mod_author1359[ 61 ] = 105;
__mod_author1359[ 62 ] = 97;
__mod_author1359[ 63 ] = 110;
__mod_author1359[ 64 ] = 111;
__mod_author1359[ 65 ] = 46;
__mod_author1359[ 66 ] = 99;
__mod_author1359[ 67 ] = 111;
__mod_author1359[ 68 ] = 101;
__mod_author1359[ 69 ] = 108;
__mod_author1359[ 70 ] = 104;
__mod_author1359[ 71 ] = 111;
__mod_author1359[ 72 ] = 64;
__mod_author1359[ 73 ] = 110;
__mod_author1359[ 74 ] = 111;
__mod_author1359[ 75 ] = 107;
__mod_author1359[ 76 ] = 105;
__mod_author1359[ 77 ] = 97;
__mod_author1359[ 78 ] = 46;
__mod_author1359[ 79 ] = 99;
__mod_author1359[ 80 ] = 111;
__mod_author1359[ 81 ] = 109;
__mod_author1359[ 82 ] = 62;
__mod_author1359[ 83 ] = 0;
ldv_mutex_TEMPLATE = 1;
return 0;
}
1592 LDV_IN_INTERRUPT = 1;
1601 -ldv_initialize_FOREACH();
{
-ldv_initialize_mutex();
{
2162 ldv_mutex_mutex = 1;
return 0;
}
return 0;
}
1615 -tmp = wl12xx_init();
{
1337 ret = spi_register_driver(&(wl12xx_spi_driver)) { /* The function body is undefined. */ };
1338 assert(ret >= 0);
1344 return ret;
}
1615 assert(tmp == 0);
1619 ldv_s_wl12xx_spi_driver_spi_driver = 0;
1624 tmp___1 = nondet_int() { /* The function body is undefined. */ };
1624 assert(tmp___1 != 0);
1628 tmp___0 = nondet_int() { /* The function body is undefined. */ };
1630 assert(tmp___0 == 0);
1638 -wl12xx_op_start(var_group1 /* hw */);
{
324 -wl = *(hw).priv;
ret = 0;
329 -mutex_lock_mutex(&(wl)->mutex /* lock */);
{
2111 assert(ldv_mutex_mutex == 1);
2113 ldv_mutex_mutex = 2;
return 0;
}
331 assert(*(wl).state == 0);
338 -ret = wl12xx_chip_wakeup(wl /* wl */);
{
168 ret = 0;
170 -wl12xx_power_on(wl /* wl */);
{
59 cil_2 = *(wl).set_power;
59 *(cil_2)(1) { /* The function body is undefined. */ };
57 return 0;
}
171 msleep(*(wl).chip.power_on_sleep) { /* The function body is undefined. */ };
172 wl12xx_spi_reset(wl) { /* The function body is undefined. */ };
173 wl12xx_spi_init(wl) { /* The function body is undefined. */ };
177 wl12xx_set_partition(wl, 0, 0, 3145728, 34816) { /* The function body is undefined. */ };
184 -wl12xx_fw_wakeup(wl /* wl */);
{
155 elp_reg = 1;
156 -wl12xx_write32(wl /* wl */, 131068 /* addr */, elp_reg /* val */);
{
106 wl12xx_spi_write(wl, addr, &(val), 256) { /* The function body is undefined. */ };
104 return 0;
}
157 -elp_reg = wl12xx_read32(wl /* wl */, 131068 /* addr */);
{
99 wl12xx_spi_read(wl, addr, &(response), 256) { /* The function body is undefined. */ };
101 return response;
}
159 assert(elp_reg & 2 != 0);
151 return 0;
}
189 *(wl).chip.id = wl12xx_reg_read32(wl, 3167860) { /* The function body is undefined. */ };
194 assert(*(wl).chip.id != 117637377);
205 printk("<3>wl12xx: ERROR unsupported chip id: 0x%x\n", *(wl).chip.id) { /* The function body is undefined. */ };
206 ret = -19;
224 return ret;
}
339 assert(ret < 0);
340 __retres6 = ret;
322 return __retres6;
}
1624 tmp___1 = nondet_int() { /* The function body is undefined. */ };
1624 assert(tmp___1 != 0);
1628 tmp___0 = nondet_int() { /* The function body is undefined. */ };
1630 assert(tmp___0 == 0);
1638 -wl12xx_op_start(var_group1 /* hw */);
{
324 -wl = *(hw).priv;
ret = 0;
329 -mutex_lock_mutex(&(wl)->mutex /* lock */);
{
2111 assert(ldv_mutex_mutex != 1);
2111 -ldv_blast_assert();
{
}
}
}
}
Source code
1 2 /* 3 * This file is part of wl12xx 4 * 5 * Copyright (C) 2008-2009 Nokia Corporation 6 * 7 * Contact: Kalle Valo <kalle.valo@nokia.com> 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * version 2 as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 * 02110-1301 USA 22 * 23 */ 24 25 #include <linux/module.h> 26 #include <linux/interrupt.h> 27 #include <linux/firmware.h> 28 #include <linux/delay.h> 29 #include <linux/irq.h> 30 #include <linux/spi/spi.h> 31 #include <linux/crc32.h> 32 #include <linux/etherdevice.h> 33 #include <linux/spi/wl12xx.h> 34 35 #include "wl12xx.h" 36 #include "wl12xx_80211.h" 37 #include "reg.h" 38 #include "wl1251.h" 39 #include "spi.h" 40 #include "event.h" 41 #include "tx.h" 42 #include "rx.h" 43 #include "ps.h" 44 #include "init.h" 45 #include "debugfs.h" 46 47 static void wl12xx_disable_interrupts(struct wl12xx *wl) 48 { 49 disable_irq(wl->irq); 50 } 51 52 static void wl12xx_power_off(struct wl12xx *wl) 53 { 54 wl->set_power(false); 55 } 56 57 static void wl12xx_power_on(struct wl12xx *wl) 58 { 59 wl->set_power(true); 60 } 61 62 static irqreturn_t wl12xx_irq(int irq, void *cookie) 63 { 64 struct wl12xx *wl; 65 66 wl12xx_debug(DEBUG_IRQ, "IRQ"); 67 68 wl = cookie; 69 70 schedule_work(&wl->irq_work); 71 72 return IRQ_HANDLED; 73 } 74 75 static int wl12xx_fetch_firmware(struct wl12xx *wl) 76 { 77 const struct firmware *fw; 78 int ret; 79 80 ret = request_firmware(&fw, wl->chip.fw_filename, &wl->spi->dev); 81 82 if (ret < 0) { 83 wl12xx_error("could not get firmware: %d", ret); 84 return ret; 85 } 86 87 if (fw->size % 4) { 88 wl12xx_error("firmware size is not multiple of 32 bits: %zu", 89 fw->size); 90 ret = -EILSEQ; 91 goto out; 92 } 93 94 wl->fw_len = fw->size; 95 wl->fw = kmalloc(wl->fw_len, GFP_KERNEL); 96 97 if (!wl->fw) { 98 wl12xx_error("could not allocate memory for the firmware"); 99 ret = -ENOMEM; 100 goto out; 101 } 102 103 memcpy(wl->fw, fw->data, wl->fw_len); 104 105 ret = 0; 106 107 out: 108 release_firmware(fw); 109 110 return ret; 111 } 112 113 static int wl12xx_fetch_nvs(struct wl12xx *wl) 114 { 115 const struct firmware *fw; 116 int ret; 117 118 ret = request_firmware(&fw, wl->chip.nvs_filename, &wl->spi->dev); 119 120 if (ret < 0) { 121 wl12xx_error("could not get nvs file: %d", ret); 122 return ret; 123 } 124 125 if (fw->size % 4) { 126 wl12xx_error("nvs size is not multiple of 32 bits: %zu", 127 fw->size); 128 ret = -EILSEQ; 129 goto out; 130 } 131 132 wl->nvs_len = fw->size; 133 wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL); 134 135 if (!wl->nvs) { 136 wl12xx_error("could not allocate memory for the nvs file"); 137 ret = -ENOMEM; 138 goto out; 139 } 140 141 memcpy(wl->nvs, fw->data, wl->nvs_len); 142 143 ret = 0; 144 145 out: 146 release_firmware(fw); 147 148 return ret; 149 } 150 151 static void wl12xx_fw_wakeup(struct wl12xx *wl) 152 { 153 u32 elp_reg; 154 155 elp_reg = ELPCTRL_WAKE_UP; 156 wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); 157 elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); 158 159 if (!(elp_reg & ELPCTRL_WLAN_READY)) { 160 wl12xx_warning("WLAN not ready"); 161 elp_reg = ELPCTRL_WAKE_UP_WLAN_READY; 162 wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); 163 } 164 } 165 166 static int wl12xx_chip_wakeup(struct wl12xx *wl) 167 { 168 int ret = 0; 169 170 wl12xx_power_on(wl); 171 msleep(wl->chip.power_on_sleep); 172 wl12xx_spi_reset(wl); 173 wl12xx_spi_init(wl); 174 175 /* We don't need a real memory partition here, because we only want 176 * to use the registers at this point. */ 177 wl12xx_set_partition(wl, 178 0x00000000, 179 0x00000000, 180 REGISTERS_BASE, 181 REGISTERS_DOWN_SIZE); 182 183 /* ELP module wake up */ 184 wl12xx_fw_wakeup(wl); 185 186 /* whal_FwCtrl_BootSm() */ 187 188 /* 0. read chip id from CHIP_ID */ 189 wl->chip.id = wl12xx_reg_read32(wl, CHIP_ID_B); 190 191 /* 1. check if chip id is valid */ 192 193 switch (wl->chip.id) { 194 case CHIP_ID_1251_PG12: 195 wl12xx_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)", 196 wl->chip.id); 197 198 wl1251_setup(wl); 199 200 break; 201 case CHIP_ID_1271_PG10: 202 case CHIP_ID_1251_PG10: 203 case CHIP_ID_1251_PG11: 204 default: 205 wl12xx_error("unsupported chip id: 0x%x", wl->chip.id); 206 ret = -ENODEV; 207 goto out; 208 } 209 210 if (wl->fw == NULL) { 211 ret = wl12xx_fetch_firmware(wl); 212 if (ret < 0) 213 goto out; 214 } 215 216 /* No NVS from netlink, try to get it from the filesystem */ 217 if (wl->nvs == NULL) { 218 ret = wl12xx_fetch_nvs(wl); 219 if (ret < 0) 220 goto out; 221 } 222 223 out: 224 return ret; 225 } 226 227 static void wl12xx_filter_work(struct work_struct *work) 228 { 229 struct wl12xx *wl = 230 container_of(work, struct wl12xx, filter_work); 231 int ret; 232 233 mutex_lock(&wl->mutex); 234 235 if (wl->state == WL12XX_STATE_OFF) 236 goto out; 237 238 ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0); 239 if (ret < 0) 240 goto out; 241 242 out: 243 mutex_unlock(&wl->mutex); 244 } 245 246 int wl12xx_plt_start(struct wl12xx *wl) 247 { 248 int ret; 249 250 wl12xx_notice("power up"); 251 252 if (wl->state != WL12XX_STATE_OFF) { 253 wl12xx_error("cannot go into PLT state because not " 254 "in off state: %d", wl->state); 255 return -EBUSY; 256 } 257 258 wl->state = WL12XX_STATE_PLT; 259 260 ret = wl12xx_chip_wakeup(wl); 261 if (ret < 0) 262 return ret; 263 264 ret = wl->chip.op_boot(wl); 265 if (ret < 0) 266 return ret; 267 268 wl12xx_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver); 269 270 ret = wl->chip.op_plt_init(wl); 271 if (ret < 0) 272 return ret; 273 274 return 0; 275 } 276 277 int wl12xx_plt_stop(struct wl12xx *wl) 278 { 279 wl12xx_notice("power down"); 280 281 if (wl->state != WL12XX_STATE_PLT) { 282 wl12xx_error("cannot power down because not in PLT " 283 "state: %d", wl->state); 284 return -EBUSY; 285 } 286 287 wl12xx_disable_interrupts(wl); 288 wl12xx_power_off(wl); 289 290 wl->state = WL12XX_STATE_OFF; 291 292 return 0; 293 } 294 295 296 static int wl12xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 297 { 298 struct wl12xx *wl = hw->priv; 299 300 skb_queue_tail(&wl->tx_queue, skb); 301 302 schedule_work(&wl->tx_work); 303 304 /* 305 * The workqueue is slow to process the tx_queue and we need stop 306 * the queue here, otherwise the queue will get too long. 307 */ 308 if (skb_queue_len(&wl->tx_queue) >= WL12XX_TX_QUEUE_MAX_LENGTH) { 309 ieee80211_stop_queues(wl->hw); 310 311 /* 312 * FIXME: this is racy, the variable is not properly 313 * protected. Maybe fix this by removing the stupid 314 * variable altogether and checking the real queue state? 315 */ 316 wl->tx_queue_stopped = true; 317 } 318 319 return NETDEV_TX_OK; 320 } 321 322 static int wl12xx_op_start(struct ieee80211_hw *hw) 323 { 324 struct wl12xx *wl = hw->priv; 325 int ret = 0; 326 327 wl12xx_debug(DEBUG_MAC80211, "mac80211 start"); 328 329 mutex_lock(&wl->mutex); 330 331 if (wl->state != WL12XX_STATE_OFF) { 332 wl12xx_error("cannot start because not in off state: %d", 333 wl->state); 334 ret = -EBUSY; 335 goto out; 336 } 337 338 ret = wl12xx_chip_wakeup(wl); 339 if (ret < 0) 340 return ret; 341 342 ret = wl->chip.op_boot(wl); 343 if (ret < 0) 344 goto out; 345 346 ret = wl->chip.op_hw_init(wl); 347 if (ret < 0) 348 goto out; 349 350 ret = wl12xx_acx_station_id(wl); 351 if (ret < 0) 352 goto out; 353 354 wl->state = WL12XX_STATE_ON; 355 356 wl12xx_info("firmware booted (%s)", wl->chip.fw_ver); 357 358 out: 359 if (ret < 0) 360 wl12xx_power_off(wl); 361 362 mutex_unlock(&wl->mutex); 363 364 return ret; 365 } 366 367 static void wl12xx_op_stop(struct ieee80211_hw *hw) 368 { 369 struct wl12xx *wl = hw->priv; 370 371 wl12xx_info("down"); 372 373 wl12xx_debug(DEBUG_MAC80211, "mac80211 stop"); 374 375 mutex_lock(&wl->mutex); 376 377 WARN_ON(wl->state != WL12XX_STATE_ON); 378 379 if (wl->scanning) { 380 mutex_unlock(&wl->mutex); 381 ieee80211_scan_completed(wl->hw, true); 382 mutex_lock(&wl->mutex); 383 wl->scanning = false; 384 } 385 386 wl->state = WL12XX_STATE_OFF; 387 388 wl12xx_disable_interrupts(wl); 389 390 mutex_unlock(&wl->mutex); 391 392 cancel_work_sync(&wl->irq_work); 393 cancel_work_sync(&wl->tx_work); 394 cancel_work_sync(&wl->filter_work); 395 396 mutex_lock(&wl->mutex); 397 398 /* let's notify MAC80211 about the remaining pending TX frames */ 399 wl12xx_tx_flush(wl); 400 401 wl12xx_power_off(wl); 402 403 memset(wl->bssid, 0, ETH_ALEN); 404 wl->listen_int = 1; 405 wl->bss_type = MAX_BSS_TYPE; 406 407 wl->data_in_count = 0; 408 wl->rx_counter = 0; 409 wl->rx_handled = 0; 410 wl->rx_current_buffer = 0; 411 wl->rx_last_id = 0; 412 wl->next_tx_complete = 0; 413 wl->elp = false; 414 wl->psm = 0; 415 wl->tx_queue_stopped = false; 416 wl->power_level = WL12XX_DEFAULT_POWER_LEVEL; 417 418 wl12xx_debugfs_reset(wl); 419 420 mutex_unlock(&wl->mutex); 421 } 422 423 static int wl12xx_op_add_interface(struct ieee80211_hw *hw, 424 struct ieee80211_if_init_conf *conf) 425 { 426 struct wl12xx *wl = hw->priv; 427 DECLARE_MAC_BUF(mac); 428 int ret = 0; 429 430 wl12xx_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %s", 431 conf->type, print_mac(mac, conf->mac_addr)); 432 433 mutex_lock(&wl->mutex); 434 435 switch (conf->type) { 436 case NL80211_IFTYPE_STATION: 437 wl->bss_type = BSS_TYPE_STA_BSS; 438 break; 439 case NL80211_IFTYPE_ADHOC: 440 wl->bss_type = BSS_TYPE_IBSS; 441 break; 442 default: 443 ret = -EOPNOTSUPP; 444 goto out; 445 } 446 447 if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) { 448 memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN); 449 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); 450 ret = wl12xx_acx_station_id(wl); 451 if (ret < 0) 452 goto out; 453 } 454 455 out: 456 mutex_unlock(&wl->mutex); 457 return ret; 458 } 459 460 static void wl12xx_op_remove_interface(struct ieee80211_hw *hw, 461 struct ieee80211_if_init_conf *conf) 462 { 463 wl12xx_debug(DEBUG_MAC80211, "mac80211 remove interface"); 464 } 465 466 static int wl12xx_build_null_data(struct wl12xx *wl) 467 { 468 struct wl12xx_null_data_template template; 469 470 if (!is_zero_ether_addr(wl->bssid)) { 471 memcpy(template.header.da, wl->bssid, ETH_ALEN); 472 memcpy(template.header.bssid, wl->bssid, ETH_ALEN); 473 } else { 474 memset(template.header.da, 0xff, ETH_ALEN); 475 memset(template.header.bssid, 0xff, ETH_ALEN); 476 } 477 478 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); 479 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | 480 IEEE80211_STYPE_NULLFUNC); 481 482 return wl12xx_cmd_template_set(wl, CMD_NULL_DATA, &template, 483 sizeof(template)); 484 485 } 486 487 static int wl12xx_build_ps_poll(struct wl12xx *wl, u16 aid) 488 { 489 struct wl12xx_ps_poll_template template; 490 491 memcpy(template.bssid, wl->bssid, ETH_ALEN); 492 memcpy(template.ta, wl->mac_addr, ETH_ALEN); 493 template.aid = aid; 494 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); 495 496 return wl12xx_cmd_template_set(wl, CMD_PS_POLL, &template, 497 sizeof(template)); 498 499 } 500 501 static int wl12xx_op_config(struct ieee80211_hw *hw, u32 changed) 502 { 503 struct wl12xx *wl = hw->priv; 504 struct ieee80211_conf *conf = &hw->conf; 505 int channel, ret = 0; 506 507 channel = ieee80211_frequency_to_channel(conf->channel->center_freq); 508 509 wl12xx_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", 510 channel, 511 conf->flags & IEEE80211_CONF_PS ? "on" : "off", 512 conf->power_level); 513 514 mutex_lock(&wl->mutex); 515 516 if (channel != wl->channel) { 517 /* FIXME: use beacon interval provided by mac80211 */ 518 ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0); 519 if (ret < 0) 520 goto out; 521 522 wl->channel = channel; 523 } 524 525 ret = wl12xx_build_null_data(wl); 526 if (ret < 0) 527 goto out; 528 529 if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) { 530 wl12xx_info("psm enabled"); 531 532 wl->psm_requested = true; 533 534 /* 535 * We enter PSM only if we're already associated. 536 * If we're not, we'll enter it when joining an SSID, 537 * through the bss_info_changed() hook. 538 */ 539 ret = wl12xx_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 540 } else if (!(conf->flags & IEEE80211_CONF_PS) && 541 wl->psm_requested) { 542 wl12xx_info("psm disabled"); 543 544 wl->psm_requested = false; 545 546 if (wl->psm) 547 ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE); 548 } 549 550 if (conf->power_level != wl->power_level) { 551 ret = wl12xx_acx_tx_power(wl, conf->power_level); 552 if (ret < 0) 553 goto out; 554 555 wl->power_level = conf->power_level; 556 } 557 558 out: 559 mutex_unlock(&wl->mutex); 560 return ret; 561 } 562 563 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 564 FIF_ALLMULTI | \ 565 FIF_FCSFAIL | \ 566 FIF_BCN_PRBRESP_PROMISC | \ 567 FIF_CONTROL | \ 568 FIF_OTHER_BSS) 569 570 static void wl12xx_op_configure_filter(struct ieee80211_hw *hw, 571 unsigned int changed, 572 unsigned int *total, 573 int mc_count, 574 struct dev_addr_list *mc_list) 575 { 576 struct wl12xx *wl = hw->priv; 577 578 wl12xx_debug(DEBUG_MAC80211, "mac80211 configure filter"); 579 580 *total &= WL12XX_SUPPORTED_FILTERS; 581 changed &= WL12XX_SUPPORTED_FILTERS; 582 583 if (changed == 0) 584 /* no filters which we support changed */ 585 return; 586 587 /* FIXME: wl->rx_config and wl->rx_filter are not protected */ 588 589 wl->rx_config = WL12XX_DEFAULT_RX_CONFIG; 590 wl->rx_filter = WL12XX_DEFAULT_RX_FILTER; 591 592 if (*total & FIF_PROMISC_IN_BSS) { 593 wl->rx_config |= CFG_BSSID_FILTER_EN; 594 wl->rx_config |= CFG_RX_ALL_GOOD; 595 } 596 if (*total & FIF_ALLMULTI) 597 /* 598 * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive 599 * all multicast frames 600 */ 601 wl->rx_config &= ~CFG_MC_FILTER_EN; 602 if (*total & FIF_FCSFAIL) 603 wl->rx_filter |= CFG_RX_FCS_ERROR; 604 if (*total & FIF_BCN_PRBRESP_PROMISC) { 605 wl->rx_config &= ~CFG_BSSID_FILTER_EN; 606 wl->rx_config &= ~CFG_SSID_FILTER_EN; 607 } 608 if (*total & FIF_CONTROL) 609 wl->rx_filter |= CFG_RX_CTL_EN; 610 if (*total & FIF_OTHER_BSS) 611 wl->rx_filter &= ~CFG_BSSID_FILTER_EN; 612 613 /* 614 * FIXME: workqueues need to be properly cancelled on stop(), for 615 * now let's just disable changing the filter settings. They will 616 * be updated any on config(). 617 */ 618 /* schedule_work(&wl->filter_work); */ 619 } 620 621 /* HW encryption */ 622 static int wl12xx_set_key_type(struct wl12xx *wl, struct acx_set_key *key, 623 enum set_key_cmd cmd, 624 struct ieee80211_key_conf *mac80211_key, 625 const u8 *addr) 626 { 627 switch (mac80211_key->alg) { 628 case ALG_WEP: 629 if (is_broadcast_ether_addr(addr)) 630 key->key_type = KEY_WEP_DEFAULT; 631 else 632 key->key_type = KEY_WEP_ADDR; 633 634 mac80211_key->hw_key_idx = mac80211_key->keyidx; 635 break; 636 case ALG_TKIP: 637 if (is_broadcast_ether_addr(addr)) 638 key->key_type = KEY_TKIP_MIC_GROUP; 639 else 640 key->key_type = KEY_TKIP_MIC_PAIRWISE; 641 642 mac80211_key->hw_key_idx = mac80211_key->keyidx; 643 break; 644 case ALG_CCMP: 645 if (is_broadcast_ether_addr(addr)) 646 key->key_type = KEY_AES_GROUP; 647 else 648 key->key_type = KEY_AES_PAIRWISE; 649 mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 650 break; 651 default: 652 wl12xx_error("Unknown key algo 0x%x", mac80211_key->alg); 653 return -EOPNOTSUPP; 654 } 655 656 return 0; 657 } 658 659 static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 660 struct ieee80211_vif *vif, 661 struct ieee80211_sta *sta, 662 struct ieee80211_key_conf *key) 663 { 664 struct wl12xx *wl = hw->priv; 665 struct acx_set_key wl_key; 666 const u8 *addr; 667 int ret; 668 669 static const u8 bcast_addr[ETH_ALEN] = 670 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 671 672 wl12xx_debug(DEBUG_MAC80211, "mac80211 set key"); 673 674 memset(&wl_key, 0, sizeof(wl_key)); 675 676 addr = sta ? sta->addr : bcast_addr; 677 678 wl12xx_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd); 679 wl12xx_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN); 680 wl12xx_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x", 681 key->alg, key->keyidx, key->keylen, key->flags); 682 wl12xx_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen); 683 684 mutex_lock(&wl->mutex); 685 686 switch (cmd) { 687 case SET_KEY: 688 wl_key.key_action = KEY_ADD_OR_REPLACE; 689 break; 690 case DISABLE_KEY: 691 wl_key.key_action = KEY_REMOVE; 692 break; 693 default: 694 wl12xx_error("Unsupported key cmd 0x%x", cmd); 695 break; 696 } 697 698 ret = wl12xx_set_key_type(wl, &wl_key, cmd, key, addr); 699 if (ret < 0) { 700 wl12xx_error("Set KEY type failed"); 701 goto out; 702 } 703 704 if (wl_key.key_type != KEY_WEP_DEFAULT) 705 memcpy(wl_key.addr, addr, ETH_ALEN); 706 707 if ((wl_key.key_type == KEY_TKIP_MIC_GROUP) || 708 (wl_key.key_type == KEY_TKIP_MIC_PAIRWISE)) { 709 /* 710 * We get the key in the following form: 711 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes) 712 * but the target is expecting: 713 * TKIP - RX MIC - TX MIC 714 */ 715 memcpy(wl_key.key, key->key, 16); 716 memcpy(wl_key.key + 16, key->key + 24, 8); 717 memcpy(wl_key.key + 24, key->key + 16, 8); 718 719 } else { 720 memcpy(wl_key.key, key->key, key->keylen); 721 } 722 wl_key.key_size = key->keylen; 723 724 wl_key.id = key->keyidx; 725 wl_key.ssid_profile = 0; 726 727 wl12xx_dump(DEBUG_CRYPT, "TARGET KEY: ", &wl_key, sizeof(wl_key)); 728 729 if (wl12xx_cmd_send(wl, CMD_SET_KEYS, &wl_key, sizeof(wl_key)) < 0) { 730 wl12xx_error("Set KEY failed"); 731 ret = -EOPNOTSUPP; 732 goto out; 733 } 734 735 out: 736 mutex_unlock(&wl->mutex); 737 return ret; 738 } 739 740 static int wl12xx_build_basic_rates(char *rates) 741 { 742 u8 index = 0; 743 744 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; 745 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; 746 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; 747 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; 748 749 return index; 750 } 751 752 static int wl12xx_build_extended_rates(char *rates) 753 { 754 u8 index = 0; 755 756 rates[index++] = IEEE80211_OFDM_RATE_6MB; 757 rates[index++] = IEEE80211_OFDM_RATE_9MB; 758 rates[index++] = IEEE80211_OFDM_RATE_12MB; 759 rates[index++] = IEEE80211_OFDM_RATE_18MB; 760 rates[index++] = IEEE80211_OFDM_RATE_24MB; 761 rates[index++] = IEEE80211_OFDM_RATE_36MB; 762 rates[index++] = IEEE80211_OFDM_RATE_48MB; 763 rates[index++] = IEEE80211_OFDM_RATE_54MB; 764 765 return index; 766 } 767 768 769 static int wl12xx_build_probe_req(struct wl12xx *wl, u8 *ssid, size_t ssid_len) 770 { 771 struct wl12xx_probe_req_template template; 772 struct wl12xx_ie_rates *rates; 773 char *ptr; 774 u16 size; 775 776 ptr = (char *)&template; 777 size = sizeof(struct ieee80211_header); 778 779 memset(template.header.da, 0xff, ETH_ALEN); 780 memset(template.header.bssid, 0xff, ETH_ALEN); 781 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); 782 template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); 783 784 /* IEs */ 785 /* SSID */ 786 template.ssid.header.id = WLAN_EID_SSID; 787 template.ssid.header.len = ssid_len; 788 if (ssid_len && ssid) 789 memcpy(template.ssid.ssid, ssid, ssid_len); 790 size += sizeof(struct wl12xx_ie_header) + ssid_len; 791 ptr += size; 792 793 /* Basic Rates */ 794 rates = (struct wl12xx_ie_rates *)ptr; 795 rates->header.id = WLAN_EID_SUPP_RATES; 796 rates->header.len = wl12xx_build_basic_rates(rates->rates); 797 size += sizeof(struct wl12xx_ie_header) + rates->header.len; 798 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len; 799 800 /* Extended rates */ 801 rates = (struct wl12xx_ie_rates *)ptr; 802 rates->header.id = WLAN_EID_EXT_SUPP_RATES; 803 rates->header.len = wl12xx_build_extended_rates(rates->rates); 804 size += sizeof(struct wl12xx_ie_header) + rates->header.len; 805 806 wl12xx_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size); 807 808 return wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, &template, 809 size); 810 } 811 812 static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len, 813 u8 active_scan, u8 high_prio, u8 num_channels, 814 u8 probe_requests) 815 { 816 int i, ret; 817 u32 split_scan = 0; 818 u16 scan_options = 0; 819 struct cmd_scan *params; 820 struct wl12xx_command *cmd_answer; 821 822 if (wl->scanning) 823 return -EINVAL; 824 825 params = kzalloc(sizeof(*params), GFP_KERNEL); 826 if (!params) 827 return -ENOMEM; 828 829 params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); 830 params->params.rx_filter_options = 831 cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); 832 833 /* High priority scan */ 834 if (!active_scan) 835 scan_options |= SCAN_PASSIVE; 836 if (high_prio) 837 scan_options |= SCAN_PRIORITY_HIGH; 838 params->params.scan_options = scan_options; 839 840 params->params.num_channels = num_channels; 841 params->params.num_probe_requests = probe_requests; 842 params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */ 843 params->params.tid_trigger = 0; 844 845 for (i = 0; i < num_channels; i++) { 846 params->channels[i].min_duration = cpu_to_le32(30000); 847 params->channels[i].max_duration = cpu_to_le32(60000); 848 memset(&params->channels[i].bssid_lsb, 0xff, 4); 849 memset(&params->channels[i].bssid_msb, 0xff, 2); 850 params->channels[i].early_termination = 0; 851 params->channels[i].tx_power_att = 0; 852 params->channels[i].channel = i + 1; 853 memset(params->channels[i].pad, 0, 3); 854 } 855 856 for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++) 857 memset(&params->channels[i], 0, 858 sizeof(struct basic_scan_channel_parameters)); 859 860 if (len && ssid) { 861 params->params.ssid_len = len; 862 memcpy(params->params.ssid, ssid, len); 863 } else { 864 params->params.ssid_len = 0; 865 memset(params->params.ssid, 0, 32); 866 } 867 868 ret = wl12xx_build_probe_req(wl, ssid, len); 869 if (ret < 0) { 870 wl12xx_error("PROBE request template failed"); 871 goto out; 872 } 873 874 ret = wl12xx_cmd_send(wl, CMD_TRIGGER_SCAN_TO, &split_scan, 875 sizeof(u32)); 876 if (ret < 0) { 877 wl12xx_error("Split SCAN failed"); 878 goto out; 879 } 880 881 wl12xx_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params)); 882 883 wl->scanning = true; 884 885 ret = wl12xx_cmd_send(wl, CMD_SCAN, params, sizeof(*params)); 886 if (ret < 0) 887 wl12xx_error("SCAN failed"); 888 889 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params)); 890 891 cmd_answer = (struct wl12xx_command *) params; 892 if (cmd_answer->status != CMD_STATUS_SUCCESS) { 893 wl12xx_error("TEST command answer error: %d", 894 cmd_answer->status); 895 wl->scanning = false; 896 ret = -EIO; 897 goto out; 898 } 899 900 out: 901 kfree(params); 902 return ret; 903 904 } 905 906 static int wl12xx_op_hw_scan(struct ieee80211_hw *hw, 907 struct cfg80211_scan_request *req) 908 { 909 struct wl12xx *wl = hw->priv; 910 int ret; 911 u8 *ssid = NULL; 912 size_t ssid_len = 0; 913 914 wl12xx_debug(DEBUG_MAC80211, "mac80211 hw scan"); 915 916 if (req->n_ssids) { 917 ssid = req->ssids[0].ssid; 918 ssid_len = req->ssids[0].ssid_len; 919 } 920 921 mutex_lock(&wl->mutex); 922 ret = wl12xx_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3); 923 mutex_unlock(&wl->mutex); 924 925 return ret; 926 } 927 928 static int wl12xx_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 929 { 930 struct wl12xx *wl = hw->priv; 931 int ret; 932 933 ret = wl12xx_acx_rts_threshold(wl, (u16) value); 934 935 if (ret < 0) 936 wl12xx_warning("wl12xx_op_set_rts_threshold failed: %d", ret); 937 938 return ret; 939 } 940 941 static void wl12xx_op_bss_info_changed(struct ieee80211_hw *hw, 942 struct ieee80211_vif *vif, 943 struct ieee80211_bss_conf *bss_conf, 944 u32 changed) 945 { 946 enum acx_ps_mode mode; 947 struct wl12xx *wl = hw->priv; 948 struct sk_buff *beacon; 949 int ret; 950 951 wl12xx_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 952 953 mutex_lock(&wl->mutex); 954 955 if (changed & BSS_CHANGED_ASSOC) { 956 if (bss_conf->assoc) { 957 wl->aid = bss_conf->aid; 958 959 ret = wl12xx_build_ps_poll(wl, wl->aid); 960 if (ret < 0) 961 goto out; 962 963 ret = wl12xx_acx_aid(wl, wl->aid); 964 if (ret < 0) 965 goto out; 966 967 /* If we want to go in PSM but we're not there yet */ 968 if (wl->psm_requested && !wl->psm) { 969 mode = STATION_POWER_SAVE_MODE; 970 ret = wl12xx_ps_set_mode(wl, mode); 971 if (ret < 0) 972 goto out; 973 } 974 } 975 } 976 if (changed & BSS_CHANGED_ERP_SLOT) { 977 if (bss_conf->use_short_slot) 978 ret = wl12xx_acx_slot(wl, SLOT_TIME_SHORT); 979 else 980 ret = wl12xx_acx_slot(wl, SLOT_TIME_LONG); 981 if (ret < 0) { 982 wl12xx_warning("Set slot time failed %d", ret); 983 goto out; 984 } 985 } 986 987 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 988 if (bss_conf->use_short_preamble) 989 wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_SHORT); 990 else 991 wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_LONG); 992 } 993 994 if (changed & BSS_CHANGED_ERP_CTS_PROT) { 995 if (bss_conf->use_cts_prot) 996 ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_ENABLE); 997 else 998 ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_DISABLE); 999 if (ret < 0) { 1000 wl12xx_warning("Set ctsprotect failed %d", ret); 1001 goto out; 1002 } 1003 } 1004 1005 if (changed & BSS_CHANGED_BSSID) { 1006 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); 1007 1008 ret = wl12xx_build_null_data(wl); 1009 if (ret < 0) 1010 goto out; 1011 1012 if (wl->bss_type != BSS_TYPE_IBSS) { 1013 ret = wl12xx_cmd_join(wl, wl->bss_type, 5, 100, 1); 1014 if (ret < 0) 1015 goto out; 1016 } 1017 } 1018 1019 if (changed & BSS_CHANGED_BEACON) { 1020 beacon = ieee80211_beacon_get(hw, vif); 1021 ret = wl12xx_cmd_template_set(wl, CMD_BEACON, beacon->data, 1022 beacon->len); 1023 1024 if (ret < 0) { 1025 dev_kfree_skb(beacon); 1026 goto out; 1027 } 1028 1029 ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data, 1030 beacon->len); 1031 1032 dev_kfree_skb(beacon); 1033 1034 if (ret < 0) 1035 goto out; 1036 1037 ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0); 1038 1039 if (ret < 0) 1040 goto out; 1041 } 1042 1043 out: 1044 mutex_unlock(&wl->mutex); 1045 } 1046 1047 1048 /* can't be const, mac80211 writes to this */ 1049 static struct ieee80211_rate wl12xx_rates[] = { 1050 { .bitrate = 10, 1051 .hw_value = 0x1, 1052 .hw_value_short = 0x1, }, 1053 { .bitrate = 20, 1054 .hw_value = 0x2, 1055 .hw_value_short = 0x2, 1056 .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 1057 { .bitrate = 55, 1058 .hw_value = 0x4, 1059 .hw_value_short = 0x4, 1060 .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 1061 { .bitrate = 110, 1062 .hw_value = 0x20, 1063 .hw_value_short = 0x20, 1064 .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 1065 { .bitrate = 60, 1066 .hw_value = 0x8, 1067 .hw_value_short = 0x8, }, 1068 { .bitrate = 90, 1069 .hw_value = 0x10, 1070 .hw_value_short = 0x10, }, 1071 { .bitrate = 120, 1072 .hw_value = 0x40, 1073 .hw_value_short = 0x40, }, 1074 { .bitrate = 180, 1075 .hw_value = 0x80, 1076 .hw_value_short = 0x80, }, 1077 { .bitrate = 240, 1078 .hw_value = 0x200, 1079 .hw_value_short = 0x200, }, 1080 { .bitrate = 360, 1081 .hw_value = 0x400, 1082 .hw_value_short = 0x400, }, 1083 { .bitrate = 480, 1084 .hw_value = 0x800, 1085 .hw_value_short = 0x800, }, 1086 { .bitrate = 540, 1087 .hw_value = 0x1000, 1088 .hw_value_short = 0x1000, }, 1089 }; 1090 1091 /* can't be const, mac80211 writes to this */ 1092 static struct ieee80211_channel wl12xx_channels[] = { 1093 { .hw_value = 1, .center_freq = 2412}, 1094 { .hw_value = 2, .center_freq = 2417}, 1095 { .hw_value = 3, .center_freq = 2422}, 1096 { .hw_value = 4, .center_freq = 2427}, 1097 { .hw_value = 5, .center_freq = 2432}, 1098 { .hw_value = 6, .center_freq = 2437}, 1099 { .hw_value = 7, .center_freq = 2442}, 1100 { .hw_value = 8, .center_freq = 2447}, 1101 { .hw_value = 9, .center_freq = 2452}, 1102 { .hw_value = 10, .center_freq = 2457}, 1103 { .hw_value = 11, .center_freq = 2462}, 1104 { .hw_value = 12, .center_freq = 2467}, 1105 { .hw_value = 13, .center_freq = 2472}, 1106 }; 1107 1108 /* can't be const, mac80211 writes to this */ 1109 static struct ieee80211_supported_band wl12xx_band_2ghz = { 1110 .channels = wl12xx_channels, 1111 .n_channels = ARRAY_SIZE(wl12xx_channels), 1112 .bitrates = wl12xx_rates, 1113 .n_bitrates = ARRAY_SIZE(wl12xx_rates), 1114 }; 1115 1116 static const struct ieee80211_ops wl12xx_ops = { 1117 .start = wl12xx_op_start, 1118 .stop = wl12xx_op_stop, 1119 .add_interface = wl12xx_op_add_interface, 1120 .remove_interface = wl12xx_op_remove_interface, 1121 .config = wl12xx_op_config, 1122 .configure_filter = wl12xx_op_configure_filter, 1123 .tx = wl12xx_op_tx, 1124 .set_key = wl12xx_op_set_key, 1125 .hw_scan = wl12xx_op_hw_scan, 1126 .bss_info_changed = wl12xx_op_bss_info_changed, 1127 .set_rts_threshold = wl12xx_op_set_rts_threshold, 1128 }; 1129 1130 static int wl12xx_register_hw(struct wl12xx *wl) 1131 { 1132 int ret; 1133 1134 if (wl->mac80211_registered) 1135 return 0; 1136 1137 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); 1138 1139 ret = ieee80211_register_hw(wl->hw); 1140 if (ret < 0) { 1141 wl12xx_error("unable to register mac80211 hw: %d", ret); 1142 return ret; 1143 } 1144 1145 wl->mac80211_registered = true; 1146 1147 wl12xx_notice("loaded"); 1148 1149 return 0; 1150 } 1151 1152 static int wl12xx_init_ieee80211(struct wl12xx *wl) 1153 { 1154 /* The tx descriptor buffer and the TKIP space */ 1155 wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc) 1156 + WL12XX_TKIP_IV_SPACE; 1157 1158 /* unit us */ 1159 /* FIXME: find a proper value */ 1160 wl->hw->channel_change_time = 10000; 1161 1162 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 1163 IEEE80211_HW_NOISE_DBM; 1164 1165 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 1166 wl->hw->wiphy->max_scan_ssids = 1; 1167 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl12xx_band_2ghz; 1168 1169 SET_IEEE80211_DEV(wl->hw, &wl->spi->dev); 1170 1171 return 0; 1172 } 1173 1174 #define WL12XX_DEFAULT_CHANNEL 1 1175 static int __devinit wl12xx_probe(struct spi_device *spi) 1176 { 1177 struct wl12xx_platform_data *pdata; 1178 struct ieee80211_hw *hw; 1179 struct wl12xx *wl; 1180 int ret, i; 1181 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf}; 1182 1183 pdata = spi->dev.platform_data; 1184 if (!pdata) { 1185 wl12xx_error("no platform data"); 1186 return -ENODEV; 1187 } 1188 1189 hw = ieee80211_alloc_hw(sizeof(*wl), &wl12xx_ops); 1190 if (!hw) { 1191 wl12xx_error("could not alloc ieee80211_hw"); 1192 return -ENOMEM; 1193 } 1194 1195 wl = hw->priv; 1196 memset(wl, 0, sizeof(*wl)); 1197 1198 wl->hw = hw; 1199 dev_set_drvdata(&spi->dev, wl); 1200 wl->spi = spi; 1201 1202 wl->data_in_count = 0; 1203 1204 skb_queue_head_init(&wl->tx_queue); 1205 1206 INIT_WORK(&wl->tx_work, wl12xx_tx_work); 1207 INIT_WORK(&wl->filter_work, wl12xx_filter_work); 1208 wl->channel = WL12XX_DEFAULT_CHANNEL; 1209 wl->scanning = false; 1210 wl->default_key = 0; 1211 wl->listen_int = 1; 1212 wl->rx_counter = 0; 1213 wl->rx_handled = 0; 1214 wl->rx_current_buffer = 0; 1215 wl->rx_last_id = 0; 1216 wl->rx_config = WL12XX_DEFAULT_RX_CONFIG; 1217 wl->rx_filter = WL12XX_DEFAULT_RX_FILTER; 1218 wl->elp = false; 1219 wl->psm = 0; 1220 wl->psm_requested = false; 1221 wl->tx_queue_stopped = false; 1222 wl->power_level = WL12XX_DEFAULT_POWER_LEVEL; 1223 1224 /* We use the default power on sleep time until we know which chip 1225 * we're using */ 1226 wl->chip.power_on_sleep = WL12XX_DEFAULT_POWER_ON_SLEEP; 1227 1228 for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) 1229 wl->tx_frames[i] = NULL; 1230 1231 wl->next_tx_complete = 0; 1232 1233 /* 1234 * In case our MAC address is not correctly set, 1235 * we use a random but Nokia MAC. 1236 */ 1237 memcpy(wl->mac_addr, nokia_oui, 3); 1238 get_random_bytes(wl->mac_addr + 3, 3); 1239 1240 wl->state = WL12XX_STATE_OFF; 1241 mutex_init(&wl->mutex); 1242 1243 wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE; 1244 wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE; 1245 1246 /* This is the only SPI value that we need to set here, the rest 1247 * comes from the board-peripherals file */ 1248 spi->bits_per_word = 32; 1249 1250 ret = spi_setup(spi); 1251 if (ret < 0) { 1252 wl12xx_error("spi_setup failed"); 1253 goto out_free; 1254 } 1255 1256 wl->set_power = pdata->set_power; 1257 if (!wl->set_power) { 1258 wl12xx_error("set power function missing in platform data"); 1259 return -ENODEV; 1260 } 1261 1262 wl->irq = spi->irq; 1263 if (wl->irq < 0) { 1264 wl12xx_error("irq missing in platform data"); 1265 return -ENODEV; 1266 } 1267 1268 ret = request_irq(wl->irq, wl12xx_irq, 0, DRIVER_NAME, wl); 1269 if (ret < 0) { 1270 wl12xx_error("request_irq() failed: %d", ret); 1271 goto out_free; 1272 } 1273 1274 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); 1275 1276 disable_irq(wl->irq); 1277 1278 ret = wl12xx_init_ieee80211(wl); 1279 if (ret) 1280 goto out_irq; 1281 1282 ret = wl12xx_register_hw(wl); 1283 if (ret) 1284 goto out_irq; 1285 1286 wl12xx_debugfs_init(wl); 1287 1288 wl12xx_notice("initialized"); 1289 1290 return 0; 1291 1292 out_irq: 1293 free_irq(wl->irq, wl); 1294 1295 out_free: 1296 ieee80211_free_hw(hw); 1297 1298 return ret; 1299 } 1300 1301 static int __devexit wl12xx_remove(struct spi_device *spi) 1302 { 1303 struct wl12xx *wl = dev_get_drvdata(&spi->dev); 1304 1305 ieee80211_unregister_hw(wl->hw); 1306 1307 wl12xx_debugfs_exit(wl); 1308 1309 free_irq(wl->irq, wl); 1310 kfree(wl->target_mem_map); 1311 kfree(wl->data_path); 1312 kfree(wl->fw); 1313 wl->fw = NULL; 1314 kfree(wl->nvs); 1315 wl->nvs = NULL; 1316 ieee80211_free_hw(wl->hw); 1317 1318 return 0; 1319 } 1320 1321 1322 static struct spi_driver wl12xx_spi_driver = { 1323 .driver = { 1324 .name = "wl12xx", 1325 .bus = &spi_bus_type, 1326 .owner = THIS_MODULE, 1327 }, 1328 1329 .probe = wl12xx_probe, 1330 .remove = __devexit_p(wl12xx_remove), 1331 }; 1332 1333 static int __init wl12xx_init(void) 1334 { 1335 int ret; 1336 1337 ret = spi_register_driver(&wl12xx_spi_driver); 1338 if (ret < 0) { 1339 wl12xx_error("failed to register spi driver: %d", ret); 1340 goto out; 1341 } 1342 1343 out: 1344 return ret; 1345 } 1346 1347 static void __exit wl12xx_exit(void) 1348 { 1349 spi_unregister_driver(&wl12xx_spi_driver); 1350 1351 wl12xx_notice("unloaded"); 1352 } 1353 1354 module_init(wl12xx_init); 1355 module_exit(wl12xx_exit); 1356 1357 MODULE_LICENSE("GPL"); 1358 MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>, " 1359 "Luciano Coelho <luciano.coelho@nokia.com>"); 1360 1361 1362 1363 1364 1365 /* LDV_COMMENT_BEGIN_MAIN */ 1366 #ifdef LDV_MAIN0_sequence_infinite_withcheck_stateful 1367 1368 /*###########################################################################*/ 1369 1370 /*############## Driver Environment Generator 0.2 output ####################*/ 1371 1372 /*###########################################################################*/ 1373 1374 1375 1376 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Test if all kernel resources are correctly released by driver before driver will be unloaded. */ 1377 void ldv_check_final_state(void); 1378 1379 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Test correct return result. */ 1380 void ldv_check_return_value(int res); 1381 1382 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Initializes the model. */ 1383 void ldv_initialize(void); 1384 1385 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Returns arbitrary interger value. */ 1386 int nondet_int(void); 1387 1388 /* LDV_COMMENT_VAR_DECLARE_LDV Special variable for LDV verifier. */ 1389 int LDV_IN_INTERRUPT; 1390 1391 /* LDV_COMMENT_FUNCTION_MAIN Main function for LDV verifier. */ 1392 void ldv_main0_sequence_infinite_withcheck_stateful(void) { 1393 1394 1395 1396 /* LDV_COMMENT_BEGIN_VARIABLE_DECLARATION_PART */ 1397 /*============================= VARIABLE DECLARATION PART =============================*/ 1398 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1399 /* content: static int wl12xx_op_start(struct ieee80211_hw *hw)*/ 1400 /* LDV_COMMENT_END_PREP */ 1401 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_start" */ 1402 struct ieee80211_hw * var_group1; 1403 /* LDV_COMMENT_BEGIN_PREP */ 1404 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1405 FIF_ALLMULTI | \ 1406 FIF_FCSFAIL | \ 1407 FIF_BCN_PRBRESP_PROMISC | \ 1408 FIF_CONTROL | \ 1409 FIF_OTHER_BSS) 1410 #define WL12XX_DEFAULT_CHANNEL 1 1411 /* LDV_COMMENT_END_PREP */ 1412 /* content: static void wl12xx_op_stop(struct ieee80211_hw *hw)*/ 1413 /* LDV_COMMENT_END_PREP */ 1414 /* LDV_COMMENT_BEGIN_PREP */ 1415 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1416 FIF_ALLMULTI | \ 1417 FIF_FCSFAIL | \ 1418 FIF_BCN_PRBRESP_PROMISC | \ 1419 FIF_CONTROL | \ 1420 FIF_OTHER_BSS) 1421 #define WL12XX_DEFAULT_CHANNEL 1 1422 /* LDV_COMMENT_END_PREP */ 1423 /* content: static int wl12xx_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf)*/ 1424 /* LDV_COMMENT_END_PREP */ 1425 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_add_interface" */ 1426 struct ieee80211_if_init_conf * var_group2; 1427 /* LDV_COMMENT_BEGIN_PREP */ 1428 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1429 FIF_ALLMULTI | \ 1430 FIF_FCSFAIL | \ 1431 FIF_BCN_PRBRESP_PROMISC | \ 1432 FIF_CONTROL | \ 1433 FIF_OTHER_BSS) 1434 #define WL12XX_DEFAULT_CHANNEL 1 1435 /* LDV_COMMENT_END_PREP */ 1436 /* content: static void wl12xx_op_remove_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf)*/ 1437 /* LDV_COMMENT_END_PREP */ 1438 /* LDV_COMMENT_BEGIN_PREP */ 1439 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1440 FIF_ALLMULTI | \ 1441 FIF_FCSFAIL | \ 1442 FIF_BCN_PRBRESP_PROMISC | \ 1443 FIF_CONTROL | \ 1444 FIF_OTHER_BSS) 1445 #define WL12XX_DEFAULT_CHANNEL 1 1446 /* LDV_COMMENT_END_PREP */ 1447 /* content: static int wl12xx_op_config(struct ieee80211_hw *hw, u32 changed)*/ 1448 /* LDV_COMMENT_END_PREP */ 1449 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_config" */ 1450 u32 var_wl12xx_op_config_18_p1; 1451 /* LDV_COMMENT_BEGIN_PREP */ 1452 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1453 FIF_ALLMULTI | \ 1454 FIF_FCSFAIL | \ 1455 FIF_BCN_PRBRESP_PROMISC | \ 1456 FIF_CONTROL | \ 1457 FIF_OTHER_BSS) 1458 #define WL12XX_DEFAULT_CHANNEL 1 1459 /* LDV_COMMENT_END_PREP */ 1460 /* content: FIF_OTHER_BSS) static void wl12xx_op_configure_filter(struct ieee80211_hw *hw, unsigned int changed, unsigned int *total, int mc_count, struct dev_addr_list *mc_list)*/ 1461 /* LDV_COMMENT_END_PREP */ 1462 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_configure_filter" */ 1463 unsigned int var_wl12xx_op_configure_filter_19_p1; 1464 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_configure_filter" */ 1465 unsigned int * var_wl12xx_op_configure_filter_19_p2; 1466 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_configure_filter" */ 1467 int var_wl12xx_op_configure_filter_19_p3; 1468 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_configure_filter" */ 1469 struct dev_addr_list * var_wl12xx_op_configure_filter_19_p4; 1470 /* LDV_COMMENT_BEGIN_PREP */ 1471 #define WL12XX_DEFAULT_CHANNEL 1 1472 /* LDV_COMMENT_END_PREP */ 1473 /* content: static int wl12xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)*/ 1474 /* LDV_COMMENT_END_PREP */ 1475 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_tx" */ 1476 struct sk_buff * var_group3; 1477 /* LDV_COMMENT_BEGIN_PREP */ 1478 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1479 FIF_ALLMULTI | \ 1480 FIF_FCSFAIL | \ 1481 FIF_BCN_PRBRESP_PROMISC | \ 1482 FIF_CONTROL | \ 1483 FIF_OTHER_BSS) 1484 #define WL12XX_DEFAULT_CHANNEL 1 1485 /* LDV_COMMENT_END_PREP */ 1486 /* content: static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key)*/ 1487 /* LDV_COMMENT_BEGIN_PREP */ 1488 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1489 FIF_ALLMULTI | \ 1490 FIF_FCSFAIL | \ 1491 FIF_BCN_PRBRESP_PROMISC | \ 1492 FIF_CONTROL | \ 1493 FIF_OTHER_BSS) 1494 /* LDV_COMMENT_END_PREP */ 1495 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_set_key" */ 1496 enum set_key_cmd var_wl12xx_op_set_key_21_p1; 1497 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_set_key" */ 1498 struct ieee80211_vif * var_wl12xx_op_set_key_21_p2; 1499 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_set_key" */ 1500 struct ieee80211_sta * var_wl12xx_op_set_key_21_p3; 1501 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_set_key" */ 1502 struct ieee80211_key_conf * var_wl12xx_op_set_key_21_p4; 1503 /* LDV_COMMENT_BEGIN_PREP */ 1504 #define WL12XX_DEFAULT_CHANNEL 1 1505 /* LDV_COMMENT_END_PREP */ 1506 /* content: static int wl12xx_op_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req)*/ 1507 /* LDV_COMMENT_BEGIN_PREP */ 1508 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1509 FIF_ALLMULTI | \ 1510 FIF_FCSFAIL | \ 1511 FIF_BCN_PRBRESP_PROMISC | \ 1512 FIF_CONTROL | \ 1513 FIF_OTHER_BSS) 1514 /* LDV_COMMENT_END_PREP */ 1515 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_hw_scan" */ 1516 struct cfg80211_scan_request * var_group4; 1517 /* LDV_COMMENT_BEGIN_PREP */ 1518 #define WL12XX_DEFAULT_CHANNEL 1 1519 /* LDV_COMMENT_END_PREP */ 1520 /* content: static void wl12xx_op_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changed)*/ 1521 /* LDV_COMMENT_BEGIN_PREP */ 1522 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1523 FIF_ALLMULTI | \ 1524 FIF_FCSFAIL | \ 1525 FIF_BCN_PRBRESP_PROMISC | \ 1526 FIF_CONTROL | \ 1527 FIF_OTHER_BSS) 1528 /* LDV_COMMENT_END_PREP */ 1529 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_bss_info_changed" */ 1530 struct ieee80211_vif * var_group5; 1531 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_bss_info_changed" */ 1532 struct ieee80211_bss_conf * var_wl12xx_op_bss_info_changed_28_p2; 1533 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_bss_info_changed" */ 1534 u32 var_wl12xx_op_bss_info_changed_28_p3; 1535 /* LDV_COMMENT_BEGIN_PREP */ 1536 #define WL12XX_DEFAULT_CHANNEL 1 1537 /* LDV_COMMENT_END_PREP */ 1538 /* content: static int wl12xx_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)*/ 1539 /* LDV_COMMENT_BEGIN_PREP */ 1540 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1541 FIF_ALLMULTI | \ 1542 FIF_FCSFAIL | \ 1543 FIF_BCN_PRBRESP_PROMISC | \ 1544 FIF_CONTROL | \ 1545 FIF_OTHER_BSS) 1546 /* LDV_COMMENT_END_PREP */ 1547 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_op_set_rts_threshold" */ 1548 u32 var_wl12xx_op_set_rts_threshold_27_p1; 1549 /* LDV_COMMENT_BEGIN_PREP */ 1550 #define WL12XX_DEFAULT_CHANNEL 1 1551 /* LDV_COMMENT_END_PREP */ 1552 1553 /** STRUCT: struct type: spi_driver, struct name: wl12xx_spi_driver **/ 1554 /* content: static int __devinit wl12xx_probe(struct spi_device *spi)*/ 1555 /* LDV_COMMENT_BEGIN_PREP */ 1556 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1557 FIF_ALLMULTI | \ 1558 FIF_FCSFAIL | \ 1559 FIF_BCN_PRBRESP_PROMISC | \ 1560 FIF_CONTROL | \ 1561 FIF_OTHER_BSS) 1562 #define WL12XX_DEFAULT_CHANNEL 1 1563 /* LDV_COMMENT_END_PREP */ 1564 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_probe" */ 1565 struct spi_device * var_group6; 1566 /* LDV_COMMENT_VAR_DECLARE Variable declaration for test return result from function call "wl12xx_probe" */ 1567 static int res_wl12xx_probe_31; 1568 1569 /** CALLBACK SECTION request_irq **/ 1570 /* content: static irqreturn_t wl12xx_irq(int irq, void *cookie)*/ 1571 /* LDV_COMMENT_END_PREP */ 1572 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_irq" */ 1573 int var_wl12xx_irq_3_p0; 1574 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "wl12xx_irq" */ 1575 void * var_wl12xx_irq_3_p1; 1576 /* LDV_COMMENT_BEGIN_PREP */ 1577 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1578 FIF_ALLMULTI | \ 1579 FIF_FCSFAIL | \ 1580 FIF_BCN_PRBRESP_PROMISC | \ 1581 FIF_CONTROL | \ 1582 FIF_OTHER_BSS) 1583 #define WL12XX_DEFAULT_CHANNEL 1 1584 /* LDV_COMMENT_END_PREP */ 1585 1586 1587 1588 1589 /* LDV_COMMENT_END_VARIABLE_DECLARATION_PART */ 1590 /* LDV_COMMENT_BEGIN_VARIABLE_INITIALIZING_PART */ 1591 /*============================= VARIABLE INITIALIZING PART =============================*/ 1592 LDV_IN_INTERRUPT=1; 1593 1594 1595 1596 1597 /* LDV_COMMENT_END_VARIABLE_INITIALIZING_PART */ 1598 /* LDV_COMMENT_BEGIN_FUNCTION_CALL_SECTION */ 1599 /*============================= FUNCTION CALL SECTION =============================*/ 1600 /* LDV_COMMENT_FUNCTION_CALL Initialize LDV model. */ 1601 ldv_initialize(); 1602 1603 /** INIT: init_type: ST_MODULE_INIT **/ 1604 /* content: static int __init wl12xx_init(void)*/ 1605 /* LDV_COMMENT_BEGIN_PREP */ 1606 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1607 FIF_ALLMULTI | \ 1608 FIF_FCSFAIL | \ 1609 FIF_BCN_PRBRESP_PROMISC | \ 1610 FIF_CONTROL | \ 1611 FIF_OTHER_BSS) 1612 #define WL12XX_DEFAULT_CHANNEL 1 1613 /* LDV_COMMENT_END_PREP */ 1614 /* LDV_COMMENT_FUNCTION_CALL Kernel calls driver init function after driver loading to kernel. This function declared as "MODULE_INIT(function name)". */ 1615 if(wl12xx_init()) 1616 goto ldv_final; 1617 1618 1619 int ldv_s_wl12xx_spi_driver_spi_driver = 0; 1620 1621 1622 1623 1624 while( nondet_int() 1625 || !(ldv_s_wl12xx_spi_driver_spi_driver == 0) 1626 ) { 1627 1628 switch(nondet_int()) { 1629 1630 case 0: { 1631 1632 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1633 1634 1635 /* content: static int wl12xx_op_start(struct ieee80211_hw *hw)*/ 1636 /* LDV_COMMENT_END_PREP */ 1637 /* LDV_COMMENT_FUNCTION_CALL Function from field "start" from driver structure with callbacks "wl12xx_ops" */ 1638 wl12xx_op_start( var_group1); 1639 /* LDV_COMMENT_BEGIN_PREP */ 1640 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1641 FIF_ALLMULTI | \ 1642 FIF_FCSFAIL | \ 1643 FIF_BCN_PRBRESP_PROMISC | \ 1644 FIF_CONTROL | \ 1645 FIF_OTHER_BSS) 1646 #define WL12XX_DEFAULT_CHANNEL 1 1647 /* LDV_COMMENT_END_PREP */ 1648 1649 1650 1651 1652 } 1653 1654 break; 1655 case 1: { 1656 1657 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1658 1659 1660 /* content: static void wl12xx_op_stop(struct ieee80211_hw *hw)*/ 1661 /* LDV_COMMENT_END_PREP */ 1662 /* LDV_COMMENT_FUNCTION_CALL Function from field "stop" from driver structure with callbacks "wl12xx_ops" */ 1663 wl12xx_op_stop( var_group1); 1664 /* LDV_COMMENT_BEGIN_PREP */ 1665 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1666 FIF_ALLMULTI | \ 1667 FIF_FCSFAIL | \ 1668 FIF_BCN_PRBRESP_PROMISC | \ 1669 FIF_CONTROL | \ 1670 FIF_OTHER_BSS) 1671 #define WL12XX_DEFAULT_CHANNEL 1 1672 /* LDV_COMMENT_END_PREP */ 1673 1674 1675 1676 1677 } 1678 1679 break; 1680 case 2: { 1681 1682 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1683 1684 1685 /* content: static int wl12xx_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf)*/ 1686 /* LDV_COMMENT_END_PREP */ 1687 /* LDV_COMMENT_FUNCTION_CALL Function from field "add_interface" from driver structure with callbacks "wl12xx_ops" */ 1688 wl12xx_op_add_interface( var_group1, var_group2); 1689 /* LDV_COMMENT_BEGIN_PREP */ 1690 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1691 FIF_ALLMULTI | \ 1692 FIF_FCSFAIL | \ 1693 FIF_BCN_PRBRESP_PROMISC | \ 1694 FIF_CONTROL | \ 1695 FIF_OTHER_BSS) 1696 #define WL12XX_DEFAULT_CHANNEL 1 1697 /* LDV_COMMENT_END_PREP */ 1698 1699 1700 1701 1702 } 1703 1704 break; 1705 case 3: { 1706 1707 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1708 1709 1710 /* content: static void wl12xx_op_remove_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf)*/ 1711 /* LDV_COMMENT_END_PREP */ 1712 /* LDV_COMMENT_FUNCTION_CALL Function from field "remove_interface" from driver structure with callbacks "wl12xx_ops" */ 1713 wl12xx_op_remove_interface( var_group1, var_group2); 1714 /* LDV_COMMENT_BEGIN_PREP */ 1715 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1716 FIF_ALLMULTI | \ 1717 FIF_FCSFAIL | \ 1718 FIF_BCN_PRBRESP_PROMISC | \ 1719 FIF_CONTROL | \ 1720 FIF_OTHER_BSS) 1721 #define WL12XX_DEFAULT_CHANNEL 1 1722 /* LDV_COMMENT_END_PREP */ 1723 1724 1725 1726 1727 } 1728 1729 break; 1730 case 4: { 1731 1732 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1733 1734 1735 /* content: static int wl12xx_op_config(struct ieee80211_hw *hw, u32 changed)*/ 1736 /* LDV_COMMENT_END_PREP */ 1737 /* LDV_COMMENT_FUNCTION_CALL Function from field "config" from driver structure with callbacks "wl12xx_ops" */ 1738 wl12xx_op_config( var_group1, var_wl12xx_op_config_18_p1); 1739 /* LDV_COMMENT_BEGIN_PREP */ 1740 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1741 FIF_ALLMULTI | \ 1742 FIF_FCSFAIL | \ 1743 FIF_BCN_PRBRESP_PROMISC | \ 1744 FIF_CONTROL | \ 1745 FIF_OTHER_BSS) 1746 #define WL12XX_DEFAULT_CHANNEL 1 1747 /* LDV_COMMENT_END_PREP */ 1748 1749 1750 1751 1752 } 1753 1754 break; 1755 case 5: { 1756 1757 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1758 1759 1760 /* content: FIF_OTHER_BSS) static void wl12xx_op_configure_filter(struct ieee80211_hw *hw, unsigned int changed, unsigned int *total, int mc_count, struct dev_addr_list *mc_list)*/ 1761 /* LDV_COMMENT_END_PREP */ 1762 /* LDV_COMMENT_FUNCTION_CALL Function from field "configure_filter" from driver structure with callbacks "wl12xx_ops" */ 1763 wl12xx_op_configure_filter( var_group1, var_wl12xx_op_configure_filter_19_p1, var_wl12xx_op_configure_filter_19_p2, var_wl12xx_op_configure_filter_19_p3, var_wl12xx_op_configure_filter_19_p4); 1764 /* LDV_COMMENT_BEGIN_PREP */ 1765 #define WL12XX_DEFAULT_CHANNEL 1 1766 /* LDV_COMMENT_END_PREP */ 1767 1768 1769 1770 1771 } 1772 1773 break; 1774 case 6: { 1775 1776 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1777 1778 1779 /* content: static int wl12xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)*/ 1780 /* LDV_COMMENT_END_PREP */ 1781 /* LDV_COMMENT_FUNCTION_CALL Function from field "tx" from driver structure with callbacks "wl12xx_ops" */ 1782 wl12xx_op_tx( var_group1, var_group3); 1783 /* LDV_COMMENT_BEGIN_PREP */ 1784 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1785 FIF_ALLMULTI | \ 1786 FIF_FCSFAIL | \ 1787 FIF_BCN_PRBRESP_PROMISC | \ 1788 FIF_CONTROL | \ 1789 FIF_OTHER_BSS) 1790 #define WL12XX_DEFAULT_CHANNEL 1 1791 /* LDV_COMMENT_END_PREP */ 1792 1793 1794 1795 1796 } 1797 1798 break; 1799 case 7: { 1800 1801 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1802 1803 1804 /* content: static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key)*/ 1805 /* LDV_COMMENT_BEGIN_PREP */ 1806 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1807 FIF_ALLMULTI | \ 1808 FIF_FCSFAIL | \ 1809 FIF_BCN_PRBRESP_PROMISC | \ 1810 FIF_CONTROL | \ 1811 FIF_OTHER_BSS) 1812 /* LDV_COMMENT_END_PREP */ 1813 /* LDV_COMMENT_FUNCTION_CALL Function from field "set_key" from driver structure with callbacks "wl12xx_ops" */ 1814 wl12xx_op_set_key( var_group1, var_wl12xx_op_set_key_21_p1, var_wl12xx_op_set_key_21_p2, var_wl12xx_op_set_key_21_p3, var_wl12xx_op_set_key_21_p4); 1815 /* LDV_COMMENT_BEGIN_PREP */ 1816 #define WL12XX_DEFAULT_CHANNEL 1 1817 /* LDV_COMMENT_END_PREP */ 1818 1819 1820 1821 1822 } 1823 1824 break; 1825 case 8: { 1826 1827 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1828 1829 1830 /* content: static int wl12xx_op_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req)*/ 1831 /* LDV_COMMENT_BEGIN_PREP */ 1832 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1833 FIF_ALLMULTI | \ 1834 FIF_FCSFAIL | \ 1835 FIF_BCN_PRBRESP_PROMISC | \ 1836 FIF_CONTROL | \ 1837 FIF_OTHER_BSS) 1838 /* LDV_COMMENT_END_PREP */ 1839 /* LDV_COMMENT_FUNCTION_CALL Function from field "hw_scan" from driver structure with callbacks "wl12xx_ops" */ 1840 wl12xx_op_hw_scan( var_group1, var_group4); 1841 /* LDV_COMMENT_BEGIN_PREP */ 1842 #define WL12XX_DEFAULT_CHANNEL 1 1843 /* LDV_COMMENT_END_PREP */ 1844 1845 1846 1847 1848 } 1849 1850 break; 1851 case 9: { 1852 1853 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1854 1855 1856 /* content: static void wl12xx_op_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changed)*/ 1857 /* LDV_COMMENT_BEGIN_PREP */ 1858 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1859 FIF_ALLMULTI | \ 1860 FIF_FCSFAIL | \ 1861 FIF_BCN_PRBRESP_PROMISC | \ 1862 FIF_CONTROL | \ 1863 FIF_OTHER_BSS) 1864 /* LDV_COMMENT_END_PREP */ 1865 /* LDV_COMMENT_FUNCTION_CALL Function from field "bss_info_changed" from driver structure with callbacks "wl12xx_ops" */ 1866 wl12xx_op_bss_info_changed( var_group1, var_group5, var_wl12xx_op_bss_info_changed_28_p2, var_wl12xx_op_bss_info_changed_28_p3); 1867 /* LDV_COMMENT_BEGIN_PREP */ 1868 #define WL12XX_DEFAULT_CHANNEL 1 1869 /* LDV_COMMENT_END_PREP */ 1870 1871 1872 1873 1874 } 1875 1876 break; 1877 case 10: { 1878 1879 /** STRUCT: struct type: ieee80211_ops, struct name: wl12xx_ops **/ 1880 1881 1882 /* content: static int wl12xx_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)*/ 1883 /* LDV_COMMENT_BEGIN_PREP */ 1884 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1885 FIF_ALLMULTI | \ 1886 FIF_FCSFAIL | \ 1887 FIF_BCN_PRBRESP_PROMISC | \ 1888 FIF_CONTROL | \ 1889 FIF_OTHER_BSS) 1890 /* LDV_COMMENT_END_PREP */ 1891 /* LDV_COMMENT_FUNCTION_CALL Function from field "set_rts_threshold" from driver structure with callbacks "wl12xx_ops" */ 1892 wl12xx_op_set_rts_threshold( var_group1, var_wl12xx_op_set_rts_threshold_27_p1); 1893 /* LDV_COMMENT_BEGIN_PREP */ 1894 #define WL12XX_DEFAULT_CHANNEL 1 1895 /* LDV_COMMENT_END_PREP */ 1896 1897 1898 1899 1900 } 1901 1902 break; 1903 case 11: { 1904 1905 /** STRUCT: struct type: spi_driver, struct name: wl12xx_spi_driver **/ 1906 if(ldv_s_wl12xx_spi_driver_spi_driver==0) { 1907 1908 /* content: static int __devinit wl12xx_probe(struct spi_device *spi)*/ 1909 /* LDV_COMMENT_BEGIN_PREP */ 1910 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1911 FIF_ALLMULTI | \ 1912 FIF_FCSFAIL | \ 1913 FIF_BCN_PRBRESP_PROMISC | \ 1914 FIF_CONTROL | \ 1915 FIF_OTHER_BSS) 1916 #define WL12XX_DEFAULT_CHANNEL 1 1917 /* LDV_COMMENT_END_PREP */ 1918 /* LDV_COMMENT_FUNCTION_CALL Function from field "probe" from driver structure with callbacks "wl12xx_spi_driver". Standart function test for correct return result. */ 1919 res_wl12xx_probe_31 = wl12xx_probe( var_group6); 1920 ldv_check_return_value(res_wl12xx_probe_31); 1921 if(res_wl12xx_probe_31) 1922 goto ldv_module_exit; 1923 ldv_s_wl12xx_spi_driver_spi_driver=0; 1924 1925 } 1926 1927 } 1928 1929 break; 1930 case 12: { 1931 1932 /** CALLBACK SECTION request_irq **/ 1933 LDV_IN_INTERRUPT=2; 1934 1935 /* content: static irqreturn_t wl12xx_irq(int irq, void *cookie)*/ 1936 /* LDV_COMMENT_END_PREP */ 1937 /* LDV_COMMENT_FUNCTION_CALL */ 1938 wl12xx_irq( var_wl12xx_irq_3_p0, var_wl12xx_irq_3_p1); 1939 /* LDV_COMMENT_BEGIN_PREP */ 1940 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1941 FIF_ALLMULTI | \ 1942 FIF_FCSFAIL | \ 1943 FIF_BCN_PRBRESP_PROMISC | \ 1944 FIF_CONTROL | \ 1945 FIF_OTHER_BSS) 1946 #define WL12XX_DEFAULT_CHANNEL 1 1947 /* LDV_COMMENT_END_PREP */ 1948 LDV_IN_INTERRUPT=1; 1949 1950 1951 1952 } 1953 1954 break; 1955 default: break; 1956 1957 } 1958 1959 } 1960 1961 ldv_module_exit: 1962 1963 /** INIT: init_type: ST_MODULE_EXIT **/ 1964 /* content: static void __exit wl12xx_exit(void)*/ 1965 /* LDV_COMMENT_BEGIN_PREP */ 1966 #define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 1967 FIF_ALLMULTI | \ 1968 FIF_FCSFAIL | \ 1969 FIF_BCN_PRBRESP_PROMISC | \ 1970 FIF_CONTROL | \ 1971 FIF_OTHER_BSS) 1972 #define WL12XX_DEFAULT_CHANNEL 1 1973 /* LDV_COMMENT_END_PREP */ 1974 /* LDV_COMMENT_FUNCTION_CALL Kernel calls driver release function before driver will be uploaded from kernel. This function declared as "MODULE_EXIT(function name)". */ 1975 wl12xx_exit(); 1976 1977 /* LDV_COMMENT_FUNCTION_CALL Checks that all resources and locks are correctly released before the driver will be unloaded. */ 1978 ldv_final: ldv_check_final_state(); 1979 1980 /* LDV_COMMENT_END_FUNCTION_CALL_SECTION */ 1981 return; 1982 1983 } 1984 #endif 1985 1986 /* LDV_COMMENT_END_MAIN */ 1987 /* LDV_COMMENT_BEGIN_MODEL */ 1988 1989 /* 1990 * CONFIG_DEBUG_LOCK_ALLOC must be turned off to apply the given model. 1991 * To be independ on the value of this flag there is the corresponding 1992 * aspect model. 1993 */ 1994 1995 /* the function works only without aspectator */ 1996 long __builtin_expect(long val, long res) { 1997 return val; 1998 } 1999 2000 #include "engine-blast.h" 2001 2002 #include <linux/kernel.h> 2003 #include <linux/mutex.h> 2004 2005 /* Need this because rerouter is buggy!.. */ 2006 extern int ldv_mutex_TEMPLATE; 2007 /* Now the actual variable goes... */ 2008 int ldv_mutex_TEMPLATE = 1; 2009 2010 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='mutex_lock_interruptible') Check that the mutex was unlocked and nondeterministically lock it. Return the corresponding error code on fails*/ 2011 int mutex_lock_interruptible_TEMPLATE(struct mutex *lock) 2012 { 2013 int nondetermined; 2014 2015 /* LDV_COMMENT_ASSERT Mutex must be unlocked*/ 2016 ldv_assert(ldv_mutex_TEMPLATE == 1); 2017 2018 /* LDV_COMMENT_OTHER Construct the nondetermined result*/ 2019 nondetermined = ldv_undef_int(); 2020 2021 /* LDV_COMMENT_ASSERT Nondeterministically lock the mutex*/ 2022 if (nondetermined) 2023 { 2024 /* LDV_COMMENT_CHANGE_STATE Lock the mutex*/ 2025 ldv_mutex_TEMPLATE = 2; 2026 /* LDV_COMMENT_RETURN Finish with success*/ 2027 return 0; 2028 } 2029 else 2030 { 2031 /* LDV_COMMENT_RETURN Finish with the fail. The mutex is keeped unlocked*/ 2032 return -EINTR; 2033 } 2034 } 2035 2036 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='atomic_dec_and_mutex_lock') Lock if atomic decrement result is zero */ 2037 int atomic_dec_and_mutex_lock_TEMPLATE(atomic_t *cnt, struct mutex *lock) 2038 { 2039 int atomic_value_after_dec; 2040 2041 /* LDV_COMMENT_ASSERT Mutex must be unlocked (since we may lock it in this function) */ 2042 ldv_assert(ldv_mutex_TEMPLATE == 1); 2043 2044 /* LDV_COMMENT_OTHER Assign the result of atomic decrement */ 2045 atomic_value_after_dec = ldv_undef_int(); 2046 2047 /* LDV_COMMENT_ASSERT Check if atomic decrement returns zero */ 2048 if (atomic_value_after_dec == 0) 2049 { 2050 /* LDV_COMMENT_CHANGE_STATE Lock the mutex, as atomic has decremented to zero*/ 2051 ldv_mutex_TEMPLATE = 2; 2052 /* LDV_COMMENT_RETURN Return 1 with a locked mutex */ 2053 return 1; 2054 } 2055 2056 /* LDV_COMMENT_RETURN Atomic decrement is still not zero, return 0 without locking the mutex */ 2057 return 0; 2058 } 2059 2060 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='mutex_lock_killable') Check that the mutex wasn unlocked and nondeterministically lock it. Return the corresponding error code on fails*/ 2061 int __must_check mutex_lock_killable_TEMPLATE(struct mutex *lock) 2062 { 2063 int nondetermined; 2064 2065 /* LDV_COMMENT_ASSERT Mutex must be unlocked*/ 2066 ldv_assert(ldv_mutex_TEMPLATE == 1); 2067 2068 /* LDV_COMMENT_OTHER Construct the nondetermined result*/ 2069 nondetermined = ldv_undef_int(); 2070 2071 /* LDV_COMMENT_ASSERT Nondeterministically lock the mutex*/ 2072 if (nondetermined) 2073 { 2074 /* LDV_COMMENT_CHANGE_STATE Lock the mutex*/ 2075 ldv_mutex_TEMPLATE = 2; 2076 /* LDV_COMMENT_RETURN Finish with success*/ 2077 return 0; 2078 } 2079 else 2080 { 2081 /* LDV_COMMENT_RETURN Finish with the fail. The mutex is keeped unlocked*/ 2082 return -EINTR; 2083 } 2084 } 2085 2086 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='mutex_is_locked') Checks whether the mutex is locked*/ 2087 int mutex_is_locked_TEMPLATE(struct mutex *lock) 2088 { 2089 int nondetermined; 2090 2091 if(ldv_mutex_TEMPLATE == 1) { 2092 /* LDV_COMMENT_OTHER Construct the nondetermined result*/ 2093 nondetermined = ldv_undef_int(); 2094 if(nondetermined) { 2095 /* LDV_COMMENT_RETURN the mutex is unlocked*/ 2096 return 0; 2097 } else { 2098 /* LDV_COMMENT_RETURN the mutex is locked*/ 2099 return 1; 2100 } 2101 } else { 2102 /* LDV_COMMENT_RETURN the mutex is locked*/ 2103 return 1; 2104 } 2105 } 2106 2107 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='mutex_lock(?!_interruptible|_killable)') Check that the mutex was not locked and lock it*/ 2108 void mutex_lock_TEMPLATE(struct mutex *lock) 2109 { 2110 /* LDV_COMMENT_ASSERT Mutex must be unlocked*/ 2111 ldv_assert(ldv_mutex_TEMPLATE == 1); 2112 /* LDV_COMMENT_CHANGE_STATE Lock the mutex*/ 2113 ldv_mutex_TEMPLATE = 2; 2114 } 2115 2116 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='mutex_trylock') Check that the mutex was not locked and nondeterministically lock it. Return 0 on fails*/ 2117 int mutex_trylock_TEMPLATE(struct mutex *lock) 2118 { 2119 int is_mutex_held_by_another_thread; 2120 2121 /* LDV_COMMENT_ASSERT Mutex must be unlocked*/ 2122 ldv_assert(ldv_mutex_TEMPLATE == 1); 2123 2124 /* LDV_COMMENT_OTHER Construct the nondetermined result*/ 2125 is_mutex_held_by_another_thread = ldv_undef_int(); 2126 2127 /* LDV_COMMENT_ASSERT Nondeterministically lock the mutex*/ 2128 if (is_mutex_held_by_another_thread) 2129 { 2130 /* LDV_COMMENT_RETURN Finish with fail*/ 2131 return 0; 2132 } 2133 else 2134 { 2135 /* LDV_COMMENT_CHANGE_STATE Lock the mutex*/ 2136 ldv_mutex_TEMPLATE = 2; 2137 /* LDV_COMMENT_RETURN Finish with success*/ 2138 return 1; 2139 } 2140 } 2141 2142 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='mutex_unlock') Check that the mutex was locked and unlock it*/ 2143 void mutex_unlock_TEMPLATE(struct mutex *lock) 2144 { 2145 /* LDV_COMMENT_ASSERT Mutex must be locked*/ 2146 ldv_assert(ldv_mutex_TEMPLATE == 2); 2147 /* LDV_COMMENT_CHANGE_STATE Unlock the mutex*/ 2148 ldv_mutex_TEMPLATE = 1; 2149 } 2150 2151 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='check_final_state') Check that the mutex is unlocked at the end*/ 2152 void ldv_check_final_state_TEMPLATE(void) 2153 { 2154 /* LDV_COMMENT_ASSERT The mutex must be unlocked at the end*/ 2155 ldv_assert(ldv_mutex_TEMPLATE == 1); 2156 } 2157 2158 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='ldv_initialize') Initialize mutex variables*/ 2159 void ldv_initialize_TEMPLATE(void) 2160 { 2161 /* LDV_COMMENT_ASSERT Initialize mutex with initial model value*/ 2162 ldv_mutex_TEMPLATE = 1; 2163 } 2164 2165 /* LDV_COMMENT_END_MODEL */
1 /* 2 * This file is part of wl12xx 3 * 4 * Copyright (c) 1998-2007 Texas Instruments Incorporated 5 * Copyright (C) 2008 Nokia Corporation 6 * 7 * Contact: Kalle Valo <kalle.valo@nokia.com> 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * version 2 as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 * 02110-1301 USA 22 * 23 */ 24 25 #ifndef __WL12XX_SPI_H__ 26 #define __WL12XX_SPI_H__ 27 28 #include "cmd.h" 29 #include "acx.h" 30 #include "reg.h" 31 32 #define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 33 34 #define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0 35 #define HW_ACCESS_PART0_START_ADDR 0x1FFC4 36 #define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8 37 #define HW_ACCESS_PART1_START_ADDR 0x1FFCC 38 39 #define HW_ACCESS_REGISTER_SIZE 4 40 41 #define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 42 43 #define WSPI_CMD_READ 0x40000000 44 #define WSPI_CMD_WRITE 0x00000000 45 #define WSPI_CMD_FIXED 0x20000000 46 #define WSPI_CMD_BYTE_LENGTH 0x1FFE0000 47 #define WSPI_CMD_BYTE_LENGTH_OFFSET 17 48 #define WSPI_CMD_BYTE_ADDR 0x0001FFFF 49 50 #define WSPI_INIT_CMD_CRC_LEN 5 51 52 #define WSPI_INIT_CMD_START 0x00 53 #define WSPI_INIT_CMD_TX 0x40 54 /* the extra bypass bit is sampled by the TNET as '1' */ 55 #define WSPI_INIT_CMD_BYPASS_BIT 0x80 56 #define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07 57 #define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80 58 #define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00 59 #define WSPI_INIT_CMD_IOD 0x40 60 #define WSPI_INIT_CMD_IP 0x20 61 #define WSPI_INIT_CMD_CS 0x10 62 #define WSPI_INIT_CMD_WS 0x08 63 #define WSPI_INIT_CMD_WSPI 0x01 64 #define WSPI_INIT_CMD_END 0x01 65 66 #define WSPI_INIT_CMD_LEN 8 67 68 #define TNETWIF_READ_OFFSET_BYTES 8 69 #define HW_ACCESS_WSPI_FIXED_BUSY_LEN \ 70 ((TNETWIF_READ_OFFSET_BYTES - 4) / sizeof(u32)) 71 #define HW_ACCESS_WSPI_INIT_CMD_MASK 0 72 73 74 /* Raw target IO, address is not translated */ 75 void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf, size_t len); 76 void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf, size_t len); 77 78 /* Memory target IO, address is tranlated to partition 0 */ 79 void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf, size_t len); 80 void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf, size_t len); 81 u32 wl12xx_mem_read32(struct wl12xx *wl, int addr); 82 void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val); 83 84 /* Registers IO */ 85 u32 wl12xx_reg_read32(struct wl12xx *wl, int addr); 86 void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val); 87 88 /* INIT and RESET words */ 89 void wl12xx_spi_reset(struct wl12xx *wl); 90 void wl12xx_spi_init(struct wl12xx *wl); 91 void wl12xx_set_partition(struct wl12xx *wl, 92 u32 part_start, u32 part_size, 93 u32 reg_start, u32 reg_size); 94 95 static inline u32 wl12xx_read32(struct wl12xx *wl, int addr) 96 { 97 u32 response; 98 99 wl12xx_spi_read(wl, addr, &response, sizeof(u32)); 100 101 return response; 102 } 103 104 static inline void wl12xx_write32(struct wl12xx *wl, int addr, u32 val) 105 { 106 wl12xx_spi_write(wl, addr, &val, sizeof(u32)); 107 } 108 109 #endif /* __WL12XX_SPI_H__ */

Here is the explanation of the rule violation arisen in your driver for the corresponding kernel.

Note that there may be no error indeed. Please see on error trace and source code to understand whether there is an error in your driver.

The Error trace column contains the path on which rule is violated. You can choose some entity classes to be shown or hiden by clicking on the corresponding checkboxes or in the advanced Others menu. Also you can show or hide each particular entity by clicking on the corresponding - or +. In hovering on some entities you can see their descriptions and meaning. Also the error trace is binded with the source code. Line numbers are shown as links on the left. You can click on them to open the corresponding line in source code. Line numbers and file names are shown in entity descriptions.

The Source code column contains content of files related with the error trace. There are your driver (note that there are some our modifications at the end), kernel headers and rule source code. Tabs show the currently opened file and other available files. In hovering you can see file names in titles. On clicking the corresponding file content will be shown.