1720c6343SVivien Didelot /* 2720c6343SVivien Didelot * Marvell 88E6xxx Address Translation Unit (ATU) support 3720c6343SVivien Didelot * 4720c6343SVivien Didelot * Copyright (c) 2008 Marvell Semiconductor 5720c6343SVivien Didelot * Copyright (c) 2017 Savoir-faire Linux, Inc. 6720c6343SVivien Didelot * 7720c6343SVivien Didelot * This program is free software; you can redistribute it and/or modify 8720c6343SVivien Didelot * it under the terms of the GNU General Public License as published by 9720c6343SVivien Didelot * the Free Software Foundation; either version 2 of the License, or 10720c6343SVivien Didelot * (at your option) any later version. 11720c6343SVivien Didelot */ 12720c6343SVivien Didelot 13720c6343SVivien Didelot #include "mv88e6xxx.h" 14720c6343SVivien Didelot #include "global1.h" 15720c6343SVivien Didelot 16720c6343SVivien Didelot /* Offset 0x0A: ATU Control Register */ 17720c6343SVivien Didelot 18*c3a7d4adSVivien Didelot int mv88e6xxx_g1_atu_set_learn2all(struct mv88e6xxx_chip *chip, bool learn2all) 19*c3a7d4adSVivien Didelot { 20*c3a7d4adSVivien Didelot u16 val; 21*c3a7d4adSVivien Didelot int err; 22*c3a7d4adSVivien Didelot 23*c3a7d4adSVivien Didelot err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_CONTROL, &val); 24*c3a7d4adSVivien Didelot if (err) 25*c3a7d4adSVivien Didelot return err; 26*c3a7d4adSVivien Didelot 27*c3a7d4adSVivien Didelot if (learn2all) 28*c3a7d4adSVivien Didelot val |= GLOBAL_ATU_CONTROL_LEARN2ALL; 29*c3a7d4adSVivien Didelot else 30*c3a7d4adSVivien Didelot val &= ~GLOBAL_ATU_CONTROL_LEARN2ALL; 31*c3a7d4adSVivien Didelot 32*c3a7d4adSVivien Didelot return mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL, val); 33*c3a7d4adSVivien Didelot } 34*c3a7d4adSVivien Didelot 35720c6343SVivien Didelot int mv88e6xxx_g1_atu_set_age_time(struct mv88e6xxx_chip *chip, 36720c6343SVivien Didelot unsigned int msecs) 37720c6343SVivien Didelot { 38720c6343SVivien Didelot const unsigned int coeff = chip->info->age_time_coeff; 39720c6343SVivien Didelot const unsigned int min = 0x01 * coeff; 40720c6343SVivien Didelot const unsigned int max = 0xff * coeff; 41720c6343SVivien Didelot u8 age_time; 42720c6343SVivien Didelot u16 val; 43720c6343SVivien Didelot int err; 44720c6343SVivien Didelot 45720c6343SVivien Didelot if (msecs < min || msecs > max) 46720c6343SVivien Didelot return -ERANGE; 47720c6343SVivien Didelot 48720c6343SVivien Didelot /* Round to nearest multiple of coeff */ 49720c6343SVivien Didelot age_time = (msecs + coeff / 2) / coeff; 50720c6343SVivien Didelot 51720c6343SVivien Didelot err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_CONTROL, &val); 52720c6343SVivien Didelot if (err) 53720c6343SVivien Didelot return err; 54720c6343SVivien Didelot 55720c6343SVivien Didelot /* AgeTime is 11:4 bits */ 56720c6343SVivien Didelot val &= ~0xff0; 57720c6343SVivien Didelot val |= age_time << 4; 58720c6343SVivien Didelot 59720c6343SVivien Didelot return mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL, val); 60720c6343SVivien Didelot } 61