summaryrefslogtreecommitdiff
path: root/sys/dev/usb/usbnet.c
AgeCommit message (Collapse)Author
2022-09-22usbnet(9): Omit needless miilock around uno_stop.riastradh
This time for real!
2022-09-20revert rev 1.111 (which was 1.106 again, without the 1.107 changes).mrg
fixes an assert reported by msaitoh@. also fix another missing miilock assert in usbnet_stop() that triggered for me.
2022-09-13usbnet(9): Call mii_down once we've finished with mii_tick.riastradh
2022-08-23usbnet(9): Don't touch ifp->if_flags in usbnet_start_locked.riastradh
Instead, consult unp->unp_txstopped -- but the caller already guarantees it is not stopped, so turn the conditional into an assertion anyway.
2022-08-20usbnet(9): New usbnet_ispromisc(un).riastradh
Replaces ifp->if_flags & IFF_PROMISC in multicast filter updates.
2022-08-20usbnet(9): Rename core lock -> mii lock.riastradh
No functional change intended.
2022-08-20usbnet(9): Limit scope of core lock to mii and tick scheduling.riastradh
Bringing the interface up or down is serialized by IFNET_LOCK, and we prevent further mii callbacks with mii_down, so there's no need for another lock to serialize uno_init, uno_stop, and the mii callbacks.
2022-08-20usbnet(9): Call mii_down once we've finished with mii_tick.riastradh
2022-08-20usbnet(9): Simplify core lock use in usbnet_tick_task.riastradh
2022-08-20usbnet(9): Call uno_tick before mii stuff.riastradh
The one driver that uses it, cue(4), uses it just for statistics gathering; hard to imagine that order could be important here. But this will allow for some simplification of the surrounding code.
2022-08-20usbnet(9): Assert core lock is held on usbnet_set_link.riastradh
This is only allowed to be called via the uno_statchg callback, which in turn is called only with the core lock held. (usbnet_set_link is also called internally in usbnet(9) with the core lock held.)
2022-08-20usbnet(9): Split unp_stopping into stopped/txstopped/rxstopped.riastradh
In practical terms this could be done with one variable and an atomic store, but serializing all access with a lock makes reasoning easier, and the locks have to be taken by the logic that queries the variables anyway, and the variables are set only under heavy-weight configuration changes anyway. What this accomplishes is disentangling lock order between rxlock and txlock: they are never taken at the same time, so no order is needed. I renamed unp_stopping to unp_stopped for a compiler-assisted audit to make sure I reviewed every case of it.
2022-08-20usbnet(9): Don't touch unp_stopping in usbnet_pipe_intr.riastradh
This access was unprotected by a lock, but it's not necessary anyway: usbnet_stop aborts the pipes, and the xfer doesn't call usbd_transfer to reschedule itself -- it's an intr pipe, so it's rescheduled internally by usbdi(9) in a way that usbd_abort_pipe atomically prevents.
2022-08-20usbnet(9): Omit needless un->un_intr test in usbnet_pipe_intr.riastradh
un->un_intr can't change after attach, and we don't open the pipe if it's null. So no need to test it.
2022-08-20usbnet(9): Revert previous -- usbnet_media_upd does have IFNET_LOCK.riastradh
Not sure why I thought otherwise.
2022-08-20usbnet(9): Avoid ether_mediachange if stopped.riastradh
We are called without IFNET_LOCK held here, so touching ifp->if_flags is forbidden, but that's the first thing ether_mediachange does. XXX not right either, need to eliminate the check from ether_mediachange
2022-08-16usbnet(9): Omit needless usbnet_core_mutex function.riastradh
While here, use inline, not __inline__, since this is not a header file where inline might be redefined by the user.
2022-08-12usbnet(9): Fix mbuf alignment and narrow bounds check.riastradh
In usbnet.c rev. 1.16, usbnet_newbuf was first passed a buffer length to verify it fits within MCLBYTES. It also changed m_adj to go before, not after, setting m_len and m_pkthdr.len -- which had the effect of making the m_adj a no-op, because after MGETHDR the mbuf has zero length and m_adj stops at the length of the mbuf, so nothing was aligned as intended. To make this aligned as intended, we require the buffer length to be _below_ MCLBYTES, by ETHER_ALIGN, so there's room for the ethernet header in a maximum-length payload. Once we do that, it is safe to initialize m_len = m_pkthdr.len = ETHER_ALIGN + buflen, which is below the actual size of the mbuf (MHLEN or MCLBYTES, depending), and _then_ do m_adj to align the pointer.
2022-08-07usbnet(9): Simplify assertions now that urndis(4) is less sketchy.riastradh
2022-03-05usbnet(9): uno_init is now optional.riastradh
Update assertion and man page accordingly.
2022-03-03usb: usbd_close_pipe never fails. Make it return void.riastradh
Prune dead branches as a result of this change.
2022-03-03usb: usbd_abort_pipe never fails. Make it return void.riastradh
Prune dead branches as a result of this change.
2022-03-03usbnet: On if_stop, abort xfers before resetting hardware.riastradh
uno_stop is supposed to have exclusive access to the hardware; this ensures that any concurrent uno_rx_loop has completed before we enter uno_stop.
2022-03-03usbnet: Omit needless detachcv name parameter to usbnet_attach.riastradh
2022-03-03usbnet: Omit empty uno_init functions.riastradh
2022-03-03usbnet: Factor usbnet_init_rx_tx out into usbnet_if_init.riastradh
Make it private; no need for drivers to call it any more.
2022-03-03usbnet: Handle usbnet_set_link for drivers with no media detect.riastradh
2022-03-03usbnet drivers: From *_uno_init, call *_uno_stop, not usbnet_stop.riastradh
Make usbnet_stop private now that no drivers use it. None of the driver-independent logic in usbnet_stop has any effect at this point because we are guaranteed not to be running, so only the driver-dependent logic in *_uno_stop (at most) is needed. For drivers with no *_uno_stop, just omit the call to usbnet_stop altogether. Some of this logic is obviously redundant with the subsequent call to *_reset -- to be addressed in a subsequent commit.
2022-03-03usbnet: Do nothing on if_init/stop if already in the target state.riastradh
The network stack _shouldn't_ ever call us if so, but I'm not yet sure it _won't_.
2022-03-03usbnet: Delete the core lock from the API.riastradh
Init/stop and ioctl happen under IFNET_LOCK. Multicast updates only happen after init and before stop. Core lock is no longer a relevant part of the API. Internally, it serves essentially just to lock out asynchronous mii activity during init/stop.
2022-03-03usbnet: Make usbnet_mii_readreg/writereg/statchg private to usbnet.c.riastradh
No drivers need to use these.
2022-03-03usbnet: Apply hardware multicast filter updates synchronously again.riastradh
To make this work: 1. Do it only under a new lock, unp_mcastlock. This lock lives at IPL_SOFTCLOCK so it can be taken from network stack callouts. It is forbidden to acquire the usbnet core lock under unp_mcastlock. 2. Do it only after usbnet_init_rx_tx and before usbnet_stop; if issued at any other time, drop the update on the floor. 3. Make usbnet_init_rx_tx apply any pending multicast filter updates under the lock before setting the flag that allows SIOCADDMULTI or SIOCDELMULTI to apply the updates. 4. Remove core lock asserts from various drivers' register access routines. This is necessary because the multicast filter updates are done with register reads/writes, but _cannot_ take the core lock when the caller holds softnet_lock. This now programs the hardware multicast filter redundantly in many drivers which already explicitly call *_uno_mcast from the *_uno_init routines. This is probably harmless, but it will likely be better to remove the explicit calls.
2022-03-03usbnet: Take the core lock around uno_mcast.riastradh
Every driver does this already. This will enable us to change the lock that serializes access to the registers so we can go back to doing this synchronously in SIOCADDMULTI/SIOCDELMULTI.
2022-03-03usbnet: No need for the core lock in usbnet_ifflags_cb.riastradh
The only state this touches is unp_if_flags, and all paths touching it also hold IFNET_LOCK -- not to mention this is the only path that touches unp_if_flags in the first place!
2022-03-03usbnet: Make the tx/rx locks private to usbnet.c.riastradh
Suffice it for the drivers to know that uno_tx_prepare and uno_rx_loop have exclusive access to the chain, and, for tx, exclusive access to the mbuf.
2022-03-03usbnet: usbnet_busy is no longer referenced; release it!riastradh
2022-03-03usbnet: No need for usbnet_busy in mii callbacks.riastradh
After mii_detach, these have all completed and no new ones can be made, and detach doesn't start destroying anything until after mii_detach has returned, so there is no need to hang onto a reference count here.
2022-03-03usbnet: No need for usbnet_busy in usbnet_init_rx_tx or usbnet_stop.riastradh
These run with IFNET_LOCK held, and the interface cannot be detached until the IFNET_LOCK is released, so there is no need to hang onto a reference count here.
2022-03-03usbnet: Split multicast filter reprogramming into separate operation.riastradh
2022-03-03usbnet: Omit needless locking around usbnet_isdying.riastradh
Now that is tested and set with atomic_load/store, there is no need to hold the lock -- which means we can set it while the core lock is held during, e.g., a reset sequence, and use that to interrupt the sequence so it doesn't get stuck waiting to time out when the device is physically removed.
2022-03-03usbnet: Use atomic_load/store_relaxed for unp_dying.riastradh
This way we don't need to hold the core lock to avoid upsetting sanitizers (which probably find the current code upsetting), and we can use it to exit early from timeout loops that run under the core lock (which is probably not necessary for them to do anyway, but let's worry about that later).
2022-03-03usbnet: Print diagnostic about refcnt stragglers.riastradh
I don't think there can be any, but this message, if printed, would falsify my hypothesis!
2022-03-03usbnet: Enter uno_init with the core lock held.riastradh
This reduces code in all drivers except urndis(4) and aue(4). However, it's still safe for urndis to drop the core lock because the ifnet is locked, and the ifnet lock covers the DOWN->UP (uno_init) and UP->DOWN (uno_stop) transitions.
2022-03-03usbnet: Assert ioctl locking.riastradh
2022-03-03usbnet: Impart blame on whose ifnet is unlocked in uno_init.riastradh
2022-03-03usbnet: Don't waste time calling uno_stop if device is detaching.riastradh
The hardware is most likely gone, so trying to write to its registers (and, in some cases, wait until a timeout for a device to reset) is a waste of time. Even if it was detached only in software with drvctl, reattaching it will reset the device anyway.
2022-03-03usbnet: Avoid IFNET_LOCK on detach if we never attached the ifp.riastradh
2022-03-03usbnet: Clear watchdog timer before stopping hardware.riastradh
No need to take the lock again -- which might not be necessary because the callout and task have completed, but let's obviate the need to think about that.
2022-03-03usbnet: Omit needless locking/busying/testing in usbnet_tick_task.riastradh
usbnet_stop waits for the task to complete before resetting the hardware, and usbnet_detach waits for usbnet_stop to complete before destroying anything, so there's no need for any of this.
2022-03-03usbnet: Omit needless tests in usbnet_tick.riastradh
It's harmless for us to schedule the tick task even if unp_dying or unp_stopping is set by now, because usbnet_stop will just wait for it to finish anyway, and the callout can't be scheduled again until the interface is done stopping and is brought back up again. No need for unp == NULL test -- un->un_pri is initialized well before this callout can be scheduled, and is nulled out only at the end of usbnet_detach, at which point we have already halted this callout.