aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/myri10ge/myri10ge.c
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2008-05-08 20:21:10 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-30 22:11:46 -0400
commit779297320d192655c2f95a870c12e9b307612429 (patch)
tree6fbd2355900d21cb0852109e49890739286a4630 /drivers/net/myri10ge/myri10ge.c
parenta5b17df04c4ad8f25fc598fce37fccb4b387c94c (diff)
myri10ge: add routines for multislices
Add several routines that multislices support will use. Signed-off-by: Brice Goglin <brice@myri.com> Signed-off-by: Andrew Gallatin <gallatin@myri.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/myri10ge/myri10ge.c')
-rw-r--r--drivers/net/myri10ge/myri10ge.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 36be6efc6398..f3ef9e3c48cd 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1928,6 +1928,76 @@ myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
1928 return 0; 1928 return 0;
1929} 1929}
1930 1930
1931#if 0
1932static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice)
1933{
1934 struct myri10ge_cmd cmd;
1935 struct myri10ge_slice_state *ss;
1936 int status;
1937
1938 ss = &mgp->ss[slice];
1939 cmd.data0 = 0; /* single slice for now */
1940 status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0);
1941 ss->tx.lanai = (struct mcp_kreq_ether_send __iomem *)
1942 (mgp->sram + cmd.data0);
1943
1944 cmd.data0 = slice;
1945 status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET,
1946 &cmd, 0);
1947 ss->rx_small.lanai = (struct mcp_kreq_ether_recv __iomem *)
1948 (mgp->sram + cmd.data0);
1949
1950 cmd.data0 = slice;
1951 status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd, 0);
1952 ss->rx_big.lanai = (struct mcp_kreq_ether_recv __iomem *)
1953 (mgp->sram + cmd.data0);
1954
1955 if (myri10ge_wcfifo && mgp->wc_enabled) {
1956 ss->tx.wc_fifo = (u8 __iomem *)
1957 mgp->sram + MXGEFW_ETH_SEND_4 + 64 * slice;
1958 ss->rx_small.wc_fifo = (u8 __iomem *)
1959 mgp->sram + MXGEFW_ETH_RECV_SMALL + 64 * slice;
1960 ss->rx_big.wc_fifo = (u8 __iomem *)
1961 mgp->sram + MXGEFW_ETH_RECV_BIG + 64 * slice;
1962 } else {
1963 ss->tx.wc_fifo = NULL;
1964 ss->rx_small.wc_fifo = NULL;
1965 ss->rx_big.wc_fifo = NULL;
1966 }
1967 return status;
1968
1969}
1970
1971static int myri10ge_set_stats(struct myri10ge_priv *mgp, int slice)
1972{
1973 struct myri10ge_cmd cmd;
1974 struct myri10ge_slice_state *ss;
1975 int status;
1976
1977 ss = &mgp->ss[slice];
1978 cmd.data0 = MYRI10GE_LOWPART_TO_U32(ss->fw_stats_bus);
1979 cmd.data1 = MYRI10GE_HIGHPART_TO_U32(ss->fw_stats_bus);
1980 cmd.data2 = sizeof(struct mcp_irq_data);
1981 status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0);
1982 if (status == -ENOSYS) {
1983 dma_addr_t bus = ss->fw_stats_bus;
1984 if (slice != 0)
1985 return -EINVAL;
1986 bus += offsetof(struct mcp_irq_data, send_done_count);
1987 cmd.data0 = MYRI10GE_LOWPART_TO_U32(bus);
1988 cmd.data1 = MYRI10GE_HIGHPART_TO_U32(bus);
1989 status = myri10ge_send_cmd(mgp,
1990 MXGEFW_CMD_SET_STATS_DMA_OBSOLETE,
1991 &cmd, 0);
1992 /* Firmware cannot support multicast without STATS_DMA_V2 */
1993 mgp->fw_multicast_support = 0;
1994 } else {
1995 mgp->fw_multicast_support = 1;
1996 }
1997 return 0;
1998}
1999#endif
2000
1931static int myri10ge_open(struct net_device *dev) 2001static int myri10ge_open(struct net_device *dev)
1932{ 2002{
1933 struct myri10ge_priv *mgp = netdev_priv(dev); 2003 struct myri10ge_priv *mgp = netdev_priv(dev);
@@ -3106,6 +3176,192 @@ static void myri10ge_watchdog_timer(unsigned long arg)
3106 mgp->watchdog_pause = rx_pause_cnt; 3176 mgp->watchdog_pause = rx_pause_cnt;
3107} 3177}
3108 3178
3179#if 0
3180static void myri10ge_free_slices(struct myri10ge_priv *mgp)
3181{
3182 struct myri10ge_slice_state *ss;
3183 struct pci_dev *pdev = mgp->pdev;
3184 size_t bytes;
3185 int i;
3186
3187 if (mgp->ss == NULL)
3188 return;
3189
3190 for (i = 0; i < mgp->num_slices; i++) {
3191 ss = &mgp->ss[i];
3192 if (ss->rx_done.entry != NULL) {
3193 bytes = mgp->max_intr_slots *
3194 sizeof(*ss->rx_done.entry);
3195 dma_free_coherent(&pdev->dev, bytes,
3196 ss->rx_done.entry, ss->rx_done.bus);
3197 ss->rx_done.entry = NULL;
3198 }
3199 if (ss->fw_stats != NULL) {
3200 bytes = sizeof(*ss->fw_stats);
3201 dma_free_coherent(&pdev->dev, bytes,
3202 ss->fw_stats, ss->fw_stats_bus);
3203 ss->fw_stats = NULL;
3204 }
3205 }
3206 kfree(mgp->ss);
3207 mgp->ss = NULL;
3208}
3209
3210static int myri10ge_alloc_slices(struct myri10ge_priv *mgp)
3211{
3212 struct myri10ge_slice_state *ss;
3213 struct pci_dev *pdev = mgp->pdev;
3214 size_t bytes;
3215 int i;
3216
3217 bytes = sizeof(*mgp->ss) * mgp->num_slices;
3218 mgp->ss = kzalloc(bytes, GFP_KERNEL);
3219 if (mgp->ss == NULL) {
3220 return -ENOMEM;
3221 }
3222
3223 for (i = 0; i < mgp->num_slices; i++) {
3224 ss = &mgp->ss[i];
3225 bytes = mgp->max_intr_slots * sizeof(*ss->rx_done.entry);
3226 ss->rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes,
3227 &ss->rx_done.bus,
3228 GFP_KERNEL);
3229 if (ss->rx_done.entry == NULL)
3230 goto abort;
3231 memset(ss->rx_done.entry, 0, bytes);
3232 bytes = sizeof(*ss->fw_stats);
3233 ss->fw_stats = dma_alloc_coherent(&pdev->dev, bytes,
3234 &ss->fw_stats_bus,
3235 GFP_KERNEL);
3236 if (ss->fw_stats == NULL)
3237 goto abort;
3238 ss->mgp = mgp;
3239 ss->dev = mgp->dev;
3240 netif_napi_add(ss->dev, &ss->napi, myri10ge_poll,
3241 myri10ge_napi_weight);
3242 }
3243 return 0;
3244abort:
3245 myri10ge_free_slices(mgp);
3246 return -ENOMEM;
3247}
3248
3249/*
3250 * This function determines the number of slices supported.
3251 * The number slices is the minumum of the number of CPUS,
3252 * the number of MSI-X irqs supported, the number of slices
3253 * supported by the firmware
3254 */
3255static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
3256{
3257 struct myri10ge_cmd cmd;
3258 struct pci_dev *pdev = mgp->pdev;
3259 char *old_fw;
3260 int i, status, ncpus, msix_cap;
3261
3262 mgp->num_slices = 1;
3263 msix_cap = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
3264 ncpus = num_online_cpus();
3265
3266 if (myri10ge_max_slices == 1 || msix_cap == 0 ||
3267 (myri10ge_max_slices == -1 && ncpus < 2))
3268 return;
3269
3270 /* try to load the slice aware rss firmware */
3271 old_fw = mgp->fw_name;
3272 if (old_fw == myri10ge_fw_aligned)
3273 mgp->fw_name = myri10ge_fw_rss_aligned;
3274 else
3275 mgp->fw_name = myri10ge_fw_rss_unaligned;
3276 status = myri10ge_load_firmware(mgp, 0);
3277 if (status != 0) {
3278 dev_info(&pdev->dev, "Rss firmware not found\n");
3279 return;
3280 }
3281
3282 /* hit the board with a reset to ensure it is alive */
3283 memset(&cmd, 0, sizeof(cmd));
3284 status = myri10ge_send_cmd(mgp, MXGEFW_CMD_RESET, &cmd, 0);
3285 if (status != 0) {
3286 dev_err(&mgp->pdev->dev, "failed reset\n");
3287 goto abort_with_fw;
3288 return;
3289 }
3290
3291 mgp->max_intr_slots = cmd.data0 / sizeof(struct mcp_slot);
3292
3293 /* tell it the size of the interrupt queues */
3294 cmd.data0 = mgp->max_intr_slots * sizeof(struct mcp_slot);
3295 status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd, 0);
3296 if (status != 0) {
3297 dev_err(&mgp->pdev->dev, "failed MXGEFW_CMD_SET_INTRQ_SIZE\n");
3298 goto abort_with_fw;
3299 }
3300
3301 /* ask the maximum number of slices it supports */
3302 status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_RSS_QUEUES, &cmd, 0);
3303 if (status != 0)
3304 goto abort_with_fw;
3305 else
3306 mgp->num_slices = cmd.data0;
3307
3308 /* Only allow multiple slices if MSI-X is usable */
3309 if (!myri10ge_msi) {
3310 goto abort_with_fw;
3311 }
3312
3313 /* if the admin did not specify a limit to how many
3314 * slices we should use, cap it automatically to the
3315 * number of CPUs currently online */
3316 if (myri10ge_max_slices == -1)
3317 myri10ge_max_slices = ncpus;
3318
3319 if (mgp->num_slices > myri10ge_max_slices)
3320 mgp->num_slices = myri10ge_max_slices;
3321
3322 /* Now try to allocate as many MSI-X vectors as we have
3323 * slices. We give up on MSI-X if we can only get a single
3324 * vector. */
3325
3326 mgp->msix_vectors = kzalloc(mgp->num_slices *
3327 sizeof(*mgp->msix_vectors), GFP_KERNEL);
3328 if (mgp->msix_vectors == NULL)
3329 goto disable_msix;
3330 for (i = 0; i < mgp->num_slices; i++) {
3331 mgp->msix_vectors[i].entry = i;
3332 }
3333
3334 while (mgp->num_slices > 1) {
3335 /* make sure it is a power of two */
3336 while (!is_power_of_2(mgp->num_slices))
3337 mgp->num_slices--;
3338 if (mgp->num_slices == 1)
3339 goto disable_msix;
3340 status = pci_enable_msix(pdev, mgp->msix_vectors,
3341 mgp->num_slices);
3342 if (status == 0) {
3343 pci_disable_msix(pdev);
3344 return;
3345 }
3346 if (status > 0)
3347 mgp->num_slices = status;
3348 else
3349 goto disable_msix;
3350 }
3351
3352disable_msix:
3353 if (mgp->msix_vectors != NULL) {
3354 kfree(mgp->msix_vectors);
3355 mgp->msix_vectors = NULL;
3356 }
3357
3358abort_with_fw:
3359 mgp->num_slices = 1;
3360 mgp->fw_name = old_fw;
3361 myri10ge_load_firmware(mgp, 0);
3362}
3363#endif
3364
3109static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3365static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3110{ 3366{
3111 struct net_device *netdev; 3367 struct net_device *netdev;