Compare commits

...

10 Commits

Author SHA1 Message Date
Kevin Lo fa75c1cc24 mwl: return ENOMEM when rx buffer allocation fails
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (push) Waiting to run
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (push) Waiting to run
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (push) Waiting to run
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (push) Waiting to run
Cross-build Kernel / amd64 macos-latest (clang-18) (push) Waiting to run
Cross-build Kernel / aarch64 macos-latest (clang-18) (push) Waiting to run
The malloc() failure path returned error, which is 0 at this point,
so callers would treat the allocation failure as success.
Return ENOMEM instead to correctly propagate the out-of-memory condition.

Reviewed by:	adrian
Differential Revision:	https://reviews.freebsd.org/D42282
2026-06-15 09:43:57 +08:00
Jim Huang Chen db887713de kldload: Improve error handling
Address a failure in linker_load_module (sys/kern/kern_linker.c) to
verify that an already-loaded module matches the version requirement,
which caused the method to return the error (EEXIST).  This was then
propagated back up to kldload, which incorrectly printed that the module
had already been loaded.

Add a lookup to modlist_lookup2 to distinguish between the two cases:
- A module is already loaded that is of the correct version, so the
  error EEXIST should be returned
- An already-loaded module is of the incorrect version, so the error
  ENOEXEC is returned (changed from ENOENT)

Reviewed by:	imp, kib
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57002
2026-06-14 19:45:50 -04:00
Bjoern A. Zeeb 1c601bf516 LinuxKPI: 802.11: lock down mac80211 downcalls
Add lock assertions and "might_sleep" annotations to various
mac80211 operation downcalls into the driver.

Make sure the code to these is all covered by locks--pushing more wiphy
lock into the code--or lock assertions as well.  Split up parts of the
MC code up into an unlocked and locked version to avoid recurive locking.

Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2026-06-14 22:56:20 +00:00
Bjoern A. Zeeb 134e90e01d mt76: mt7921: depend on lindebugfs and turn debugfs support on
Add the missing MODULE_DEPEND() calls for lindebugfs.
It is unfortunate that they are shared code between various bus
implementations.  Ideally we would leave the MODULE_DEPEND() calls
in the debugfs.c file instead of adding extra #ifdef guards to the
bus attachment files.

Turn debugfs support on for mt76(core) and the mt7921 module for now.

Sponsonred by:	The FreeBSD Foundation
MFC after:	3 days
2026-06-14 22:55:53 +00:00
Bjoern A. Zeeb b662295ecb mt76: mt7921: terminate fw log messages with \n
In order to make the firmware messages spewed on the console readable
write one message per line and not one very long line.

Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2026-06-14 22:55:23 +00:00
Bjoern A. Zeeb baf8561bdc mt76: ensure net80211 com instance before returning from driver load
Do as we have done for iwlwifi (f808c43ad9,  bee60c9897) add a
completion event for device registration which calls into 802.11
and creates the wifi "device" (net80211 com instance).
This is needed as otherwise the deferred work in the mt76 drivers
(mt7915, mt7921, mt7925, mt7996; but not the 7615 [*]) would make
driver loading return before the wifi device is there.  We would then
continue, e.g., during rc startup and race possibly trying to create
a vap (wlan interface) with the underlying device not being registered
yet and fail.

[*] the 7615 does not seem to do this asynchronously so is fine.

Sponsored by:	The FreeBSD Foundation
Tested on:	7921, others to be tested at time
MFC after:	3 days
2026-06-14 22:55:14 +00:00
Bjoern A. Zeeb b8ec4929e9 callout: ddb: resolve symbol of callout function
In the ddb show callout function try to resolve the symbol of the
callout function to improve debugging.  In my case I went through
various callouts from show ktr to check what they were and this saved
me opening lldb/gdb next to it (and still having the old kernel as
the panic to debug was upon reboot).

Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
Reviewed by:	rlibby
Differential Revision: https://reviews.freebsd.org/D57521
2026-06-14 22:31:39 +00:00
Bjoern A. Zeeb 84008e34ce lindebugfs: improve an error message
In case the fill function fails do not report (read/write) but the
actual operation only given we can easily determine it.

Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
Reviewed by:	dumbbell, emaste
Differential Revision: https://reviews.freebsd.org/D57523
2026-06-14 22:31:38 +00:00
Bjoern A. Zeeb 3fa40c5eb8 linudebugfs: fix simple_attr_write_common() kernel buffer
With 2cf15144da we added a kernel buffer for parsing input copying the
user buffer into that.  The problem is that we only copy exactly as many
bytes as the user supplied.  printf 1 would have a write_size of 1, while
echo 1 would have a write_size of 2 (1\n).  But in order to check and
parse we need a terminating '\0'.

