Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rt2x00: fix rfkill regression on rt2500pci

As reported by Niels, starting rfkill polling during device probe
(commit e2bc7c5, generally sane change) broke rfkill on rt2500pci
device. I considered that bug as some initalization issue, which
should be fixed on rt2500pci specific code. But after several
attempts (see bug report for details) we fail to find working solution.
Hence I decided to revert to old behaviour on rt2500pci to fix
regression.

Additionally patch also unregister rfkill on device remove instead
of ifconfig down, what was another issue introduced by bad commit.

Bug report:
https://bugzilla.kernel.org/show_bug.cgi?id=73821

Fixes: e2bc7c5f3cb8 ("rt2x00: Fix rfkill_polling register function.")
Cc: stable@vger.kernel.org
Bisected-by: Niels <nille0386@googlemail.com>
Reported-and-tested-by: Niels <nille0386@googlemail.com>
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Stanislaw Gruszka and committed by
John W. Linville
616a8394 2fc68eb1

+28 -4
+6 -1
drivers/net/wireless/rt2x00/rt2500pci.c
··· 1681 1681 /* 1682 1682 * Detect if this device has an hardware controlled radio. 1683 1683 */ 1684 - if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) 1684 + if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) { 1685 1685 __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); 1686 + /* 1687 + * On this device RFKILL initialized during probe does not work. 1688 + */ 1689 + __set_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags); 1690 + } 1686 1691 1687 1692 /* 1688 1693 * Check if the BBP tuning should be enabled.
+1
drivers/net/wireless/rt2x00/rt2x00.h
··· 693 693 REQUIRE_SW_SEQNO, 694 694 REQUIRE_HT_TX_DESC, 695 695 REQUIRE_PS_AUTOWAKE, 696 + REQUIRE_DELAYED_RFKILL, 696 697 697 698 /* 698 699 * Capabilities
+21 -3
drivers/net/wireless/rt2x00/rt2x00dev.c
··· 1126 1126 return; 1127 1127 1128 1128 /* 1129 - * Unregister extra components. 1129 + * Stop rfkill polling. 1130 1130 */ 1131 - rt2x00rfkill_unregister(rt2x00dev); 1131 + if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) 1132 + rt2x00rfkill_unregister(rt2x00dev); 1132 1133 1133 1134 /* 1134 1135 * Allow the HW to uninitialize. ··· 1166 1165 } 1167 1166 1168 1167 set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags); 1168 + 1169 + /* 1170 + * Start rfkill polling. 1171 + */ 1172 + if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) 1173 + rt2x00rfkill_register(rt2x00dev); 1169 1174 1170 1175 return 0; 1171 1176 } ··· 1382 1375 rt2x00link_register(rt2x00dev); 1383 1376 rt2x00leds_register(rt2x00dev); 1384 1377 rt2x00debug_register(rt2x00dev); 1385 - rt2x00rfkill_register(rt2x00dev); 1378 + 1379 + /* 1380 + * Start rfkill polling. 1381 + */ 1382 + if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) 1383 + rt2x00rfkill_register(rt2x00dev); 1386 1384 1387 1385 return 0; 1388 1386 ··· 1401 1389 void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) 1402 1390 { 1403 1391 clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); 1392 + 1393 + /* 1394 + * Stop rfkill polling. 1395 + */ 1396 + if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) 1397 + rt2x00rfkill_unregister(rt2x00dev); 1404 1398 1405 1399 /* 1406 1400 * Disable radio.