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

Configure Feed

Select the types of activity you want to include in your feed.

at v3.0-rc7 145 lines 3.8 kB view raw
1/**************************************************************************** 2 * Driver for Solarflare Solarstorm network controllers and boards 3 * Copyright 2009-2010 Solarflare Communications Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published 7 * by the Free Software Foundation, incorporated herein by reference. 8 */ 9 10#include "net_driver.h" 11#include "efx.h" 12#include "mac.h" 13#include "mcdi.h" 14#include "mcdi_pcol.h" 15 16static int efx_mcdi_set_mac(struct efx_nic *efx) 17{ 18 u32 reject, fcntl; 19 u8 cmdbytes[MC_CMD_SET_MAC_IN_LEN]; 20 21 memcpy(cmdbytes + MC_CMD_SET_MAC_IN_ADDR_OFST, 22 efx->net_dev->dev_addr, ETH_ALEN); 23 24 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU, 25 EFX_MAX_FRAME_LEN(efx->net_dev->mtu)); 26 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_DRAIN, 0); 27 28 /* The MCDI command provides for controlling accept/reject 29 * of broadcast packets too, but the driver doesn't currently 30 * expose this. */ 31 reject = (efx->promiscuous) ? 0 : 32 (1 << MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN); 33 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_REJECT, reject); 34 35 switch (efx->wanted_fc) { 36 case EFX_FC_RX | EFX_FC_TX: 37 fcntl = MC_CMD_FCNTL_BIDIR; 38 break; 39 case EFX_FC_RX: 40 fcntl = MC_CMD_FCNTL_RESPOND; 41 break; 42 default: 43 fcntl = MC_CMD_FCNTL_OFF; 44 break; 45 } 46 if (efx->wanted_fc & EFX_FC_AUTO) 47 fcntl = MC_CMD_FCNTL_AUTO; 48 49 MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl); 50 51 return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, cmdbytes, sizeof(cmdbytes), 52 NULL, 0, NULL); 53} 54 55static int efx_mcdi_get_mac_faults(struct efx_nic *efx, u32 *faults) 56{ 57 u8 outbuf[MC_CMD_GET_LINK_OUT_LEN]; 58 size_t outlength; 59 int rc; 60 61 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); 62 63 rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, 64 outbuf, sizeof(outbuf), &outlength); 65 if (rc) 66 goto fail; 67 68 *faults = MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT); 69 return 0; 70 71fail: 72 netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", 73 __func__, rc); 74 return rc; 75} 76 77int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, 78 u32 dma_len, int enable, int clear) 79{ 80 u8 inbuf[MC_CMD_MAC_STATS_IN_LEN]; 81 int rc; 82 efx_dword_t *cmd_ptr; 83 int period = enable ? 1000 : 0; 84 u32 addr_hi; 85 u32 addr_lo; 86 87 BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_LEN != 0); 88 89 addr_lo = ((u64)dma_addr) >> 0; 90 addr_hi = ((u64)dma_addr) >> 32; 91 92 MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_ADDR_LO, addr_lo); 93 MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_ADDR_HI, addr_hi); 94 cmd_ptr = (efx_dword_t *)MCDI_PTR(inbuf, MAC_STATS_IN_CMD); 95 EFX_POPULATE_DWORD_7(*cmd_ptr, 96 MC_CMD_MAC_STATS_CMD_DMA, !!enable, 97 MC_CMD_MAC_STATS_CMD_CLEAR, clear, 98 MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE, 1, 99 MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE, !!enable, 100 MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR, 0, 101 MC_CMD_MAC_STATS_CMD_PERIODIC_NOEVENT, 1, 102 MC_CMD_MAC_STATS_CMD_PERIOD_MS, period); 103 MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len); 104 105 rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf), 106 NULL, 0, NULL); 107 if (rc) 108 goto fail; 109 110 return 0; 111 112fail: 113 netif_err(efx, hw, efx->net_dev, "%s: %s failed rc=%d\n", 114 __func__, enable ? "enable" : "disable", rc); 115 return rc; 116} 117 118static int efx_mcdi_mac_reconfigure(struct efx_nic *efx) 119{ 120 int rc; 121 122 rc = efx_mcdi_set_mac(efx); 123 if (rc != 0) 124 return rc; 125 126 /* Restore the multicast hash registers. */ 127 efx->type->push_multicast_hash(efx); 128 129 return 0; 130} 131 132 133static bool efx_mcdi_mac_check_fault(struct efx_nic *efx) 134{ 135 u32 faults; 136 int rc = efx_mcdi_get_mac_faults(efx, &faults); 137 return (rc != 0) || (faults != 0); 138} 139 140 141const struct efx_mac_operations efx_mcdi_mac_operations = { 142 .reconfigure = efx_mcdi_mac_reconfigure, 143 .update_stats = efx_port_dummy_op_void, 144 .check_fault = efx_mcdi_mac_check_fault, 145};