1afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings/**************************************************************************** 2afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings * Driver for Solarflare Solarstorm network controllers and boards 30a6f40c66ba388e6349a11bea146955716c4d492Ben Hutchings * Copyright 2009-2010 Solarflare Communications Inc. 4afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings * 5afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings * This program is free software; you can redistribute it and/or modify it 6afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings * under the terms of the GNU General Public License version 2 as published 7afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings * by the Free Software Foundation, incorporated herein by reference. 8afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings */ 9afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 10afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings#include "net_driver.h" 11afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings#include "efx.h" 12afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings#include "mcdi.h" 13afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings#include "mcdi_pcol.h" 14afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 15cd2d5b529cdb9bd274f3e4bc68d37d4d63b7f383Ben Hutchingsint efx_mcdi_set_mac(struct efx_nic *efx) 16afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings{ 17afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings u32 reject, fcntl; 18afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings u8 cmdbytes[MC_CMD_SET_MAC_IN_LEN]; 19afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 20afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings memcpy(cmdbytes + MC_CMD_SET_MAC_IN_ADDR_OFST, 21afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings efx->net_dev->dev_addr, ETH_ALEN); 22afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 23afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU, 24afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings EFX_MAX_FRAME_LEN(efx->net_dev->mtu)); 25afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_DRAIN, 0); 26afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 27afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings /* The MCDI command provides for controlling accept/reject 28afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings * of broadcast packets too, but the driver doesn't currently 29afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings * expose this. */ 30afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings reject = (efx->promiscuous) ? 0 : 31afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings (1 << MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN); 32afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_REJECT, reject); 33afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 34afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings switch (efx->wanted_fc) { 35afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings case EFX_FC_RX | EFX_FC_TX: 36afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings fcntl = MC_CMD_FCNTL_BIDIR; 37afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings break; 38afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings case EFX_FC_RX: 39afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings fcntl = MC_CMD_FCNTL_RESPOND; 40afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings break; 41afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings default: 42afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings fcntl = MC_CMD_FCNTL_OFF; 43afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings break; 44afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings } 45afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings if (efx->wanted_fc & EFX_FC_AUTO) 46afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings fcntl = MC_CMD_FCNTL_AUTO; 47a606f4325dca6950996abbae452d33f2af095f39Steve Hodgson if (efx->fc_disable) 48a606f4325dca6950996abbae452d33f2af095f39Steve Hodgson fcntl = MC_CMD_FCNTL_OFF; 49afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 50afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl); 51afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 52afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, cmdbytes, sizeof(cmdbytes), 53afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings NULL, 0, NULL); 54afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings} 55afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 561daf417029ddc10b7854430c1e1118df791d0eafBen Hutchingsbool efx_mcdi_mac_check_fault(struct efx_nic *efx) 57afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings{ 58afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings u8 outbuf[MC_CMD_GET_LINK_OUT_LEN]; 59afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings size_t outlength; 60afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings int rc; 61afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 62afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); 63afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 64afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, 65afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings outbuf, sizeof(outbuf), &outlength); 661daf417029ddc10b7854430c1e1118df791d0eafBen Hutchings if (rc) { 671daf417029ddc10b7854430c1e1118df791d0eafBen Hutchings netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", 681daf417029ddc10b7854430c1e1118df791d0eafBen Hutchings __func__, rc); 691daf417029ddc10b7854430c1e1118df791d0eafBen Hutchings return true; 701daf417029ddc10b7854430c1e1118df791d0eafBen Hutchings } 71afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 721daf417029ddc10b7854430c1e1118df791d0eafBen Hutchings return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0; 73afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings} 74afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 75afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchingsint efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, 76afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings u32 dma_len, int enable, int clear) 77afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings{ 78afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings u8 inbuf[MC_CMD_MAC_STATS_IN_LEN]; 79afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings int rc; 80afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings efx_dword_t *cmd_ptr; 813a595102d4298a357d70aaf1d47ae86d92708ea9Steve Hodgson int period = enable ? 1000 : 0; 82afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings u32 addr_hi; 83afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings u32 addr_lo; 84afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 8505a9320f7e64b69cbf612a69b7358546519ffc30Ben Hutchings BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0); 86afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 87afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings addr_lo = ((u64)dma_addr) >> 0; 88afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings addr_hi = ((u64)dma_addr) >> 32; 89afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 90afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_ADDR_LO, addr_lo); 91afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_ADDR_HI, addr_hi); 92afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings cmd_ptr = (efx_dword_t *)MCDI_PTR(inbuf, MAC_STATS_IN_CMD); 933a595102d4298a357d70aaf1d47ae86d92708ea9Steve Hodgson EFX_POPULATE_DWORD_7(*cmd_ptr, 9405a9320f7e64b69cbf612a69b7358546519ffc30Ben Hutchings MC_CMD_MAC_STATS_IN_DMA, !!enable, 9505a9320f7e64b69cbf612a69b7358546519ffc30Ben Hutchings MC_CMD_MAC_STATS_IN_CLEAR, clear, 9605a9320f7e64b69cbf612a69b7358546519ffc30Ben Hutchings MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE, 1, 9705a9320f7e64b69cbf612a69b7358546519ffc30Ben Hutchings MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE, !!enable, 9805a9320f7e64b69cbf612a69b7358546519ffc30Ben Hutchings MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR, 0, 9905a9320f7e64b69cbf612a69b7358546519ffc30Ben Hutchings MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT, 1, 10005a9320f7e64b69cbf612a69b7358546519ffc30Ben Hutchings MC_CMD_MAC_STATS_IN_PERIOD_MS, period); 101afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len); 102afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 103afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf), 104afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings NULL, 0, NULL); 105afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings if (rc) 106afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings goto fail; 107afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 108afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings return 0; 109afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 110afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchingsfail: 11162776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings netif_err(efx, hw, efx->net_dev, "%s: %s failed rc=%d\n", 11262776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings __func__, enable ? "enable" : "disable", rc); 113afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings return rc; 114afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings} 115afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 116710b208dc2687fdb3370110d54a67fb2288835ebBen Hutchingsint efx_mcdi_mac_reconfigure(struct efx_nic *efx) 117afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings{ 118afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings int rc; 119afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 12030b81cda9516878906b44fed16aac9df1dbb89c7Ben Hutchings WARN_ON(!mutex_is_locked(&efx->mac_lock)); 12130b81cda9516878906b44fed16aac9df1dbb89c7Ben Hutchings 122afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings rc = efx_mcdi_set_mac(efx); 123afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings if (rc != 0) 124afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings return rc; 125afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings 12630b81cda9516878906b44fed16aac9df1dbb89c7Ben Hutchings return efx_mcdi_rpc(efx, MC_CMD_SET_MCAST_HASH, 12730b81cda9516878906b44fed16aac9df1dbb89c7Ben Hutchings efx->multicast_hash.byte, 12830b81cda9516878906b44fed16aac9df1dbb89c7Ben Hutchings sizeof(efx->multicast_hash), 12930b81cda9516878906b44fed16aac9df1dbb89c7Ben Hutchings NULL, 0, NULL); 130afd4aea03f597f29421dc5767e7d1f754730ec23Ben Hutchings} 131