• Kristian Evensen's avatar
    cdc_ether: Improve ZTE MF823/831/910 handling · bfe9b9d2
    Kristian Evensen authored
    The firmware in several ZTE devices (at least the MF823/831/910
    modems/mifis) use OS fingerprinting to determine which type of device to
    export. In addition, these devices export a REST API which can be used to
    control the type of device. So far, on Linux, the devices have been seen as
    RNDIS or CDC Ether.
    
    When CDC Ether is used, devices of the same type are, as with RNDIS,
    exported with the same, bogus random MAC address. In addition, the devices
    (at least on all firmware revisions I have found) use the bogus MAC when
    sending traffic routed from external networks. And as a final feature, the
    devices sometimes export the link state incorrectly. There are also
    references online to several other ZTE devices displaying this behavior,
    with several different PIDs and MAC addresses.
    
    This patch tries to improve the handling of ZTE devices by doing the
    following:
    
    * Create a new driver_info-struct that is used by ZTE devices that do not
    have an explicit entry in the product table. This struct is the same as the
    default cdc_ether driver info, but a new bind- and an rx_fixup-function
    have been added.
    
    * In the new bind function, we check if we have read a random MAC from the
    device. If we have, then we generate a new random MAC address. This will
    ensure that all devices get a unique MAC.
    
    * The rx_fixup-function replaces the destination MAC address in the skb
    with that of the device. I have not seen a revision of these devices that
    behaves correctly (i.e., sets the right destination MAC), so I chose not to
    do any comparison with for example the known, bogus addresses.
    
    * The MF823/MF832/MF910 sometimes export cdc carrier on twice on connect
    (the correct behavior is off then on). Work around this by manually setting
    carrier to off if an on-notification is received and the NOCARRIER-bit is
    not set.
    
    This change will affect all devices, but it should take care of similar
    mistakes made by other manufacturers. I tried to think of/look/test for
    problems/regressions that could be introduced by this behavior, but could
    not find any. However, my familiarity with this code path is not that
    great, so there could be something I have overlooked.
    
    I have tested this patch with multiple revisions of all three devices, and
    they behave as expected. In other words, they all got a valid, random MAC,
    the correct operational state and I can receive/sent traffic without
    problems. I also tested with some other cdc_ether devices I have and did
    not find any problems/regressions caused by the two general changes.
    
    v3->v4:
    * Forgot to remove unused variables, sorry about that (thanks David
    Miller).
    
    v2->v3:
    * I had forgot to remove the random MAC generation from usbnet_cdc_bind()
    (thanks Oliver).
    * Rework logic in the ZTE bind-function a bit.
    
    v1->v2:
    * Only generate random MAC for ZTE devices (thanks Oliver Neukum).
    * Set random MAC and do RX fixup for all ZTE devices that do not have a
    product-entry, as the bogus MAC have been seen on devices with several
    different PIDs/MAC addresses. In other words, it seems to be the default
    behavior of ZTE CDC Ether devices (thanks Lars Melin).
    Signed-off-by: default avatarKristian Evensen <kristian.evensen@gmail.com>
    Acked-by: default avatarOliver Neukum <oneukum@suse.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    bfe9b9d2
cdc_ether.c 23.1 KB