Overallocate the kernel buffer by 1 and make sure it is always '\0'
terminated.

Remove the check that the string needs to be of different length than
the write_size as this will always fail unless the user passes in, e.g.,
"1\02\n\0" somehow in which case we won't bother as kstrto*ll() will
not only handle the '\n' but also stop at '\0' and should be fine or
it will fail and we will error.

In theory we could use a static buffer here as well as we know a maximum
possible length of digits plus \n and \0 and take a min of that buffer
length and write_size and then error on a small buffer but given this is
an optional debug interface, do not bother with any alloc (size).

Fixes:		2cf15144da ("lindebugfs: Pass user buffer pointers ..")
Sponsored by:	The FreeBSD Foundation
Reviewed by:	dumbbell
MFC after:	3 days
Differential Revision: https://reviews.freebsd.org/D57522
2026-06-14 22:31:38 +00:00
Bjoern A. Zeeb 009d92b25f mt76: mt7921: prevent PM from scheduling another delayed work on detach
Amongst others mt76_connac_pm_unref() is calling mt76_connac_power_save_sched()
which will (normaly) re-schedule the pm_work.
In various parts we also cancel that work, also during PCI detach ("shutdown",
"remove" in LinuxKPI terms).
However we also keep calling mt76_connac_pm_unref() in the detach path and thus
we get to a point where we re-scheduled the work but then the device goes away.
At that point LinuxKPI delayed work has a callput pending which is embedded in
the work structure (pm_work).  The moment we free the device that structure
and callout is gone but the callout is still on the list and once that list
is walked we panic.

Simply prevent mt76_connac_power_save_sched() from getting to the point of
possibly re-scheduling the pm_work by setting pm->enable to false in the
beginning of the detach path.

