aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/atheros/atl1e
diff options
context:
space:
mode:
authorAndrea Merello <andrea.merello@gmail.com>2013-10-03 15:18:37 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-03 17:01:12 -0400
commit40dc9ab277eb3d2d3d3442c20accb5dfa577e680 (patch)
tree0b727a07d6743e755458822283d45b8c4f4260fb /drivers/net/ethernet/atheros/atl1e
parent1d3d59108e53ce9815651ee20633506d559bacf6 (diff)
atl1e: enable support for NETIF_F_RXALL and NETIF_F_RXCRC features
This patch allows (optionally, via ethtool) the atl1e NIC to: - Receive bad frames (runt, bad-fcs, etc..) - Receive full frames without stripping the FCS. This has been tested on my board by injecting runt and bad-fcs frames with a FPGA-based device. The particular scenario of receiving very short frames (<4 bytes) without passing FCS to the upper layer has been also tested: This could be potentially dangerous because the driver performs a 4 byte subtraction on the frame length, but I finally have NOT added anything to avoid this because it seems the NIC always discards frames so much short.. If someone still have some reason to worry about this, please tell me.. I will add an explicit SW check.. Signed-off-by: Andrea Merello <andrea.merello@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros/atl1e')
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e_main.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index 1966444590f6..7a73f3a9fcb5 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -313,6 +313,34 @@ static void atl1e_set_multi(struct net_device *netdev)
313 } 313 }
314} 314}
315 315
316static void __atl1e_rx_mode(netdev_features_t features, u32 *mac_ctrl_data)
317{
318
319 if (features & NETIF_F_RXALL) {
320 /* enable RX of ALL frames */
321 *mac_ctrl_data |= MAC_CTRL_DBG;
322 } else {
323 /* disable RX of ALL frames */
324 *mac_ctrl_data &= ~MAC_CTRL_DBG;
325 }
326}
327
328static void atl1e_rx_mode(struct net_device *netdev,
329 netdev_features_t features)
330{
331 struct atl1e_adapter *adapter = netdev_priv(netdev);
332 u32 mac_ctrl_data = 0;
333
334 netdev_dbg(adapter->netdev, "%s\n", __func__);
335
336 atl1e_irq_disable(adapter);
337 mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL);
338 __atl1e_rx_mode(features, &mac_ctrl_data);
339 AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
340 atl1e_irq_enable(adapter);
341}
342
343
316static void __atl1e_vlan_mode(netdev_features_t features, u32 *mac_ctrl_data) 344static void __atl1e_vlan_mode(netdev_features_t features, u32 *mac_ctrl_data)
317{ 345{
318 if (features & NETIF_F_HW_VLAN_CTAG_RX) { 346 if (features & NETIF_F_HW_VLAN_CTAG_RX) {
@@ -394,6 +422,10 @@ static int atl1e_set_features(struct net_device *netdev,
394 if (changed & NETIF_F_HW_VLAN_CTAG_RX) 422 if (changed & NETIF_F_HW_VLAN_CTAG_RX)
395 atl1e_vlan_mode(netdev, features); 423 atl1e_vlan_mode(netdev, features);
396 424
425 if (changed & NETIF_F_RXALL)
426 atl1e_rx_mode(netdev, features);
427
428
397 return 0; 429 return 0;
398} 430}
399 431
@@ -1057,7 +1089,8 @@ static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
1057 value |= MAC_CTRL_PROMIS_EN; 1089 value |= MAC_CTRL_PROMIS_EN;
1058 if (netdev->flags & IFF_ALLMULTI) 1090 if (netdev->flags & IFF_ALLMULTI)
1059 value |= MAC_CTRL_MC_ALL_EN; 1091 value |= MAC_CTRL_MC_ALL_EN;
1060 1092 if (netdev->features & NETIF_F_RXALL)
1093 value |= MAC_CTRL_DBG;
1061 AT_WRITE_REG(hw, REG_MAC_CTRL, value); 1094 AT_WRITE_REG(hw, REG_MAC_CTRL, value);
1062} 1095}
1063 1096
@@ -1405,7 +1438,8 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
1405 rx_page_desc[que].rx_nxseq++; 1438 rx_page_desc[que].rx_nxseq++;
1406 1439
1407 /* error packet */ 1440 /* error packet */
1408 if (prrs->pkt_flag & RRS_IS_ERR_FRAME) { 1441 if ((prrs->pkt_flag & RRS_IS_ERR_FRAME) &&
1442 !(netdev->features & NETIF_F_RXALL)) {
1409 if (prrs->err_flag & (RRS_ERR_BAD_CRC | 1443 if (prrs->err_flag & (RRS_ERR_BAD_CRC |
1410 RRS_ERR_DRIBBLE | RRS_ERR_CODE | 1444 RRS_ERR_DRIBBLE | RRS_ERR_CODE |
1411 RRS_ERR_TRUNC)) { 1445 RRS_ERR_TRUNC)) {
@@ -1418,7 +1452,10 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
1418 } 1452 }
1419 1453
1420 packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) & 1454 packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
1421 RRS_PKT_SIZE_MASK) - 4; /* CRC */ 1455 RRS_PKT_SIZE_MASK);
1456 if (likely(!(netdev->features & NETIF_F_RXFCS)))
1457 packet_size -= 4; /* CRC */
1458
1422 skb = netdev_alloc_skb_ip_align(netdev, packet_size); 1459 skb = netdev_alloc_skb_ip_align(netdev, packet_size);
1423 if (skb == NULL) 1460 if (skb == NULL)
1424 goto skip_pkt; 1461 goto skip_pkt;
@@ -2245,7 +2282,8 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
2245 NETIF_F_HW_VLAN_CTAG_RX; 2282 NETIF_F_HW_VLAN_CTAG_RX;
2246 netdev->features = netdev->hw_features | NETIF_F_LLTX | 2283 netdev->features = netdev->hw_features | NETIF_F_LLTX |
2247 NETIF_F_HW_VLAN_CTAG_TX; 2284 NETIF_F_HW_VLAN_CTAG_TX;
2248 2285 /* not enabled by default */
2286 netdev->hw_features |= NETIF_F_RXALL | NETIF_F_RXFCS;
2249 return 0; 2287 return 0;
2250} 2288}
2251 2289