diff options
Diffstat (limited to 'backport/compat/backport-4.10.c')
-rw-r--r-- | backport/compat/backport-4.10.c | 276 |
1 files changed, 0 insertions, 276 deletions
diff --git a/backport/compat/backport-4.10.c b/backport/compat/backport-4.10.c deleted file mode 100644 index a35c699e..00000000 --- a/backport/compat/backport-4.10.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright(c) 2017 Hauke Mehrtens <hauke@hauke-m.de> - * - * Backport functionality introduced in Linux 4.10. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/ethtool.h> -#include <linux/mii.h> -#include <linux/page_ref.h> -#include <linux/gfp.h> - -#if LINUX_VERSION_IS_GEQ(4,6,0) -#if LINUX_VERSION_IS_LESS(4,7,0) -static bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, - const unsigned long *src) -{ - bool retval = true; - - /* TODO: following test will soon always be true */ - if (__ETHTOOL_LINK_MODE_MASK_NBITS > 32) { - __ETHTOOL_DECLARE_LINK_MODE_MASK(ext); - - bitmap_zero(ext, __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_fill(ext, 32); - bitmap_complement(ext, ext, __ETHTOOL_LINK_MODE_MASK_NBITS); - if (bitmap_intersects(ext, src, - __ETHTOOL_LINK_MODE_MASK_NBITS)) { - /* src mask goes beyond bit 31 */ - retval = false; - } - } - *legacy_u32 = src[0]; - return retval; -} - -static void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst, - u32 legacy_u32) -{ - bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS); - dst[0] = legacy_u32; -} -#endif - -static u32 mii_get_an(struct mii_if_info *mii, u16 addr) -{ - int advert; - - advert = mii->mdio_read(mii->dev, mii->phy_id, addr); - - return mii_lpa_to_ethtool_lpa_t(advert); -} - -/** - * mii_ethtool_set_link_ksettings - set settings that are specified in @cmd - * @mii: MII interfaces - * @cmd: requested ethtool_link_ksettings - * - * Returns 0 for success, negative on error. - */ -int mii_ethtool_set_link_ksettings(struct mii_if_info *mii, - const struct ethtool_link_ksettings *cmd) -{ - struct net_device *dev = mii->dev; - u32 speed = cmd->base.speed; - - if (speed != SPEED_10 && - speed != SPEED_100 && - speed != SPEED_1000) - return -EINVAL; - if (cmd->base.duplex != DUPLEX_HALF && cmd->base.duplex != DUPLEX_FULL) - return -EINVAL; - if (cmd->base.port != PORT_MII) - return -EINVAL; - if (cmd->base.phy_address != mii->phy_id) - return -EINVAL; - if (cmd->base.autoneg != AUTONEG_DISABLE && - cmd->base.autoneg != AUTONEG_ENABLE) - return -EINVAL; - if ((speed == SPEED_1000) && (!mii->supports_gmii)) - return -EINVAL; - - /* ignore supported, maxtxpkt, maxrxpkt */ - - if (cmd->base.autoneg == AUTONEG_ENABLE) { - u32 bmcr, advert, tmp; - u32 advert2 = 0, tmp2 = 0; - u32 advertising; - - ethtool_convert_link_mode_to_legacy_u32( - &advertising, cmd->link_modes.advertising); - - if ((advertising & (ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full)) == 0) - return -EINVAL; - - /* advertise only what has been requested */ - advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE); - tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4); - if (mii->supports_gmii) { - advert2 = mii->mdio_read(dev, mii->phy_id, - MII_CTRL1000); - tmp2 = advert2 & - ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); - } - tmp |= ethtool_adv_to_mii_adv_t(advertising); - - if (mii->supports_gmii) - tmp2 |= ethtool_adv_to_mii_ctrl1000_t(advertising); - if (advert != tmp) { - mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp); - mii->advertising = tmp; - } - if ((mii->supports_gmii) && (advert2 != tmp2)) - mii->mdio_write(dev, mii->phy_id, MII_CTRL1000, tmp2); - - /* turn on autonegotiation, and force a renegotiate */ - bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); - bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); - mii->mdio_write(dev, mii->phy_id, MII_BMCR, bmcr); - - mii->force_media = 0; - } else { - u32 bmcr, tmp; - - /* turn off auto negotiation, set speed and duplexity */ - bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); - tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | - BMCR_SPEED1000 | BMCR_FULLDPLX); - if (speed == SPEED_1000) - tmp |= BMCR_SPEED1000; - else if (speed == SPEED_100) - tmp |= BMCR_SPEED100; - if (cmd->base.duplex == DUPLEX_FULL) { - tmp |= BMCR_FULLDPLX; - mii->full_duplex = 1; - } else { - mii->full_duplex = 0; - } - if (bmcr != tmp) - mii->mdio_write(dev, mii->phy_id, MII_BMCR, tmp); - - mii->force_media = 1; - } - return 0; -} -EXPORT_SYMBOL(mii_ethtool_set_link_ksettings); - - -/** - * mii_ethtool_get_link_ksettings - get settings that are specified in @cmd - * @mii: MII interface - * @cmd: requested ethtool_link_ksettings - * - * The @cmd parameter is expected to have been cleared before calling - * mii_ethtool_get_link_ksettings(). - * - * Returns 0 for success, negative on error. - */ -int mii_ethtool_get_link_ksettings(struct mii_if_info *mii, - struct ethtool_link_ksettings *cmd) -{ - struct net_device *dev = mii->dev; - u16 bmcr, bmsr, ctrl1000 = 0, stat1000 = 0; - u32 nego, supported, advertising, lp_advertising; - - supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | - SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII); - if (mii->supports_gmii) - supported |= SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full; - - /* only supports twisted-pair */ - cmd->base.port = PORT_MII; - - /* this isn't fully supported at higher layers */ - cmd->base.phy_address = mii->phy_id; - cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C22; - - advertising = ADVERTISED_TP | ADVERTISED_MII; - - bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); - bmsr = mii->mdio_read(dev, mii->phy_id, MII_BMSR); - if (mii->supports_gmii) { - ctrl1000 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); - stat1000 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000); - } - if (bmcr & BMCR_ANENABLE) { - advertising |= ADVERTISED_Autoneg; - cmd->base.autoneg = AUTONEG_ENABLE; - - advertising |= mii_get_an(mii, MII_ADVERTISE); - if (mii->supports_gmii) - advertising |= mii_ctrl1000_to_ethtool_adv_t(ctrl1000); - - if (bmsr & BMSR_ANEGCOMPLETE) { - lp_advertising = mii_get_an(mii, MII_LPA); - lp_advertising |= - mii_stat1000_to_ethtool_lpa_t(stat1000); - } else { - lp_advertising = 0; - } - - nego = advertising & lp_advertising; - - if (nego & (ADVERTISED_1000baseT_Full | - ADVERTISED_1000baseT_Half)) { - cmd->base.speed = SPEED_1000; - cmd->base.duplex = !!(nego & ADVERTISED_1000baseT_Full); - } else if (nego & (ADVERTISED_100baseT_Full | - ADVERTISED_100baseT_Half)) { - cmd->base.speed = SPEED_100; - cmd->base.duplex = !!(nego & ADVERTISED_100baseT_Full); - } else { - cmd->base.speed = SPEED_10; - cmd->base.duplex = !!(nego & ADVERTISED_10baseT_Full); - } - } else { - cmd->base.autoneg = AUTONEG_DISABLE; - - cmd->base.speed = ((bmcr & BMCR_SPEED1000 && - (bmcr & BMCR_SPEED100) == 0) ? - SPEED_1000 : - ((bmcr & BMCR_SPEED100) ? - SPEED_100 : SPEED_10)); - cmd->base.duplex = (bmcr & BMCR_FULLDPLX) ? - DUPLEX_FULL : DUPLEX_HALF; - - lp_advertising = 0; - } - - mii->full_duplex = cmd->base.duplex; - - ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, - supported); - ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, - advertising); - ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising, - lp_advertising); - - /* ignore maxtxpkt, maxrxpkt for now */ - - return 0; -} -EXPORT_SYMBOL(mii_ethtool_get_link_ksettings); -#endif /* LINUX_VERSION_IS_GEQ(4,6,0) */ - -#if LINUX_VERSION_IS_GEQ(4,2,0) -void __page_frag_cache_drain(struct page *page, unsigned int count) -{ - VM_BUG_ON_PAGE(page_ref_count(page) == 0, page); - - if (page_ref_sub_and_test(page, count)) { - unsigned int order = compound_order(page); - - /* - * __free_pages_ok() is not exported so call - * __free_pages() which decrements the ref counter - * and increment the ref counter before. - */ - page_ref_inc(page); - __free_pages(page, order); - } -} -EXPORT_SYMBOL_GPL(__page_frag_cache_drain); -#endif |