The are likely more paths which will need the same treatment as the code
is by far anything from "symmetric" (that is the attach path is highly
bus independent while the detach path is implemented per-bus).  Also
other chipsets share the same "logical paths" with their own names, so
they will need this too once we get to them.

Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2026-06-14 22:31:38 +00:00
22 changed files with 199 additions and 58 deletions
+1
View File
@@ -12,6 +12,7 @@
[EXTERR_CAT_FILEDESC] = "kern/kern_descrip.c",
[EXTERR_CAT_PROCEXIT] = "kern/kern_exit.c",
[EXTERR_CAT_FORK] = "kern/kern_fork.c",
[EXTERR_CAT_LINKER] = "kern/kern_linker.c",
[EXTERR_CAT_GENIO] = "kern/sys_generic.c",
[EXTERR_CAT_VFSBIO] = "kern/vfs_bio.c",
[EXTERR_CAT_INOTIFY] = "kern/vfs_inotify.c",
+8 -9
View File
@@ -95,8 +95,9 @@ path_check(const char *kldname, int quiet)
if (sb.st_dev != dev || sb.st_ino != ino) {
if (!quiet)
warnx("%s will be loaded from %s, not the "
"current directory", kldname, element);
warnx(
"%s will be loaded from %s, not the current directory",
kldname, element);
break;
} else if (sb.st_dev == dev && sb.st_ino == ino)
break;
@@ -171,15 +172,13 @@ main(int argc, char** argv)
if (!quiet) {
switch (errno) {
case EEXIST:
warnx("can't load %s: module "
"already loaded or "
"in kernel", argv[0]);
warnx(
"can't load %s: module already loaded or in kernel", argv[0]);
break;
case ENOEXEC:
warnx("an error occurred while "
"loading module %s. "
"Please check dmesg(8) for "
"more details.", argv[0]);
warnx(
"an error occurred while loading module %s. Please check dmesg(8) for more details.",
argv[0]);
break;
default:
warn("can't load %s", argv[0]);
+2 -2
View File
@@ -191,8 +191,8 @@ debugfs_fill(PFS_FILL_ARGS)
if (rc < 0) {
#ifdef INVARIANTS
printf("%s:%d read/write failed with %zd\n", __func__, __LINE__,
rc);
printf("%s:%d %s failed with %zd\n", __func__, __LINE__,
(uio->uio_rw == UIO_READ) ? "read" : "write", rc);
#endif
return (-rc);
}
+48 -10
View File
@@ -511,6 +511,8 @@ lkpi_sync_chanctx_cw_from_rx_bw(struct ieee80211_hw *hw,
enum ieee80211_sta_rx_bandwidth old_bw;
uint32_t changed;
lockdep_assert_wiphy(hw->wiphy);
chanctx_conf = rcu_dereference_protected(vif->bss_conf.chanctx_conf,
lockdep_is_held(&hw->wiphy->mtx));
if (chanctx_conf == NULL)
@@ -749,6 +751,9 @@ lkpi_sta_sync_from_ni(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct ieee80211_node *ni, bool updchnctx)
{
if (updchnctx)
lockdep_assert_wiphy(hw->wiphy);
/*
* Ensure rx_nss is at least 1 as otherwise drivers run into
* unexpected problems.
@@ -1950,7 +1955,7 @@ lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt)
}
static void
lkpi_update_mcast_filter(struct ieee80211com *ic)
lkpi_update_mcast_filter_locked(struct ieee80211com *ic)
{
struct lkpi_hw *lhw;
struct ieee80211_hw *hw;
@@ -1959,6 +1964,9 @@ lkpi_update_mcast_filter(struct ieee80211com *ic)
bool scanning;
lhw = ic->ic_softc;
hw = LHW_TO_HW(lhw);
lockdep_assert_wiphy(hw->wiphy);
LKPI_80211_LHW_SCAN_LOCK(lhw);
scanning = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
@@ -1973,7 +1981,6 @@ lkpi_update_mcast_filter(struct ieee80211com *ic)
if (lhw->mc_all_multi || lhw->ops->prepare_multicast == NULL)
flags |= FIF_ALLMULTI;
hw = LHW_TO_HW(lhw);
mc = lkpi_80211_mo_prepare_multicast(hw, &lhw->mc_list);
changed_flags = (lhw->mc_flags ^ flags) & FIF_FLAGS_MASK;
@@ -1989,6 +1996,20 @@ lkpi_update_mcast_filter(struct ieee80211com *ic)
LKPI_80211_LHW_MC_UNLOCK(lhw);
}
static void
lkpi_update_mcast_filter(struct ieee80211com *ic)
{
struct lkpi_hw *lhw;
struct ieee80211_hw *hw;
lhw = ic->ic_softc;
hw = LHW_TO_HW(lhw);
wiphy_lock(hw->wiphy);
lkpi_update_mcast_filter_locked(ic);
wiphy_unlock(hw->wiphy);
}
static enum ieee80211_bss_changed
lkpi_update_dtim_tsf(struct ieee80211_vif *vif, struct ieee80211_node *ni,
struct ieee80211vap *vap, const char *_f, int _l)
@@ -2118,6 +2139,8 @@ lkpi_hw_conf_idle(struct ieee80211_hw *hw, bool new)
int error;
bool old;
lockdep_assert_wiphy(hw->wiphy);
old = hw->conf.flags & IEEE80211_CONF_IDLE;
if (old == new)
return;
@@ -2135,8 +2158,12 @@ static enum ieee80211_bss_changed
lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
struct lkpi_hw *lhw)
{
enum ieee80211_bss_changed changed;
struct ieee80211_hw *hw;
struct lkpi_vif *lvif;
enum ieee80211_bss_changed changed;
hw = LHW_TO_HW(lhw);
lockdep_assert_wiphy(hw->wiphy);
changed = 0;
sta->aid = 0;
@@ -2147,7 +2174,7 @@ lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
changed |= BSS_CHANGED_ASSOC;
IMPROVE();
lkpi_update_mcast_filter(lhw->ic);
lkpi_update_mcast_filter_locked(lhw->ic);
/*
* Executing the bss_info_changed(BSS_CHANGED_ASSOC) with
@@ -2397,6 +2424,8 @@ lkpi_set_chanctx_conf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct lkpi_chanctx *lchanctx;
int error;
lockdep_assert_wiphy(hw->wiphy);
if (vif->bss_conf.chanctx_conf == chanctx_conf) {
if (!changed_set) {
IMPROVE("OBSOLETE?");
@@ -3075,7 +3104,7 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int
lkpi_bss_info_change(hw, vif, bss_changed);
/* Prepare_multicast && configure_filter. */
lkpi_update_mcast_filter(vap->iv_ic);
lkpi_update_mcast_filter_locked(vap->iv_ic);
out:
wiphy_unlock(hw->wiphy);
@@ -4198,12 +4227,13 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
ic_printf(ic, "%s: conf_tx ac %u failed %d\n",
__func__, ac, error);
}
wiphy_unlock(hw->wiphy);
bss_changed = BSS_CHANGED_QOS;
lkpi_bss_info_change(hw, vif, bss_changed);
/* Force MC init. */
lkpi_update_mcast_filter(ic);
lkpi_update_mcast_filter_locked(ic);
wiphy_unlock(hw->wiphy);
ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
@@ -4713,8 +4743,11 @@ lkpi_ic_scan_start(struct ieee80211com *ic)
lvif = VAP_TO_LVIF(vap);
vif = LVIF_TO_VIF(lvif);
if (vap->iv_state == IEEE80211_S_SCAN)
if (vap->iv_state == IEEE80211_S_SCAN) {
wiphy_lock(hw->wiphy);
lkpi_hw_conf_idle(hw, false);
wiphy_unlock(hw->wiphy);
}
LKPI_80211_LHW_SCAN_LOCK(lhw);
lhw->scan_flags |= LKPI_LHW_SCAN_RUNNING;
@@ -4967,7 +5000,8 @@ lkpi_ic_scan_start(struct ieee80211com *ic)
return;
}
lkpi_update_mcast_filter(ic);
wiphy_lock(hw->wiphy);
lkpi_update_mcast_filter_locked(ic);
TRACE_SCAN(ic, "Starting HW_SCAN: scan_flags %b, "
"ie_len %d, n_ssids %d, n_chan %d, common_ie_len %d [%d, %d]",
lhw->scan_flags, LKPI_LHW_SCAN_BITS, hw_req->req.ie_len,
@@ -4977,6 +5011,7 @@ lkpi_ic_scan_start(struct ieee80211com *ic)
hw_req->ies.len[NL80211_BAND_5GHZ]);
error = lkpi_80211_mo_hw_scan(hw, vif, hw_req);
wiphy_unlock(hw->wiphy);
if (error != 0) {
bool scan_done;
int e;
@@ -5122,8 +5157,11 @@ lkpi_ic_scan_end(struct ieee80211com *ic)
/* Send PS to stop buffering if n80211 does not for us? */
if (vap->iv_state == IEEE80211_S_SCAN)
if (vap->iv_state == IEEE80211_S_SCAN) {
wiphy_lock(hw->wiphy);
lkpi_hw_conf_idle(hw, true);
wiphy_unlock(hw->wiphy);
}
}
/*
@@ -218,6 +218,8 @@ lkpi_80211_mo_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct lkpi_hw *lhw;
int error;
lockdep_assert_wiphy(hw->wiphy);
/*
* MUST NOT return EPERM as that is a "magic number 1" based on rtw88
* driver indicating hw_scan is not supported despite the ops call
@@ -244,6 +246,8 @@ lkpi_80211_mo_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct lkpi_hw *lhw;
lockdep_assert_wiphy(hw->wiphy);
lhw = HW_TO_LHW(hw);
if (lhw->ops->cancel_hw_scan == NULL)
return;
@@ -291,6 +295,8 @@ lkpi_80211_mo_prepare_multicast(struct ieee80211_hw *hw,
struct lkpi_hw *lhw;
u64 ptr;
/* This seems fine without the wiphy lock. */
lhw = HW_TO_LHW(hw);
if (lhw->ops->prepare_multicast == NULL)
return (0);
@@ -306,6 +312,8 @@ lkpi_80211_mo_configure_filter(struct ieee80211_hw *hw, unsigned int changed_fla
{
struct lkpi_hw *lhw;
lockdep_assert_wiphy(hw->wiphy);
lhw = HW_TO_LHW(hw);
if (lhw->ops->configure_filter == NULL)
return;
@@ -429,6 +437,8 @@ lkpi_80211_mo_config(struct ieee80211_hw *hw, uint32_t changed)
struct lkpi_hw *lhw;
int error;
lockdep_assert_wiphy(hw->wiphy);
lhw = HW_TO_LHW(hw);
if (lhw->ops->config == NULL) {
error = EOPNOTSUPP;
@@ -497,6 +507,9 @@ lkpi_80211_mo_add_chanctx(struct ieee80211_hw *hw,
struct lkpi_chanctx *lchanctx;
int error;
might_sleep();
lockdep_assert_wiphy(hw->wiphy);
lhw = HW_TO_LHW(hw);
if (lhw->ops->add_chanctx == NULL) {
error = EOPNOTSUPP;
@@ -520,6 +533,9 @@ lkpi_80211_mo_change_chanctx(struct ieee80211_hw *hw,
{
struct lkpi_hw *lhw;
might_sleep();
lockdep_assert_wiphy(hw->wiphy);
lhw = HW_TO_LHW(hw);
if (lhw->ops->change_chanctx == NULL)
return;
@@ -535,6 +551,9 @@ lkpi_80211_mo_remove_chanctx(struct ieee80211_hw *hw,
struct lkpi_hw *lhw;
struct lkpi_chanctx *lchanctx;
might_sleep();
lockdep_assert_wiphy(hw->wiphy);
lhw = HW_TO_LHW(hw);
if (lhw->ops->remove_chanctx == NULL)
return;
@@ -163,15 +163,12 @@ simple_attr_write_common(struct file *filp, const char __user *ubuf,
if (*ppos != 0 || write_size < 1)
return (-EINVAL);
buf = malloc(write_size, M_LSATTR, M_WAITOK);
buf = malloc(write_size + 1, M_LSATTR, M_WAITOK);
if (copy_from_user(buf, ubuf, write_size) != 0) {
free(buf, M_LSATTR);
return (-EFAULT);
}
if (strnlen(buf, write_size) == write_size) {
free(buf, M_LSATTR);
return (-EINVAL);
}
buf[write_size] = '\0';
mutex_lock(&sattr->mutex);
+3
View File
@@ -124,3 +124,6 @@ mt76_register_debugfs_fops(struct mt76_phy *phy,
return dir;
}
EXPORT_SYMBOL_GPL(mt76_register_debugfs_fops);
#if defined(__FreeBSD__)
MODULE_DEPEND(mt76_core, lindebugfs, 1, 1, 1);
#endif
+4
View File
@@ -814,6 +814,10 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
set_bit(MT76_STATE_REGISTERED, &phy->state);
sched_set_fifo_low(dev->tx_worker.task);
#if defined(__FreeBSD__)
complete(&dev->drv_start_complete);
#endif
return 0;
}
EXPORT_SYMBOL_GPL(mt76_register_device);
+3
View File
@@ -1026,6 +1026,9 @@ struct mt76_dev {
} test_mtd;
#endif
struct workqueue_struct *wq;
#if defined(__FreeBSD__)
struct completion drv_start_complete;
#endif
union {
struct mt76_mmio mmio;
@@ -862,6 +862,9 @@ mt7915_init_hardware(struct mt7915_dev *dev, struct mt7915_phy *phy2)
mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
INIT_WORK(&dev->init_work, mt7915_init_work);
#if defined(__FreeBSD__)
init_completion(&dev->mt76.drv_start_complete);
#endif
ret = mt7915_dma_init(dev, phy2);
if (ret)
@@ -1298,6 +1301,9 @@ int mt7915_register_device(struct mt7915_dev *dev)
}
ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
#if defined(__FreeBSD__)
wait_for_completion(&dev->mt76.drv_start_complete);
#endif
dev->recovery.hw_init_done = true;
@@ -308,6 +308,9 @@ int mt7921_register_device(struct mt792x_dev *dev)
INIT_WORK(&dev->reset_work, mt7921_mac_reset_work);
INIT_WORK(&dev->init_work, mt7921_init_work);
#if defined(__FreeBSD__)
init_completion(&dev->mt76.drv_start_complete);
#endif
INIT_WORK(&dev->phy.roc_work, mt7921_roc_work);
timer_setup(&dev->phy.roc_timer, mt792x_roc_timer, 0);
@@ -359,6 +362,10 @@ int mt7921_register_device(struct mt792x_dev *dev)
queue_work(system_percpu_wq, &dev->init_work);
#if defined(__FreeBSD__)
wait_for_completion(&dev->mt76.drv_start_complete);
#endif
return 0;
}
EXPORT_SYMBOL_GPL(mt7921_register_device);
@@ -234,7 +234,11 @@ mt7921_mcu_debug_msg_event(struct mt792x_dev *dev, struct sk_buff *skb)
if (!msg->content[i])
msg->content[i] = ' ';
}
#if defined(__linux__)
wiphy_info(mt76_hw(dev)->wiphy, "%.*s", len, msg->content);
#elif defined(__FreeBSD__)
wiphy_info(mt76_hw(dev)->wiphy, "%.*s\n", len, msg->content);
#endif
}
}
@@ -51,6 +51,17 @@ static void mt7921e_unregister_device(struct mt792x_dev *dev)
if (dev->phy.chip_cap & MT792x_CHIP_CAP_WF_RF_PIN_CTRL_EVT_EN)
wiphy_rfkill_stop_polling(hw->wiphy);
#if defined(__FreeBSD__)
/*
* Prevent scheduling ps_work again in mt76_connac_power_save_sched().
* Otherwise upon shutdown we may have delayed work pending, which on
* FreeBSD means there is a callout running, but the ps_work will be
* freed along with the mt792x_dev and so there is a callout on a list
* which no longer exists.
*/
pm->enable = false;
#endif
cancel_work_sync(&dev->init_work);
mt76_unregister_device(&dev->mt76);
mt76_for_each_q_rx(&dev->mt76, i)
@@ -598,4 +609,7 @@ MODULE_VERSION(mt7921_pci, 1);
MODULE_DEPEND(mt7921_pci, mt76_core, 1, 1, 1);
MODULE_DEPEND(mt7921_pci, linuxkpi, 1, 1, 1);
MODULE_DEPEND(mt7921_pci, linuxkpi_wlan, 1, 1, 1);
#if defined(CONFIG_MT7921_DEBUGFS)
MODULE_DEPEND(mt7921_pci, lindebugfs, 1, 1, 1);
#endif
#endif
@@ -352,4 +352,7 @@ MODULE_DEPEND(mt7921_usb, mt76_core, 1, 1, 1);
MODULE_DEPEND(mt7921_usb, linuxkpi, 1, 1, 1);
MODULE_DEPEND(mt7921_usb, linuxkpi_wlan, 1, 1, 1);
MODULE_DEPEND(mt7921_usb, linuxkpi_usb, 1, 1, 1);
#if defined(CONFIG_MT7921_DEBUGFS)
MODULE_DEPEND(mt7921_usb, lindebugfs, 1, 1, 1);
#endif
#endif
@@ -228,6 +228,9 @@ int mt7925_register_device(struct mt792x_dev *dev)
INIT_WORK(&dev->reset_work, mt7925_mac_reset_work);
INIT_WORK(&dev->init_work, mt7925_init_work);
#if defined(__FreeBSD__)
init_completion(&dev->mt76.drv_start_complete);
#endif
INIT_WORK(&dev->phy.roc_work, mt7925_roc_work);
timer_setup(&dev->phy.roc_timer, mt792x_roc_timer, 0);
@@ -282,6 +285,10 @@ int mt7925_register_device(struct mt792x_dev *dev)
queue_work(system_percpu_wq, &dev->init_work);
#if defined(__FreeBSD__)
wait_for_completion(&dev->mt76.drv_start_complete);
#endif
return 0;
}
EXPORT_SYMBOL_GPL(mt7925_register_device);
@@ -1222,6 +1222,9 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
}
INIT_WORK(&dev->init_work, mt7996_init_work);
#if defined(__FreeBSD__)
init_completion(&dev->mt76.drv_start_complete);
#endif
INIT_WORK(&dev->wed_rro.work, mt7996_wed_rro_work);
INIT_LIST_HEAD(&dev->wed_rro.poll_list);
spin_lock_init(&dev->wed_rro.lock);
@@ -1736,6 +1739,9 @@ int mt7996_register_device(struct mt7996_dev *dev)
#endif
ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
#if defined(__FreeBSD__)
wait_for_completion(&dev->mt76.drv_start_complete);
#endif
dev->recovery.hw_init_done = true;
+1 -1
View File
@@ -2165,7 +2165,7 @@ mwl_rxdma_setup(struct mwl_softc *sc)
bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO);
if (bf == NULL) {
device_printf(sc->sc_dev, "malloc of %u rx buffers failed\n", bsize);
return error;
return ENOMEM;
}
sc->sc_rxdma.dd_bufptr = bf;
+55 -28
View File
@@ -32,10 +32,12 @@
#include "opt_hwpmc_hooks.h"
#include "opt_hwt_hooks.h"
#define EXTERR_CATEGORY EXTERR_CAT_LINKER
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/boottrace.h>
#include <sys/eventhandler.h>
#include <sys/exterrvar.h>
#include <sys/fcntl.h>
#include <sys/jail.h>
#include <sys/kernel.h>
@@ -455,13 +457,14 @@ linker_load_file(const char *filename, linker_file_t *result)
/* Refuse to load modules if securelevel raised */
if (prison0.pr_securelevel > 0)
return (EPERM);
return (EXTERROR(EPERM, "security level %jd",
prison0.pr_securelevel));
sx_assert(&kld_sx, SA_XLOCKED);
lf = linker_find_file_by_name(filename);
if (lf) {
KLD_DPF(FILE, ("linker_load_file: file %s is already loaded,"
" incrementing refs\n", filename));
KLD_DPF(FILE,
("linker_load_file: file %s is already loaded, incrementing refs\n", filename));
*result = lf;
lf->refs++;
return (0);
@@ -508,7 +511,7 @@ linker_load_file(const char *filename, linker_file_t *result)
*/
if (modules && TAILQ_EMPTY(&lf->modules)) {
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
return (ENOEXEC);
return (EXTERROR(ENOEXEC, "no modules loaded"));
}
linker_file_enable_sysctls(lf);
@@ -535,17 +538,19 @@ linker_load_file(const char *filename, linker_file_t *result)
__func__, filename);
/*
* Format not recognized or otherwise unloadable.
* When loading a module that is statically built into
* the kernel EEXIST percolates back up as the return
* value. Preserve this so that apps like sysinstall
* can recognize this special case and not post bogus
* dialog boxes.
* Format not recognized, version incompatible, or
* otherwise unloadable. When loading a module that is
* statically built into the kernel EEXIST percolates
* back up as the return value. Preserve this so that
* apps like sysinstall can recognize this special case
* and not post bogus dialog boxes.
*/
if (error != EEXIST)
error = ENOEXEC;
error = EXTERROR(ENOEXEC,
"module format or version error");
} else
error = ENOENT; /* Nothing found */
error = EXTERROR(ENOENT, "kld file not found");
/* Nothing found */
return (error);
}
@@ -2249,6 +2254,7 @@ linker_load_module(const char *kldname, const char *modname,
struct linker_file *parent, const struct mod_depend *verinfo,
struct linker_file **lfpp)
{
modlist_t mod;
linker_file_t lfdep;
const char *filename;
char *pathname;
@@ -2259,16 +2265,15 @@ linker_load_module(const char *kldname, const char *modname,
/*
* We have to load KLD
*/
KASSERT(verinfo == NULL, ("linker_load_module: verinfo"
" is not NULL"));
MPASS(verinfo == NULL);
if (!linker_root_mounted())
return (ENXIO);
return (EXTERROR(ENXIO, "root not yet mounted"));
pathname = linker_search_kld(kldname);
} else {
if (modlist_lookup2(modname, verinfo) != NULL)
return (EEXIST);
return (EXTERROR(EEXIST, "module already loaded"));
if (!linker_root_mounted())
return (ENXIO);
return (EXTERROR(ENXIO, "root not yet mounted"));
if (kldname != NULL)
pathname = strdup(kldname, M_LINKER);
else
@@ -2279,7 +2284,7 @@ linker_load_module(const char *kldname, const char *modname,
strlen(modname), verinfo);
}
if (pathname == NULL)
return (ENOENT);
return (EXTERROR(ENOENT, "kld file not found"));
/*
* Can't load more than one file with the same basename XXX:
@@ -2288,16 +2293,36 @@ linker_load_module(const char *kldname, const char *modname,
* provide different versions of the same modules.
*/
filename = linker_basename(pathname);
if (linker_find_file_by_name(filename))
error = EEXIST;
else do {
lfdep = linker_find_file_by_name(filename);
if (lfdep) {
mod = modlist_lookup(modname, 0);
MPASS(mod != NULL);
if (modname && verinfo &&
modlist_lookup2(modname, verinfo) == NULL) {
/*
* Desired module is already loaded, but the correct
* version does not exist.
*/
error = EXTERROR(ENOEXEC,
"incompatible module version %jd already loaded",
mod->version);
} else {
error = EXTERROR(EEXIST,
"module version %jd already loaded",
mod->version);
}
} else do {
error = linker_load_file(pathname, &lfdep);
if (error)
break;
if (modname && verinfo &&
modlist_lookup2(modname, verinfo) == NULL) {
mod = modlist_lookup(modname, 0);
error = EXTERROR(ENOEXEC,
"incompatible module version %jd already loaded",
mod->version);
linker_file_unload(lfdep, LINKER_UNLOAD_FORCE);
error = ENOENT;
break;
}
if (parent)
@@ -2343,10 +2368,11 @@ linker_load_dependencies(linker_file_t lf)
ver = ((const struct mod_version *)mp->md_data)->mv_version;
mod = modlist_lookup(modname, ver);
if (mod != NULL) {
printf("interface %s.%d already present in the KLD"
" '%s'!\n", modname, ver,
mod->container->filename);
return (EEXIST);
printf(
"interface %s.%d already present in the KLD '%s'!\n",
modname, ver, mod->container->filename);
return (EXTERROR(EEXIST,
"module version %jd already loaded", ver));
}
}
@@ -2376,8 +2402,9 @@ linker_load_dependencies(linker_file_t lf)
}
error = linker_load_module(NULL, modname, lf, verinfo, NULL);
if (error) {
printf("KLD %s: depends on %s - not available or"
" version mismatch\n", lf->filename, modname);
printf(
"KLD %s: depends on %s - not available or version mismatch\n",
lf->filename, modname);
break;
}
}
+3 -1
View File
@@ -1485,7 +1485,9 @@ _show_callout(struct callout *c)
C_DB_PRINTF("%" PRId64, c_time);
C_DB_PRINTF("%" PRId64, c_precision);
C_DB_PRINTF("%p", c_arg);
C_DB_PRINTF("%p", c_func);
db_printf(" %s = %p (", "c_func", c->c_func);
db_printsym((db_addr_t)c->c_func, DB_STGY_ANY);
db_printf(")\n");
C_DB_PRINTF("%p", c_lock);
C_DB_PRINTF("%#x", c_flags);
C_DB_PRINTF("%#x", c_iflags);
+1 -1
View File
@@ -14,7 +14,7 @@ MT76_USB= 0
# General options for common code so drivers can check.
MT76_ACPI?= 0
MT76_CONFIG_PM?= 0
MT76_DEBUGFS?= 0
MT76_DEBUGFS?= 1
MT76_SOC_WED?= 0
# Other
+1 -1
View File
@@ -8,7 +8,7 @@ MT7921_PCI= 1
MT7921_SDIO= 0
MT7921_USB= 0
MT7921_DEBUGFS= 0
MT7921_DEBUGFS= 1
# Common stuff.
SRCS+= init.c main.c mac.c mcu.c
+1
View File
@@ -41,6 +41,7 @@
#define EXTERR_CAT_PROCEXIT 16
#define EXTERR_CAT_VMM 17
#define EXTERR_CAT_HWPMC_IBS 18
#define EXTERR_CAT_LINKER 19
#endif