Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: sky2: convert to hw_features

Caveats:
- driver modifies vlan_features on HW VLAN TX changes
- broken RX checksum will be reenabled on features change

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Michał Mirosław and committed by
David S. Miller
f5d64037 87267485

+61 -105
+61 -104
drivers/net/sky2.c
··· 1198 1198 1199 1199 sky2_write32(sky2->hw, 1200 1200 Q_ADDR(rxqaddr[sky2->port], Q_CSR), 1201 - (sky2->flags & SKY2_FLAG_RX_CHECKSUM) 1201 + (sky2->netdev->features & NETIF_F_RXCSUM) 1202 1202 ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); 1203 1203 } 1204 1204 1205 1205 /* Enable/disable receive hash calculation (RSS) */ 1206 - static void rx_set_rss(struct net_device *dev) 1206 + static void rx_set_rss(struct net_device *dev, u32 features) 1207 1207 { 1208 1208 struct sky2_port *sky2 = netdev_priv(dev); 1209 1209 struct sky2_hw *hw = sky2->hw; ··· 1216 1216 } 1217 1217 1218 1218 /* Program RSS initial values */ 1219 - if (dev->features & NETIF_F_RXHASH) { 1219 + if (features & NETIF_F_RXHASH) { 1220 1220 u32 key[nkeys]; 1221 1221 1222 1222 get_random_bytes(key, nkeys * sizeof(u32)); ··· 1322 1322 return err; 1323 1323 } 1324 1324 1325 - #define NETIF_F_ALL_VLAN (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX) 1325 + #define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO) 1326 1326 1327 - static void sky2_vlan_mode(struct net_device *dev) 1327 + static void sky2_vlan_mode(struct net_device *dev, u32 features) 1328 1328 { 1329 1329 struct sky2_port *sky2 = netdev_priv(dev); 1330 1330 struct sky2_hw *hw = sky2->hw; 1331 1331 u16 port = sky2->port; 1332 1332 1333 - if (dev->features & NETIF_F_HW_VLAN_RX) 1333 + if (features & NETIF_F_HW_VLAN_RX) 1334 1334 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), 1335 1335 RX_VLAN_STRIP_ON); 1336 1336 else 1337 1337 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), 1338 1338 RX_VLAN_STRIP_OFF); 1339 1339 1340 - dev->vlan_features = dev->features &~ NETIF_F_ALL_VLAN; 1341 - if (dev->features & NETIF_F_HW_VLAN_TX) 1340 + if (features & NETIF_F_HW_VLAN_TX) { 1342 1341 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), 1343 1342 TX_VLAN_TAG_ON); 1344 - else { 1343 + 1344 + dev->vlan_features |= SKY2_VLAN_OFFLOADS; 1345 + } else { 1345 1346 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), 1346 1347 TX_VLAN_TAG_OFF); 1347 1348 1348 1349 /* Can't do transmit offload of vlan without hw vlan */ 1349 - dev->vlan_features &= ~(NETIF_F_TSO | NETIF_F_SG 1350 - | NETIF_F_ALL_CSUM); 1350 + dev->vlan_features &= ~SKY2_VLAN_OFFLOADS; 1351 1351 } 1352 1352 } 1353 1353 ··· 1463 1463 rx_set_checksum(sky2); 1464 1464 1465 1465 if (!(hw->flags & SKY2_HW_RSS_BROKEN)) 1466 - rx_set_rss(sky2->netdev); 1466 + rx_set_rss(sky2->netdev, sky2->netdev->features); 1467 1467 1468 1468 /* submit Rx ring */ 1469 1469 for (i = 0; i < sky2->rx_pending; i++) { ··· 1626 1626 sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, 1627 1627 sky2->tx_ring_size - 1); 1628 1628 1629 - sky2_vlan_mode(sky2->netdev); 1629 + sky2_vlan_mode(sky2->netdev, sky2->netdev->features); 1630 + netdev_update_features(sky2->netdev); 1630 1631 1631 1632 sky2_rx_start(sky2); 1632 1633 } ··· 2262 2261 hw->chip_id == CHIP_ID_YUKON_FE_P)) 2263 2262 return -EINVAL; 2264 2263 2265 - /* TSO, etc on Yukon Ultra and MTU > 1500 not supported */ 2266 - if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) 2267 - dev->features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM); 2268 - 2269 2264 if (!netif_running(dev)) { 2270 2265 dev->mtu = new_mtu; 2266 + netdev_update_features(dev); 2271 2267 return 0; 2272 2268 } 2273 2269 ··· 2286 2288 sky2_rx_clean(sky2); 2287 2289 2288 2290 dev->mtu = new_mtu; 2291 + netdev_update_features(dev); 2289 2292 2290 2293 mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | 2291 2294 GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); ··· 2534 2535 "%s: receive checksum problem (status = %#x)\n", 2535 2536 sky2->netdev->name, status); 2536 2537 2537 - /* Disable checksum offload */ 2538 - sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM; 2538 + /* Disable checksum offload 2539 + * It will be reenabled on next ndo_set_features, but if it's 2540 + * really broken, will get disabled again 2541 + */ 2542 + sky2->netdev->features &= ~NETIF_F_RXCSUM; 2539 2543 sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), 2540 2544 BMU_DIS_RX_CHKSUM); 2541 2545 } ··· 2593 2591 2594 2592 /* This chip reports checksum status differently */ 2595 2593 if (hw->flags & SKY2_HW_NEW_LE) { 2596 - if ((sky2->flags & SKY2_FLAG_RX_CHECKSUM) && 2594 + if ((dev->features & NETIF_F_RXCSUM) && 2597 2595 (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && 2598 2596 (le->css & CSS_TCPUDPCSOK)) 2599 2597 skb->ip_summed = CHECKSUM_UNNECESSARY; ··· 2618 2616 sky2->rx_tag = length; 2619 2617 /* fall through */ 2620 2618 case OP_RXCHKS: 2621 - if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM)) 2619 + if (likely(dev->features & NETIF_F_RXCSUM)) 2622 2620 sky2_rx_checksum(sky2, status); 2623 2621 break; 2624 2622 ··· 3554 3552 { "tx_fifo_underrun", GM_TXE_FIFO_UR }, 3555 3553 }; 3556 3554 3557 - static u32 sky2_get_rx_csum(struct net_device *dev) 3558 - { 3559 - struct sky2_port *sky2 = netdev_priv(dev); 3560 - 3561 - return !!(sky2->flags & SKY2_FLAG_RX_CHECKSUM); 3562 - } 3563 - 3564 - static int sky2_set_rx_csum(struct net_device *dev, u32 data) 3565 - { 3566 - struct sky2_port *sky2 = netdev_priv(dev); 3567 - 3568 - if (data) 3569 - sky2->flags |= SKY2_FLAG_RX_CHECKSUM; 3570 - else 3571 - sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM; 3572 - 3573 - sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), 3574 - data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); 3575 - 3576 - return 0; 3577 - } 3578 - 3579 3555 static u32 sky2_get_msglevel(struct net_device *netdev) 3580 3556 { 3581 3557 struct sky2_port *sky2 = netdev_priv(netdev); ··· 4064 4084 } 4065 4085 } 4066 4086 4067 - /* In order to do Jumbo packets on these chips, need to turn off the 4068 - * transmit store/forward. Therefore checksum offload won't work. 4069 - */ 4070 - static int no_tx_offload(struct net_device *dev) 4071 - { 4072 - const struct sky2_port *sky2 = netdev_priv(dev); 4073 - const struct sky2_hw *hw = sky2->hw; 4074 - 4075 - return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U; 4076 - } 4077 - 4078 - static int sky2_set_tx_csum(struct net_device *dev, u32 data) 4079 - { 4080 - if (data && no_tx_offload(dev)) 4081 - return -EINVAL; 4082 - 4083 - return ethtool_op_set_tx_csum(dev, data); 4084 - } 4085 - 4086 - 4087 - static int sky2_set_tso(struct net_device *dev, u32 data) 4088 - { 4089 - if (data && no_tx_offload(dev)) 4090 - return -EINVAL; 4091 - 4092 - return ethtool_op_set_tso(dev, data); 4093 - } 4094 - 4095 4087 static int sky2_get_eeprom_len(struct net_device *dev) 4096 4088 { 4097 4089 struct sky2_port *sky2 = netdev_priv(dev); ··· 4166 4214 return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); 4167 4215 } 4168 4216 4169 - static int sky2_set_flags(struct net_device *dev, u32 data) 4217 + static u32 sky2_fix_features(struct net_device *dev, u32 features) 4218 + { 4219 + const struct sky2_port *sky2 = netdev_priv(dev); 4220 + const struct sky2_hw *hw = sky2->hw; 4221 + 4222 + /* In order to do Jumbo packets on these chips, need to turn off the 4223 + * transmit store/forward. Therefore checksum offload won't work. 4224 + */ 4225 + if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) 4226 + features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM); 4227 + 4228 + return features; 4229 + } 4230 + 4231 + static int sky2_set_features(struct net_device *dev, u32 features) 4170 4232 { 4171 4233 struct sky2_port *sky2 = netdev_priv(dev); 4172 - unsigned long old_feat = dev->features; 4173 - u32 supported = 0; 4174 - int rc; 4234 + u32 changed = dev->features ^ features; 4175 4235 4176 - if (!(sky2->hw->flags & SKY2_HW_RSS_BROKEN)) 4177 - supported |= ETH_FLAG_RXHASH; 4236 + if (changed & NETIF_F_RXCSUM) { 4237 + u32 on = features & NETIF_F_RXCSUM; 4238 + sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), 4239 + on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); 4240 + } 4178 4241 4179 - if (!(sky2->hw->flags & SKY2_HW_VLAN_BROKEN)) 4180 - supported |= ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN; 4242 + if (changed & NETIF_F_RXHASH) 4243 + rx_set_rss(dev, features); 4181 4244 4182 - printk(KERN_DEBUG "sky2 set_flags: supported %x data %x\n", 4183 - supported, data); 4184 - 4185 - rc = ethtool_op_set_flags(dev, data, supported); 4186 - if (rc) 4187 - return rc; 4188 - 4189 - if ((old_feat ^ dev->features) & NETIF_F_RXHASH) 4190 - rx_set_rss(dev); 4191 - 4192 - if ((old_feat ^ dev->features) & NETIF_F_ALL_VLAN) 4193 - sky2_vlan_mode(dev); 4245 + if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) 4246 + sky2_vlan_mode(dev, features); 4194 4247 4195 4248 return 0; 4196 4249 } ··· 4215 4258 .get_eeprom_len = sky2_get_eeprom_len, 4216 4259 .get_eeprom = sky2_get_eeprom, 4217 4260 .set_eeprom = sky2_set_eeprom, 4218 - .set_sg = ethtool_op_set_sg, 4219 - .set_tx_csum = sky2_set_tx_csum, 4220 - .set_tso = sky2_set_tso, 4221 - .get_rx_csum = sky2_get_rx_csum, 4222 - .set_rx_csum = sky2_set_rx_csum, 4223 4261 .get_strings = sky2_get_strings, 4224 4262 .get_coalesce = sky2_get_coalesce, 4225 4263 .set_coalesce = sky2_set_coalesce, ··· 4225 4273 .set_phys_id = sky2_set_phys_id, 4226 4274 .get_sset_count = sky2_get_sset_count, 4227 4275 .get_ethtool_stats = sky2_get_ethtool_stats, 4228 - .set_flags = sky2_set_flags, 4229 - .get_flags = ethtool_op_get_flags, 4230 4276 }; 4231 4277 4232 4278 #ifdef CONFIG_SKY2_DEBUG ··· 4504 4554 .ndo_set_mac_address = sky2_set_mac_address, 4505 4555 .ndo_set_multicast_list = sky2_set_multicast, 4506 4556 .ndo_change_mtu = sky2_change_mtu, 4557 + .ndo_fix_features = sky2_fix_features, 4558 + .ndo_set_features = sky2_set_features, 4507 4559 .ndo_tx_timeout = sky2_tx_timeout, 4508 4560 .ndo_get_stats64 = sky2_get_stats, 4509 4561 #ifdef CONFIG_NET_POLL_CONTROLLER ··· 4521 4569 .ndo_set_mac_address = sky2_set_mac_address, 4522 4570 .ndo_set_multicast_list = sky2_set_multicast, 4523 4571 .ndo_change_mtu = sky2_change_mtu, 4572 + .ndo_fix_features = sky2_fix_features, 4573 + .ndo_set_features = sky2_set_features, 4524 4574 .ndo_tx_timeout = sky2_tx_timeout, 4525 4575 .ndo_get_stats64 = sky2_get_stats, 4526 4576 }, ··· 4555 4601 /* Auto speed and flow control */ 4556 4602 sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE; 4557 4603 if (hw->chip_id != CHIP_ID_YUKON_XL) 4558 - sky2->flags |= SKY2_FLAG_RX_CHECKSUM; 4604 + dev->hw_features |= NETIF_F_RXCSUM; 4559 4605 4560 4606 sky2->flow_mode = FC_BOTH; 4561 4607 ··· 4574 4620 4575 4621 sky2->port = port; 4576 4622 4577 - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG 4578 - | NETIF_F_TSO | NETIF_F_GRO; 4623 + dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO; 4579 4624 4580 4625 if (highmem) 4581 4626 dev->features |= NETIF_F_HIGHDMA; 4582 4627 4583 4628 /* Enable receive hashing unless hardware is known broken */ 4584 4629 if (!(hw->flags & SKY2_HW_RSS_BROKEN)) 4585 - dev->features |= NETIF_F_RXHASH; 4630 + dev->hw_features |= NETIF_F_RXHASH; 4586 4631 4587 - if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) 4588 - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; 4632 + if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) { 4633 + dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; 4634 + dev->vlan_features |= SKY2_VLAN_OFFLOADS; 4635 + } 4636 + 4637 + dev->features |= dev->hw_features; 4589 4638 4590 4639 /* read the mac address */ 4591 4640 memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
-1
drivers/net/sky2.h
··· 2254 2254 u8 wol; /* WAKE_ bits */ 2255 2255 u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ 2256 2256 u16 flags; 2257 - #define SKY2_FLAG_RX_CHECKSUM 0x0001 2258 2257 #define SKY2_FLAG_AUTO_SPEED 0x0002 2259 2258 #define SKY2_FLAG_AUTO_PAUSE 0x0004 2260 2259